# $NetBSD: cond-func.mk,v 1.14 2023/11/19 21:47:52 rillig Exp $ # # Tests for those parts of the functions in .if conditions that are common # among several functions. # # The below test uses the 'defined' function since it has no side-effects. # The other functions would work equally well, except for 'empty', which # parses its argument differently from the other functions. # DEF= defined ${:UA B}= variable name with spaces ${:UVAR(value)}= variable name with parentheses ${:UVAR{value}}= variable name with balanced braces # Really strange variable names must be given indirectly via another variable, # so that no unbalanced braces appear in the top-level expression. VARNAME_UNBALANCED_BRACES= VAR{{{value ${VARNAME_UNBALANCED_BRACES}= variable name with unbalanced braces .if !defined(DEF) . error .endif # Horizontal whitespace (space tab) after the opening parenthesis is ignored. .if !defined( DEF) . error .endif # Horizontal whitespace (space tab) before the closing parenthesis is ignored. .if !defined(DEF ) . error .endif # The argument of a function must not directly contain whitespace. # expect+1: Missing closing parenthesis for defined() .if !defined(A B) . error .endif # If necessary, the whitespace can be generated by an expression. .if !defined(${:UA B}) . error .endif # Characters that could be mistaken for operators must not appear directly # in a function argument. As with whitespace, these can be generated # indirectly. # # It's not entirely clear why these characters are forbidden. # The most plausible reason seems to be typo detection. # expect+1: Missing closing parenthesis for defined() .if !defined(A&B) . error .endif # expect+1: Missing closing parenthesis for defined() .if !defined(A|B) . error .endif # Even parentheses may appear in variable names. # They must be balanced though. .if !defined(VAR(value)) . error .endif # Braces do not have any special meaning when parsing arguments. .if !defined(VAR{value}) . error .endif # Braces do not have any special meaning when parsing arguments. # They don't need to be balanced. .if !defined(VAR{{{value) . error .endif # There may be spaces around the operators and parentheses, and even # inside the parentheses. The spaces inside the parentheses are not # allowed for the 'empty' function (see cond-func-empty.mk), therefore # they are typically omitted for the other functions as well. .if ! defined ( DEF ) . error .endif # The following condition is interpreted as defined(A) && defined(B). # In lack of a function call expression, each kind of .if directive has a # default function that is called when a bare word is parsed. For the plain # .if directive, this function is defined(); see "struct If ifs" in cond.c. .if A&B . error .endif .if defined() . error .else # expect+1: The empty variable is never defined. . info The empty variable is never defined. .endif # The plain word 'defined' is interpreted as 'defined(defined)', see # CondParser_ComparisonOrLeaf. # That variable is not defined (yet). .if defined . error .else # expect+1: A plain function name is parsed as defined(...). . info A plain function name is parsed as defined(...). .endif # If a variable named 'defined' is actually defined, the bare word 'defined' # is interpreted as 'defined(defined)', and the condition evaluates to true. defined= # defined but empty .if defined # expect+1: A plain function name is parsed as defined(...). . info A plain function name is parsed as defined(...). .else . error .endif # A plain symbol name may start with one of the function names, in this case # 'defined'. .if defined-var . error .else # expect+1: Symbols may start with a function name. . info Symbols may start with a function name. .endif defined-var= # defined but empty .if defined-var # expect+1: Symbols may start with a function name. . info Symbols may start with a function name. .else . error .endif # expect+1: Missing closing parenthesis for defined() .if defined( . error .else . error .endif