Phrep includes a simple expression evaluator for #if
and #elif
directives. It allows for most common operations:
Arithmetic
#if 7 / 2 - 5 + 2.5
Comparison
#if 12 > 3
Constant substitution and tests
#if CONST > 2.0.0-beta
Regex comparisons (case-insensitive)
#if !(VER =~ beta)
Alternatives of course
#if X>0 || Y && Z<0
Constant 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_NAMES
as 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.3
is 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.