Open zerothi opened 1 year ago
Along these lines it is difficult for me to expand a variable from a name, can this be achieved (i.e. I tried to implement the bool
function).
# I kind of not expected this to work... but...
#:def expand(var)
${var}$
#:enddef
#:def bool(variable, default="True")
#:if defined(variable)
#: stop "Trying to see if I can double expand: {}={}".format(variable, expand(variable))
#: if variable.lower() in ["true", "on", "1", "yes", "y"]
True
#: elif variable.lower() in ["false", "off", "0", "no", "n"] or variable == ''
False
#: else
#: stop "Wrong boolean value: {}={}".format(variable, expand(variable))
#: endif
#:else
${default}
#:endif
#:enddef
I just can't seem to get it working
A small update, the way I am doing it now is:
#:def bool(variable, default="True")
#: if variable.lower() in ["true", "on", "1", "yes", "y"]
#: stop "Returning true == {}".format(variable)
True
#: elif variable.lower() in ["false", "off", "0", "no", "n"] or variable == ''
False
#: stop "Returning false == {}".format(variable)
#: else
#: stop "Wrong boolean value: {}".format(variable)
#: endif
#:enddef
#:if bool(getvar("WITH_OPTION", "True"))
...
#:endif
I would, however, still prefer to be able to loop variable names.
I can now also loop variable names, I encountered some spurious error messages, but finally got my head around it. I now do something like the below to get variable names from variables and parse them on the fly.
#:def set_constant(name, value=None, default=0)
#:if value == None
$:"#:set {} = {}".format(name, getvar(name, default))
#:else
$:"#:set {} = {}".format(name, value)
#:endif
#:enddef
#!
$:set_constant("FDICT_VERSION", "'{}.{}.{}'".format(PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR, PROJECT_VERSION_PATCH))
$:set_constant("FDICT_MAJOR", PROJECT_VERSION_MAJOR)
$:set_constant("FDICT_MINOR", PROJECT_VERSION_MINOR)
$:set_constant("FDICT_PATCH", PROJECT_VERSION_PATCH)
#:for v in ["ISO_C", "ISO_ENV", &
& "REAL80", "REAL128", &
& "INT8", "INT16", &
& "LOG8", "LOG16", "LOG64"]
$:set_constant("WITH_{}".format(v))
#:endfor
$:set_constant("MAXRANK", default=5)
#:for v in ["INT", "REAL", "CMPLX", "LOG", "ISO_C"]
$:set_constant("MAXRANK_{}".format(v))
#:endfor
Nice solution. The only problem I see is, that with this approach you first create (by using fypp) a file, which must be processed once more by fypp to turn the CMake values into Python-logicals.
Inspired by your comments above, I could come up with a solution, which turns the CMake values into Python bools within one preprocessing step. It uses the global variable mechanism to manipulate global variables from within a function.
#:def cmake_to_python(var, nonevalue=False)
#:mute
#:if not defined(var)
$:globalvar(var)
$:setvar(var, False)
#:else
$:globalvar(var)
$:setvar("value", getvar(var))
#:if value is None
$:setvar(var, nonevalue)
#:elif isinstance(value, str)
$:setvar(var, value.lower() in ["yes", "on", "1", "true", "y"])
#:else
$:setvar(var, bool(value))
#:endif
#:endif
#:endmute
#:enddef
#! Testing the cmake_to_python function
#:set DEFINE_SUFFIXES = ["ISO_C", "ISO_ENV", "REAL80", "REAL128", "INT8", "INT16"]
#:set DEFINES = ["WITH_" + suffix for suffix in DEFINE_SUFFIXES]
#:for define in DEFINES
$:cmake_to_python(define, nonevalue=True)
#:endfor
#:for define in DEFINES
The value of variable "${define}$" is ${getvar(define)}$
#:endfor
#! Note that WITH_* are now well defined variables with Python True/False values
Value of WITH_ISO_C is ${WITH_ISO_C}$
Thanks Balint.
Actually I wanted the two step process.
Details:
Of course it would be best if projects determine this from the configuration files of the build it-self (i.e. through cmake variables defined in the shipped project details.
However, in some cases you just want to limit your project's capabilities by following the library. In this case you want to ship a fypp
settings file that can be used.
Hope this clarifies.
This was my intent. :)
Using fypp to parse cmake options are really great, but I generally have a problem parsing
WITH_*
arguments.I would rather not do:
but rather something like:
I can of course define a function that parses this, but I think this could be very generally useful? The truth/false values could optionally be set by some global
FYPP_BOOL_TRUE/FALSE
variables?