NAME

mac - process Basis variable descriptor files


SYNOPSIS

mac [-b] [-c] [-d docfile] [-e] [-l] [-m macfile] [-p] [-r4] [-s] [-x] [-y yyfile] [-CPU] filename


DESCRIPTION

mac is a Basis utility which reads in a variable descriptor file whose format is described below under USAGE. It reads input from the specified file filename, or from standard input if no filename is specified. It produces as output (optionally) a document file containing names and the comments attached to them, a file consisting of macro definitions for the variable declarations, and a file in mppl format consisting of 'glue' routines which, at runtime, notify Basis of the declared variables and functions, and supply interface routines to compiled functions.


OPTIONS

-b
Turn on debugging output to STDERR. (Neither particularly interesting nor recommended.)

-blockdata
This option causes mac to put out the declarations and initializations of common blocks in a block data subprogram, as required by the FORTRAN standard. The default is to put them out in a subroutine (see -noblockdata, below). One can set this command line option by specifying

MACOPTS=-blockdata

in the package's PackageMake file and then running mmm.

-c
Produce files `pkg.h' and `pkgBase.cc' for interface with C++. This is an alternative to the use of the `language' reserved word detailed elsewhere in this document. See the section ``An Alternative C++ Interface'' for details.

-d docfile
If this option is specified, mac generates an extra output file named docfile, containing a list of the non-hidden groups, variables, and functions in the input variable descriptor file, arranged by group. The comments about each group, variable, and function, and its dimension or argument list (if any) are given. This file is suitable for preliminary user documentation or for use as a `cheat sheet'. It can also be used at run time to read in comments for variables, if the loading of comments into the database has been suppressed by the -x option (see below).

-e
Echo the input to STDERR. (Neither particularly interesting nor recommended.)

--configdir dir
Directory that contains the compiler configuration files compiler-c and compiler-f. Options --cconfig or --fconfig can be used to specifiy each file individually.

--cconfig file
file is the output from configcompiler that characterizes the C compiler. It defines the sizes of C types and is used to match them to basis types.

--fconfig file
file is the output from configcompiler that characterizes the fortran compiler. It defines mapping between byte sizes and kinds.

--fccfile file
The name of the fcc wrap file. The default is pkgWrap.fcc.

--FORT compiler
This option can be used to tell mac which FORTRAN compiler is being used. If mac sees -f90 and $cpu is SOL, then it does not put out the nonstandard static statement for equivalenced common variables. Also, if mmm is told to use f90 on SOL, then it does not send Prolog.SOL to mac. Prolog.SOL inserts a nonstandard 'implicit automatic' at the start of every subroutine and function. mmm automatically adds this command line option to the mac command line.

-h
Toggle the `hidden' attribute. Normally hidden groups are invisible from the Basis command line. Specifying this option brings them out of hiding.

-i
Ignore `language' directives. This option will to suppress the production of headers and wrappers when language ``C'' or language``C++'' are specified.

-[no]kind
If true, use fortran kinds to define types. Default sizes and explicit sizes such as Size4 will be converted to the appropriate kind. double precision will remain as double precision. This option requires the -fconfig option to define the kinds. The default is false.

-l
Sets the output line length to 80 instead of 72.

-m macfile
Set the name of the output file containing mppl macro definitions to macfile instead of the default `macpkg', where `pkg' is the name of the package described by the variable descriptor file. (The makefiles created by mmm(1) name this file pkg.d.) mac will not write the macro definition file if one currently exists and the new one does not differ from it. Since this can prevent superfluous compilations of an entire package, this is an important time-saving feature. For this feature to work properly, the name of the macro definition file must be either macpkg or pkg.d. See also the HIDDEN FILES section at the end of this manual.

--[no]includes
If set, write an include file for each group unless the group has the module or derived option. The default file name for each include is the group name (in lowercase) with suffix .inc. This can be changed by the file group option. The default value can be change with the package option includes=yes.

