goto


Home

Free Source Code

Program coco

Fact Sheet

Email us


Purple Sage Computing Solutions, Inc.

Program coco

Home --> Fact Sheet --> Free Source Code --> coco

About the Program coco

Go directly to Downloads

Go directly to Introduction to coco

Go directly to The coco setfile

Go directly to Using coco

Go directly to Extensions to the Standard coco

Go directly to An Example of Using coco

The program coco provides preprocessing as per Part 3 of the Fortran Standard (coco stands for "conditional compilation"). It implements the auxiliary third part of ISO/IEC 1539-1:1997 (better known as Fortran 95). (Part 2 is the ISO_VARYING_STRINGS standard, which is sometimes implemented as a module.) A restore program, similar to that described in the standard, is also available for download.

Generally, coco programs are interpreted line by line. A line is either a coco directive or a source line. The coco directives start with the characters "??" in columns 1 and 2. Lines are continued by placing an "&" as the last character of the line to be continued. Except for the "??" characters in columns 1 and 2, coco lines follow the same rules as free format lines in Fortran source code. A coco comment is any text following a "!" following the "??" characters. A coco comment may not follow the "&" at the end of a line containing a continued string.

The make_processor_model program optionally creates a file of symbol definitions which may be used by coco to control the conditional compilation according to which kinds are present on a particular processor. The programmer may then write programs with code supporting all kinds available on all processors of interest, and use coco and the other software of the Portability Project to select source code suitable for each processor. The coco.inc file contains the symbol definitions written by make_processor_model and may be included in the Fortran source file via the coco include directive, or the programmer may manually copy-and-paste it into the Fortran source. This means that a programmer may base coco's preprocessing decisions automaticly on the processor dependent kinds actually supported by the processor being used.

Back to the Top

Introduction to coco

A coco program consists of coco lines and source lines. A coco program may have an optional setfile associated with it. The setfile may be used to control what coco does with coco lines or with source lines which are not intended to be effective in the output source file. The setfile may define coco variables, if so, the setfile definitions override the value contained in the program itself. The definitions must match, however, as far as type and whether the symbol is a constant (this keeps a coco program self contained and consistent).

The standard coco directives are integer and logical declarations and assignments, if/elseif/else/endif directives, and message and stop directives. An integer or logical variable may be given a value where declared, and may be declared to be a constant. As extensions to the standard, a macro capability is provided, as is the ability to specify directories to be searched for include files not found in the current directory (see below). A further extension is the text & copy mechanism, which is a block of text which may be copied to several places within the source program. A text block may have dummy arguments associated with it, which may be replaced by actual arguments when the text block is copied.

The standard coco directives may appear in upper or lower case interchangeably and are summarized on the list below:

  • INCLUDE Directive

    ?? INCLUDE 'filename'

    The filename may appear in single quotes or double quotes. The include directive may not be continued onto subsequent lines.

  • Simple Integer Declaration:

    ?? INTEGER :: name [, name] ...

  • Integer Declaration with Initial Value

    ?? INTEGER :: name=value [, name=value] ...

    The name and name=value forms may be mixed.

  • Integer Constant Declaration

    ?? INTEGER, PARAMETER :: name=value [, name=value] ...

  • Simple Logical Declaration:

    ?? LOGICAL :: name [, name] ...

  • Logical Declaration with Initial Value

    ?? LOGICAL :: name=value [, name=value] ...

    The name and name=value forms may be mixed.

  • Logical Constant Declaration

    ?? LOGICAL, PARAMETER :: name=value [, name=value] ...

  • IF Directive

    ?? IF( logical-expression )THEN

  • ELSEIF Directive

    ?? ELSEIF( logical-expression )THEN

  • ELSE Directive

    ?? ELSE

  • ENDIF Directive

    ?? ENDIF

  • MESSAGE Directive

    ?? MESSAGE [ item [, item ]...]

    The items may be coco variables or expressions, or a string enclosed in single quotes or double quotes.

  • STOP Directive

    ?? STOP

  • Assignment Directive

    ?? name=value

    The value may be a literal value (e.g., 42 or .true.), a coco variable, or a coco expression using coco operators (+, -, *, / with integers; .and., .or., .eqv., .neqv., .not. with logicals; .eq.,==, .ne., /=, .lt., <, .le., <=, .ge., >=, and .gt., > produce a logical result from integer operands). The usual Fortran precedence rules apply. Parentheses are honored.

