On Monday 09 August 2010, Alexander Neundorf wrote: > On Monday 09 August 2010, Brad King wrote: > > On 08/07/2010 03:41 PM, Alexander Neundorf wrote: > > > # Call the function, if the keyword is present the value(s) following > > > it will # be returned in _FAIL_MESSAFE/_VERSION_VAR/_REQUIRED_VARS: > > > FPHSA_GET_OPTION_VALUE("FAIL_MESSAGE" _FAIL_MESSAGE ALL_ARGS _KEYWORDS > > > FALSE) FPHSA_GET_OPTION_VALUE("VERSION_VAR" _VERSION_VAR ALL_ARGS > > > _KEYWORDS FALSE) FPHSA_GET_OPTION_VALUE("REQUIRED_VARS" _REQUIRED_VARS > > > ALL_ARGS _KEYWORDS TRUE) > > > > I think a better name would be something like > > "cmake_get_keyword_argument". > > Ok. > > > This interface requires the same argument lists to be traversed many > > times. > > Not completely. > It stops when it has finished the arguments for one keyword and it also > removes the stuff it consumed from the list, so the list gets shorter each > call. > > > I think we should be using a macro like PARSE_ARGUMENTS from Boost's > > CMake build system (see below). This is its interface documentation: > > > > # The PARSE_ARGUMENTS macro will take the arguments of another macro and > > # define several variables. The first argument to PARSE_ARGUMENTS is a > > # prefix to put on all variables it creates. The second argument is a > > # list of names, and the third argument is a list of options. Both of > > # these lists should be quoted. The rest of PARSE_ARGUMENTS are > > # arguments from another macro to be parsed. > > # > > # PARSE_ARGUMENTS(prefix arg_names options arg1 arg2...) > > The last time I looked at some similar function (was it also in boost ?) it > didn't seem powerful enough. > I'll have a look.
Ok, attached you can find a CMakeParseArguments.cmake. Docs are still missing. The interface is similar to the one from boost, but not identical. With this version you can specify options (no values following), single-value arguments (0..1 value following) and multi-value arguments (0..n values following). This has the advantage that the function can also report the arguments which it didn't know. This is done in ${prefix}_UNPARSED_ARGUMENTS. It runs once over ARGN, but the option and argument names have to checked on each iteration, I think this can't be avoided (and is also the case in the macro from Boost). Alex P.S. Is this the current version: http://calder.sdml.cs.kent.edu/trac/origin/browser/trunk/cmake/BoostUtils.cmake ? It seems to have a bug, an option doesn't seem to terminate the collecting of values of the previous argument (but I didn't test).
if(__CMAKE_PARSE_ARGUMENTS_INCLUDED) return() endif() set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE) function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames) foreach(arg_name ${_singleArgNames} ${_multiArgNames}) set(${prefix}_${arg_name}) endforeach(arg_name) foreach(option ${_optionNames}) set(${prefix}_${option} FALSE) endforeach(option) set(${prefix}_UNPARSED_ARGUMENTS) set(insideValues FALSE) set(currentArgName) foreach(currentArg ${ARGN}) list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1) if(insideValues) if("${insideValues}" STREQUAL "SINGLE") set(${prefix}_${currentArgName} ${currentArg}) set(insideValues FALSE) elseif("${insideValues}" STREQUAL "MULTI") list(APPEND ${prefix}_${currentArgName} ${currentArg}) endif() else(insideValues) list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg}) endif(insideValues) else() if(NOT ${optionIndex} EQUAL -1) set(${prefix}_${currentArg} TRUE) set(insideValues FALSE) elseif(NOT ${singleArgIndex} EQUAL -1) set(currentArgName ${currentArg}) set(${prefix}_${currentArgName}) set(insideValues "SINGLE") elseif(NOT ${multiArgIndex} EQUAL -1) set(currentArgName ${currentArg}) set(${prefix}_${currentArgName}) set(insideValues "MULTI") endif() endif() endforeach(currentArg) foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames}) set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE) endforeach(arg_name) set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE) endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs)
cmake_minimum_required(VERSION 2.6) include(CMakeParseArguments) cmake_parse_arguments(FOO "APPEND;PREPEND" "FILENAME;WHAT;INFO" "NAMES;WORDS" BLUB APPEND FILENAME foo.txt xyz WHAT INFO "This is info" NAMES a.txt b.txt c.txt) macro(print_var _var) message(STATUS "${_var} = \"${${_var}}\"") endmacro(print_var _var) print_var(FOO_APPEND) print_var(FOO_PREPEND) print_var(FOO_FILENAME) print_var(FOO_WHAT) print_var(FOO_INFO) print_var(FOO_NAMES) print_var(FOO_WORDS) print_var(FOO_UNPARSED_ARGUMENTS)
_______________________________________________ cmake-developers mailing list cmake-developers@cmake.org http://public.kitware.com/cgi-bin/mailman/listinfo/cmake-developers