--includesdir <dir>
Output directory for files created by the --includes option. Defaults to the current directory.

--module <file>
Write out group information as a fortran module file.

-n
mmm sets this flag for NVDF's. When mac sees this flag, it will compute the path names for its header files and wrapper files differently--instead of just using the package name, it uses the full path name of pkg.d and creates <path>pkg_.H, <path>pkgcWrap.c, etc. This is so that mac, running in a different directory, will build all of the necessary mac targets at once. Because of this, during any one compilation, mac runs at most once, thus avoiding recompilations. (If mac runs more than once, it always creates a new pkg.d file --and header files, if a language option is specified-- with a later time stamp, so that any files compiled earlier in the same run which depend on any of these will recompile the next time the system recompiles.) This depends rather heavily on the fact that the package name defined by a file pkg.v should be pkg. Otherwise, mac will run at most twice: once with what it thinks is the package name, then again when it finds the real package name later.

-noblockdata
This is the mac default. It puts out the declarations and initializations of common bloak variables in a subroutine called pkgdata (where pkg is the package name). One can set this command line option by defining

MACOPTS=-noblockdata

in the package's PackageMake file and then running mmm.

-r4
This option applies only on 32-bit architectures. Normally on these architectures, variables declared `real' will default to double precision (64 bits). Specifying this option forces all variables declared `real' to be single precision (32 bits).

-p
Print the variable names to standard output; a feature of doubtful utility.

--preparse file
Dump the internal data structures to file file in a form that can be required by perl.

-s
Toggle the flag that controls whether or not mac prints a report containing names of the files written and the number of variables, groups, and functions in the file to STDOUT. The default is to print the report.

-std
Generate FORTRAN standard output from .v files. This option can be used for any package in which address manipulation for dynamics in the .v file has been moved to C code. It does the following: (1) Dynamic macros for dynamic variables (declared _real, _integer, etc., in .v files) are not emitted. Instead, the variable itself is declared as Address. (2) Point macros are suppressed, so the variable name appears unencumbered. (3) Variables are still initialized to NOTSET. (4) The use of 'loc' to extract addresses is suppressed, and the C function 'varadr' is used instead. (5) The variable by name is still entered into the database as a dynamic, and its type (_real, _integer, etc.) is entered. (6) In the pkg_.h file, the variable is declared and will be accessible by its true type, e. g., float*, integer *, etc. The -std option has no effect if the .v file contains no dynamics. Also, without the -std option, mac works exactly the same as it used to. This will enable a smooth transition to the day when all packages are standard.

-wantc
This option warns mac ahead of time that the VDF contains descriptions of C functions and subroutines, so that it will generate the necessary header and wrapper files for FORTRAN to interact with C. If mmm is run with the -wantc option, then the mac command line will automatically contain this option. Note that entering C function descriptions in the VDF is an alternative to using Fcc; the advantage of this alternative is that it makes available macro definitions from the VDF to C code (see below).

C functions entered into a VDF should be entered in groups with the attributes 'hidden' and 'language ``C'''. These function signatures should be in the same format as in other groups within the VDF, with some exceptions, e. g., in general the types should be as described in the man page for Fcc. There is no provision for C functions which return character strings to FORTRAN.

The names of the .c files containing the sources for functions should be put into the Package file under the keyword SC. Since mac will create a header file named pkg_.h (where pkg is the package being built), these files will depend on pkg_.h, and therefore pkg_.h should be listed before the names of any of the .c files in question. Note that pkg_.h makes all macro definitions in pkg.v available to the C code, and also, if there are any variables declared in language ``C'' groups, these variables will also be accessible in the C code.

-x
Do not generate code which will enter group and variable comments in the Basis database. For a program with a large number of variables and associated comments, this could save some startup time and memory. However, the comments will then not be available as documentation when one uses the Basis `list' command to view variables in the database. This is where the -d option comes in handy: it saves the comments to a document file, from which they can be read if any variables in the package are to be listed. The document file must be stored in a place where Basis can find it. This means that when you configure the package (see .BR config(1)), you must use the `codefile' variable to define a directory path to the directory containing the document file.