The name and name=value forms of the integer and logical declarations may be mixed, a name declared to be a constant, of ocurse, must be supplied with a value.

Back to the Top

The coco setfile

The programmer may use a separate file, called a setfile, which permits the programmer to change the values of variables and constants outside the coco program, and to specify what happens to elided source text and coco directives. Within the setfile, variable and constant declarations may appear, the values supplied override those (of the same name) appearing in the coco program proper. There must be a definition of the same variable within the coco program proper, only the value may be changed by the setfile. The setfile is appended to the end of the coco program's output (depending on the value of the ALTER directive, see the following).

The setfile is named according to the output file name, any ".fpp" or ".f90" suffix is discarded and ".set" is appended to make the setfile name. If a file with that name is not found, a file with the default name of "coco.set" is sought. This allows a programmer to have a default setfile for a project or directory, or to control the output on a file-by-file basis. There is only one setfile read for a multi input file invocation of coco. See Using coco for more on the command line.

The fate of source lines not appearing in the coco output and of coco directives is controlled by the ALTER directive. At most one alter directive may appear in a setfile. The -a command line option overrides the alter directive. Examples of alter directives and their effects are described in the following:

  • ?? ALTER: DELETE

    All coco lines and source lines not selected for output are deleted from the output file. Of course, these lines will not be seen by the compiler at all.

  • ?? ALTER: BLANK

    All coco lines and source lines not selected for output are replaced by blank lines in the output file. Of course, these lines will be seen by the compiler as comments.

  • ?? ALTER: SHIFT0

    All coco lines are printed with the leading "?" replaced by a "!". Source lines not selected for output are printed with a "!" in place of the character in column one. Of course, these lines will be seen by the compiler as comments.

  • ?? ALTER: SHIFT1

    All coco lines are printed with a leading "!" before the leading "?". Source lines not selected for output are printed with a "!" preceding the leading character, coco issues a warning if a line so extended exceeds 132 characters. Of course, these lines will be seen by the compiler as comments.

  • ?? ALTER: SHIFT3

    All coco lines are printed with a leading "!?>" before the leading "?". Source lines not selected for output are printed with "!?>" preceding the leading character, coco issues a warning if a line so extended exceeds 132 characters. Of course, these lines will be seen by the compiler as comments. The leading "!?>" makes it easy to write a program to undo the effects of the coco preprocessor (at least so long as the use of coco conforms to the standard and doesn't use any extensions). See the restore program available in the Downloads section.

Using coco

The coco program is written in standard Fortran 95, using two extensions from Fortran 2003. These are the get_command_count() procedure to retrieve the number of command line arguments and the get_command_argument() procedure to retrieve the command line arguments themselves. You will have to find a replacement for these routines if your processor does not support them. These procedures are available from I.S.S. Ltd. via the free F2KCLI Module for a very wide variety of compilers.

SYNOPSIS:

coco -V

coco -h

coco [[options] [--]] [ basename | output input [...]]

The coco program reads its input on stdin and writes its output to stdout if it finds no filename arguments on its command line. The coco program responds to "-V" option by printing its version information and quitting. The coco program responds to the "-h" option by printing a short help message and quitting. Any single filename command line argument has ".fpp" appended to it and used as the single input filename, ".f90" is appended and used as the output filename. If more than one filename argument appears on the command line the first is taken to be the output filename, the rest are treated, in the order of occurrence, as input filenames. Examples follow:

  • coco <input.f >output.f90

    causes coco to read the file input.f and write the file output.f90. A setfile named "coco.set" is sought.

  • coco -V

    causes coco to print its version information to stderr and stop.

  • coco -h

    causes coco to print short summary of its command line options to stderr and stop.

  • coco source

    causes coco to read source.fpp and write source.f90. The filename source.set is checked to see if it exists, if so, it is processed as the setfile. If source.set is not found, coco.set is checked to see if it exists, if so, it is processed as the setfile.

  • coco output.f90 input1.f90 input2.f90 input3.f90

    causes coco to read input1.f90, input2.f90, input3.f90 in that order and to write output.f90. The filename output.set is checked to see if it exists, if so, it is processed as the setfile. If output.set is not found, coco.set is checked to see if it exists, if so, it is processed as the setfile. If coco.set is not found, no setfile is processed.

A good default setfile contains the line ?? ALIGN: DELETE, which overrides the standard specified default of SHIFT3.

Options coco recognizes the following command line options:

  • -a? sets the alter state, with ? being one of d (delete), b (blank), 0 (shift0), 1 (shift1), 3 (shift3). The -a option overrides an ALTER directive in the setfile.
  • -d turns off date and time editing (see below).
  • -Dname[=val] defines a logical or integer constant, as if in the setfile (see below for rules).
  • -e turns off all source editing (see below) (equivalent to -d, -f, -i, -m).
  • -f turns off file name and line number editing (see below).
  • -Ffile names a file to receive documentation output (contained between ??doc and ??end doc directives (see below).
  • -h makes coco print a short summary of coco's options to stderr and quit.
  • -i turns off integer and logical editing (see below).
  • -Idir causes coco to search dir for include files not found in the current directory (see below).
  • -lfile names a file to receive coco's reports, stderr is the default (see below).
  • -m turns off macro editing (see below).
  • -n turns on source line numbering (see below).
  • -p turns on reporting of actual arguments to macros and text blocks which may need enclosing parenthesis (see below).
  • -r turns on reporting of extensions to the coco standard in the logfile (stderr by default).
  • -s makes coco work silently, suppressing all reports, including the default report, made at the end of preprocessing (overrides -p, -r, -u, -v).
  • -u makes coco report symbols declared in the setfile or on the command line, but not declared in any source file (see below).
  • -v makes coco work verbosely, reporting all file opening and closing, and a few other events, to the logfile See below.
  • -V makes coco print its version information to stderr and quit.
  • -wn controls the wrapping of lines which exceed n characters in length. The default is 132. It may be desirable to leave line wrapping on if macros are being expanded. The number n is an unsigned integer which sets the width. Set n to zero to disable wrapping of source lines. Setting n to 72 causes the continuation character to be placed beyond column 72 for fixed format source code, and the continued line is indented to column 7 with a continuation character in column 6 (for fixed format files) (see below).

-D rules The following rule applies to the -D option: if the "=" is present, it must be followed by an integer literal and name is defined to be an integer constant with the value specified. There should be an integer constant with the same name defined within the source file. If no "=" is present, then name is defined to be a logical constant with a value of ".true.". There should be a logical constant with the same name defined within the source file.

The search rule for directories specified by the -I argument and ??directory directive is that the directories specified by the -I argument are searched first. This way, the command line may override the setfile. Directory directives may not appear in the coco program proper so all include files with the same name are known to come from the same directory, and thus each occurance of any one named include file will be the same file. Since coco doesn't know what kind of operating system is in use, the user must append the appropriate separator (i.e., "/", "\" or ":") after the directory name, whether it appears in the -I argument, or the ??directory directive (see below).

Extensions to Standard coco

This program supports some extensions to standard coco. The string ?file? is replaced in source code by the current input file name and the string ?line? is replaced by the current input file line number. This editing is prevented by the -f or -e command line options. The strings ?date? is replaced by the date of the preprocessing and the string ?time? is replaced by the time of the preprocessing. This editing is prevented by the -d or -e options. The string ?coco? is replaced by the coco version and may be prevented by the -e option. These strings are internally defined and may not be changed. They may appear in either case. If they appear in an assert condition or within a text block, the line number is that of the directive.

The string ?name? is checked to see if name is the name of a coco integer or logical. If it is, it is replaced by the value of the coco integer or logical name. The name may be in either case. This editing is prevented by the -i or -e command line options.

A directive has been added to allow macro definition. If a ?name? is found which is not an integer or a logical, it is checked to see if it is the name of a macro. If so, it is replaced with the value of the macro. Arguments may be present, if so, they are substituted in the value.

  • ?? ASSERT "condition"

    This causes code to be written to the output Fortran source to verify that the logical condition is true during program execution, and to halt execution with an error message written to error_unit if it is false. The error message includes the file name and line number where the assert directive was found. The assert directive should be placed only where executable Fortran code is allowed, and the condition should refer to only those Fortran symbols in scope at that location in the source file. The condition may be delimited with single quotes or double quotes. This directive uses quotes around the condition in order to preserve the programmer's case and spacing.

  • ?? ASSERTIF( expression ) "condition"

    ?? ASSERTIF( logical expression ) " condition " acts similarly to the assert above, except that it is only active if the logical expression evaluates to true. This directive acts like an IF, ASSERT, ENDIF sequence.

  • ?? DUMP

    Causes coco to write to the logfile a summary of all symbols (integers, logicals, macros and text blocks) known at the point where the directive is encountered.

  • ?? ENDFILE

    Causes coco to act as if the end of the current input file has been encountered. The file is closed and the next input file is opened. If there is no next input file, processing is terminated and normal end of input actions occur.

  • ?? MACRO :: NAME=STRING

    This causes subsequent strings of the form ?NAME? to be replaced by STRING in the source code. This processing is prevented by the -m or -e command line options. There must not be an "(" immediately following ?NAME? (including white space). A macro definition must appear in the coco program proper, not in the setfile. A macro may not be redefined.

  • ?? MACRO :: NAME( arg[, arg]... )=STRING

    This causes subsequent strings of the form ?NAME?( str[, str]... ) to be replaced by STRING in the source code, with strs substituted for the corresponding ?arg? within STRING. A macro definition must appear in the coco program proper, not in the setfile. A macro may not be redefined. If a macro NAME definition has args, the ?name? must also (it must be followed by a "(" immediately, without any white space).

  • ?? OPTIONS

    Causes coco to print the currently in effect options to the logfile, or to stderr.

  • ?? OUTPUT "filename"

    Causes coco to use the named file as the new output file. The current output file is closed. This may be useful, for example, when one wants to write an include file using the particular set of variables, macros and text that was used to write a source file. If enabled, an end of file report is also written to the logfile, or stderr. The setfile is copied to the end of each output file.

  • ?? REPORT

    Causes coco to print its end of processing report to the logfile, with data current as of the position where the directive is encountered.

  • ?? TEXT :: NAME

    Defines the lines which follow, up to the next end text directive, as being the text block named NAME. The name must not be the name of an integer, logical, macro or another text block. This text may be copied into the coco output by using the copy directive (see below). See below for information about which directives may appear between the text directive and the matching end text directive.

  • ?? END TEXT [NAME]

    Marks the end of the text block which started with the previous text directive. The name, if present, must match the name on the preceeding text directive.

  • ?? TEXT :: NAME( arg[, arg]... )

    Defines the lines which follow, up to the next end text directive, as being the text block named NAME. The name must be unique. This text may be copied into the coco output by using the copy directive, see below. See below for information about which directives may appear between the text directive and the matching end text directive. Each arg will be substituted for ?arg? when the text is copied, see the copy directive below.

  • ?? COPY :: NAME

    Copies the text block named by NAME into the output.

  • ?? COPY :: NAME( str[, str]... )

    Copies the text block named by NAME into the output. The strs are substituted for the corresponding ?arg? within the text block definition during the copy. The copy directive may have args only if the text directive with the same name had args. Each arg on the copy directive is substituted for the corresponding arg on the text directive wherever ?arg? appears within the text block.

  • ?? COPYIF ( expression ) NAME [(...)]

    ?? COPYIF( logical expression ) NAME acts similarly to the copy directives above, except it is only active if the logical expression evaluates to true. The argument list is optional, and must match the corresponding TEXT directive.

  • ?? IFDEF ( symbol )THEN

    ?? IFDEF( symbol )THEN introduces an if-block which is active if the symbol is defined. It must be followed by an ?? ENDIF statement, no ELSEIF or ELSE directives are allowed.

  • ?? IFNDEF ( symbol )THEN

    ?? IFNDEF( symbol )THEN introduces an if-block which is active if the symbol is not defined. It must be followed by an ?? ENDIF statement, no ELSEIF or ELSE directives are allowed.

  • ?? UNDEFINE :: NAME [,NAME]...

    Causes coco to remove the definition of the named symbol(s). An error occurs if the symbol is not defined as an integer, logical, macro or text symbol.

  • ?? DOC

    Causes coco to divert lines of text, with editing if enabled, to the documentation file named on the docfile directive in the setfile. It is an error to have an active DOC ... END DOC sequence if no DOCFILE directive opened a documentation file. No assumption is made regarding the format of the documentation text, it may be man format, HTML, LaTex, plain text, or any other text lines.

  • ?? END DOC

    Ends the text diverted to the documentation file. Further lines are treated as source lines and processed to the output file.

There is one name space for all integers, logicals, macros and text blocks. They are processed in the following order: file, line, date, time, integers and logicals, and lastly, macros. Also, to avoid ambiguity, dummy arguments (to macro or to text blocks) may not have the same name as variables, macros or text blocks.

Only the following directives may appear between the text and end text directives: the assert, if, elseif, else, endif, message, stop and assignment directives. While a text block may appear in an include file, an include directive may not appear within a text block. Declaration directives may not appear because each declaration may only occur once per program. Text blocks may not be nested.

If coco is being used as part of The Portability Project, the coco.inc file can be used to define coco symbols for the compiler targeted by the coco.inc file. The definitions contained in the coco.inc file match those in the standard_types module, these two files must both refer to the same processor, otherwise, suboptimal or incorrect results may occur.

Other directives may appear in the setfile, and are intended to allow the programmer to access extensions to the standard coco otherwise controlled from the command line (in case the program was compiled without the f2kcli module, or other access to the command line). These directives are listed below.

  • ?? DIRECTORY "dirname"

    The directory dirname is searched if an include file is not found in the current directory. Several DIRECTORY directives may each specify a dirname, they are searched in the order they are declared. A directory directive must appear in the setfile so each include file is known to come from the same directory, and thus be the same file. See also the -I command line option.

  • ?? EDIT: [ON|OFF]

    Turns on of off the editing of integers, logicals and macros. Only one EDIT directive may occur in a setfile. See also the -e command line option.

  • ?? LOGFILE "filename"

    The logfile is set to the named file. The file is created. Only one LOGFILE directives may occur in a setfile. See also the -l command line option.

  • ?? DOCFILE "filename"

    Causes coco to open a documentation file to receive lines of text found between ?? DOC and ?? END DOC directives in the source file(s). See also the -F command line option.

  • ?? NUMBER: [ON|OFF]

    Turns on of off the numbering of source lines. If on, source lines appearing in the output as active source lines have the input file name and line number appearing as a Fortran comment starting in column 75. See also the -n command line option.

  • ?? PARENS: [ON|OFF]

    Turns on of off the reporting of actual arguments to macros and text blocks which may require enclosing parenthesis to have the effect intended. Only one PARENS directives may occur in a setfile. For exmaple, an actual argument of a+b may result in a+b*a+b when (a+b)*(a+b) was intended. This warning is based on the argument alone, without regard to the text of the macro or text block. See also the -p command line option.

  • ?? VERBOSE: [ON|OFF]

    Turns on of off the reporting of file openings and closings. Note that the opening of the setfile cannot be reported this way, because the setfile is already being read when this directive is executed. Only one VERBOSE directives may occur in a setfile. See also the -v command line option.

  • ?? WARN: [ON|OFF]

    Turns on or off the reporting of integers and logicals declared in the setfile, but not in any source file. Only one WARN directives may occur in a setfile. See also the -u command line option.

  • ?? WRAP: n

    The integer n is taken as the new value of the wrapping length, if possible. A wrap directive must appear in the setfile. Only one WRAP directives may occur in a setfile. See also the -w command line option.

Back to the Top

An Example of Using coco

Statement of the problem to be solved: A single source file is to be prepared which will specify a Fortran 95 Module containing a cube root function to support all kinds of reals on any processor at a computer center. Using the programs of the Portability Project, specifically, the standard_types module to provide kind parameters and the coco.inc include file, this module may be written as follows:

?? include 'coco.inc'
			
module cube_root
			
use standard_types
			
implicit none

private
			
public cbrt
			
interface cbrt
?? if( single_k )then
   module procedure single_cbrt
?? endif
?? if( double_k )then
   module procedure double_cbrt
?? endif
?? if( quad_k )then
   module procedure quad_cbrt
?? endif
end interface
			
contains
			
?? if( single_k )then
elemental real( kind= single_k) function single_cbrt( x)
real( kind= single_k), intent( in) :: x
	
   single_cbrt = sign( exp( log( abs( x)) / 3.0_single_k), x)
			
end function single_cbrt
?? endif
			
?? if( double_k )then
elemental real( kind= double_k) function double_cbrt( x)
real( kind= double_k), intent( in) :: x
			
   double_cbrt = sign( exp( log( abs( x)) / 3.0_double_k), x)
			
end function double_cbrt
?? endif
			
?? if( quad_k )then
elemental real( kind= quad_k) function quad_cbrt( x)
real( kind= quad_k), intent( in) :: x
			
   quad_cbrt = sign( exp( log( abs( x)) / 3.0_quad_k), x)
			
end function quad_cbrt
?? endif
			
end module cube_root
			

Note that the single_k, double_k, and quad_k which appear in the Fortran source proper are the three kind parameters which are defined in the module standard_types. The single_k, double_k and quad_k which appear in the coco if directives are coco logical variables which are defined in the coco.inc coco include file. Both coco.inc and the source code for standard_types are made (semi-)automatically by the make_processor_model program of the Portability Project All the Fortran kind parameters are valid on any processor, because if the kind isn't supported, the corresponding coco logical variable is set to false, thereby preventing the code from being present in the verison of the source for that processor.

Solving the same problem, but this time using the text-copy mechanism, is shown below:

?? include 'coco.inc'
			
module cube_root

?? text :: cbrt( kind)
elemental real( kind= ?kind?_k) function ?kind?_cbrt( x)
real( kind= ?kind?_k), intent( in) :: x
	
   ?kind?_cbrt = exp( log( abs( x)) / 3.0_?kind?_k)
			
end function ?kind?_cbrt
?? end text cbrt
			
use standard_types
			
implicit none
			
public cbrt
			
interface cbrt
?? if( single_k )then
   module procedure single_cbrt
?? endif
?? if( double_k )then
   module procedure double_cbrt
?? endif
?? if( quad_k )then
   module procedure quad_cbrt
?? endif
end interface
			
contains
			
?? if( single_k )then
?? copy :: cbrt( single)
?? endif
			
?? if( double_k )then
?? copy :: cbrt( double)
?? endif
			
?? if( quad_k )then
?? copy :: cbrt( quad)
?? endif
			
end module cube_root
			

Note that this time, the source for the cbrt() function need be specified only once, the text-copy mechanism performs the copy-paste-substitute operation on demand. A further simplification is to replace the if ... copy ... endif sequences with copyif directives, as shown below:

?? include 'coco.inc'
			
module cube_root

?? text :: cbrt( kind)
elemental real( kind= ?kind?_k) function ?kind?_cbrt( x)
real( kind= ?kind?_k), intent( in) :: x
	
   ?kind?_cbrt = exp( log( abs( x)) / 3.0_?kind?_k)
			
end function ?kind?_cbrt
?? end text cbrt
			
use standard_types
			
implicit none
			
public cbrt
			
interface cbrt
?? if( single_k )then
   module procedure single_cbrt
?? endif
?? if( double_k )then
   module procedure double_cbrt
?? endif
?? if( quad_k )then
   module procedure quad_cbrt
?? endif
end interface
			
contains
			
?? copyif( single_k) cbrt( single)
			
?? copyif( double_k) cbrt( double)
			
?? copyif( quad_k) cbrt( quad)
			
end module cube_root
			

Back to the Top

Downloads

To download a source code for the coco program, click coco preprocessor. You will need the free F2KCLI Module from I.S.S. to compile coco program if your compiler doesn"t support the Fortran 2003 command line access intrinsic procedures. Download the restore program which can un-do coco processing under certain circumstances. Coco no longer needs a standard_types module.

For more information about the standard_types module, click here.

Back to the Top

Please see our Fact Sheet, or E-mail us for more information.


Home - Fact Sheet - Free Source Code - Fortran Links - Email us

Back to the Top