Form of Input Text for gnatprep (GNAT User’s Guide for Native Platforms)

#### 3.10.2.5 Form of Input Text for `gnatprep` ¶

The input text contains preprocessor conditional inclusion lines as well as general symbol substitution sequences.

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> = <integer>
    <expression> ::=  <symbol> > <integer>
    <expression> ::=  <symbol> >= <integer>
    <expression> ::=  <symbol> < <integer>
    <expression> ::=  <symbol> <= <integer>
    <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> )

For the first test, (<expression> ::= <symbol>), the symbol must have either the value true or false. The right-hand of the symbol definition must be one of the (case-insensitive) literals `True` or `False`. If the value is true, the corresponding lines are included and if the value is false, they are excluded.

When comparing a symbol to an integer, the integer is any non negative literal integer as defined in the Ada Reference Manual, such as 3, 16#FF# or 2#11#. The symbol value must also be a non negative integer. Integer values in the range 0 .. 2**31-1 are supported.

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, the result depends on whether or not you have specified the `-u` switch. If you have, the symbol is treated as if it had the value false and the test fails. If not, it’s an error to reference an undefined symbol. It’s also an error to reference a symbol that you have defined with a value other than `True` or `False`.

The use of the `not` operator inverts the sense of this logical test. You can’t combine the `not` operator with the `or` or `and` operators without parentheses. For example, you can’t write “if not X or Y then” allowed, but can write either “if (not X) or Y then” or “if not (X or Y) then”.

The `then` keyword is optional, as shown.

You must place the `#` in the first non-blank character on a line, i.e., it must be preceded only by spaces or horizontal tabs, but otherwise the format is free form. You may place spaces or tabs between the `#` and the keyword. The keywords and the symbols are case insensitive, as in normal Ada code. You can write comments on a preprocessor line, but other than that, you can’t place any other tokens on a preprocessor line. You can have any number of `elsif` clauses, including none at all. The `else` is optional, as in Ada.

You obtain symbol substitution outside of preprocessor lines 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 resulting output substitutes the value of the symbol in place of `$symbol` in the output file.

Note that although you can’t substitute strings within a string literal, you can 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.