-xmitid=0
The mac default is to transmit dimension strings for dynamic variables from the variable descriptor file to the macro definition file unchanged, i. e., identifiers are transmitted as is. In the case when the identifier is a variable, however, some compilers will not handle the declaration. By setting using this command line option, non-range dimensions consisting of or starting with an identifier will be replaced by a 1 in the Dynamic declaration. mac does not expand macros; this is done by mppl later. Hence a dimension which is actually a macro name will be turned into a 1 by this option, so it should be used with care.

-y yyfile
Set the name of the output file containing the run time package connections to yyfile instead of the default `yypkg', where `pkg' is the name of the package being described. (The makefiles created by mmm(1) name this file pkg.y.m.) mac will not write the package connection file if one currently exists and the new one does not differ from it. For this feature to work properly, the name of the package connection file must be either yypkg or pkg.y.m. See also the HIDDEN FILES section at the end of this manual.

-CPU
Produce output which is to be compiled on the specified CPU, which may be one of CS2, SOL, SUN4, HP700, RS6000, SGI, GENERIC, XMP, YMP, C90, CRAY2, ULTRIX, VAX, MAC, IRIX64, AXP, or MIPS. The variable descriptor file can be set up to contain alternate declarations for different architectures, or definitions which are only used on some architectures and not others (see USAGE, below). Normally mac assumes that it is processing for the architecture that it is currently running on; this option allows that default to be overruled.


USAGE

Input File Format

The input file is divided into three parts, which must be in the order shown:

1. The name of the package.

2. Macro specifications and usertype declarations, which may be intermingled.

3. Group declarations, which contain the declarations of variables, commands, and functions.

Comments, which begin with octothorpe `#' and extend to the end of the line, may occur anywhere. Those occurring prior to the declaration of the first group are ignored. Comments occurring after a group declaration but before the declaration of its first variable are attached to the group name. Comments occurring after the declaration of a variable but before the declaration of the next, will be attached to that variable. Code for entering comments into the Basis database will be generated unless the -x option is chosen, and a document file containing variables and their comments will be created if the -d option has been specified.

Comments may also begin with `$' and extend to the end of the line. Such comments are totally ignored (and discarded) by mac.

Any line in the variable descriptor file which begins with a percent sign `%' will be passed on to the macfile unchanged, but with the `%' stripped off. This allows the user to pass complicated macro definitions on to mppl for processing.

The variable descriptor file may contain specifications that the definitions which follow, until specifications are changed, will only be processed for certain architectures. Normally the default architecture is the one on which mac is running, but this may be changed by the -D option mentioned above. Initially mac will process all lines regardless of architecture.

For example:

  SYSTEM SUN4 HP700 SOL

specifies that the lines which follow will be processed only for the three architectures specified. A subsequent specification such as

  SYSTEM +SGI

will add SGI to the list of architectures for which the following lines will be specified. Similarly -CPU for one of the allowed cpu's mentioned above would remove that particular cpu from the list of allowed ones. Finally, the reserved word ALL will process lines which follow for all architectures known to mac.

A description of the formats of the three sections and their components follows. Note that formats are relatively free form; line breaks have no more significance than spaces. Although individual definitions and declarations may be separated by commas, this is not necessary. However, the user is encouraged not to take full advantage of this notational freedom, but attempt to use standard, easy-to-read formats.

Package Name

The package name is a string of no more than three alphanumeric characters beginning with an alphabetic character. Normally the alphabetics are of lower case. (Eventually these restrictions may be removed.)

Usertype definitions

The purpose of usertype definitions is to allow the user either to define a short name for a particular FORTRAN type, or simply to specify that a certain identifier is to be used as a type name would be used, but is not further specified (presumably because it is to be defined later by mppl). Examples and explanations follow.

  <usertype> mytype

