Dynamic functions
This module implements several meta-functions that create new functions dynamically by wrapping the existing ones.
The function parameter_to_function_prefix
wraps a function
f(x1 x2 …) into a new function ${x1}_f(x2 …), that is, fixes one
argument to some predefined value so that the wrapped function could be
called with one argument less.
The function trace_functions
wraps a function f into a new function
_trace_f that prints a trace message f(${ARGN}) into the log context
with the same name f, and then calls the original function with unchanged
arguments.
The function dynamic_call
forwards given arguments to a given function
without any changes.
The function eval
emulates return values for functions and macros:
function(concat_function _param1 _param2)
result_is("${_param1}_${_param2}")
endfunction()
set(_ind 2)
eval(EXPR "a = ${_ind} + 3")
message(STATUS "a = ${a}") # prints a = 5
eval("b = concat_function(cmake language)")
message(STATUS "b = ${b}") # prints b = cmake_language
When to use
With the help of trace_functions
, it’s easy to single-out calls to
a specific function without changing the source of that function.
parameter_to_function_prefix
is written specifically to wrap the
GlobalMap module, but it could be useful in other contexts as well.
Functions
- parameter_to_function_prefix
parameter_to_function_prefix(<function list>>)
For each given function fn, creates a counterpart ${_prefix}_${fn} that has all the parameters of the original function except the first one, and does nothing but calls fn with the arguments given to ${_prefix}_${fn}.
Note
Since the argument count changes, the logic that depends on ARGN, ARGC and similar values, may break. Be careful when wrapping a function that depends on exact argument count and order.
- trace_functions
trace_functions(<function list>>)
For each given function fn, creates a counterpart _trace_fn that prints a trace message called fn(${ARGN}) into the log context fn and then calls the original function with the unchanged arguments. For example:
trace_functions(global_set)
log_level(global_set TRACE)
log_to_file(global_set global_set.log)
# will append 'global_set(a bcd)' to 'global_set.log'
# before calling 'global_set'
_trace_global_set(a bcd)
- dynamic_call
dynamic_call(<function> <argument list>)
Calls the given function with the given arguments. For example:
log_level(dynamic_call TRACE)
log_to_file(dynamic_call dynamic_call.log)
dynamic_call(${function_name} ${ARGN})
# will append 'global_set(a bcd)' to 'global_set.log'
# before calling 'global_set'
_trace_global_set(a bcd)
- eval
eval("<var> = <function>(<argument>...)")
Calls the given function with the given arguments and stores the result
in the result variable var
. The function function
must call one of
result_is
, result_expr
to publish the result:
function(function_with_result _param1 _param2)
result_expr(${_param1} + ${_param2})
endfunction()
function(function_with_result_2 _param1 _param2)
result_is("${_param1}_${_param2}")
endfunction()
macro(macro_with_result _param1 _param2)
result_is("${_param1}_${_param2}")
endmacro()
function(eval_test)
eval("a = function_with_result(3 4)")
assert_same(${a} 7)
eval("b = function_with_result_2(cmake language)")
assert_same(${b} cmake_language)
set(_ind 2)
eval(EXPR "a = ${_ind} + 3")
assert_same(${a} 5)
eval("a = macro_with_result(1 2)")
assert_same(${a} 1_2)
endfunction()