[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
gnatprep
This chapter discusses how to use GNAT's gnatprep
utility for simple
preprocessing.
Although designed for use with GNAT, gnatprep
does not depend on any
special GNAT features.
For further discussion of conditional compilation in general, see
D. Conditional Compilation.
17.1 Preprocessing Symbols 17.2 Using gnatprep
17.3 Switches for gnatprep
17.4 Form of Definitions File 17.5 Form of Input Text for gnatprep
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Preprocessing symbols are defined in definition files and referred to in sources to be preprocessed. A Preprocessing symbol is an identifier, following normal Ada (case-insensitive) rules for its syntax, with the restriction that all characters need to be in the ASCII set (no accented letters).
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
gnatprep
To call gnatprep
use
$ gnatprep [switches] infile outfile [deffile] |
where
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
gnatprep
"--! "
. This option will result in line numbers
being preserved in the output file.
True
. This switch
can be used in place of a definition file.
Source_Reference
pragma to be generated that
references the original input file, so that error messages will use
the file name of this original file. The use of this switch implies
that preprocessor lines are not to be removed from the file, so its
use will force `-b' mode if
`-c'
has not been specified explicitly.
Note that if the file to be preprocessed contains multiple units, then
it will be necessary to gnatchop
the output file from
gnatprep
. If a Source_Reference
pragma is present
in the preprocessed file, it will be respected by
gnatchop -r
so that the final chopped files will correctly refer to the original
input source file for gnatprep
.
#if
or #elsif
test will be treated as an error.
Note: if neither `-b' nor `-c' is present, then preprocessor lines and deleted lines are completely removed from the output, unless -r is specified, in which case -b is assumed.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The definitions file contains lines of the form
symbol := value |
where symbol is a preprocessing symbol, and value is one of the following:
Comment lines may also appear in the definitions file, starting with
the usual --
,
and comments may be added to the definitions lines.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
gnatprep
The input text may contain preprocessor conditional inclusion lines, as well as general symbol substitution sequences.
The preprocessor conditional inclusion commands have the form
#if expression [then] lines #elsif expression [then] lines #elsif expression [then] lines ... #else lines #end if; |
In this example, expression is defined by the following grammar:
expression ::= <symbol> expression ::= <symbol> = "<value>" expression ::= <symbol> = <symbol> expression ::= <symbol> 'Defined expression ::= not expression expression ::= expression and expression expression ::= expression or expression expression ::= expression and then expression expression ::= expression or else expression expression ::= ( expression ) |
The following restriction exists: it is not allowed to have "and" or "or" following "not" in the same expression without parentheses. For example, this is not allowed:
not X or Y |
This should be one of the following:
(not X) or Y not (X or Y) |
For the first test (expression ::= <symbol>) the symbol must have
either the value true or false, that is to say the right-hand of the
symbol definition must be one of the (case-insensitive) literals
True
or False
. If the value is true, then the
corresponding lines are included, and if the value is false, they are
excluded.
The test (expression ::= <symbol> 'Defined
) is true only if
the symbol has been defined in the definition file or by a `-D'
switch on the command line. Otherwise, the test is false.
The equality tests are case insensitive, as are all the preprocessor lines.
If the symbol referenced is not defined in the symbol definitions file,
then the effect depends on whether or not switch `-u'
is specified. If so, then the symbol is treated as if it had the value
false and the test fails. If this switch is not specified, then
it is an error to reference an undefined symbol. It is also an error to
reference a symbol that is defined with a value other than True
or False
.
The use of the not
operator inverts the sense of this logical test.
The not
operator cannot be combined with the or
or and
operators, without parentheses. For example, "if not X or Y then" is not
allowed, but "if (not X) or Y then" and "if not (X or Y) then" are.
The then
keyword is optional as shown
The #
must be the first non-blank character on a line, but
otherwise the format is free form. Spaces or tabs may appear between
the #
and the keyword. The keywords and the symbols are case
insensitive as in normal Ada code. Comments may be used on a
preprocessor line, but other than that, no other tokens may appear on a
preprocessor line. Any number of elsif
clauses can be present,
including none at all. The else
is optional, as in Ada.
The #
marking the start of a preprocessor line must be the first
non-blank character on the line, i.e., it must be preceded only by
spaces or horizontal tabs.
Symbol substitution outside of preprocessor lines is obtained by using the sequence
$symbol |
anywhere within a source line, except in a comment or within a
string literal. The identifier
following the $
must match one of the symbols defined in the symbol
definition file, and the result is to substitute the value of the
symbol in place of $symbol
in the output file.
Note that although the substitution of strings within a string literal
is not possible, it is possible to have a symbol whose defined value is
a string literal. So instead of setting XYZ to hello
and writing:
Header : String := "$XYZ"; |
you should set XYZ to "hello"
and write:
Header : String := $XYZ; |
and then the substitution will occur as desired.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |