preprocessor directives(1) — Commands
Digital
NAME
Preprocessor Directives − supply and process replacement macro definitions before compilation
SYNOPSIS
#DEFINE
The format for a #DEFINE preprocessor directive is:
#DEFINE <preprocessor-identifier>
[<preprocessor-identifier-1> ]
[<decimal-literal> ]
[<integer-literal> ]
[ ] . . . <eol>
[<string-literal> ]
[<operator> ]
[<punctuators> ]
[ ]
#IF
The format for a #IF preprocessor directive is:
{DEFINED (<identifier>) }
#IF {<boolean-expression> } <eol>
{ }
[[ <preprocessor-identifier-1> ] ]
[[ <decimal-literal> ] ]
[[ <integer-literal> ] ]
[[ <string-literal> ] . . . <eol> ]
[[ <operator> ] ]
[[ <punctuators> ] ]
[ ]
[#DEFINE ]
[#IF ]
[#INCLUDE ]
[#UNDEF ]
[ #ELIF <boolean-expression> <eol> ]
[ [ ] ]
[ [[ <preprocessor-identifier-1> ] ] ]
[ [[ <decimal-literal> ] ] ]
[ [[ <integer-literal> ]. . . <eol> ] ]
[ [[ <string-literal> ] ] ]
[ [[ <operator> ] ] ]
[ [[ <punctuators> ] ] ]
[ [ ] ]
[ [#DEFINE ] ]
[ [#IF ] ]
[ [#INCLUDE ] ]
[ [#UNDEF ] ]
[ ]
[ #ELSE <boolean-expression> <eol> ]
[ [ ] ]
[ [[ <preprocessor-identifier-1> ] ] ]
[ [[ <decimal-literal> ] ] ]
[ [[ <integer-literal> ]. . . <eol> ] ]
[ [[ <string-literal> ] ] ]
[ [[ <operator> ] ] ]
[ [[ <punctuators> ] ] ]
[ [ ] ]
[ [#DEFINE ] ]
[ [#IF ] ]
[ [#INCLUDE ] ]
[ [#UNDEF ] ]
[ ]
#ENDIF <eol>
#IFDEF
The format for a #IFDEF preprocessor directive is:
#IFDEF <preprocessor-identifier-1> <eol>
[[ <preprocessor-identifier-1> ] ]
[[ <decimal-literal> ] ]
[[ <integer-literal> ] ]
[[ <string-literal> ] . . . <eol> ]
[[ <operator> ] ]
[[ <punctuators> ] ]
[ ]
[#DEFINE ]
[#IF ]
[#INCLUDE ]
[#UNDEF ]
[#ELIF <boolean-expression> <eol> ]
[[ ] ]
[[ [<preprocessor-identifier-1> ] ] ]
[[ [<decimal-literal> ] ] ]
[[ [<integer-literal> ] . . . <eol>] ]
[[ [<string-literal> ] ] ]
[[ [<operator> ] ] ]
[[ [<punctuators> ] ] ]
[[ ] ]
[[ #DEFINE ] ]
[[ #IF ] ]
[[ #INCLUDE ] ]
[[ #UNDEF ] ]
[ ]
[#ELSE <boolean-expression> <eol> ]
[[ ] ]
[[ [<preprocessor-identifier-1> ] ] ]
[[ [<decimal-literal> ] ] ]
[[ [<integer-literal> ] . . . <eol>] ]
[[ [<string-literal> ] ] ]
[[ [<operator> ] ] ]
[[ [<punctuators> ] ] ]
[[ ] ]
[[ #DEFINE ] ]
[[ #IF ] ]
[[ #INCLUDE ] ]
[[ #UNDEF ] ]
[ ]
#ENDIF <eol>
#IFNDEF
The format for a #IFNDEF preprocessor directive is:
#IFNDEF <preprocessor-identifier-1> <eol>
[ [<preprocessor-identifier-1> ] ]
[ [<decimal-literal> ] ]
[ [<integer-literal> ] ]
[ [<string-literal> ] . . . <eol>]
[ [<operator> ] ]
[ [<punctuators> ] ]
[ ]
[ #DEFINE ]
[ #IF ]
[ #INCLUDE ]
[ #UNDEF ]
[ #ELIF <boolean-expression> <eol> ]
[ [ ] ]
[ [[ <preprocessor-identifier-1> ] ] ]
[ [[ <decimal-literal> ] ] ]
[ [[ <integer-literal> ]. . . <eol> ] ]
[ [[ <string-literal> ] ] ]
[ [[ <operator> ] ] ]
[ [[ <punctuators> ] ] ]
[ [ ] ]
[ [#DEFINE ] ]
[ [#IF ] ]
[ [#INCLUDE ] ]
[ [#UNDEF ] ]
[ ]
[ #ELSE <boolean-expression> <eol> ]
[ [ ] ]
[ [[ <preprocessor-identifier-1> ] ] ]
[ [[ <decimal-literal> ] ] ]
[ [[ <integer-literal> ]. . . <eol> ] ]
[ [[ <string-literal> ] ] ]
[ [[ <operator> ] ] ]
[ [[ <punctuators> ] ] ]
[ [ ] ]
[ [#DEFINE ] ]
[ [#IF ] ]
[ [#INCLUDE ] ]
[ [#UNDEF ] ]
[ ]
#ENDIF <eol>
#INCLUDE
The format for a #INCLUDE preprocessor directive is:
#INCLUDE <file-name> <eol>
#CINCLUDE <file-name> <eol>
#UNDEF
The format for a #UNDEF preprocessor directive is:
#UNDEF <preprocessor-identifier-1> <eol>
PARAMETERS
•preprocessor-identifier
An unqualified internal identifier specifying a preprocessor macro that can be used in other preprocessor directives and STDL source lines. The identifier must follow the syntax described in the Identifiers section in the stdl_syntax man page.
The preprocessor macro definition is valid for the rest of the source file unless removed by a #UNDEF preprocessor directive. If the preprocessor macro appears in another preprocessor directive or STDL source line, the compiler replaces the macro with the valid definition.
The preprocessor identifier is a superset of reserved words, predefined words, and user-defined words. During preprocessing, all reserved words, predefined words, and user-defined words are treated as preprocessor identifiers. For example, you can replace all occurrences of an STDL reserved word with another word during preprocessing. This is not recommended.
•preprocessor-identifier-1
An unqualified internal identifier specifying a preprocessor macro that is defined in a preceding #DEFINE preprocessor directive. If there is no intervening #UNDEF preprocessor directive, the compiler replaces the macro with the definition. If there is an intervening #UNDEF directive, the identifier has no effect.
•decimal-literal
Sequence of numeric characters from the STDL alphanumeric character set. See the Decimal Literal section in the stdl_syntax man page.
•integer-literal
Sequence of numeric characters from the STDL alphanumeric character set. See the Integer Literal section in the stdl_syntax man page.
•string-literal
A sequence of characters selected from one execution character set. See the String Literal section in the stdl_syntax man page.
•operator
A character or characters from the STDL alphanumeric character set specifying a relational, an arithmetic, or an assignment operation to be performed. See the Operators section in the stdl_syntax man page.
•punctuators
A character or characters from the STDL alphanumeric character set specifying a syntactic separation used in an STDL definition or specification. For example, a comma (,) to separate arguments. See the Punctuators section in the stdl_syntax man page.
•eol
A carriage return-line feed pair signalling the end of the source line.
•identifier
An internal unqualified identifier representing a preprocessor identifier. The identifier must follow the syntax described in the Identifiers section in the stdl_syntax man page. See the description of the Boolean expression parameter for information on the processing of DEFINED.
•Boolean-expression
A condition that produces a truth value when evaluated; the truth value can be either true or false. Before the Boolean expression is evaluated, the compiler does the following:
1. Replaces any occurrence of DEFINED (identifier) as
follows:
o If identifier is defined as a preprocessor macro, it
is replaced by a Boolean term that evaluates to true.
o If identifier is not defined as a preprocessor macro,
it is replaced by a Boolean term that evaluates to
false.
2. Replaces with their definitions all preprocessor
identifiers that are defined as preprocessor macros.
3. Except for AND, NOT, and OR, replaces all remaining
preprocessor identifiers with Boolean terms that
evaluate to false.
A Boolean expression in a #IF, #IFDEF, or #IFNDEF
preprocessing directive:
o Refers only to preprocessing identifiers and integer
literals.
o Cannot contain a string literal.
See the Boolean Expressions section in the stdl_syntax man page.
•file-name
An operating system name specifying the external file containing STDL source lines that replace the #INCLUDE or #CINCLUDE directive for compilation. The file name must:
o Contain between 1 and 255 characters
o Contain only the following characters from the SIMPLE-
LATIN character set:
- Letters (uppercase and lowercase characters are
equivalent)
- Numbers
- Underscore (_) and hyphen (-)
- Period (.)
o Begin with a letter
o Not contain STDL reserved or predefined words
o Be an unqualified file name (that is, no directory
specification)
If you do not specify a file type, the compiler assumes a type of .stdl.
DESCRIPTION
Use preprocessor directives in STDL source files to supply and process replacement macro definitions before compilation, allowing source to be conditionally compiled. The preprocessing directives define and logically test preprocessor identifiers that can be nil or STDL source language elements that replace the identifiers.
The preprocessing directives are:
o #DEFINE
Specifies a preprocessor identifier and a preprocessor
replacement macro statement to be associated with that
identifier.
o #IF
Tests an identifier to allow conditional inclusion
of STDL source statements in definitions and
specifications.
o #IFDEF
Conditionally includes source statements based on
whether a preprocessor macro is defined.
o #IFNDEF
Conditionally includes source statements based on
whether a preprocessor macro is not defined.
o #INCLUDE
Calls into a file the contents of an external file,
allowing an STDL definition or specification to be
shared in multiple places.
o #UNDEF
Removes the preprocessor macro definition in effect from
a preceding #DEFINE directive.
Preprocessing syntax is separate from STDL syntax and is processed before any STDL syntax. Write preprocessor directives using the STDL alphanumeric source character set. Lowercase Latin letters are equivalent to uppercase Latin letters in the directives.
During preprocessing, the STDL compiler examines each source file line-by-line. (Contrast this with STDL syntax translation, which is done without regard to lines.) A source line that has the preprocessor directive flag character (#) as its first nonwhite space character is a preprocessing directive. Because preprocessor directives are lexically identified by the (#) flag, they are not STDL reserved words.
Preprocessing directive lines can contain comments. The #DEFINE directive is the only preprocessing directive on whose line STDL syntax can appear.
Preprocessing consists of the following semantic actions:
o The compiler removes all comments and replaces them with
white space.
o The compiler applies preprocessing syntax to the source
file. Line demarcation significant as is indicated
by the end-of-line character shown in the format
descriptions.
o The compiler interprets any preprocessor directive
according to the rules for that particular directive.
o For the source lines included in the translation, the
compiler scans for preprocessor identifiers. If an
identifier is defined and not preceded by the #UNDEF
directive, the compiler substitutes the macro definition
for the identifier.
o The compiler scans any substituted macro definitions
for preprocessor identifiers. If an identifier different
from the previously substituted identifier is found,
the compiler substitutes the macro definition for the
identifier. If any preprocessor identifier is identical
to a previously replaced identifier in the substituted
definitions, no replacement is done. Macro replacement
is recursive unless the preprocessor identifier is
identical.
o When the compiler skips text, it tracks preprocessor
directives only to find a matching #ENDIF or #ELSE.
o If a source file is included by the #INCLUDE
preprocessor directive, the compiler applies all the
preprocessing actions.
Unless the syntax descriptions of the preprocessor directives state so, preprocessor lines are not subject to macro substitution.
#DEFINE
Use #DEFINE preprocessor directives to conditionally insert multiple lines of code used at various places in the source file. For the remainder of the source file, the preprocessing identifier specified in a #DEFINE directive is valid as a preprocessor macro. The compiler rules for the directive are:
1. The compiler saves the definition associated with the
preprocessor macro.
To remove the definition in effect, use the #UNDEF
directive.
2. In any source after the #DEFINE directive, the compiler
replaces any occurrence of the preprocessor identifier
with the macro definition.
If the definition is nil, the compiler effectively
removes occurrences of the preprocessing identifier.
3. The compiler removes the #DEFINE before translation.
The scope of the macro definition is independent of any
other STDL syntax scope.
The preprocessor identifier in the #DEFINE directive is not subject to macro replacement. If the preprocessor identifier is previously defined as a preprocessor macro, the current definition must equal the previous definition. To change a definition, use the #UNDEF preprocessor directive to invalidate the current definition and a #DEFINE preprocessor directive to supply a new definition.
#IF
Within a #IF, #IFDEF, or #IFNDEF preprocessor directive, at most one substitution is included in the source to be compiled.
For a #IF, the substitution is included only if the test evaluates to true.
The #IF must be terminated by a #ENDIF directive. Statements can be nested up to six levels. The compiler removes the #IF directive before translation.
#IFDEF
Within a #IF, #IFDEF, or #IFNDEF preprocessor directive, at most one substitution is included in the source to be compiled.
For a #IFDEF, the substitution is included only if the preprocessor identifier is defined as a preprocessor macro.
The #IFDEF must be terminated by a #ENDIF directive. Statements can be nested up to six levels.
A preprocessor identifier in a #IFDEF preprocessor directive is not subject to macro substitution.
The compiler removes the #IFDEF directive before translation.
#IFNDEF
Within a #IF, #IFDEF, or #IFNDEF preprocessor directive, at most one substitution is included in the source to be compiled.
For a #IFNDEF, the substitution is included only if the preprocessor identifier is NOT defined as a preprocessor macro.
The #IFNDEF must be terminated by a #ENDIF directive. Statements can be nested up to six levels.
A preprocessor identifier in a #IFNDEF preprocessor directive is not subject to macro substitution.
The compiler removes the #IFNDEF directive before translation.
#ELIF
For a #ELIF preprocessor directive, the substitution is included only if no previous substitution within the #IF, #IFDEF, or #IFNDEF is included and the test evaluates to true.
#ELSE
For a #ELSE preprocessor directive, the substitution is included only if no previous substitution within the #IF, #IFDEF, or #IFNDEF is included.
#INCLUDE and #CINCLUDE
The #INCLUDE directive brings into a source file all source lines from an external file. The source lines from the external file lexically unconditionally replace the source line that contains the #INCLUDE directive. The #CINCLUDE directive is a conditional #INCLUDE; it does not include source lines if the file has already been included.
The compiler preprocesses an input source file. Sometimes the input source file can be a single definition, for example, a data type definition. Usually, however, the input source file must include more than one definition or specification. For example, an input source file for a processing group specification also requires the data type definitions for the workspace arguments used in the processing procedures. In other cases, you may find it convenient to include multiple definitions and specifications in the input source file, even when you can compile them as separate input source files.
Often you need to use a definition or specification in more than one source file. Write the definition or specification once, and use the #INCLUDE or #CINCLUDE preprocessor to include it in multiple input source files.
A task source file can contain task definitions for only one task group.
Do not use #INCLUDE or #CINCLUDE in include files that contain lines of source code that you plan to debug. Instead, include the definitions directly in the input source file that you compile. Source lines contained within the included file are not visible to the ACMSxp debugger.
When you invoke the compiler, have the necessary include files in the directory containing the top-level input source file. However, you can specify a search path on the command so that, if the files are not in that directory, the compiler looks for them in the directories specified in the search path. The compiler stores output files in the current working directory, but you can specify a different output directory using an option flag.
A recursive reference to the same external source file generates an error and stops the compilation.
#UNDEF
The #UNDEF preprocessor directive removes the definition of a specified preprocessor identifier as a preprocessor macro for the rest of the source file. If another #DEFINE preprocessor directive is used, the definition is in effect again.
Use a #UNDEF statement to override a macro definition at various places in the source file or to change a macro definition. If you use the #UNDEF immediately before a #DEFINE preprocessor directive, you can redefine the preprocessor macro.
A preprocessor identifier is not subject to macro replacement in a #UNDEF preprocessor directive.
EXCEPTIONS
Preprocessor directives do not generate exceptions or error messages.
EXAMPLES
The following example shows the use of some preprocessor directives.
1. #DEFINE a b
TASK a IN tskgrp
The compiler substitutes for the macro a to give the
following line for translation:
TASK b IN tskgrp
2. #DEFINE a b
#DEFINE b a
a = 1;
The compiler substitutes for the macro a. Because the
macro definition is also subject to substitution, the
compiler replaces b with a. The recursion stops, because
the replacement a in the second line is identical to a
previously replace preprocessor identifier. The result
gives the following line for translation:
a = 1;
3. #DEFINE a b
#DEFINE b c
a = 1;
The compiler substitutes b for the macro a and c for b
to give the following line for translation:
c = 1;
4. #DEFINE a b
#UNDEFINE a
#DEFINE a c
c = 1;
The compiler substitutes c for the macro a to give the
following line for translation:
c = 1;
The intervening #UNDEFINE is necessary, because the
compiler prevents you from redefining a macro.
5. #DEFINE a b
#DEFINE c a
a = 1;
c = 1;
The compiler yields the following two assignment
statements for translation:
b = 1;
b = 1;
In the first line the compiler replaces the macro a
with b and in the second line replaces c with b (the
definition for the preprocessor identifier c is itself
subject to substitution).
6. #DEFINE a a
a = 1;
The compiler replaces the macro a with its definition
a. Because the replacement equals a previously replaced
preprocessor identifier, the recursion stops.
7. #IF DEFINED (system1)
#DEFINE file "sys1"
#ELSE
#DEFINE file "default"
#ENDIF
#INCLUDE file
This example shows a #IF preprocessor directive
determining the name of the file to be included by
the #INCLUDE preprocessor directive. If the identifier
system1 is defined as a preprocessor macro, the term
evaluates as true and the macro file has the definition
sys1. If system1 is not defined as a preprocessor macro,
the term evaluates to false, and the definition for file
is default. The #INCLUDE preprocessor directive can load
either the sys1.stdl file or the default.stdl file.
RELATED INFORMATION
Commands: stdl(1)
Syntax: statement(1), stdl_syntax(1)