fpp: Fortran preprocessor

Contents

Name

fpp - the Fortran language preprocessor for the NAGWare f95 compiler.

Synopsis

fpp[options][input-file[output-file]]

Description

fpp is the preprocessor for the NAGWare f95 compiler. fpp optionally accepts two filenames as arguments. input-file and output-file are, respectively, the input file read and the output file written by the preprocessor. By default standard input and output are used.

Options

-c_com = {yes|no}
By default, C style comments are recognized. Turn this off by specifying -c_com=no
-Dname
Define the preprocessor variable name as 1 (one). This is the same as if a -D name=1 option appeared on the fpp command line, or as if a

#define name 1

line appeared in the source file, which is processed by fpp.

-Dname=def
Define name as if by a #define directive. This is the same as if a

#define name def

line appeared in the source file that fpp is processing. The -D option has lower precedence than the -U option. That is, if the same name is used in both a -U option and a -D option, the name will be undefined regardless of the order of the options.

-e
Accept extended source lines, up to 132 characters long.
-fixed
Specifies fixed format input source.
-free
Specifies free format input source.
-Idirectory
Insert directory into the search path for #include files with names not beginning with `/'. directory is inserted ahead of the standard list of ``include'' directories. Thus, #include files with names enclosed in double-quotes (") are searched for first in the directory of the file with the #include line, then in directories named with -I options, and lastly, in directories from the standard list. For #include files with names enclosed in angle-brackets (<>), the directory of the file with the #include line is not searched.
-M
Generate a list of makefile dependencies and write them to the standard output. This list indicates that the object file which would be generated from the input file depends on the input file as well as the include files referenced.
-macro = {yes|no_com|no}
By default, macros are expanded everywhere. Turn off macro expansion in comments by specifying -macro=no_com and turn off macro expansion all together by specifying -macro=no
-P
Do not put line numbering directives to the output file. This directive appears as

#line-number file-name

-Uname
Remove any initial definition of name, where name is a fpp variable that is predefined by a particular preprocessor. Here is a partial list of symbols that may be predefined, depending upon the architecture of the system:
Operating System
unix , __unix , and __SVR4
Hardware
sun, __sun, sparc, and __sparc
-undef
Remove initial definitions for all predefined symbols.
-w
Suppress warning messages.
-w0
Suppress warning messages.
-Xu
Convert upper-case letters to lower-case, except within character-string constants. The default is to not convert upper-case letters to lower-case.
-Xw
For fixed form source files (See below) fpp assumes that the symbol ' ' (space) is insignificant. By default for this form the 'space' symbol is the delimiter of tokens.
-Ydirectory
Use the specified directory in place of the standard list of directories when searching for #include files.

Usage

Source files

fpp operates on both fixed and free form source files. Files with '.F' extension are assumed to be in fixed form. Other files (e.g. ending with '.F90') are assumed to be in free form. These assumptions can be overridden by the '-fixed' and '-free' options. Tab format lines are recognised in fixed form.

A source file may contain fpp tokens. fpp tokens are close to those of Fortran. They are:

Output

Output consists of a modified copy of the input, plus lines of the form:

#line_number file_name

inserted to indicate the original source line number and filename of the output line that follows. There is the '-P' option (See above) which disables the generation of these lines.

Directives

All fpp directives start with the hash symbol (#) as the first character on a line. White space (SPACE or TAB characters) can appear after the initial '#' for proper indentation. The directives can be divided into the following groups:

Macro definition

The #define directive is used to define both simple string variables and more complicated macros:

#define name token-string

This is the definition of a fpp variable. Wherever 'name' appears in the source lines following the definition, 'token-string' will be substituted for 'name'.

#define name(argument[,argument]...)token-string

This is the definition of a function-like macro. Occurrences of the macro 'name' followed by the comma-separated list of arguments within parentheses are substituted by the token string produced from the macro definition. Every occurrence of an argument identifier from the macro definition's arguments list is substituted by the token sequence representing the corresponding macro actual argument.

In these definitions, spaces between the macro name and the '(' symbol are prohibited to prevent the directive being interpreted as a fpp variable definition with the rest of the line beginning with the '(' symbol being interpreted as a token-string.

#undef name

Remove any definition for 'name' (produced by 'D' options, #define directives or by default). No additional tokens are permitted on the directive line after the name.

Including external files

There are two forms of file inclusion:
	#include "filename"

	#include 
Read in the contents of filename at this location. The lines read in from the file are processed by fpp as if it were a part of the current file.

When the notation is used, filename is only searched for in the standard ``include'' directories. See the 'I' and 'Y' options above for more detail. No additional tokens are permitted in the directive line after the final `"' or `>'.

Line control

        #line-number "filename"
Generate line control information for the next pass of the compiler. The integer-constant is interpreted as the line number of the next line and the filename is interpreted as the name of the file from where it comes. If "filename" is not given, the current filename is unchanged.

Conditional selection of source text

There are two forms of conditional selection of source text

  1)
      #if condition_1
       block_1
      #elif condition_2
       block_2
      #else
       block_n
      #endif

  2)
      #ifdef name
       block_1
      #elif condition
       block_2
      #else
       block_n
      #endif

  or
      #ifndef name
       block_1
      #elif condition
       block_2
      #else
       block_n
      #endif

