250 строки
6.6 KiB
Plaintext
250 строки
6.6 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
|
||
|
#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.
|
||
|
|
||
|
An #else section can be followed by an #else section, as in:
|
||
|
|
||
|
#if 1
|
||
|
used
|
||
|
#else
|
||
|
not used
|
||
|
#else
|
||
|
used again
|
||
|
#endif
|
||
|
|
||
|
Whether this is wise or not is left up to the reader to decide.
|
||
|
|
||
|
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
|
||
|
|
||
|
#else blocks need not come last, which can lead to some odd
|
||
|
constructs.
|
||
|
|
||
|
#ifdef foo
|
||
|
included if foo is defined
|
||
|
#else
|
||
|
included if foo is not defined
|
||
|
#elifdef bar
|
||
|
included if foo is defined and bar is defined
|
||
|
#else
|
||
|
included if either foo or bar are not defined
|
||
|
#endif
|
||
|
|
||
|
Note in particular the following holds:
|
||
|
|
||
|
#if 1
|
||
|
always included
|
||
|
#elif 1
|
||
|
never included
|
||
|
#else
|
||
|
always included
|
||
|
#endif
|
||
|
|
||
|
That is to say, #else is relative to whether the previous conditional
|
||
|
was included _only_. It isn't an "and" relationship with previous
|
||
|
conditionals. This is arguably a bug.
|
||
|
|
||
|
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 #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:
|
||
|
|
||
|
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 occurances of "@foo@" by the value of the variable
|
||
|
"foo". If @foo@ is not defined, the preprocessor will terminate
|
||
|
with a fatal error.
|
||
|
|
||
|
attemptSubstitution
|
||
|
Replaces occurances 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] [--] 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.
|
||
|
|
||
|
--
|
||
|
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>
|