AMake Preprocessor

AMake understands the following preprocessor modes:

#<instruction> C like preprocessor (without spaces, unless --enable-spaces was used on the command line)
Note: this option can be used to include C like header files with lists of #define which would be necessary to your makefile scripts
!<instruction> DOS like preprocessor (in this case the preprocessor instructions are case insensitive)
.<instruction> BSD like preprocessor
<instruction> GNU make like preprocessor; AMake will first check whether the word could be a target or a macro name, if not it will check if it is a preprocessor instruction, if not there is probably a problem

AMake understands the following preprocessor instructions:

Instruction Comments
#define <variable name> ... sets a macro; like the C preprocessor #define
[override] define <variable names>
...
endef
sets one or more macros; note that this instruction can't start with any introducer for GNU make compatibility only
#echo ...
#message ...
prints out what follows (which can include macro references)
#elif <expr>
#elifdef <expr>
#elifndef <expr>
#elifmake <expr>
#elifnmake <expr>
#elifeq <word> <words>
#elifeq (<str1>, <str2>)
#elifeq "<str1>" "<str2>"
#elifeq '<str1>' '<str2>'
#elifneq <word> <words>
#elifneq (<str1>, <str2>)
#elifneq "<str1>" "<str2>"
#elifneq '<str1>' '<str2>'
#elifeqi <word> <words>
#elifeqi (<str1>, <str2>)
#elifeqi "<str1>" "<str2>"
#elifeqi '<str1>' '<str2>'
#elifneqi <word> <words>
#elifneqi (<str1>, <str2>)
#elifneqi "<str1>" "<str2>"
#elifneqi '<str1>' '<str2>'

switch the state of the current level of #if/#endif if it was false and this instruction returns true; the long syntax can also be used as in:

#elseifdef <expr>


and

#else ifdef <expr>

#else switch the state of the current level of #if/#endif if it always were false
#end terminate the current file
#endfor terminate the current #for loop
#endif terminate the current #if block
#error ... generate a user error (that's exactly what's missing in any C compiler preprocessor!!!)
#export [<variable names> [<assign opertor> <value>]] exports the specified variables (and sets them)
#for <variable name> in <list of words> repeat the #for/#endfor block with <variable> set to each word of the <list of words> one after another
#ident "..." sets the IDENTIFICATION variable to the given string
#if <expr>
#ifdef <expr>
#ifndef <expr>
#ifmake <expr>
#ifnmake <expr>
#ifeq <word> <words>
#ifeq (<str1>, <str2>)
#ifeq "<str1>" "<str2>"
#ifeq '<str1>' '<str2>'
#ifneq <word> <words>
#ifneq (<str1>, <str2>)
#ifneq "<str1>" "<str2>"
#ifneq '<str1>' '<str2>'
#ifeqi <word> <words>
#ifeqi (<str1>, <str2>)
#ifeqi "<str1>" "<str2>"
#ifeqi '<str1>' '<str2>'
#ifneqi <word> <words>
#ifneqi (<str1>, <str2>)
#ifneqi "<str1>" "<str2>"
#ifneqi '<str1>' '<str2>'
evaluate the expression, if true parse what follows this instruction, otherwise set the status to false and skip everything until the #endif or one of the #else instruction
#include "filename"
#include <filename>
#sinclude "filename"
#sinclude <filename>
#-include "filename"
#-include <filename>
include the specified filename; the directories specified with the -I option, the directories specified with the vpath instruction, the paths listed in $(PREFIX), then the default directories, are checked for the files; if they don't exist, and the filename doesn't include any pattern and none of the -include or sinclude instruction was used, then no error is generated and AMake tries to create the file (see the .REDO flag)
#includedir <path> add paths to be used with the #include instructions
#override <variable names> <assign operator> <value> set any variables whatever the way these were defined (i.e. on the command line)
#shell ... execute the following commands in a shell
#undef <variable> undefine a variable
#unexport [<variable names> [<assign operator> <value>]] unexport the specified variables (and sets them)
#vpath [<easy pattern> [<paths>] specify a list of paths used to search the files matching the easy pattern
#warn ... generate a user warning

AMake supports all the following operators and function calls in the expressions used with the preprocessor expressions. The list is given in the order of priority of the operators. It is the same as in any C preprocessor.

Operator Comment
<words> a list of words
'(' <expr> ')' a group of expressions
<function> '('[<words>]')' call an internal function
'[' <shell command> ']' execute a shell command and return the exit value
'!' <expr> logical not
'~' <expr> bitwise not
'-' <expr> negate
'+' <expr> identity
<expr1> '**' <expr2> compute <expr1> power <expr2>
<expr1> '*' <expr2> compute <expr1> multiply by <expr2>
<expr1> '/' <expr2> compute <expr1> divided by <expr2>
<expr1> '%' <expr2> compute <expr1> modulo <expr2>
<expr1> '+' <expr2> compute <expr1> plus <expr2>
<expr1> '-' <expr2> compute <expr1> minus <expr2>
<expr1> '<<' <expr2> compute <expr1> shifted left by <expr2> bits
<expr1> '>>' <expr2> compute <expr1> shifted right by <expr2> bits
<expr1> '<' <expr2> return true if <expr1> is smaller than <expr2>
<expr1> '<=' <expr2>
<expr1> '=<' <expr2>
return true if <expr1> is smaller or equal to <expr2>
<expr1> '>' <expr2> return true if <expr1> is larger than <expr2>
<expr1> '>=' <expr2>
<expr1> '=>' <expr2>
return true if <expr1> is larger or equal to <expr2>
<expr1> '==' <expr2> return true if <expr1> is equal to <expr2>
<expr1> '!=' <expr2>
<expr1> '<>' <expr2>
return true if <expr1> is equal to <expr2>
<expr1> '&' <expr2> compute <expr1> bitwise and <expr2>
<expr1> '^' <expr2> compute <expr1> bitwise exclusive or <expr2>
<expr1> '|' <expr2> compute <expr1> bitwise or <expr2>
<expr1> '&&' <expr2> compute <expr1> logical and <expr2>
<expr1> '||' <expr2> compute <expr1> logical or <expr2>

AMake understands all the following functions in it's preprocessor expressions:

Function Comments
count(<list of words>) the number of words in the <list of words>
defined(<variable>)
$d(<variable>)
true when <variable> is defined
debug() true when the -d or --debug was used on the command line
empty(<variable>) true when <variable> is empty
exists(<filename>) true when <filename> exists
islocked() true when -l or --lock was used and AMake is already running in this directory
make(<target>) true when <target> is a main target
sizeof(<string>) the number of characters in <string>
target(<word>) true when <word> is a target
system(<word>) true when <word> corresponds to the system on which AMake is running or when <word> is equal to IMAKE and the --imake option was explicitly or implicitly used
version(<version>) true when <version> is smaller or equal to AMake's version