Allows the identifier `mytype' to be used as if it were a legal FORTRAN type. Presumably later macro processing by mppl or Basis will resolve the real name of this type. This also allows `_mytype' (meaning a pointer to something of type `mytype') to be used in declarations.

  usertype mytype1 mytype2

This is similar to a macro definition; `mytype1' will be treated like a legal FORTRAN type name, but replaced by `mytype2' wherever else it occurs. Presumably later macro processing by mppl or Basis will resolve the real name of `mytype2'. Similarly to the above, `_mytype1' may also be used, and will be replaced by `_mytype2'.

  usertype mytype <MPPL-type>

In this case, <MPPL-type> represents any of the many types recognized by mppl, which includes all the familiar types recognized by FORTRAN. These types include integer, logical, real, complex, double, character, character*N, as well as such things as integer(Size2), meaning a two-byte integer, and real(Size8), meaning an eight-byte or 64-bit real. Some other mppl types are Address, Filedes, Filename, and Varname.

  usertype mytype - character

This type of definition is used to specify that `mytype' is to be used as if it were a legal FORTRAN character type (but otherwise unspecified). This is done because many FORTRAN compilers demand that characters be put into separate common blocks from other variables, due to alignment problems. This definition is required for any usertype which will eventually become a character type.

Macro definitions

Macro definitions take one of the two forms

  macro_name = <expression>

or

  define macro_name <expression>

In either of these two forms, <expression> is evaluated, if possible, and if not, any parts of the expression which may be evaluated are replaced by their values, and mac puts out a macro definition in standard mppl form to the macfile.

Previously defined macro names appearing in <expression> will be evaluated, except that anything enclosed in square brackets will be transmitted unchanged, with the brackets suppressed. The components of <expression> may be numerical constants, identifiers, or character strings. Constants may be integers in decimal, hexadecimal, or octal format, or real numbers in standard FORTRAN `e' or `f' format. Hexadecimal numbers must begin with a `0' and end with `x' or `X'. Octal numbers consist of a string of digits between `0' and `7' ending with a `b' or `B'. The operators allowed in <expression> are `+', `-' (unary and binary), `*', `/', and `**', with the usual precedence rules. Balanced parentheses may be used to alter operator precedence.

The reserved words integer, real, and character may be used as prefix operators to coerce a component to the particular type specified, and have the same precedence as unary minus (higher than any other operator). mac also has its own coercion protocol, similar to FORTRAN's. For the arithmetic operators `+', `-', `*', and`/' with integer operand(s), the result is integer. If an operand is real, the result is real (real arithmetic is done in double precision by perl). In the case of the exponentiation operator `**', the result is real unless both operands are integer and the exponent is non-negative.

Group declaration

The first part of a group declaration is the group header, which specifies the name of the group and attributes or properties which are to be attached to all the variables declared in that group. The general form of a group header can be any one of the following:

  ******* Group_name <properties> :
  Group Group_name <properties> :
  ******* Group Group_name <properties> :

Note that either the string of asterisks, or the reserved word Group, or both (with asterisks first) must be present. There must be at least three asterisks in the string, if it is present. The group header must be terminated by a colon. The group name is an identifier which begins with an upper case letter.

<properties> is a list which may include a FORTRAN or mppl type or a usertype or a pointer to such (i. e., the type name preceded by an underscore `_'), dimension specification(s), a common block name, specification of units, a language specification, and attributes. Whatever occurs in the list will apply to each variable declared in the group, unless the variable's declaration explicitly overrules the group's. FORTRAN and mppl types and .usertypes have been discussed earlier in this document. We will discuss briefly, in turn, each of the other <property>s.

Dimension specifications may take either (or both) of the following two forms:

compileas ( <dimension_list )>
Each variable in the group will be compiled as if it had been declared with the specified dimensions. The <dimension_list> may be any legal FORTRAN dimension declaration, and may include expressions which contain macro names.