else- and elif-part are optional. There may be more than one elif-part. Condition is an expression involving fpp constants, macros and intrinsic functions. Condition expressions are similar to cpp expressions, and may contain any cpp operations and operands with the exception of c long, octal and hexadecimal constants. Additionally, fpp will accept and evaluate Fortran logical operations .NOT. .AND. .OR. .EQV. .NEQV. .GT. .LT. .LE. .GE. etc. and logical constants .TRUE. .FALSE.

Details

Scope of macro or variable definitions

The scope of a definition begins from the place of its definition and encloses all the source lines (and source lines from included files) from that definition line to the end of the current file.

There are the following exceptions to the scope effected by an fpp definition:

The scope of the macro effect can be limited by means of the #undef directive.

End of macro definition

Macro definition can be of any length and is limited only by the 'newline' symbol. A Macro can be defined in multiple lines. A Macro can be continued to the next line with the insertion of '\'. So, the occurrence of a 'newline' without a macro-continuation signifies the end of the macro definition.

For example:

  #define long_macro_name(x,\
  y) x*y

Function-like macro definition

The number of macro call arguments should be the same as the number of arguments in the corresponding macro definition. An error is flagged if they don't.

Cancelling macro definitions of both kinds

  #undef name
After this directive, 'name' would not interpreted by fpp as a macro or variable name. If this name has not been defined earlier as a macro name, then the given directive has no effect

Conditional source code selection

Subsequent lines up to the matching #else, #elif, or #endif directive, appear in the output only if their constant-expression yields a true value.

The lines following the #elif directive appear in the output only if all of the following conditions hold:

If the constant-expression evaluates to .TRUE., subsequent #elif and #else directives are ignored up to the matching #endif. Any constant-expression allowed in an #if directive is allowed in an #elif directive.

The intrinsic function `defined' can be used in a constant-expression also.

The following items are permitted:

Only these items, integer constants, and names can be used within a constant-expression. Names which have not been defined with the help of the 'D' option, a #define directive or by default, get 0 as the value. The C operation '!=' (not equal) can be used in #if or #elif directive, but NOT in #define directive, where the symbol '!' is considered as the Fortran comment symbol.
#ifdefname
Subsequent lines up to the matching #else, #elif, or #endif appear in the output only if the name has been defined, either by a #define directive or by the 'D' option, and in the absence of an intervening #undef directive. No additional tokens are permitted on the directive line after name.
#ifndefname
Subsequent lines up to the matching #else, #elif, or #endif appear in the output only if name has not been defined, or if its definition has been removed with an #undef directive. No additional tokens are permitted on the directive line after name.
#elifconstant-expression
Any number of #elif directives may appear between an #if, #ifdef, or #ifndef directive and a matching #else or #endif directive.
#else
This inverts the sense of the conditional directive otherwise in effect. If the preceding conditional would indicate that lines are to be included, then lines between the #else and the matching #endif are ignored. If the preceding conditional indicates that lines would be ignored, subsequent lines are included in the output.Conditional directives and corresponding #else directives can be nested.
#endif
End a section of lines begun by one of the conditional directives #if, #ifdef, or #ifndef. Each such directive must have a matching #endif.

Including external files

Files are searched as follows:

for #include "file_name":

for #include : fpp directives (beginning with the # symbol in the first position of lines) can be placed anywhere in a source code, in particular before a Fortran continuation line. The only exception is the prohibition of fpp directives within a macro call divided on several lines by means of continuation symbols.

Comments

fpp permits comments of two kinds:
  1. Fortran language comments. A source line containing one of the symbols 'C', 'c', '*', 'd' or 'D' in the first position, is considered as a comment line. Within such lines macro expansions are not performed. The '!' symbol is interpreted as the beginning of a comment extending to the end of the line. The only exception is the case when this symbol occurs within a constant-expression in #if and #elif directives (See above).
  2. They are excluded from the output and macro expansions are not performed within these symbols. fpp comments can be nested and for each parasymbol '/*' there must be a corresponding parasymbol '*/'. fpp comments are suitable for excluding the compilation of large portions of source instead of commenting every line with Fortran comment symbols.

Intrinsic functions

The intrinsic function

defined(name) or defined name

Returns:

Macro expression

If, during expansion of a macro, the column width of a line exceeds column 72 (for the fixed format) or column 132 (for the free format), fpp inserts appropriate continuation lines.

In the fixed form there is limitation on macro expansions in label fields (positions 1-5):

In the fixed form when the '-Xw' option has been specified an ambiguity may appear if a macro call occurs in a statement position and a macro name begins or coincides with a Fortran keyword. For example, in the following text:
  #define call p(x)   call f(x)
          call p(0)

fpp can not determine with certainty how to interpret the 'call p' token sequence. It could be considered as a macro name. The current implementation does the following:

In the above example the macro expansion would be performed and the following warning would be output:

warning: possibly incorrect substitution of macro callp

It should be noted that this situation appears only when preprocessing a fixed format source code and when the space symbol is not interpreted as a token delimiter. It should be said also that if a macro name coincides with a keyword beginning part, as in the following case:

     #define INT    INTEGER*8
             INTEGER k
then in accordance with the described algorithm, the INTEGER keyword will be found earlier than the INT macro name. Thus, there will be no warning when preprocessing such a macro definition.

Diagnostics

There are three kinds of diagnostic messages:

The messages produced by fpp are intended to be self-explanatory. The line number and filename where the error occurred are printed along with the diagnostic.

See Also

f95(1).