253 строки
6.7 KiB
Plaintext
253 строки
6.7 KiB
Plaintext
Preprocessor
|
|
============
|
|
|
|
This is a very primitive line based preprocessor, for times when using
|
|
a C preprocessor isn't an option.
|
|
|
|
|
|
Instructions
|
|
------------
|
|
|
|
Any line starting with a hash # and a letter is considered to be a
|
|
preprocessor instruction. Other lines starting with a hash are ignored
|
|
as comments.
|
|
|
|
The following preprocessor instructions are recognised.
|
|
|
|
#define VARIABLE
|
|
#define VARIABLE STRING
|
|
#undef VARIABLE
|
|
#ifdef VARIABLE
|
|
#ifndef VARIABLE
|
|
#if VARIABLE
|
|
#if !VARIABLE
|
|
#if VARIABLE==STRING
|
|
#if VARIABLE!=STRING
|
|
#else
|
|
#elifdef VARIABLE
|
|
#elifndef VARIABLE
|
|
#elif VARIABLE
|
|
#elif !VARIABLE
|
|
#elif VARIABLE==STRING
|
|
#elif VARIABLE!=STRING
|
|
#endif
|
|
#error STRING
|
|
#include FILENAME
|
|
#includesubst @VAR@FILENAME
|
|
#expand STRING
|
|
#literal STRING
|
|
#filter FILTER1 FILTER2 ... FILTERn
|
|
#unfilter FILTER1 FILTER2 ... FILTERn
|
|
|
|
Whitespace is significant -- for instance, '#define TEST foo' is not
|
|
the same as '#define TEST foo '. The first defines TEST to be a three
|
|
character string, the second defines it to be four characters long.
|
|
|
|
The conditionals (#ifdef, #ifndef, #if, #else, #elifdef, #elifndef,
|
|
#elif, #endif) can be nested to arbitrary depth.
|
|
|
|
The #elifdef, #elifndef, and #elif instructions are equivalent to
|
|
#else instructions combined with the relevant conditional. For
|
|
example,
|
|
|
|
#ifdef foo
|
|
block 1
|
|
#elifdef bar
|
|
block 2
|
|
#endif
|
|
|
|
...could be written as:
|
|
|
|
#ifdef foo
|
|
block 1
|
|
#else
|
|
#ifdef bar
|
|
block 2
|
|
#endif
|
|
#endif
|
|
|
|
An #else block is included if all previous conditions were false, and
|
|
is equivalent to #elif 1, i.e.:
|
|
|
|
#ifdef foo
|
|
foo is defined
|
|
#else
|
|
foo is not defined
|
|
#endif
|
|
|
|
...is equivalent to:
|
|
|
|
#ifdef foo
|
|
foo is defined
|
|
#elif 1
|
|
foo is not defined
|
|
#endif
|
|
|
|
#else is not required to be the last condition in an if/el*/endif
|
|
series. In particular, along with #else's equivalence to #elif 1
|
|
this means that the following holds:
|
|
|
|
#if 0
|
|
never included
|
|
#else
|
|
always included
|
|
#else
|
|
never included
|
|
#elif 1
|
|
never included
|
|
#endif
|
|
|
|
The #error instruction stops execution at this point with a fatal
|
|
error. The error message will include the given STRING.
|
|
|
|
The #include instruction causes the specified file FILENAME to be
|
|
recursively processed, as if it was inserted at the current position
|
|
in the file. This means conditionals can be started in one file and
|
|
ended in another, although this practice is strongly discouraged.
|
|
There is no predefined limit to the depth of #includes, and there is
|
|
no restriction on self-inclusion, so care should be taken to avoid
|
|
infinite loops.
|
|
|
|
The #includesubst instruction behaves like #include, except that any
|
|
variables in @ATSIGNS@ are expanded, like the substitution filter.
|
|
|
|
The #expand instruction will print the given STRING with variable
|
|
substitutions. See the substitution section below.
|
|
|
|
The #literal instruction will print the given STRING with a newline,
|
|
with absolutely no other fixups, guaranteed. This can be used to
|
|
output lines starting with a #, which would otherwise be stripped out
|
|
as comments.
|
|
|
|
The #filter instruction enables the specified filters. You can turn
|
|
off filters using #unfilter. See the Filters section below.
|
|
|
|
|
|
Variables
|
|
---------
|
|
|
|
Variables consist of any alphanumeric string. They are defined using
|
|
the -D command line argument and the #define instruction.
|
|
|
|
To define all environment variables, so that you can use __HOME__,
|
|
etc, with #expand, use the -E argument. Note that arguments that use
|
|
non-word characters (like "!") are not included. (In particular,
|
|
cygwin is known to include all kinds of weird characters in its
|
|
environment variables.)
|
|
|
|
Two special variables are predefined, FILE and LINE. They can be
|
|
passed to #define and #undef, but FILE is automatically redefined at
|
|
the top of each file, and LINE is increased by one at the start of
|
|
each line.
|
|
|
|
The variable '1' is predefined with value 1. The variable '0' is not
|
|
defined. This allows constructs such as
|
|
|
|
#if 0
|
|
...
|
|
#endif
|
|
|
|
...to be used to quickly comment out large sections. Note, however,
|
|
that these are simply variables, and can be redefined. This is
|
|
strongly discouraged.
|
|
|
|
|
|
Substitution
|
|
------------
|
|
|
|
In any line starting with the instruction #expand, variable names
|
|
contained between double underscores, like __THIS__, are expanded to
|
|
their string values, or the empty string if they are not defined.
|
|
|
|
For example to print the current filename:
|
|
|
|
#expand <!-- This file is automatically generated from __FILE__ -->
|
|
|
|
Normal lines are not affected.
|
|
|
|
See also the substitution filter below.
|
|
|
|
|
|
Filters
|
|
-------
|
|
|
|
The following filters are supported:
|
|
|
|
emptyLines
|
|
Strips blank lines from the output.
|
|
|
|
slashslash
|
|
Strips everything from the first two consecutive slash (/)
|
|
characters until the end of the line.
|
|
|
|
spaces
|
|
Collapses sequences of spaces into a single space.
|
|
|
|
substitution
|
|
Replaces occurrences of "@foo@" by the value of the variable
|
|
"foo". If @foo@ is not defined, the preprocessor will terminate
|
|
with a fatal error.
|
|
|
|
attemptSubstitution
|
|
Replaces occurrences of "@foo@" by the value of the variable
|
|
"foo". If @foo@ is not defined, the empty string is used instead.
|
|
|
|
Filters are run in alphabetical order, on a per-line basis.
|
|
|
|
|
|
Command Line Arguments
|
|
----------------------
|
|
|
|
Syntax:
|
|
preprocessor.pl [-Dvariable[=value]] [-E] [-Ffilter]
|
|
[-Ifilename] [-d] [--marker=<c>] [--] filenames...
|
|
|
|
-Dvariable
|
|
Set variable to 1 before processing the files.
|
|
|
|
-Dvariable=value
|
|
Set variable to value before processing the files.
|
|
|
|
-E
|
|
Define all environment variables.
|
|
|
|
-Ffilter
|
|
Enables the specified filter.
|
|
|
|
-Ifilename
|
|
Include filename before any other files.
|
|
|
|
-d
|
|
Run through the files on the command line, listing the files they
|
|
depend on given the specified environment variables and filters.
|
|
Doesn't recurse into those files. The output is given as one
|
|
dependency per line, and filenames are given relative to the
|
|
current directory.
|
|
|
|
--line-endings=type
|
|
Set the type of line endings to use. "type" can be either "cr",
|
|
"lf", or "crlf". The default is whatever your platform uses for
|
|
perl's "\n" character.
|
|
|
|
--marker=<c>
|
|
Use the character <c> instead of '#' as the marker for preprocessor
|
|
instructions.
|
|
|
|
--
|
|
Indicates the end of non-filename arguments.
|
|
|
|
-
|
|
Indicates that input should come from standard input.
|
|
|
|
If no filenames are provided, standard input is used instead. If many
|
|
files are provided, they are processed sequentially, as if they were
|
|
one big file. -I files are handled before the other files, in the
|
|
order specified, but after handling any -D, -E, -F, and -d arguments.
|
|
|
|
|
|
Contact Details
|
|
---------------
|
|
|
|
Feel free to e-mail me if you have any questions:
|
|
Ian Hickson <preprocessor@software.hixie.ch>
|