Phrep includes a simple expression evaluator for #if and #elif
directives. It allows for most common operations:
Arithmetic
#if 7 / 2 - 5 + 2.5Comparison
#if 12 > 3Constant substitution and tests
#if CONST > 2.0.0-betaRegex comparisons (case-insensitive)
#if !(VER =~ beta)Alternatives of course
#if X>0 || Y && Z<0Constant checks via
defined()function#if defined(WHATEVER)Works basically just like
#ifdef. There's also apragma(..)function to look up current processing options.And allows to use a few elected PHP functions:
#if is_int(strpos(abc, b))Simple file checks even:
#if file_exists("lib/scope.php")One can also use strpos, stripos, strstr, stristr, is_int, is_float, is_numeric, max, min, function_exists, and class_exists.
Invalid expressions:
#if (1 + - / 0)Will obviously fail. In the default mode, this will simply skip the condition as falsy (with a warning). In the -W or
#pragma(fail=1)mode, it'll however abort further preprocessing.
The expression evaluation is mostly careless with types.
It usually expands both literal
CONST_NAMESas well as string-quoted"CONST_NAMES"eagerly.Even numbers may be quoted
"1" + "2" == "3". (Which suits the most common use cases though.)And it does all comparisions under the presumption they could be version numbers. For example
1.2 > 2.3is a version comparison, as is"PKG_VERSION" >= 2.0.0. (Relying on PHPs version_compare internally. Though could switch to plain float fallbacks later..)Only function names and operators must be noted literally (
defined, not"defined"as string).
It's somewhat of an gimmick anyway. You don't commonly need a lot of
conditions to control a build/preprocessing run (#ifdef often suffices).
The MacroExpression handler is mainly there for some crude compatibility
with CPP and preprocess.py. Converting expressions into PHP evaluable code
would just have been more work. Probably.