limited ( <dimension_list )>
The effect of this declaration is to cause Basis to treat the variables as if their dimensions were those in the limited <dimension_list>, even though they were declared with some different (presumably larger) size. This allows Basis to access arrays which may be only partly full, and allows the user to manage the size of such arrays. (The limiting string may be changed by a call to the Basis function `setlimit'; see the Basis manual for details.)

A common block name is simply an identifier enclosed in slashes, thus: /name/. All variables in Basis groups are eventually placed into labeled common; normally mac generates names for these blocks automatically. The user may specify the name of the common block for any group to supersede the generated name. Warning: character variables can not be in a common block with any other type, so beware of using this feature carelessly.

A unit specification is any character string enclosed in square brackets, for example: [g/cc] and [lbs.]. Units are purely informational, but can be good documentation for physical quantities. They will be printed out along with other information when the user uses the Basis `list' command to view variables which have units.

A language specification consists of the reserved word language followed by the name of a language in quotes, such as ``FORTRAN'' (the default), ``C'', or ``C++''. This will tell mac that all variables and/or functions in this group were written in that language and to generate the `glue' routines that allow them to be accessed from the Basis command line. There are some restrictions and caveats regarding ``C'' and ``C++'' declarations; please read the later section ``MAC and the C/C++ Interface'' for details.

Attributes are simply identifiers or one of the two reserved words hidden or local. These attributes will be attached to each variable in the group. At runtime it is possible to list (or perform other actions) on all variables which possess a specified attribute. If a group possesses the hidden attribute, then it will not be visible to the Basis command line. Many internal variables and functions in Basis are hidden so that only Basis developers may access them. The local attribute means that the variables in this group will not be put into a common block and will not be visible to the Basis command line; such variables will be purely local to any routine in which they are declared by the `Use' macro.

As we shall see below, some of the group properties may be overruled by the declarations in an individual variable or function.

Variable declaration

A variable declaration may consist of nothing but a name--all of its other properties will then be defaulted from those of the group that it is in. If that group does not have a type, then the variable's type will be the FORTRAN default, depending on its initial letter. A complete variable specification always begins with the name of the variable being declared, and will look something like the following:

 var_name <dims> <type> <comp_as> <lim> <units> <patts> <matts> <alias> <init>

where:

<dims>
is the specification of the dimensions of the variable, if any. These are the dimensions that will be entered into the Basis database for the variable; the variable will be compiled with these dimensions unless there is a compileas specification either on the variable or on its group.

<type>
is, as usual, a FORTRAN or mppl type or a usertype, or a pointer to one of these (a type name prefixed with an underscore `_').

<comp_as>
is a compileas specification, which, if present, overrides the group's compileas, if it has one.

<lim>
is the variable's limited specification, which, if present, overrides the group's limited, if it has one.

<units>
is the variable's <units> specification (a character string enclosed in square brackets), which, if present, overrides the group's <units> specification, if it has one.

<patts>
is a list of one or more attribute names each preceded by a plus sign. These attributes will be added to any the variable already has (previous <patts> or ones inherited from the group).

<matts>
is a list of one or more attribute names each preceded by a minus sign. These attributes will be removed from those the variable already has (previous <patts> or ones inherited from the group).

<alias>
is the name of another variable enclosed in single or double quotes. This is to be the name of a variable which will be equivalenced to the one being declared.

<init>
is an initializer, i. e., a number or a list of numbers contained between slashes, as in a FORTRAN `data' statement. In fact, mac generates a FORTRAN data statement for each variable declared with an initializer.

Subroutine declaration

A subroutine is a FORTRAN subroutine which is to be called from the Basis command line. It is specified as follows; as in variable declarations, most components are optional. Only the reserved word subroutine is required.

  sub_name <args> subroutine <units> <patts> <matts>
<args>
is a parentheses-enclosed, comma-separated list of the names of the formal parameters. Each of these may optionally have its type specified by putting a colon and the type name after the variable name. The type may be any FORTRAN or mppl type. The type name `string' is also allowed, for character variables of arbitrary size. If the types are not declared for any parameters, then the FORTRAN defaults will be used.

<units>, <patts>, and <matts> are the same as in variable declarations.

Function declaration

A function is a FORTRAN function which is to be invoked from the Basis command line. It is specified as follows; as in variable declarations, most components are optional. Only the reserved word function is required.

func_name <args> <type> function <units> <patts> <matts>

<type>
is the type of value which the function is to return. If not specified, the FORTRAN default will be used.

<args>, <units>, <patts>, and <matts> are as described above for subroutines and variables.

Builtin declaration

A builtin is a function which may be called from the FORTRAN command line; it differs from compiled functions in that it can have a variable number of parameters, and its parameters and the values it returns can be any legitimate Basis data objects, including arrays. The user is referred to the Basis manual for details on how to write builtin functions.

Builtin functions are specified as follows. The reserved word builtin and the specification of the number of arguments are required.

b_name <b_args> builtin <arg_spec> <patts> <matts>

<b_args>
specifies the formal parameters of the builtin. This string is used only for documentation and has no fixed format, other than being enclosed in parentheses. It can (and in most cases probably should) contain a list of the formal parameters. Types are usually irrelevant but can be declared, especially if they cannot be converted to another type (`string', for instance). Other conventions include such things as (x[,k]) or (x;k) meaning that the second parameter is optional, and (u1,[u2, ...,]) meaning that there are an arbitrary number of parameters, of which only the first is required.

<arg_spec>
specifies the number of arguments. The specification is enclosed in square brackets. It may be a single integer, such as [3], meaning always three arguments are required. It may specify a range, such as [2-4], meaning up to four arguments, with two being required. It may specify an arbitrary number, such as [1-ARBITRARY].

Command declaration

The command declaration is used to name what by any other designation would be a subroutine, function, or builtin; the distinction is in the way it is invoked from the Basis command line. For instance, a subroutine sub with arguments a and b, and a function f with argument x might be called as follows:

  call sub(a,b)

and

  y = f(x)

whereas a command com with three arguments, an integer, a real, and a string, might be called as follows:

  com  4   3.056e2  "this is a string"

Commands are a privilege granted to those who prefer a command line syntax to the more standard way of invoking functions and subroutines. They are declared as follows:

com_name <carg_spec> command <alias> <units> <patts> <matts>

where:

<carg_spec>
specifies whether the arguments to the command are expressions to be evaluated, or strings. (If this is not specified, then all arguments are assumed to be expressions.) <carg_spec> is a parentheses-enclosed list of the letters `e' (expression) and `s' (string), possibly also containing balanced parentheses. Some examples are: (ese) means that the first argument (if any) is an expression, the second (if any) is a string, and the third and any subsequent arguments (if any) will be expressions; (s(es)) means that the first argument is a string, and that after that, arguments are expression, string, expression, string, etc. Normally command arguments are delimited by commas, spaces, and equal signs. Prefixing an n to the specification such as (nese) means that only commas and equal signs are delimiters.

<alias>
is the name of a function, subroutine, or builtin enclosed in single or double quotes. This is the function for which the command is an alias, i. e., it is the function that will be called with the command's arguments when the command is executed at run time. If <alias> is not present, it defaults to com_name. This function, whether named the same as the command or not, must have been defined as a function, subroutine, or builtin in some variable descriptor file, so that the runtime system is able to interface with it. A command whose name is the same as the function it invokes can be referenced only as a command; if for some reason you want sometimes to use command syntax and sometimes to use regular function syntax, then the command alias must be different from cmd_name.


MAC AND THE C/C++ INTERFACE

In conjunction with mmm and Fcc (see mmm(1) and Fcc(1)), mac will automate the process of allowing your FORTRAN code to call C or C++ functions, and allowing C or C++ code to access FORTRAN variables declared in one or more groups. If a variable descriptor file (VDF for short) contains C and/or C++ groups, then the `Package' file used as input to mmm must specify the files which contain these groups, so that mmm will know about the files created by mac and be able to produce makefile rules to compile them correctly.

Suppose a package named `xyz', for example, contains a group for which the language ``C'' directive is issued. Then mac creates the following files:

xyz_.h
a header file with a #include for Fcc.h (see Fcc(1)), also containing #define's for each macro in the VDF (ensuring that the C code therefore ``knows'' each VDF macro), a struct definition for the variables in the common block whose name is the correctly mangled FORTRAN name of the block, and extern declarations for the C variables used to access the FORTRAN variables. Naming conventions for these variables are discussed below. Any C code referring to these variables should `#include' this file.

xyzWrap.fcc
an Fcc input file (see Fcc(1)) containing declarations of the C routines to be called from FORTRAN, in the correct format for input to Fcc. Fcc produces actual C code from this file (in a file named xyzWrap.c), which contains ``wrapper'' routines, which are simple C functions whose names are the correctly mangled names that FORTRAN uses to call the C code, and which contain code which sets up parameters correctly for passing (e. g., converts FORTRAN strings to null-terminated C strings) and then calls the actual C functions. Naming conventions for these C functions are discussed below.

If package `xyz' contains a group for which the language ``C++'' directive is issued, then mac will create files named xyz_.H and xyzCBase.C, which are C++ header and source files analogous to the above C files, and will put declarations of any C++ functions in xyzWrap.fcc. (Note that this file has the same name whether it contains C or C++ functions, or both.)

If the package contains both C and C++ groups, then all four of the above files will be created, compiled, and linked in. It should be noted that as mac begins processing a VDF, it has no way of anticipating whether there will be C and/or C++ groups in the file. Therefore mac always creates four files according to the above naming convention. If there are no C or C++ groups, these files will be essentially empty except for comments, and, if there were macro definitions, some #define's in the header files.

Variable declarations

Variables are declared in the same format as they would normally be in a VDF, as described earlier in this document. The name of the variable must be lower case. The name by which the variable is to be accessed in C (or C++) must be the same lower case name. How the variable is accessed differs depending on whether it is to be accessed by C or by C++ code, and on whether it is a scalar or an array. Scalar names are passed to C code as pointers; hence a variable called `x' in the FORTRAN will be referred to as `*x' in C. On the other hand, scalar names are passed to C++ code as references; hence a variable called `x' in the FORTRAN will also be referred to as `x' in C++. Array names are passed to both languages as pointers; see below for more details. All C and C++ accessible variables that are not `hidden' or `local' will be entered into the Basis database and thus known to the command line.

The way variables are actually transmitted is that the header file contains a declaration of a struct which is equivalent to the FORTRAN common block and contains the same variables in the same order. It also contains extern declarations of the corresponding C/C++ variables. The C/C++ source file contains the actual definitions of the C/C++ variables, where they are set to the addresses of (or references to) the variables in the struct. (This saves the user from having to know the FORTRAN common block names and from using the struct member notation.)

There are a few special caveats with respect to sharing FORTRAN variables:

arrays
The user must remember that FORTRAN arrays are stored by columns rather than by rows as in C/C++, and that C/C++ arrays are always 0-based. Arrays of more than one dimension in FORTRAN have to be treated as one-dimensional arrays in C/C++, and offsets done by hand. For instance, an element w(i,j) of a FORTRAN array w declared with dimensions (5,10) would be referred to in C/C++ code as w[i-1+(j-1)*5].

complex type
C/C++ has no complex type. To C/C++ code, a FORTRAN complex number looks like a vector of two reals (or doubles). Therefore a FORTRAN complex array will look to C/C++ like a FORTRAN array of reals or doubles, with an extra first dimension of 2.

character type
A FORTRAN character string will look to C/C++ like an array of characters of the same length. Bear in mind that FORTRAN strings are not null-terminated, so you have to have some way of telling the C/C++ program how long the string is. An array of character strings will appear to C/C++ to be an array of characters with an extra first dimension whose value is the length of the strings.

Function Declarations

The C/C++ interface supports subroutines (i. e., C/C++ functions of type void) and functions (C/C++ functions which return a scalar value). The value returned may not be of type character*N, since FORTRAN and C++ character strings are incompatible. If a C/C++ function is to compute and return some character string, then it should be done via a reference parameter.

The FORTRAN name of the subroutine or function should be all lower case. This is the name by which the function will be called in FORTRAN code or from the Basis command line (if it is not in a `hidden' group). The C/C++ name of the function defaults to the same name but with the initial letter capitalized; however, the user may take advantage of the mac alias feature to give the C/C++ function some other name. In C++ code, the function must be of global scope and must be declared `extern ``C''' so that its name will not be mangled. As mentioned earlier, mac produces an input file for the Fcc utility, which will run at compile time and produce C functions which are the ones FORTRAN or the command line actually calls. These functions translate parameters to what C/C++ expects, and then call the C/C++ function. See Fcc(1) for details.

There are some restrictions on the types of function parameters and the types which functions can return. The allowed types for parameters are logical, integer, real, real(Size4), real(Size8), real(Size16), string, character, and Address. As mentioned previously, do not use string or character for function types. Again, the reader is referred to Fcc(1) for details.


AN ALTERNATIVE C++ INTERFACE

The alternative interface offered by the -c command line option has both advantages and disadvantages with respect to the interface described above. On the one hand it allows automatic access from C++ to FORTRAN, in addition to FORTRAN to C++, which the `language' option does not offer. Like the `language' option, it mangles FORTRAN names for C; it also provides a wrapper routine with the mangled name which in turn calls a C++ function inside a class named `pkg' (where `pkg' is the name of the package created by the VDF). Thus the user must place all functions to be accessed from FORTRAN into one class, called `pkg'. A disadvantage of the interface is that it passes variables directly back and forth without making copies. In particular FORTRAN strings are not converted to C strings and vice versa, which can be a serious complication; the C++ code needs to know the maximum length of strings passed from FORTRAN, since they are not null-terminated. (Neither C++ nor FORTRAN functions can return character string values, as mentioned in the previous section.) Another disadvantage is that this access method requires a library of C++ classes which provide easier and more natural access to FORTRAN arrays, but at the cost of having to include this additional library and of having two distinct accessing methods, one for FORTRAN arrays and one for C++ arrays. Finally, to call a FORTRAN function or to access a FORTRAN variable from C++, it is necessary to prefix the name with `pkg::', since mac puts all wrapper routines in the class named `pkg'.

When using the -c option, the VDF has the same basic format as without it. There are, as usual, some restrictions on types of variables and parameters; in general, they must be standard FORTRAN types such as integer, real, double, logical, and character*N, except that, as mentioned above, the return type of a function can not be a character*N. Purely mppl types such as Varname, Address, etc., may not be used.

There are two additional reserved words, cfunction and csubroutine, which are used to designate C++ functions and subroutines which are to be callable from FORTRAN. Routines declared with function and subroutine are taken to be FORTRAN functions to be callable from C++.

The user is encouraged to use mac on a sample VDF and study the C++ interface produced.


HIDDEN FILES

Whenever mac processes a VDF (say pkg.v), it produces a number of hidden files (files whose names start with .). These are to facilitate the feature that prevents new macro definition and package connection files from being written unless they have been changed, and to prevent mac from running when pkg.v has not been changed.

The temporary hidden files are named .tmp.$$, pkg.d$$, and pkg.y.m$$. The latter two are used to contain the new macro definition and package connection files for comparison with the old ones (if they exist), and .tmp.$$ is used to contain the ``diff'' of the old and new.

The permanent hidden files are .pkgd and .pkgym. These are used to keep mac from running twice and to keep it from running at all if they have a newer time stamp than pkg.v. The time stamps of pkg.d and pkg.y.m can not be used to control whether mac runs, because they may not need to be changed each time par.v changes, and so can be allowed to have older time stamps.


SEE ALSO

mmm(1), Fcc(1), config(1).