Cloned SEACAS for EXODUS library with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

257 lines
9.1 KiB

# @HEADER
# ************************************************************************
#
# TriBITS: Tribal Build, Integrate, and Test System
# Copyright 2013 Sandia Corporation
#
# Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
# the U.S. Government retains certain rights in this software.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the Corporation nor the names of the
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# ************************************************************************
# @HEADER
include(TribitsDeprecatedHelpers)
macro(parse_arguments_deprecated_warning)
tribits_deprecated_command(parse_arguments
MESSAGE "Use cmake_parse_arguments() instead.")
endmacro()
parse_arguments_deprecated_warning()
# Set PARSE_ARGUMENTS_DUMP_OUTPUT_ENABLED to TRUE to see output from parsing.
function(parse_arguments_dump_output OUTPUT_STR)
if (PARSE_ARGUMENTS_DUMP_OUTPUT_ENABLED)
message("${OUTPUT_STR}")
endif()
endfunction()
# @MACRO: parse_arguments()
#
# Parse a set of macro/function input arguments into different lists. This
# allows the easy implementation of keyword-based user-defined macros and
# functions.
#
# Usage::
#
# parse_arguments(
# <prefix> <argNamesList> <optionNamesList>
# <inputArgsList>
# )
#
# Arguments to this macro are:
#
# ``<prefix>``
#
# Prefix ``<prefix>_`` added the list and option variables created listed
# in ``<argNamesList>`` and ``<optionNamesList>``.
#
# ``<argNamesList>``
#
# Quoted array of list arguments (e.g. ``"<argName0>;<argName1>;..."``).
# For each variable name ``<argNamei>``, a local variable will be created
# in the current scope with the name ``<prefix>_<argNamei>`` which gives
# the list of variables parsed out of ``<inputArgsList>``.
#
# ``<optionNamesList>``
#
# Quoted array of list options (e.g. ``"<optName0>;<optName1>;..."``)
# typically pass in as ``${ARGN}`` in the outer function/macro. For each
# variable name ``<optNamei>``, a local variable will be created in the
# current scope with the name ``<prefix>_<optNamei>`` that is either set
# to ``TRUE`` or ``FALSE`` depending if ``<optNamei>`` appears in
# ``<inputArgsList>`` or not.
#
# ``<inputArgsList>``
#
# List of arguments keyword-based arguments passed in through the outer
# macro or function to be parsed out into the different argument and
# option lists.
#
# What this macro does is very simple yet very useful. What it does is to
# allow one to create one's own user-defined keyword-based macros and
# functions like is used by some built-in CMake commands.
#
# For example, consider the following user-defined macro that uses both
# positional and keyword-based arguments using ``parse_arguments()``::
#
# macro(parse_special_vars BASE_NAME)
#
# parse_arguments(
# #prefix
# ${BASE_NAME}
# #lists
# "ARG0;ARG1;ARG2"
# #options
# "OPT0;OPT1"
# ${ARGN}
# )
#
# endmacro()
#
# Calling this macro as::
#
# parse_special_vars(MyVar ARG0 a b ARG2 c OPT1)
#
# sets the following variables in the current scope::
#
# MyVar_ARG0="a;b"
# MyVar_ARG1=""
# MyVar_ARG2="c"
# MyVar_OPT0="FALSE"
# MyVar_OPT1="TRUE"
#
# This allows one to define user-defined macros and functions that have a
# mixture of positional arguments and keyword-based arguments like one can do
# in other languages. The keyword-based arguments can be passed in any order
# and those that are missing are empty (or false for options) by default.
#
# Any initial arguments that are not recognized as ``<argNamesList>`` or
# ``<optionNamesList>`` keyword arguments will be put into the local variable
# ``<prefix>_DEFAULT_ARGS``. If no arguments in ``<inputArgsList>``
# (typically ``${ARGN}``) match any in ``<argNamesList>``, then all non-option
# arguments are put into ``<prefix>_DEFAULT_ARGS``. For example, if one
# passes in::
#
# parse_special_vars(MyVar ARG5 a b c)
#
# you will get::
#
# MyVar_DEFAULT_ARGS="ARG5;a;b;c"
# MyVar_ARG0=""
# MyVar_ARG1=""
# MyVar_ARG2=""
# MyVar_OPT0="FALSE"
# MyVar_OPT1="FALSE"
#
# Multiple occurrences of keyword arguments in ``<inputArgsList>`` is allowed
# but only the last one listed will be recorded. For example, if one calls::
#
# parse_special_vars(MyVar ARG1 a b ARG1 c)
#
# then this will set::
#
# MyVar_ARG0=""
# MyVar_ARG1="c"
# MyVar_ARG2=""
# MyVar_OPT0="FALSE"
# MyVar_OPT1="FALSE"
#
# This is actually consistent with the way that most argument list parsers
# behave with respect to multiple instances of the same argument so hopefully
# this will not be a surprise to anyone.
#
# If one puts an option keyword in the middle of a keyword argument list, the
# option keyword will get pulled out of the list. For example, if one calls::
#
# parse_special_vars(MyVar ARG0 a OPT0 c)
#
# then this will set::
#
# MyVar_ARG0="a;c"
# MyVar_ARG1=""
# MyVar_ARG2=""
# MyVar_OPT0="TRUE"
# MyVar_OPT1="FALSE"
#
# This is confusing behavior so users would be smart not to mix option
# arguments inside of list arguments.
#
# If ``PARSE_ARGUMENTS_DUMP_OUTPUT_ENABLED`` is set to ``TRUE``, then a bunch
# of detailed debug info will be printed. This should only be used in the
# most desperate of debug situations because it will print a *lot* of output!
#
# **PERFORMANCE:** This function will scale as::
#
# o( (len(<argNamesList>) * len(<optionNamesList>)) * len(<inputArgsList>) )
#
# Therefore, this could scale very badly for large sets of argument and option
# names and input argument list names.
#
macro(parse_arguments prefix arg_names option_names)
parse_arguments_deprecated_warning()
parse_arguments_dump_output("PARSE_ARGUMENTS: prefix='${prefix}'")
parse_arguments_dump_output("PARSE_ARGUMENTS: arg_names='${arg_names}'")
parse_arguments_dump_output("PARSE_ARGUMENTS: option_names='${option_names}'")
parse_arguments_dump_output("PARSE_ARGUMENTS: ARGN='${ARGN}'")
foreach(arg_name ${arg_names})
set(${prefix}_${arg_name})
endforeach()
foreach(option ${option_names})
set(${prefix}_${option} FALSE)
endforeach()
set(DEFAULT_ARGS)
set(current_arg_name DEFAULT_ARGS)
set(current_arg_list)
foreach(arg ${ARGN})
set(larg_names ${arg_names})
list(FIND larg_names "${arg}" is_arg_name)
if (is_arg_name GREATER -1)
set(${prefix}_${current_arg_name} "${current_arg_list}")
parse_arguments_dump_output("PARSE_ARGUMENTS: ${prefix}_${current_arg_name} = '${${prefix}_${current_arg_name}}'" )
set(current_arg_name "${arg}")
set(current_arg_list)
else()
set(loption_names "${option_names}")
list(FIND loption_names "${arg}" is_option)
if (is_option GREATER -1)
set(${prefix}_${arg} TRUE)
parse_arguments_dump_output( "PARSE_ARGUMENTS: ${prefix}_${arg} = '${${prefix}_${arg}}'" )
else()
list(APPEND current_arg_list "${arg}")
endif()
endif()
endforeach()
set(${prefix}_${current_arg_name} "${current_arg_list}")
parse_arguments_dump_output( "PARSE_ARGUMENTS: ${prefix}_${current_arg_name} = '${${prefix}_${current_arg_name}}'" )
endmacro()
# NOTE: If the above function turns out to be a performance bottle neck, there
# are a few things that could be done to improve performance. One thing you
# could do is replace the o(len(arg_names)) and o(len(option_names)) lookup
# with o(1) lookups by creating CMake variables of the name
# ${OUTER_FUNC_NAME}_arg_<argNamei> and then just look of that variable exists
# or not. That should use a hash function. That might actually slow things
# down for short lists however so we would have to measure, measure,
# measure. I would have to pass in the function/macro name to disambiguate
# the variable names. It would really be better if CMake would provide a
# sorted list find operation. That would make this much faster for large
# numbers of argument and option names.