aboutsummaryrefslogtreecommitdiff
path: root/pkg/tbtables/cfitsio/cfortran.doc
diff options
context:
space:
mode:
authorJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
committerJoe Hunkeler <jhunkeler@gmail.com>2015-08-11 16:51:37 -0400
commit40e5a5811c6ffce9b0974e93cdd927cbcf60c157 (patch)
tree4464880c571602d54f6ae114729bf62a89518057 /pkg/tbtables/cfitsio/cfortran.doc
downloadiraf-osx-40e5a5811c6ffce9b0974e93cdd927cbcf60c157.tar.gz
Repatch (from linux) of OSX IRAF
Diffstat (limited to 'pkg/tbtables/cfitsio/cfortran.doc')
-rw-r--r--pkg/tbtables/cfitsio/cfortran.doc2051
1 files changed, 2051 insertions, 0 deletions
diff --git a/pkg/tbtables/cfitsio/cfortran.doc b/pkg/tbtables/cfitsio/cfortran.doc
new file mode 100644
index 00000000..6c6f4b3a
--- /dev/null
+++ b/pkg/tbtables/cfitsio/cfortran.doc
@@ -0,0 +1,2051 @@
+/* cfortran.doc 4.3 */
+/* www-zeus.desy.de/~burow OR anonymous ftp@zebra.desy.de */
+/* Burkhard Burow burow@desy.de 1990 - 1998. */
+
+
+ cfortran.h : Interfacing C or C++ and FORTRAN
+
+Supports: Alpha and VAX VMS, Alpha OSF, DECstation and VAX Ultrix, IBM RS/6000,
+ Silicon Graphics, Sun, CRAY, Apollo, HP9000, LynxOS, Convex, Absoft,
+ f2c, g77, NAG f90, PowerStation Fortran with Visual C++, NEC SX-4,
+ Portland Group.
+
+C and C++ are generally equivalent as far as cfortran.h is concerned.
+Unless explicitly noted otherwise, mention of C implicitly includes C++.
+C++ compilers tested include:
+ SunOS> CC +p +w # Clean compiles.
+ IRIX> CC # Clean compiles.
+ IRIX> CC -fullwarn # Still some warnings to be overcome.
+ GNU> g++ -Wall # Compiles are clean, other than warnings for unused
+ # cfortran.h static routines.
+
+N.B.: The best documentation on interfacing C or C++ and Fortran is in
+ the chapter named something like 'Interfacing C and Fortran'
+ to be found in the user's guide of almost every Fortran compiler.
+ Understanding this information for one or more Fortran compilers
+ greatly clarifies the aims and actions of cfortran.h.
+ Such a chapter generally also addresses issues orthogonal to cfortran.h,
+ for example the order of array indices, the index of the first element,
+ as well as compiling and linking issues.
+
+
+0 Short Summary of the Syntax Required to Create the Interface
+--------------------------------------------------------------
+
+e.g. Prototyping a FORTRAN subroutine for C:
+
+/* PROTOCCALLSFSUBn is optional for C, but mandatory for C++. */
+
+ PROTOCCALLSFSUB2(SUB_NAME,sub_name,STRING,PINT)
+#define SUB_NAME(A,B) CCALLSFSUB2(SUB_NAME,sub_name,STRING,PINT, A,B)
+
+ ^ - -
+ number of arguments _____| | STRING BYTE PBYTE BYTEV(..)|
+ / | STRINGV DOUBLE PDOUBLE DOUBLEV(..)|
+ / | PSTRING FLOAT PFLOAT FLOATV(..)|
+ types of arguments ____ / | PNSTRING INT PINT INTV(..)|
+ \ | PPSTRING LOGICAL PLOGICAL LOGICALV(..)|
+ \ | PSTRINGV LONG PLONG LONGV(..)|
+ \ | ZTRINGV SHORT PSHORT SHORTV(..)|
+ | PZTRINGV ROUTINE PVOID SIMPLE |
+ - -
+
+
+e.g. Prototyping a FORTRAN function for C:
+/* PROTOCCALLSFFUNn is mandatory for both C and C++. */
+PROTOCCALLSFFUN1(INT,FUN_NAME,fun_name,STRING)
+#define FUN_NAME(A) CCALLSFFUN1(FUN_NAME,fun_name,STRING, A)
+
+e.g. calling FUN_NAME from C: {int a; a = FUN_NAME("hello");}
+
+
+e.g. Creating a FORTRAN-callable wrapper for
+ a C function returning void, with a 7 dimensional integer array argument:
+ [Not supported from C++.]
+FCALLSCSUB1(csub_name,CSUB_NAME,csub_name,INTVVVVVVV)
+
+
+e.g. Creating a FORTRAN-callable wrapper for other C functions:
+FCALLSCFUN1(STRING,cfun_name,CFUN_NAME,cfun_name,INT)
+ [ ^-- BYTE, DOUBLE, FLOAT, INT, LOGICAL, LONG, SHORT, VOID
+ are other types returned by functions. ]
+
+
+e.g. COMMON BLOCKs:
+FORTRAN: common /fcb/ v,w,x
+ character *(13) v, w(4), x(3,2)
+C:
+typedef struct { char v[13],w[4][13],x[2][3][13]; } FCB_DEF;
+#define FCB COMMON_BLOCK(FCB,fcb)
+COMMON_BLOCK_DEF(FCB_DEF,FCB);
+FCB_DEF FCB; /* Define, i.e. allocate memory, in exactly one *.c file. */
+
+e.g. accessing FCB in C: printf("%.13s",FCB.v);
+
+
+
+I Introduction
+--------------
+
+cfortran.h is an easy-to-use powerful bridge between C and FORTRAN.
+It provides a completely transparent, machine independent interface between
+C and FORTRAN routines (= subroutines and/or functions) and global data,
+i.e. structures and COMMON blocks.
+
+The complete cfortran.h package consists of 4 files: the documentation in
+cfortran.doc, the engine cfortran.h, examples in cfortest.c and
+cfortex.f/or. [cfortex.for under VMS, cfortex.f on other machines.]
+
+The cfortran.h package continues to be developed. The most recent version is
+available via www at http://www-zeus.desy.de/~burow
+or via anonymous ftp at zebra.desy.de (131.169.2.244).
+
+The examples may be run using one of the following sets of instructions:
+
+N.B. Unlike earlier versions, cfortran.h 3.0 and later versions
+ automatically uses the correct ANSI ## or pre-ANSI /**/
+ preprocessor operator as required by the C compiler.
+
+N.B. As a general rule when trying to determine how to link C and Fortran,
+ link a trivial Fortran program using the Fortran compilers verbose option,
+ in order to see how the Fortran compiler drives the linker. e.g.
+ unix> cat f.f
+ END
+ unix> f77 -v f.f
+ .. lots of info. follows ...
+
+N.B. If using a C main(), i.e. Fortran PROGRAM is not entry of the executable,
+ and if the link bombs with a complaint about
+ a missing "MAIN" (e.g. MAIN__, MAIN_, f90_main or similar),
+ then Fortran has hijacked the entry point to the executable
+ and wishes to call the rest of the executable via "MAIN".
+ This can usually be satisfied by doing e.g. 'cc -Dmain=MAIN__ ...'
+ but often kills the command line arguments in argv and argc.
+ The f77 verbose option, usually -v, may point to a solution.
+
+
+RS/6000> # Users are strongly urged to use f77 -qextname and cc -Dextname
+RS/6000> # Use -Dextname=extname if extname is a symbol used in the C code.
+RS/6000> xlf -c -qextname cfortex.f
+RS/6000> cc -c -Dextname cfortest.c
+RS/6000> xlf -o cfortest cfortest.o cfortex.o && cfortest
+
+DECFortran> #Only DECstations with DECFortran for Ultrix RISC Systems.
+DECFortran> cc -c -DDECFortran cfortest.c
+DECFortran> f77 -o cfortest cfortest.o cfortex.f && cfortest
+
+IRIX xxxxxx 5.2 02282015 IP20 mips
+MIPS> # DECstations and Silicon Graphics using the MIPS compilers.
+MIPS> cc -o cfortest cfortest.c cfortex.f -lI77 -lU77 -lF77 && cfortest
+MIPS> # Can also let f77 drive linking, e.g.
+MIPS> cc -c cfortest.c
+MIPS> f77 -o cfortest cfortest.o cfortex.f && cfortest
+
+Apollo> # Some 'C compiler 68K Rev6.8' break. [See Section II o) Notes: Apollo]
+Apollo> f77 -c cfortex.f && cc -o cfortest cfortest.c cfortex.o && cfortest
+
+VMS> define lnk$library sys$library:vaxcrtl
+VMS> cc cfortest.c
+VMS> fortran cfortex.for
+VMS> link/exec=cfortest cfortest,cfortex
+VMS> run cfortest
+
+OSF1 xxxxxx V3.0 347 alpha
+Alpha/OSF> # Probably better to let cc drive linking, e.g.
+Alpha/OSF> f77 -c cfortex.f
+Alpha/OSF> cc -o cfortest cfortest.c cfortex.o -lUfor -lfor -lFutil -lots -lm
+Alpha/OSF> cfortest
+Alpha/OSF> # Else may need 'cc -Dmain=MAIN__' to let f77 drive linking.
+
+Sun> # Some old cc(1) need a little help. [See Section II o) Notes: Sun]
+Sun> f77 -o cfortest cfortest.c cfortex.f -lc -lm && cfortest
+Sun> # Some older f77 may require 'cc -Dmain=MAIN_'.
+
+CRAY> cft77 cfortex.f
+CRAY> cc -c cfortest.c
+CRAY> segldr -o cfortest.e cfortest.o cfortex.o
+CRAY> ./cfortest.e
+
+NEC> cc -c -Xa cfortest.c
+NEC> f77 -o cfortest cfortest.o cfortex.f && cfortest
+
+VAX/Ultrix/cc> # For cc on VAX Ultrix only, do the following once to cfortran.h.
+VAX/Ultrix/cc> mv cfortran.h cftmp.h && grep -v "^#pragma" <cftmp.h >cfortran.h
+
+VAX/Ultrix/f77> # In the following, 'CC' is either 'cc' or 'gcc -ansi'. NOT'vcc'
+VAX/Ultrix/f77> CC -c -Dmain=MAIN_ cfortest.c
+VAX/Ultrix/f77> f77 -o cfortest cfortex.f cfortest.o && cfortest
+
+LynxOS> # In the following, 'CC' is either 'cc' or 'gcc -ansi'.
+LynxOS> # Unfortunately cc is easily overwhelmed by cfortran.h,
+LynxOS> # and won't compile some of the cfortest.c demos.
+LynxOS> f2c -R cfortex.f
+LynxOS> CC -Dlynx -o cfortest cfortest.c cfortex.c -lf2c && cfortest
+
+HP9000> # Tested with HP-UX 7.05 B 9000/380 and with A.08.07 A 9000/730
+HP9000> # CC may be either 'c89 -Aa' or 'cc -Aa'
+HP9000> # Depending on the compiler version, you may need to include the
+HP9000> # option '-tp,/lib/cpp' or worse, you'll have to stick to the K&R C.
+HP9000> # [See Section II o) Notes: HP9000]
+HP9000> # Users are strongly urged to use f77 +ppu and cc -Dextname
+HP9000> # Use -Dextname=extname if extname is a symbol used in the C code.
+HP9000> CC -Dextname -c cfortest.c
+HP9000> f77 +ppu cfortex.f -o cfortest cfortest.o && cfortest
+HP9000> # Older f77 may need
+HP9000> f77 -c cfortex.f
+HP9000> CC -o cfortest cfortest.c cfortex.o -lI77 -lF77 && cfortest
+
+HP0000> # If old-style f77 +800 compiled objects are required:
+HP9000> # #define hpuxFortran800
+HP9000> cc -c -Aa -DhpuxFortran800 cfortest.c
+HP9000> f77 +800 -o cfortest cfortest.o cfortex.f
+
+f2c> # In the following, 'CC' is any C compiler.
+f2c> f2c -R cfortex.f
+f2c> CC -o cfortest -Df2cFortran cfortest.c cfortex.c -lf2c && cfortest
+
+Portland Group $ # Presumably other C compilers also work.
+Portland Group $ pgcc -DpgiFortran -c cfortest.c
+Portland Group $ pgf77 -o cfortest cfortex.f cfortest.o && cfortest
+
+NAGf90> # cfortex.f is distributed with Fortran 77 style comments.
+NAGf90> # To convert to f90 style comments do the following once to cfortex.f:
+NAGf90> mv cfortex.f cf_temp.f && sed 's/^C/\!/g' cf_temp.f > cfortex.f
+NAGf90> # In the following, 'CC' is any C compiler.
+NAGf90> CC -c -DNAGf90Fortran cfortest.c
+NAGf90> f90 -o cfortest cfortest.o cfortex.f && cfortest
+
+PC> # On a PC with PowerStation Fortran and Visual_C++
+PC> cl /c cftest.c
+PC> fl32 cftest.obj cftex.for
+
+GNU> # GNU Fortran
+GNU> # See Section VI caveat on using 'gcc -traditional'.
+GNU> gcc -ansi -Wall -O -c -Df2cFortran cfortest.c
+GNU> g77 -ff2c -o cfortest cfortest.o cfortex.f && cfortest
+
+AbsoftUNIX> # Absoft Fortran for all UNIX based operating systems.
+AbsoftUNIX> # e.g. Linux or Next on Intel or Motorola68000.
+AbsoftUNIX> # Absoft f77 -k allows Fortran routines to be safely called from C.
+AbsoftUNIX> gcc -ansi -Wall -O -c -DAbsoftUNIXFortran cfortest.c
+AbsoftUNIX> f77 -k -o cfortest cfortest.o cfortex.f && cfortest
+
+AbsoftPro> # Absoft Pro Fortran for MacOS
+AbsoftPro> # Use #define AbsoftProFortran
+
+CLIPPER> # INTERGRAPH CLIX using CLIPPER C and Fortran compilers.
+CLIPPER> # N.B. - User, not cfortran.h, is responsible for
+CLIPPER> # f77initio() and f77uninitio() if required.
+CLIPPER> # - LOGICAL values are not mentioned in CLIPPER doc.s,
+CLIPPER> # so they may not yet be correct in cfortran.h.
+CLIPPER> # - K&R mode (-knr or Ac=knr) breaks FLOAT functions
+CLIPPER> # (see CLIPPER doc.s) and cfortran.h does not fix it up.
+CLIPPER> # [cfortran.h ok for old sun C which made the same mistake.]
+CLIPPER> acc cfortest.c -c -DCLIPPERFortran
+CLIPPER> af77 cfortex.f cfortest.o -o cfortest
+
+
+By changing the SELECTion ifdef of cfortest.c and recompiling one can try out
+a few dozen different few-line examples.
+
+
+
+The benefits of using cfortran.h include:
+1. Machine/OS/compiler independent mixing of C and FORTRAN.
+
+2. Identical (within syntax) calls across languages, e.g.
+C FORTRAN
+ CALL HBOOK1(1,'pT spectrum of pi+',100,0.,5.,0.)
+/* C*/
+ HBOOK1(1,"pT spectrum of pi+",100,0.,5.,0.);
+
+3. Each routine need only be set up once in its lifetime. e.g.
+/* Setting up a FORTRAN routine to be called by C.
+ ID,...,VMX are merely the names of arguments.
+ These tags must be unique w.r.t. each other but are otherwise arbitrary. */
+PROTOCCALLSFSUB6(HBOOK1,hbook1,INT,STRING,INT,FLOAT,FLOAT,FLOAT)
+#define HBOOK1(ID,CHTITLE,NX,XMI,XMA,VMX) \
+ CCALLSFSUB6(HBOOK1,hbook1,INT,STRING,INT,FLOAT,FLOAT,FLOAT, \
+ ID,CHTITLE,NX,XMI,XMA,VMX)
+
+4. Source code is NOT required for the C routines exported to FORTRAN, nor for
+ the FORTRAN routines imported to C. In fact, routines are most easily
+ prototyped using the information in the routines' documentation.
+
+5. Routines, and the code calling them, can be coded naturally in the language
+ of choice. C routines may be coded with the natural assumption of being
+ called only by C code. cfortran.h does all the required work for FORTRAN
+ code to call C routines. Similarly it also does all the work required for C
+ to call FORTRAN routines. Therefore:
+ - C programmers need not embed FORTRAN argument passing mechanisms into
+ their code.
+ - FORTRAN code need not be converted into C code. i.e. The honed and
+ time-honored FORTRAN routines are called by C.
+
+6. cfortran.h is a single ~1700 line C include file; portable to most
+ remaining, if not all, platforms.
+
+7. STRINGS and VECTORS of STRINGS along with the usual simple arguments to
+ routines are supported as are functions returning STRINGS or numbers. Arrays
+ of pointers to strings and values of structures as C arguments, will soon be
+ implemented. After learning the machinery of cfortran.h, users can expand
+ it to create custom types of arguments. [This requires no modification to
+ cfortran.h, all the preprocessor directives required to implement the
+ custom types can be defined outside cfortran.h]
+
+8. cfortran.h requires each routine to be exported to be explicitly set up.
+ While is usually only be done once in a header file it would be best if
+ applications were required to do no work at all in order to cross languages.
+ cfortran.h's simple syntax could be a convenient back-end for a program
+ which would export FORTRAN or C routines directly from the source code.
+
+
+ -----
+
+Example 1 - cfortran.h has been used to make the C header file hbook.h,
+ which then gives any C programmer, e.g. example.c, full and
+ completely transparent access to CERN's HBOOK library of routines.
+ Each HBOOK routine required about 3 lines of simple code in
+ hbook.h. The example also demonstrates how FORTRAN common blocks
+ are defined and used.
+
+/* hbook.h */
+#include "cfortran.h"
+ :
+PROTOCCALLSFSUB6(HBOOK1,hbook1,INT,STRING,INT,FLOAT,FLOAT,FLOAT)
+#define HBOOK1(ID,CHTITLE,NX,XMI,XMA,VMX) \
+ CCALLSFSUB6(HBOOK1,hbook1,INT,STRING,INT,FLOAT,FLOAT,FLOAT, \
+ ID,CHTITLE,NX,XMI,XMA,VMX)
+ :
+/* end hbook.h */
+
+/* example.c */
+#include "hbook.h"
+ :
+typedef struct {
+ int lines;
+ int status[SIZE];
+ float p[SIZE]; /* momentum */
+} FAKE_DEF;
+#define FAKE COMMON_BLOCK(FAKE,fake)
+COMMON_BLOCK_DEF(FAKE_DEF,FAKE);
+ :
+main ()
+{
+ :
+ HBOOK1(1,"pT spectrum of pi+",100,0.,5.,0.);
+/* c.f. the call in FORTRAN:
+ CALL HBOOK1(1,'pT spectrum of pi+',100,0.,5.,0.)
+*/
+ :
+ FAKE.p[7]=1.0;
+ :
+}
+
+N.B. i) The routine is language independent.
+ ii) hbook.h is machine independent.
+ iii) Applications using routines via cfortran.h are machine independent.
+
+ -----
+
+Example 2 - Many VMS System calls are most easily called from FORTRAN, but
+ cfortran.h now gives that ease in C.
+
+#include "cfortran.h"
+
+PROTOCCALLSFSUB3(LIB$SPAWN,lib$spawn,STRING,STRING,STRING)
+#define LIB$SPAWN(command,input_file,output_file) \
+ CCALLSFSUB3(LIB$SPAWN,lib$spawn,STRING,STRING,STRING, \
+ command,input_file,output_file)
+
+main ()
+{
+LIB$SPAWN("set term/width=132","","");
+}
+
+Obviously the cfortran.h command above could be put into a header file along
+with the description of the other system calls, but as this example shows, it's
+not much hassle to set up cfortran.h for even a single call.
+
+ -----
+
+Example 3 - cfortran.h and the source cstring.c create the cstring.obj library
+ which gives FORTRAN access to all the functions in C's system
+ library described by the system's C header file string.h.
+
+C EXAMPLE.FOR
+ PROGRAM EXAMPLE
+ DIMENSION I(20), J(30)
+ :
+ CALL MEMCPY(I,J,7)
+ :
+ END
+
+/* cstring.c */
+#include <string.h> /* string.h prototypes memcpy() */
+#include "cfortran.h"
+
+ :
+FCALLSCSUB3(memcpy,MEMCPY,memcpy,PVOID,PVOID,INT)
+ :
+
+
+The simplicity exhibited in the above example exists for many but not all
+machines. Note 4. of Section II ii) details the limitations and describes tools
+which try to maintain the best possible interface when FORTRAN calls C
+routines.
+
+ -----
+
+
+II Using cfortran.h
+-------------------
+
+The user is asked to look at the source files cfortest.c and cfortex.f
+for clarification by example.
+
+o) Notes:
+
+o Specifying the Fortran compiler
+ cfortran.h generates interfaces for the default Fortran compiler. The default
+can be overridden by defining,
+ . in the code, e.g.: #define NAGf90Fortran
+ OR . in the compile directive, e.g.: unix> cc -DNAGf90Fortran
+one of the following before including cfortran.h:
+ NAGf90Fortran f2cFortran hpuxFortran apolloFortran sunFortran
+ IBMR2Fortran CRAYFortran mipsFortran DECFortran vmsFortran
+ CONVEXFortran PowerStationFortran AbsoftUNIXFortran
+ SXFortran pgiFortran AbsoftProFortran
+This also allows crosscompilation.
+If wanted, NAGf90Fortran, f2cFortran, DECFortran, AbsoftUNIXFortran,
+AbsoftProFortran and pgiFortran must be requested by the user.
+
+o /**/
+ cfortran.h (ab)uses the comment kludge /**/ when the ANSI C preprocessor
+catenation operator ## doesn't exist. In at least MIPS C, this kludge is
+sensitive to blanks surrounding arguments to macros.
+ Therefore, for applications using non-ANSI C compilers, the argtype_i,
+routine_name, routine_type and common_block_name arguments to the
+PROTOCCALLSFFUNn, CCALLSFSUB/FUNn, FCALLSCSUB/FUNn and COMMON_BLOCK macros
+--- MUST NOT --- be followed by any white space characters such as
+blanks, tabs or newlines.
+
+o LOGICAL
+ FORTRAN LOGICAL values of .TRUE. and .FALSE. do not agree with the C
+representation of TRUE and FALSE on all machines. cfortran.h does the
+conversion for LOGICAL and PLOGICAL arguments and for functions returning
+LOGICAL. Users must convert arrays of LOGICALs from C to FORTRAN with the
+C2FLOGICALV(array_name, elements_in_array); macro. Similarly, arrays of LOGICAL
+values may be converted from the FORTRAN into C representation by using
+F2CLOGICALV(array_name, elements_in_array);
+
+ When C passes or returns LOGICAL values to FORTRAN, by default cfortran.h
+only makes the minimal changes required to the value. [e.g. Set/Unset the
+single relevant bit or do nothing for FORTRAN compilers which use 0 as FALSE
+and treat all other values as TRUE.] Therefore cfortran.h will pass LOGICALs
+to FORTRAN which do not have an identical representation to .TRUE. or .FALSE.
+This is fine except for abuses of FORTRAN/77 in the style of:
+ logical l
+ if (l .eq. .TRUE.) ! (1)
+instead of the correct:
+ if (l .eqv. .TRUE.) ! (2)
+or:
+ if (l) ! (3)
+For FORTRAN code which treats LOGICALs from C in the method of (1),
+LOGICAL_STRICT must be defined before including cfortran.h, either in the
+code, "#define LOGICAL_STRICT", or compile with "cc -DLOGICAL_STRICT".
+There is no reason to use LOGICAL_STRICT for FORTRAN code which does not do (1).
+At least the IBM's xlf and the Apollo's f77 do not even allow code along the
+lines of (1).
+
+ DECstations' DECFortran and MIPS FORTRAN compilers use different internal
+representations for LOGICAL values. [Both compilers are usually called f77,
+although when both are installed on a single machine the MIPS' one is usually
+renamed. (e.g. f772.1 for version 2.10.)] cc doesn't know which FORTRAN
+compiler is present, so cfortran.h assumes MIPS f77. To use cc with DECFortran
+define the preprocessor constant 'DECFortran'.
+e.g. i) cc -DDECFortran -c the_code.c
+ or ii) #define DECFortran /* in the C code or add to cfortran.h. */
+
+ MIPS f77 [SGI and DECstations], f2c, and f77 on VAX Ultrix treat
+.eqv./.neqv. as .eq./.ne.. Therefore, for these compilers, LOGICAL_STRICT is
+defined by default in cfortran.h. [The Sun and HP compilers have not been
+tested, so they may also require LOGICAL_STRICT as the default.]
+
+o SHORT and BYTE
+ They are irrelevant for the CRAY where FORTRAN has no equivalent to C's short.
+Similarly BYTE is irrelevant for f2c and for VAX Ultrix f77 and fort. The
+author has tested SHORT and BYTE with a modified cfortest.c/cfortex.f on all
+machines supported except for the HP9000 and the Sun.
+
+ BYTE is a signed 8-bit quantity, i.e. values are -128 to 127, on all machines
+except for the SGI [at least for MIPS Computer Systems 2.0.] On the SGI it is
+an unsigned 8-bit quantity, i.e. values are 0 to 255, although the SGI 'FORTRAN
+77 Programmers Guide' claims BYTE is signed. Perhaps MIPS 2.0 is dated, since
+the DECstations using MIPS 2.10 f77 have a signed BYTE.
+
+ To minimize the difficulties of signed and unsigned BYTE, cfortran.h creates
+the type 'INTEGER_BYTE' to agree with FORTRAN's BYTE. Users may define
+SIGNED_BYTE or UNSIGNED_BYTE, before including cfortran.h, to specify FORTRAN's
+BYTE. If neither is defined, cfortran.h assumes SIGNED_BYTE.
+
+o CRAY
+ The type DOUBLE in cfortran.h corresponds to FORTRAN's DOUBLE PRECISION.
+ The type FLOAT in cfortran.h corresponds to FORTRAN's REAL.
+
+On a classic CRAY [i.e. all models except for the t3e]:
+( 64 bit) C float == C double == Fortran REAL
+(128 bit) C long double == Fortran DOUBLE PRECISION
+Therefore when moving a mixed C and FORTRAN app. to/from a classic CRAY,
+either the C code will have to change,
+or the FORTRAN code and cfortran.h declarations will have to change.
+DOUBLE_PRECISION is a cfortran.h macro which provides the former option,
+i.e. the C code is automatically changed.
+DOUBLE_PRECISION is 'long double' on classic CRAY and 'double' elsewhere.
+DOUBLE_PRECISION thus corresponds to FORTRAN's DOUBLE PRECISION
+on all machines, including classic CRAY.
+
+On a classic CRAY with the fortran compiler flag '-dp':
+Fortran DOUBLE PRECISION thus is also the faster 64bit type.
+(This switch is often used since the application is usually satisfied by
+ 64 bit precision and the application needs the speed.)
+DOUBLE_PRECISION is thus not required in this case,
+since the classic CRAY behaves like all other machines.
+If DOUBLE_PRECISION is used nonetheless, then on the classic CRAY
+the default cfortran.h behavior must be overridden,
+for example by the C compiler option '-DDOUBLE_PRECISION=double'.
+
+On a CRAY t3e:
+(32 bit) C float == Fortran Unavailable
+(64 bit) C double == C long double == Fortran REAL == Fortran DOUBLE PRECISION
+Notes:
+- (32 bit) is available as Fortran REAL*4 and
+ (64 bit) is available as Fortran REAL*8.
+ Since cfortran.h is all about more portability, not about less portability,
+ the use of the nonstandard REAL*4 and REAL*8 is strongly discouraged.
+- Fortran DOUBLE PRECISION is folded to REAL with the following warning:
+ 'DOUBLE PRECISION is not supported on this platform. REAL will be used.'
+ Similarly, Fortran REAL*16 is mapped to REAL*8 with a warning.
+This behavior differs from that of other machines, including the classic CRAY.
+FORTRAN_REAL is thus introduced for the t3e,
+just as DOUBLE_PRECISION is introduced for the classic CRAY.
+FORTRAN_REAL is 'double' on t3e and 'float' elsewhere.
+FORTRAN_REAL thus corresponds to FORTRAN's REAL on all machines, including t3e.
+
+
+o f2c
+ f2c, by default promotes REAL functions to double. cfortran.h does not (yet)
+support this, so the f2c -R option must be used to turn this promotion off.
+
+o f2c
+[Thanks to Dario Autiero for pointing out the following.]
+f2c has a strange feature in that either one or two underscores are appended
+to a Fortran name of a routine or common block,
+depending on whether or not the original name contains an underscore.
+
+ S.I. Feldman et al., "A fortran to C converter",
+ Computing Science Technical Report No. 149.
+
+ page 2, chapter 2: INTERLANGUAGE conventions
+ ...........
+ To avoid conflict with the names of library routines and with names that
+ f2c generates,
+ Fortran names may have one or two underscores appended. Fortran names are
+ forced to lower case (unless the -U option described in Appendix B is in
+ effect); external names, i.e. the names of fortran procedures and common
+ blocks, have a single underscore appended if they do not contain any
+ underscore and have a pair of underscores appended if they do contain
+ underscores. Thus fortran subroutines names ABC, A_B_C and A_B_C_ result
+ in C functions named abc_, a_b_c__ and a_b_c___.
+ ...........
+
+cfortran.h is unable to change the naming convention on a name by name basis.
+Fortran routine and common block names which do not contain an underscore
+are unaffected by this feature.
+Names which do contain an underscore may use the following work-around:
+
+/* First 2 lines are a completely standard cfortran.h interface
+ to the Fortran routine E_ASY . */
+ PROTOCCALLSFSUB2(E_ASY,e_asy, PINT, INT)
+#define E_ASY(A,B) CCALLSFSUB2(E_ASY,e_asy, PINT, INT, A, B)
+#ifdef f2cFortran
+#define e_asy_ e_asy__
+#endif
+/* Last three lines are a work-around for the strange f2c naming feature. */
+
+o NAG f90
+ The Fortran 77 subset of Fortran 90 is supported. Extending cfortran.h to
+interface C with all of Fortran 90 has not yet been examined.
+ The NAG f90 library hijacks the main() of any program and starts the user's
+program with a call to: void f90_main(void);
+While this in itself is only a minor hassle, a major problem arises because
+NAG f90 provides no mechanism to access command line arguments.
+ At least version 'NAGWare f90 compiler Version 1.1(334)' appended _CB to
+common block names instead of the usual _. To fix, add this to cfortran.h:
+#ifdef old_NAG_f90_CB_COMMON
+#define COMMON_BLOCK CFC_ /* for all other Fortran compilers */
+#else
+#define COMMON_BLOCK(UN,LN) _(LN,_CB)
+#endif
+
+o RS/6000
+ Using "xlf -qextname ...", which appends an underscore, '_', to all FORTRAN
+external references, requires "cc -Dextname ..." so that cfortran.h also
+generates these underscores.
+Use -Dextname=extname if extname is a symbol used in the C code.
+The use of "xlf -qextname" is STRONGLY ENCOURAGED, since it allows for
+transparent naming schemes when mixing C and Fortran.
+
+o HP9000
+ Using "f77 +ppu ...", which appends an underscore, '_', to all FORTRAN
+external references, requires "cc -Dextname ..." so that cfortran.h also
+generates these underscores.
+Use -Dextname=extname if extname is a symbol used in the C code.
+The use of "f77 +ppu" is STRONGLY ENCOURAGED, since it allows for
+transparent naming schemes when mixing C and Fortran.
+
+ At least one release of the HP /lib/cpp.ansi preprocessor is broken and will
+go into an infinite loop when trying to process cfortran.h with the
+## catenation operator. The K&R version of cfortran.h must then be used and the
+K&R preprocessor must be specified. e.g.
+ HP9000> cc -Aa -tp,/lib/cpp -c source.c
+The same problem with a similar solution exists on the Apollo.
+An irrelevant error message '0: extraneous name /usr/include' will appear for
+each source file due to another HP bug, and can be safely ignored.
+e.g. 'cc -v -c -Aa -tp,/lib/cpp cfortest.c' will show that the driver passes
+'-I /usr/include' instead of '-I/usr/include' to /lib/cpp
+
+On some machines the above error causes compilation to stop; one must then use
+K&R C, as with old HP compilers which don't support function prototyping.
+cfortran.h has to be informed that K&R C is to being used, e.g.
+HP9000> cc -D__CF__KnR -c source.c
+
+o AbsoftUNIXFortran
+By default, cfortran.h follows the default AbsoftUNIX/ProFortran and prepends _C
+to each COMMON BLOCK name. To override the cfortran.h behavior
+#define COMMON_BLOCK(UN,LN) before #including cfortran.h.
+[Search for COMMON_BLOCK in cfortran.h for examples.]
+
+o Apollo
+On at least one release, 'C compiler 68K Rev6.8(168)', the default C
+preprocessor, from cc -A xansi or cc -A ansi, enters an infinite loop when
+using cfortran.h. This Apollo bug can be circumvented by using:
+ . cc -DANSI_C_preprocessor=0 to force use of /**/, instead of '##'.
+ AND . The pre-ANSI preprocessor, i.e. use cc -Yp,/usr/lib
+The same problem with a similar solution exists on the HP.
+
+o Sun
+Old versions of cc(1), say <~1986, may require help for cfortran.h applications:
+ . #pragma may not be understood, hence cfortran.h and cfortest.c may require
+ sun> mv cfortran.h cftmp.h && grep -v "^#pragma" <cftmp.h >cfortran.h
+ sun> mv cfortest.c cftmp.c && grep -v "^#pragma" <cftmp.c >cfortest.c
+ . Old copies of math.h may not include the following from a newer math.h.
+ [For an ancient math.h on a 386 or sparc, get similar from a new math.h.]
+ #ifdef mc68000 /* 5 lines Copyright (c) 1988 by Sun Microsystems, Inc. */
+ #define FLOATFUNCTIONTYPE int
+ #define RETURNFLOAT(x) return (*(int *)(&(x)))
+ #define ASSIGNFLOAT(x,y) *(int *)(&x) = y
+ #endif
+
+o CRAY, Sun, Apollo [pre 6.8 cc], VAX Ultrix and HP9000
+ Only FORTRAN routines with less than 15 arguments can be prototyped for C,
+since these compilers don't allow more than 31 arguments to a C macro. This can
+be overcome, [see Section IV], with access to any C compiler without this
+limitation, e.g. gcc, on ANY machine.
+
+o VAX Ultrix
+ vcc (1) with f77 is not supported. Although:
+VAXUltrix> f77 -c cfortex.f
+VAXUltrix> vcc -o cfortest cfortest.c cfortex.o -lI77 -lU77 -lF77 && cfortest
+will link and run. However, the FORTRAN standard I/O is NOT merged with the
+stdin and stdout of C, and instead uses the files fort.6 and fort.5. For vcc,
+f77 can't drive the linking, as for gcc and cc, since vcc objects must be
+linked using lk (1). f77 -v doesn't tell much, and without VAX Ultrix manuals,
+the author can only wait for the info. required.
+
+ fort (1) is not supported. Without VAX Ultrix manuals the author cannot
+convince vcc/gcc/cc and fort to generate names of routines and COMMON blocks
+that match at the linker, lk (1). i.e. vcc/gcc/cc prepend a single underscore
+to external references, e.g. NAME becomes _NAME, while fort does not modify the
+references. So ... either fort has prepend an underscore to external
+references, or vcc/gcc/cc have to generate unmodified names. man 1 fort
+mentions JBL, is JBL the only way?
+
+o VAX VMS C
+ The compiler 'easily' exhausts its table space and generates:
+%CC-F-BUGCHECK, Compiler bug check during parser phase .
+ Submit an SPR with a problem description.
+ At line number 777 in DISK:[DIR]FILE.C;1.
+where the line given, '777', includes a call across C and FORTRAN via
+cfortran.h, usually with >7 arguments and/or very long argument expressions.
+This SPR can be staved off, with the simple modification to cfortran.h, such
+that the relevant CCALLSFSUBn (or CCALLSFFUNn or FCALLSCFUNn) is not
+cascaded up to CCALLSFSUB14, and instead has its own copy of the contents of
+CCALLSFSUB14. [If these instructions are not obvious after examining cfortran.h
+please contact the author.]
+[Thanks go to Mark Kyprianou (kyp@stsci.edu) for this solution.]
+
+o Mips compilers
+ e.g. DECstations and SGI, require applications with a C main() and calls to
+GETARG(3F), i.e. FORTRAN routines returning the command line arguments, to use
+two macros as shown:
+ :
+CF_DECLARE_GETARG; /* This must be external to all routines. */
+ :
+main(int argc, char *argv[])
+{
+ :
+CF_SET_GETARG(argc,argv); /* This must precede any calls to GETARG(3F). */
+ :
+}
+The macros are null and benign on all other systems. Sun's GETARG(3F) also
+doesn't work with a generic C main() and perhaps a workaround similar to the
+Mips' one exists.
+
+o Alpha/OSF
+Using the DEC Fortran and the DEC C compilers of DEC OSF/1 [RT] V1.2 (Rev. 10),
+Fortran, when called from C, has occasional trouble using a routine received as
+a dummy argument.
+
+e.g. In the following the Fortran routine 'e' will crash when it tries to use
+ the C routine 'c' or the Fortran routine 'f'.
+ The example works on other systems.
+
+C FORTRAN /* C */
+ integer function f() #include <stdio.h>
+ f = 2 int f_();
+ return int e_(int (*u)());
+ end
+ int c(){ return 1;}
+ integer function e(u) int d (int (*u)()) { return u();}
+ integer u
+ external u main()
+ e=u() { /* Calls to d work. */
+ return printf("d (c ) returns %d.\n",d (c ));
+ end printf("d (f_) returns %d.\n",d (f_));
+ /* Calls to e_ crash. */
+ printf("e_(c ) returns %d.\n",e_(c ));
+ printf("e_(f_) returns %d.\n",e_(f_));
+ }
+
+Solutions to the problem are welcomed!
+A kludge which allows the above example to work correctly, requires an extra
+argument to be given when calling the dummy argument function.
+i.e. Replacing 'e=u()' by 'e=u(1)' allows the above example to work.
+
+
+o The FORTRAN routines are called using macro expansions, therefore the usual
+caveats for expressions in arguments apply. The expressions to the routines may
+be evaluated more than once, leading to lower performance and in the worst case
+bizarre bugs.
+
+o For those who wish to use cfortran.h in large applications. [See Section IV.]
+This release is intended to make it easy to get applications up and running.
+This implies that applications are not as efficient as they could be:
+- The current mechanism is inefficient if a single header file is used to
+ describe a large library of FORTRAN functions. Code for a static wrapper fn.
+ is generated in each piece of C source code for each FORTRAN function
+ specified with the CCALLSFFUNn statement, irrespective of whether or not the
+ function is ever called.
+- Code for several static utility routines internal to cfortran.h is placed
+ into any source code which #includes cfortran.h. These routines should
+ probably be in a library.
+
+
+i) Calling FORTRAN routines from C:
+ --------------------------------
+
+The FORTRAN routines are defined by one of the following two instructions:
+
+for a SUBROUTINE:
+/* PROTOCCALLSFSUBn is optional for C, but mandatory for C++. */
+PROTOCCALLSFSUBn(ROUTINE_NAME,routine_name,argtype_1,...,argtype_n)
+#define Routine_name(argname_1,..,argname_n) \
+CCALLSFSUBn(ROUTINE_NAME,routine_name,argtype_1,...,argtype_n, \
+ argname_1,..,argname_n)
+
+for a FUNCTION:
+PROTOCCALLSFFUNn(routine_type,ROUTINE_NAME,routine_name,argtype_1,...,argtype_n)
+#define Routine_name(argname_1,..,argname_n) \
+CCALLSFFUNn(ROUTINE_NAME,routine_name,argtype_1,...,argtype_n, \
+ argname_1,..,argname_n)
+
+Where:
+'n' = 0->14 [SUBROUTINE's ->27] (easily expanded in cfortran.h to > 14 [27]) is
+ the number of arguments to the routine.
+Routine_name = C name of the routine (IN UPPER CASE LETTERS).[see 2.below]
+ROUTINE_NAME = FORTRAN name of the routine (IN UPPER CASE LETTERS).
+routine_name = FORTRAN name of the routine (IN lower case LETTERS).
+routine_type = the type of argument returned by FORTRAN functions.
+ = BYTE, DOUBLE, FLOAT, INT, LOGICAL, LONG, SHORT, STRING, VOID.
+ [Instead of VOID one would usually use CCALLSFSUBn.
+ VOID forces a wrapper function to be used.]
+argtype_i = the type of argument passed to the FORTRAN routine and must be
+ consistent in the definition and prototyping of the routine s.a.
+ = BYTE, DOUBLE, FLOAT, INT, LOGICAL, LONG, SHORT, STRING.
+ For vectors, i.e. 1 dim. arrays use
+ = BYTEV, DOUBLEV, FLOATV, INTV, LOGICALV, LONGV, SHORTV,
+ STRINGV, ZTRINGV.
+ For vectors of vectors, i.e. 2 dim. arrays use
+ = BYTEVV, DOUBLEVV, FLOATVV, INTVV, LOGICALVV, LONGVV, SHORTVV.
+ For n-dim. arrays, 1<=n<=7 [7 is the maximum in Fortran 77],
+ = BYTEV..nV's..V, DOUBLEV..V, FLOATV..V, INTV..V, LOGICALV..V,
+ LONGV..V, SHORTV..V.
+ N.B. Array dimensions and types are checked by the C compiler.
+ For routines changing the values of an argument, the keyword is
+ prepended by a 'P'.
+ = PBYTE, PDOUBLE, PFLOAT, PINT, PLOGICAL, PLONG, PSHORT,
+ PSTRING, PSTRINGV, PZTRINGV.
+ For EXTERNAL procedures passed as arguments use
+ = ROUTINE.
+ For exceptional arguments which require no massaging to fit the
+ argument passing mechanisms use
+ = PVOID.
+ The argument is cast and passed as (void *).
+ Although PVOID could be used to describe all array arguments on
+ most (all?) machines , it shouldn't be because the C compiler
+ can no longer check the type and dimension of the array.
+argname_i = any valid unique C tag, but must be consistent in the definition
+ as shown.
+
+Notes:
+
+1. cfortran.h may be expanded to handle a more argument type. To suppport new
+arguments requiring complicated massaging when passed between Fortran and C,
+the user will have to understand cfortran.h and follow its code and mechanisms.
+
+To define types requiring little or no massaging when passed between Fortran
+and C, the pseudo argument type SIMPLE may be used.
+For a user defined type called 'newtype', the definitions required are:
+
+/* The following 7 lines are required verbatim.
+ 'newtype' is the name of the new user defined argument type.
+*/
+#define newtype_cfV( T,A,B,F) SIMPLE_cfV(T,A,B,F)
+#define newtype_cfSEP(T, B) SIMPLE_cfSEP(T,B)
+#define newtype_cfINT(N,A,B,X,Y,Z) SIMPLE_cfINT(N,A,B,X,Y,Z)
+#define newtype_cfSTR(N,T,A,B,C,D,E) SIMPLE_cfSTR(N,T,A,B,C,D,E)
+#define newtype_cfCC( T,A,B) SIMPLE_cfCC(T,A,B)
+#define newtype_cfAA( T,A,B) newtype_cfB(T,A) /* Argument B not used. */
+#define newtype_cfU( T,A) newtype_cfN(T,A)
+
+/* 'parameter_type(A)' is a declaration for 'A' and describes the type of the
+parameter expected by the Fortran function. This type will be used in the
+prototype for the function, if using ANSI C, and to declare the argument used
+by the intermediate function if calling a Fortran FUNCTION.
+Valid 'parameter_type(A)' include: int A
+ void (*A)()
+ double A[17]
+*/
+#define newtype_cfN( T,A) parameter_type(A) /* Argument T not used. */
+
+/* Before any argument of the new type is passed to the Fortran routine, it may
+be massaged as given by 'massage(A)'.
+*/
+#define newtype_cfB( T,A) massage(A) /* Argument T not used. */
+
+An example of a simple user defined type is given cfortex.f and cfortest.c.
+Two uses of SIMPLE user defined types are [don't show the 7 verbatim #defines]:
+
+/* Pass the address of a structure, using a type called PSTRUCT */
+#define PSTRUCT_cfN( T,A) void *A
+#define PSTRUCT_cfB( T,A) (void *) &(A)
+
+/* Pass an integer by value, (not standard F77 ), using a type called INTVAL */
+#define INTVAL_cfN( T,A) int A
+#define INTVAL_cfB( T,A) (A)
+
+[If using VAX VMS, surrounding the #defines with "#pragma (no)standard" allows
+ the %CC-I-PARAMNOTUSED messages to be avoided.]
+
+Upgrades to cfortran.h try to be, and have been, backwards compatible. This
+compatibility cannot be offered to user defined types. SIMPLE user defined
+types are less of a risk since they require so little effort in their creation.
+If a user defined type is required in more than one C header file of interfaces
+to libraries of Fortran routines, good programming practice, and ease of code
+maintenance, suggests keeping any user defined type within a single file which
+is #included as required. To date, changes to the SIMPLE macros were introduced
+in versions 2.6, 3.0 and 3.2 of cfortran.h.
+
+
+2. Routine_name is the name of the macro which the C programmer will use in
+order to call a FORTRAN routine. In theory Routine_name could be any valid and
+unique name, but in practice, the name of the FORTRAN routine in UPPER CASE
+works everywhere and would seem to be an obvious choice.
+
+
+3. <BYTE|DOUBLE|BYTE|DOUBLE|FLOAT|INT|LOGICAL|LONG|SHORT><V|VV|VVV|...>
+
+cfortran.h encourages the exact specification of the type and dimension of
+array parameters because it allows the C compiler to detect errors in the
+arguments when calling the routine.
+
+cfortran.h does not strictly require the exact specification since the argument
+is merely the address of the array and is passed on to the calling routine.
+Any array parameter could be declared as PVOID, but this circumvents
+C's compiletime ability to check the correctness of arguments and is therefore
+discouraged.
+
+Passing the address of these arguments implies that PBYTEV, PFLOATV, ... ,
+PDOUBLEVV, ... don't exist in cfortran.h, since by default the routine and the
+calling code share the same array, i.e. the same values at the same memory
+location.
+
+These comments do NOT apply to arrays of (P)S/ZTRINGV. For these parameters,
+cfortran.h passes a massaged copy of the array to the routine. When the routine
+returns, S/ZTRINGV ignores the copy, while PS/ZTRINGV replaces the calling
+code's original array with copy, which may have been modified by the called
+routine.
+
+
+4. (P)STRING(V):
+- STRING - If the argument is a fixed length character array, e.g. char ar[8];,
+the string is blank, ' ', padded on the right to fill out the array before
+being passed to the FORTRAN routine. The useful size of the string is the same
+in both languages, e.g. ar[8] is passed as character*7. If the argument is a
+pointer, the string cannot be blank padded, so the length is passed as
+strlen(argument). On return from the FORTRAN routine, pointer arguments are not
+disturbed, but arrays have the terminating '\0' replaced to its original
+position. i.e. The padding blanks are never visible to the C code.
+
+- PSTRING - The argument is massaged as with STRING before being passed to the
+FORTRAN routine. On return, the argument has all trailing blanks removed,
+regardless of whether the argument was a pointer or an array.
+
+- (P)STRINGV - Passes a 1- or 2-dimensional char array. e.g. char a[7],b[6][8];
+STRINGV may thus also pass a string constant, e.g. "hiho".
+(P)STRINGV does NOT pass a pointer, e.g. char *, to either a 1- or a
+2-dimensional array, since it cannot determine the array dimensions.
+A pointer can only be passed using (P)ZTRINGV.
+N.B. If a C routine receives a character array argument, e.g. char a[2][3],
+ such an argument is actually a pointer and my thus not be passed by
+ (P)STRINGV. Instead (P)ZTRINGV must be used.
+
+- STRINGV - The elements of the argument are copied into space malloc'd, and
+each element is padded with blanks. The useful size of each element is the same
+in both languages. Therefore char bb[6][8]; is equivalent to character*7 bb(6).
+On return from the routine the malloc'd space is simply released.
+
+- PSTRINGV - Since FORTRAN has no trailing '\0', elements in an array of
+strings are contiguous. Therefore each element of the C array is padded with
+blanks and strip out C's trailing '\0'. After returning from the routine, the
+trailing '\0' is reinserted and kill the trailing blanks in each element.
+
+- SUMMARY: STRING(V) arguments are blank padded during the call to the FORTRAN
+routine, but remain original in the C code. (P)STRINGV arguments are blank
+padded for the FORTRAN call, and after returning from FORTRAN trailing blanks
+are stripped off.
+
+
+5. (P)ZTRINGV:
+- (P)ZTRINGV - is identical to (P)STRINGV,
+except that the dimensions of the array of strings is explicitly specified,
+which thus also allows a pointer to be passed.
+(P)ZTRINGV can thus pass a 1- or 2-dimensional char array, e.g. char b[6][8],
+or it can pass a pointer to such an array, e.g. char *p;.
+ZTRINGV may thus also pass a string constant, e.g. "hiho".
+If passing a 1-dimensional array, routine_name_ELEMS_j (see below) must be 1.
+[Users of (P)ZTRINGV should examine cfortest.c for examples.]:
+
+- (P)ZTRINGV must thus be used instead of (P)STRINGV whenever sizeof()
+can't be used to determine the dimensions of the array of string or strings.
+e.g. when calling FORTRAN from C with a char * received by C as an argument.
+
+- There is no (P)ZTRING type, since (P)ZTRINGV can pass a 1-dimensional
+array or a pointer to such an array, e.g. char a[7], *b;
+If passing a 1-dimensional array, routine_name_ELEMS_j (see below) must be 1.
+
+- To specify the numbers of elements,
+routine_name_ELEMS_j and routine_name_ELEMLEN_j must be defined as shown below
+before interfacing the routine with CCALLSFSUBn, PROTOCCALLSFFUNn, etc.
+
+#define routine_name_ELEMS_j ZTRINGV_ARGS(k)
+ [..ARGS for subroutines, ..ARGF for functions.]
+or
+#define routine_name_ELEMS_j ZTRINGV_NUM(l)
+Where: routine_name is as above.
+ j [1-n], is the argument being specifying.
+ k [1-n], the value of the k'th argument is the dynamic number
+ of elements for argument j. The k'th argument must be
+ of type BYTE, DOUBLE, FLOAT, INT, LONG or SHORT.
+ l the number of elements for argument j. This must be an
+ integer constant available at compile time.
+ i.e. it is static.
+
+- Similarly to specify the useful length, [i.e. don't count C's trailing '\0',]
+of each element:
+#define routine_name_ELEMLEN_j ZTRINGV_ARGS(m)
+ [..ARGS for subroutines, ..ARGF for functions.]
+or
+#define routine_name_ELEMLEN_j ZTRINGV_NUM(q)
+Where: m [1-n], as for k but this is the length of each element.
+ q as for l but this is the length of each element.
+
+
+6. ROUTINE
+The argument is an EXTERNAL procedure.
+
+When C passes a routine to Fortran, the language of the function must be
+specified as follows: [The case of some_*_function must be given as shown.]
+
+When C passes a C routine to a Fortran:
+ FORTRAN_ROUTINE(arg1, .... ,
+ C_FUNCTION(SOME_C_FUNCTION,some_c_function),
+ ...., argn);
+
+and similarly when C passes a Fortran routine to Fortran:
+ FORTRAN_ROUTINE(arg1, .... ,
+ FORTRAN_FUNCTION(SOME_FORT_FUNCTION,some_fort_function),
+ ...., argn);
+
+If fcallsc has been redefined; the same definition of fcallsc used when creating
+the wrapper for 'some_c_function' must also be defined when C_FUNCTION is used.
+See ii) 4. of this section for when and how to redefine fcallsc.
+
+ROUTINE was introduced with cfortran.h version 2.6. Earlier versions of
+cfortran.h used PVOID to pass external procedures as arguments. Using PVOID for
+this purpose is no longer recommended since it won't work 'as is' for
+apolloFortran, hpuxFortran800, AbsoftUNIXFortran, AbsoftProFortran.
+
+7. CRAY only:
+In a given piece of source code, where FFUNC is any FORTRAN routine,
+FORTRAN_FUNCTION(FFUNC,ffunc)
+disallows a previous
+#define FFUNC(..) CCALLSFSUBn(FFUNC,ffunc,...) [ or CCALLSFFUNn]
+in order to make the UPPER CASE FFUNC callable from C.
+#define Ffunc(..) ... is OK though, as are obviously any other names.
+
+
+ii) Calling C routines from FORTRAN:
+ --------------------------------
+
+Each of the following two statements to export a C routine to FORTRAN create
+FORTRAN 'wrappers', written in C, which must be compiled and linked along with
+the original C routines and with the FORTRAN calling code.
+
+FORTRAN callable 'wrappers' may also be created for C macros. i.e. in this
+section, the term 'C function' may be replaced by 'C macro'.
+
+for C functions returning void:
+FCALLSCSUBn( Routine_name,ROUTINE_NAME,routine_name,argtype_1,...,argtype_n)
+
+for all other C functions:
+FCALLSCFUNn(routine_type,Routine_name,ROUTINE_NAME,routine_name,argtype_1,...,argtype_n)
+
+Where:
+'n' = 0->27 (easily expanded to > 27) stands for the number of arguments to the
+ routine.
+Routine_name = the C name of the routine. [see 9. below]
+ROUTINE_NAME = the FORTRAN name of the routine (IN UPPER CASE LETTERS).
+routine_name = the FORTRAN name of the routine (IN lower case LETTERS).
+routine_type = the type of argument returned by C functions.
+ = BYTE, DOUBLE, FLOAT, INT, LOGICAL, LONG, SHORT, STRING, VOID.
+ [Instead of VOID, FCALLSCSUBn is recommended.]
+argtype_i = the type of argument passed to the FORTRAN routine and must be
+ consistent in the definition and prototyping of the routine
+ = BYTE, DOUBLE, FLOAT, INT, LOGICAL, LONG, SHORT, STRING.
+ For vectors, i.e. 1 dim. arrays use
+ = BYTEV, DOUBLEV, FLOATV, INTV, LOGICALV, LONGV, SHORTV, STRINGV.
+ For vectors of vectors, 2 dim. arrays use
+ = BYTEVV, DOUBLEVV, FLOATVV, INTVV, LOGICALVV, LONGVV, SHORTVV.
+ For n-dim. arrays use
+ = BYTEV..nV's..V, DOUBLEV..V, FLOATV..V, INTV..V, LOGICALV..V,
+ LONGV..V, SHORTV..V.
+ For routines changing the values of an argument, the keyword is
+ prepended by a 'P'.
+ = PBYTE, PDOUBLE, PFLOAT, PINT, PLOGICAL, PLONG, PSHORT,
+ PSTRING, PNSTRING, PPSTRING, PSTRINGV.
+ For EXTERNAL procedures passed as arguments use
+ = ROUTINE.
+ For exceptional arguments which require no massaging to fit the
+ argument passing mechanisms use
+ = PVOID.
+ The argument is cast and passed as (void *).
+
+
+Notes:
+
+0. For Fortran calling C++ routines, C++ does NOT easily allow support for:
+ STRINGV.
+ BYTEVV, DOUBLEVV, FLOATVV, INTVV, LOGICALVV, LONGVV, SHORTVV.
+ BYTEV..V, DOUBLEV..V, FLOATV..V, INTV..V, LOGICALV..V, LONGV..V, SHORTV..V.
+Though there are ways to get around this restriction,
+the restriction is not serious since these types are unlikely to be used as
+arguments for a C++ routine.
+
+1. FCALLSCSUB/FUNn expect that the routine to be 'wrapped' has been properly
+prototyped, or at least declared.
+
+
+2. cfortran.h may be expanded to handle a new argument type not already among
+the above.
+
+
+3. <BYTE|DOUBLE|BYTE|DOUBLE|FLOAT|INT|LOGICAL|LONG|SHORT><V|VV|VVV|...>
+
+cfortran.h encourages the exact specification of the type and dimension of
+array parameters because it allows the C compiler to detect errors in the
+arguments when declaring the routine using FCALLSCSUB/FUNn, assuming the
+routine to be 'wrapped' has been properly prototyped.
+
+cfortran.h does not strictly require the exact specification since the argument
+is merely the address of the array and is passed on to the calling routine.
+Any array parameter could be declared as PVOID, but this circumvents
+C's compiletime ability to check the correctness of arguments and is therefore
+discouraged.
+
+Passing the address of these arguments implies that PBYTEV, PFLOATV, ... ,
+PDOUBLEVV, ... don't exist in cfortran.h, since by default the routine and the
+calling code share the same array, i.e. the same values at the same memory
+location.
+
+These comments do NOT apply to arrays of (P)STRINGV. For these parameters,
+cfortran.h passes a massaged copy of the array to the routine. When the routine
+returns, STRINGV ignores the copy, while PSTRINGV replaces the calling
+code's original array with copy, which may have been modified by the called
+routine.
+
+
+4. (P(N))STRING arguments have any trailing blanks removed before being passed
+to C, the same holds true for each element in (P)STRINGV. Space is malloc'd in
+all cases big enough to hold the original string (elements) as well as C's
+terminating '\0'. i.e. The useful size of the string (elements) is the same in
+both languages. P(N)STRING(V) => the string (elements) will be copied from the
+malloc'd space back into the FORTRAN bytes. If one of the two escape mechanisms
+mentioned below for PNSTRING has been used, the copying back to FORTRAN is
+obviously not relevant.
+
+
+5. (PN)STRING's, [NOT PSTRING's nor (P)STRINGV's,] behavior may be overridden
+in two cases. In both cases PNSTRING and STRING behave identically.
+
+a) If a (PN)STRING argument's first 4 bytes are all the NUL character,
+i.e. '\0\0\0\0' the NULL pointer is passed to the C routine.
+
+b) If the characters of a (PN)STRING argument contain at least one HEX-00, i.e.
+the NUL character, i.e. C strings' terminating '\0', the address of the string
+is simply passed to the C routine. i.e. The argument is treated in this case as
+it would be with PPSTRING, to which we refer the reader for more detail.
+
+Mechanism a) overrides b). Therefore, to use this mechanism to pass the NULL
+string, "", to C, the first character of the string must obviously be the NUL
+character, but of the first 4 characters in the string, at least one must not
+be HEX-00.
+
+Example:
+C FORTRAN /* C */
+ character*40 str #include "cfortran.h"
+C Set up a NULL as : void cs(char *s) {if (s) printf("%s.\n",s);}
+C i) 4 NUL characters. FCALLSCSUB1(cs,CS,cs,STRING)
+C ii) NULL pointer.
+ character*4 NULL
+ NULL = CHAR(0)//CHAR(0)//CHAR(0)//CHAR(0)
+
+ data str/'just some string'/
+
+C Passing the NULL pointer to cs.
+ call cs(NULL)
+C Passing a copy of 'str' to cs.
+ call cs(str)
+C Passing address of 'str' to cs. Trailing blanks NOT killed.
+ str(40:) = NULL
+ call cs(str)
+ end
+
+Strings passed from Fortran to C via (PN)STRING must not have undefined
+contents, otherwise undefined behavior will result, since one of the above two
+escape mechanisms may occur depending on the contents of the string.
+
+This is not be a problem for STRING arguments, which are read-only in the C
+routine and hence must have a well defined value when being passed in.
+
+PNSTRING arguments require special care. Even if they are write-only in the C
+routine, PNSTRING's above two escape mechanisms require that the value of the
+argument be well defined when being passed in from Fortran to C. Therefore,
+unless one or both of PNSTRING's escape mechanisms are required, PSTRING should
+be used instead of PNSTRING.
+Prior to version 2.8, PSTRING did have the above two escape mechanisms,
+but they were removed from PSTRING to allow strings with undefined contents to
+be passed in. PNSTRING behaves like the old PSTRING.
+[Thanks go to Paul Dubois (dubios@icf.llnl.gov) for pointing out that PSTRING
+ must allow for strings with undefined contents to be passed in.]
+
+Example:
+C FORTRAN /* C */
+ character*10 s,sn #include "cfortran.h"
+ void ps(char *s) {strcpy(s,"hello");}
+C Can call ps with undef. s. FCALLSCSUB1(ps,PS,ps,PSTRING)
+ call ps(s) FCALLSCSUB1(ps,PNS,pns,PNSTRING)
+ print *,s,'=s'
+
+C Can't call pns with undef. s.
+C e.g. If first 4 bytes of s were
+C "\0\0\0\0", ps would try
+C to copy to NULL because
+C of PNSTRING mechanism.
+ sn = ""
+ call pns(sn)
+ print *,sn,'=sn'
+
+ end
+
+
+6. PPSTRING
+The address of the string argument is simply passed to the C routine. Therefore
+the C routine and the FORTRAN calling code share the same string at the same
+memory location. If the C routine modifies the string, the string will also be
+modified for the FORTRAN calling code.
+The user is responsible for negociating the differences in representation of a
+string in Fortran and in C, i.e. the differences are not automatically resolved
+as they are for (P(N)STRING(V).
+This mechanism is provided for two reasons:
+ - Some C routines require the string to exist at the given memory location,
+ after the C routine has exited. Recall that for the usual (P(N)STRING(V)
+ mechanism, a copy of the FORTRAN string is given to the C routine, and this
+ copy ceases to exist after returning to the FORTRAN calling code.
+ - This mechanism can save runtime CPU cycles over (P(N)STRING(V), since it
+ does not perform their malloc, copy and kill trailing blanks of the string
+ to be passed.
+ Only in a small minority of cases does the potential benefit of the saved
+ CPU cycles outweigh the programming effort required to manually resolve
+ the differences in representation of a string in Fortran and in C.
+
+For arguments passed via PPSTRING, the argument passed may also be an array of
+strings.
+
+
+7. ROUTINE
+ANSI C requires that the type of the value returned by the routine be known,
+For all ROUTINE arguments passed from Fortran to C, the type of ROUTINE is
+specified by defining a cast as follows:
+
+#undef ROUTINE_j
+#define ROUTINE_j (cast)
+where:
+ j [1-n], is the argument being specifying.
+ (cast) is a cast matching that of the argument expected by the C
+ function protoytpe for which a wrapper is being defined.
+
+e.g. To create a Fortran wrapper for qsort(3C):
+#undef ROUTINE_4
+#define ROUTINE_4 (int (*)(void *,void *))
+FCALLSCSUB4(qsort,FQSORT,fqsort,PVOID,INT,INT,ROUTINE)
+
+In order to maintain backward compatibility, cfortran.h defines a generic cast
+for ROUTINE_1, ROUTINE_2, ..., ROUTINE_27. The user's definition is therefore
+strictly required only for DEC C, which at the moment is the only compiler
+which insists on the correct cast for pointers to functions.
+
+When using the ROUTINE argument inside some Fortran code:
+- it is difficult to pass a C routine as the parameter,
+ since in many Fortran implementations,
+ Fortran has no access to the normal C namespace.
+ e.g. For most UNIX,
+ Fortran implicitly only has access to C routines ending in _.
+ If the calling Fortran code receives the routine as a parameter
+ it can of course easily pass it along.
+- if a Fortran routine is passed directly as the parameter,
+ the called C routine must call the parameter routine
+ using the Fortran argument passing conventions.
+- if a Fortran routine is to be passed as the parameter,
+ but if Fortran can be made to pass a C routine as the parameter,
+ then it may be best to pass a C-callable wrapper for the Fortran routine.
+ The called C routine is thus spared all Fortran argument passing conventions.
+ cfortran.h can be used to create such a C-callable wrapper
+ to the parameter Fortran routine.
+
+ONLY PowerStationFortran:
+This Fortran provides no easy way to pass a Fortran routine as an argument to a
+C routine. The problem arises because in Fortran the stack is cleared by the
+called routine, while in C/C++ it is cleared by the caller.
+The C/C++ stack clearing behavior can be changed to that of Fortran by using
+stdcall__ in the function prototype. The stdcall__ cannot be applied in this
+case since the called C routine expects the ROUTINE parameter to be a C routine
+and does not know that it should apply stdcall__.
+In principle the cfortran.h generated Fortran callable wrapper for the called C
+routine should be able to massage the ROUTINE argument such that stdcall__ is
+performed, but it is not yet known how this could be easily done.
+
+
+8. THE FOLLOWING INSTRUCTIONS ARE NOT REQUIRED FOR VAX VMS
+ ------------
+(P)STRINGV information [NOT required for VAX VMS]: cfortran.h cannot convert
+the FORTRAN vector of STRINGS to the required C vector of STRINGS without
+explicitly knowing the number of elements in the vector. The application must
+do one of the following for each (P)STRINGV argument in a routine before that
+routine's FCALLSCFUNn/SUBn is called:
+
+#define routine_name_STRV_Ai NUM_ELEMS(j)
+ or
+#define routine_name_STRV_Ai NUM_ELEM_ARG(k)
+ or
+#define routine_name_STRV_Ai TERM_CHARS(l,m)
+
+where: routine_name is as above.
+ i [i=1->n.] specifies the argument number of a STRING VECTOR.
+ j would specify a fixed number of elements.
+ k [k=1->n. k!=i] would specify an integer argument which specifies the
+ number of elements.
+ l [char] the terminating character at the beginning of an
+ element, indicating to cfortran.h that the preceding
+ elements in the vector are the valid ones.
+ m [m=1-...] the number of terminating characters required to appear
+ at the beginning of the terminating string element.
+ The terminating element is NOT passed on to
+ the C routine.
+
+e.g. #define ce_STRV_A1 TERM_CHARS(' ',2)
+ FCALLSCSUB1(ce,CE,ce,STRINGV)
+
+cfortran.h will pass on all elements, in the 1st and only argument to the C
+routine ce, of the STRING VECTOR until, but not including, the first string
+element beginning with 2 blank, ' ', characters.
+
+
+9. INSTRUCTIONS REQUIRED ONLY FOR FORTRAN COMPILERS WHICH GENERATE
+ -------------
+ ROUTINE NAMES WHICH ARE UNDISTINGUISHABLE FROM C ROUTINE NAMES
+ i.e. VAX VMS
+ AbsoftUNIXFortran (AbsoftProFortran ok, since it uses Uppercase names.)
+ HP9000 if not using the +ppu option of f77
+ IBM RS/6000 if not using the -qextname option of xlf
+ Call them the same_namespace compilers.
+
+FCALLSCSUBn(...) and FCALLSCFUNn(...), when compiled, are expanded into
+'wrapper' functions, so called because they wrap around the original C
+functions and interface the format of the original C functions' arguments and
+return values with the format of the FORTRAN call.
+
+Ideally one wants to be able to call the C routine from FORTRAN using the same
+name as the original C name. This is not a problem for FORTRAN compilers which
+append an underscore, '_', to the names of routines, since the original C
+routine has the name 'name', and the FORTRAN wrapper is called 'name_'.
+Similarly, if the FORTRAN compiler generates upper case names for routines, the
+original C routine 'name' can have a wrapper called 'NAME', [Assuming the C
+routine name is not in upper case.] For these compilers, e.g. Mips, CRAY, IBM
+RS/6000 'xlf -qextname', HP-UX 'f77 +ppu', the naming of the wrappers is done
+automatically.
+
+For same_namespace compilers things are not as simple, but cfortran.h tries to
+provide tools and guidelines to minimize the costs involved in meeting their
+constraints. The following two options can provide same_namespace compilers
+with distinct names for the wrapper and the original C function.
+
+These compilers are flagged by cfortran.h with the CF_SAME_NAMESPACE constant,
+so that the change in the C name occurs only when required.
+
+For the remainder of the discussion, routine names generated by FORTRAN
+compilers are referred to in lower case, these names should be read as upper
+case for the appropriate compilers.
+
+
+HP9000: (When f77 +ppu is not used.)
+f77 has a -U option which forces uppercase external names to be generated.
+Unfortunately, cc does not handle recursive macros. Hence, if one wished to use
+-U for separate C and FORTRAN namespaces, one would have to adopt a different
+convention of naming the macros which allow C to call FORTRAN subroutines.
+(Functions are not a problem.) The macros are currently the uppercase of the
+original FORTRAN name, and would have to be changed to lower case or mixed
+case, or to a different name. (Lower case would of course cause conflicts on
+many other machines.) Therefore, it is suggested that f77 -U not be used, and
+instead that Option a) or Option b) outlined below be used.
+
+
+VAX/VMS:
+For the name used by FORTRAN in calling a C routine to be the same as that of
+the C routine, the source code of the C routine is required. A preprocessor
+directive can then force the C compiler to generate a different name for the C
+routine.
+e.g. #if defined(vms)
+ #define name name_
+ #endif
+ void name() {printf("name: was called.\n");}
+ FCALLSCSUB0(name,NAME,name)
+
+In the above, the C compiler generates the original routine with the name
+'name_' and a wrapper called 'NAME'. This assumes that the name of the routine,
+as seen by the C programmer, is not in upper case. The VAX VMS linker is not
+case sensitive, allowing cfortran.h to export the upper case name as the
+wrapper, which then doesn't conflict with the routine name in C. Since the IBM,
+HP and AbsoftUNIXFortran platforms have case sensitive linkers
+this technique is not available to them.
+
+The above technique is required even if the C name is in mixed case, see
+Option a) for the other compilers, but is obviously not required when
+Option b) is used.
+
+
+Option a) Mixed Case names for the C routines to be called by FORTRAN.
+
+If the original C routines have mixed case names, there are no name space
+conflicts.
+
+Nevertheless for VAX/VMS, the technique outlined above must also used.
+
+
+Option b) Modifying the names of C routines when used by FORTRAN:
+
+The more robust naming mechanism, which guarantees portability to all machines,
+'renames' C routines when called by FORTRAN. Indeed, one must change the names
+on same_namespace compilers when FORTRAN calls C routines for which the source
+is unavailable. [Even when the source is available, renaming may be preferable
+to Option a) for large libraries of C routines.]
+
+Obviously, if done for a single type of machine, it must be done for all
+machines since the names of routines used in FORTRAN code cannot be easily
+redefined for different machines.
+
+The simplest way to achieve this end is to do explicitly give the modified
+FORTRAN name in the FCALLSCSUBn(...) and FCALLSCFUNn(...) declarations. e.g.
+
+FCALLSCSUB0(name,CFNAME,cfname)
+
+This allows FORTRAN to call the C routine 'name' as 'cfname'. Any name can of
+course be used for a given routine when it is called from FORTRAN, although
+this is discouraged due to the confusion it is sure to cause. e.g. Bizarre,
+but valid and allowing C's 'call_back' routine to be called from FORTRAN as
+'abcd':
+
+FCALLSCSUB0(call_back,ABCD,abcd)
+
+
+cfortran.h also provides preprocessor directives for a systematic 'renaming' of
+the C routines when they are called from FORTRAN. This is done by redefining
+the fcallsc macro before the FCALLSCSUB/FUN/n declarations as follows:
+
+#undef fcallsc
+#define fcallsc(UN,LN) preface_fcallsc(CF,cf,UN,LN)
+
+FCALLSCSUB0(hello,HELLO,hello)
+
+Will cause C's routine 'hello' to be known in FORTRAN as 'cfhello'. Similarly
+all subsequent FCALLSCSUB/FUN/n declarations will generate wrappers to allow
+FORTRAN to call C with the C routine's name prefaced by 'cf'. The following has
+the same effect, with subsequent FCALLSCSUB/FUN/n's appending the modifier to
+the original C routines name.
+
+#undef fcallsc
+#define fcallsc(UN,LN) append_fcallsc(Y,y,UN,LN)
+
+FCALLSCSUB0(Xroutine,ROUTINE,routine)
+
+Hence, C's Xroutine is called from FORTRAN as:
+ CALL XROUTINEY()
+
+The original behavior of FCALLSCSUB/FUN/n, where FORTRAN routine names are left
+identical to those of C, is returned using:
+
+#undef fcallsc
+#define fcallsc(UN,LN) orig_fcallsc(UN,LN)
+
+
+In C, when passing a C routine, i.e. its wrapper, as an argument to a FORTRAN
+routine, the FORTRAN name declared is used and the correct fcallsc must be in
+effect. E.g. Passing 'name' and 'routine' of the above examples to the FORTRAN
+routines, FT1 and FT2, respectively:
+
+/* This might not be needed if fcallsc is already orig_fcallsc. */
+#undef fcallsc
+#define fcallsc(UN,LN) orig_fcallsc(UN,LN)
+FT1(C_FUNCTION(CFNAME,cfname));
+
+#undef fcallsc
+#define fcallsc(UN,LN) append_fcallsc(Y,y,UN,LN)
+FT1(C_FUNCTION(XROUTINE,xroutine));
+
+If the names of C routines are modified when used by FORTRAN, fcallsc would
+usually be defined once in a header_file.h for the application. This definition
+would then be used and be valid for the entire application and fcallsc would at
+no point need to be redefined.
+
+
+ONCE AGAIN: THE DEFINITIONS, INSTRUCTIONS, DECLARATIONS AND DIFFICULTIES
+DESCRIBED HERE, NOTE 9. of II ii),
+APPLY ONLY FOR VAX VMS,
+ IBM RS/6000 WITHOUT THE -qextname OPTION FOR xlf, OR
+ HP-UX WITHOUT THE +ppu OPTION FOR f77
+ AbsoftUNIXFortran
+AND APPLY ONLY WHEN CREATING WRAPPERS WHICH ENABLE FORTRAN TO CALL C ROUTINES.
+
+
+
+iii) Using C to manipulate FORTRAN COMMON BLOCKS:
+ -------------------------------------------------------
+
+FORTRAN common blocks are set up with the following three constructs:
+
+1.
+#define Common_block_name COMMON_BLOCK(COMMON_BLOCK_NAME,common_block_name)
+
+Common_block_name is in UPPER CASE.
+COMMON_BLOCK_NAME is in UPPER CASE.
+common_block_name is in lower case.
+[Common_block_name actually follows the same 'rules' as Routine_name in Note 2.
+ of II i).] This construct exists to ensure that C code accessing the common
+block is machine independent.
+
+2.
+COMMON_BLOCK_DEF(TYPEDEF_OF_STRUCT, Common_block_name);
+
+where
+typedef { ... } TYPEDEF_OF_STRUCT;
+declares the structure which maps on to the common block. The #define of
+Common_block_name must come before the use of COMMON_BLOCK_DEF.
+
+3.
+In exactly one of the C source files, storage should be set aside for the
+common block with the definition:
+
+TYPEDEF_OF_STRUCT Common_block_name;
+
+The above definition may have to be omitted on some machines for a common block
+which is initialized by Fortran BLOCK DATA or is declared with a smaller size
+in the C routines than in the Fortran routines.
+
+The rules for common blocks are not well defined when linking/loading a mixture
+of C and Fortran, but the following information may help resolve problems.
+
+From the 2nd or ANSI ed. of K&R C, p.31, last paragraph:
+i)
+ An external variable must be defined, exactly once, outside of any function;
+ this sets aside storage for it.
+ii)
+ The variable must also be declared in each function that wants to access it;
+ ...
+ The declaration ... may be implicit from context.
+
+In Fortran, every routine says 'common /bar/ foo',
+i.e. part ii) of the above, but there's no part i) requirement.
+cc/ld on some machines don't require i) either.
+Therefore, when handling Fortran, and sometimes C,
+the loader/linker must automagically set aside storage for common blocks.
+
+Some loaders, including at least one for the CRAY, turn off the
+'automagically set aside storage' capability for Fortran common blocks,
+if any C object declares that common block.
+Therefore, C code should define, i.e. set aside storage,
+for the the common block as shown above.
+
+e.g.
+C Fortran
+ common /fcb/ v,w,x
+ character *(13) v, w(4), x(3,2)
+
+/* C */
+typedef struct { char v[13],w[4][13],x[2][3][13]; } FCB_DEF;
+#define Fcb COMMON_BLOCK(FCB,fcb)
+COMMON_BLOCK_DEF(FCB_DEF,Fcb);
+FCB_DEF Fcb; /* Definition, which sets aside storage for Fcb, */
+ /* may appear in at most one C source file. */
+
+
+C programs can place a string (or a multidimensional array of strings) into a
+FORTRAN common block using the following call:
+
+C2FCBSTR( CSTR, FSTR,DIMENSIONS);
+
+where:
+
+CSTR is a pointer to the first element of C's copy of the string (array).
+ The C code must use a duplicate of, not the original, common block string,
+ because the FORTRAN common block does not allocate space for C strings'
+ terminating '\0'.
+
+FSTR is a pointer to the first element of the string (array) in the common
+ block.
+
+DIMENSIONS is the number of dimensions of string array.
+ e.g. char a[10] has DIMENSIONS=0.
+ char aa[10][17] has DIMENSIONS=1.
+ etc...
+
+C2FCBSTR will copy the string (array) from CSTR to FSTR, padding with blanks,
+' ', the trailing characters as required. C2FCBSTR uses DIMENSIONS and FSTR to
+determine the lengths of the individual string elements and the total number of
+elements in the string array.
+
+Note that:
+- the number of string elements in CSTR and FSTR are identical.
+- for arrays of strings, the useful lengths of strings in CSTR and FSTR must be
+ the same. i.e. CSTR elements each have 1 extra character to accommodate the
+ terminating '\0'.
+- On most non-ANSI compilers, the DIMENSION argument cannot be prepended by any
+ blanks.
+
+
+FCB2CSTR( FSTR, CSTR,DIMENSIONS)
+
+is the inverse of C2FCBSTR, and shares the same arguments and caveats.
+FCB2CSTR copies each string element of FSTR to CSTR, minus FORTRAN strings'
+trailing blanks.
+
+
+cfortran.h USERS ARE STRONGLY URGED TO EXAMINE THE COMMON BLOCK EXAMPLES IN
+cfortest.c AND cfortex.f. The use of strings in common blocks is
+demonstrated, along with a suggested way for C to imitate FORTRAN EQUIVALENCE'd
+variables.
+
+
+ ===> USERS OF CFORTRAN.H NEED READ NO FURTHER <===
+
+
+III Some Musings
+----------------
+
+cfortran.h is simple enough to be used by the most basic of applications, i.e.
+making a single C/FORTRAN routine available to the FORTRAN/C programmers. Yet
+cfortran.h is powerful enough to easily make entire C/FORTRAN libraries
+available to FORTRAN/C programmers.
+
+
+cfortran.h is the ideal tool for FORTRAN libraries which are being (re)written
+in C, but are to (continue to) support FORTRAN users. It allows the routines to
+be written in 'natural C', without having to consider the FORTRAN argument
+passing mechanisms of any machine. It also allows C code accessing these
+rewritten routines, to use the C entry point. Without cfortran.h, one risks the
+perverse practice of C code calling a C function using FORTRAN argument passing
+mechanisms!
+
+
+Perhaps the philosophy and mechanisms of cfortran.h could be used and extended
+to create other language bridges such as ADAFORTRAN, CPASCAL, COCCAM, etc.
+
+
+The code generation machinery inside cfortran.h, i.e. the global structure is
+quite good, being clean and workable as seen by its ability to meet the needs
+and constraints of many different compilers. Though the individual instructions
+of the A..., C..., T..., R... and K... tables deserve to be cleaned up.
+
+
+
+IV Getting Serious with cfortran.h
+-----------------------------------
+
+cfortran.h is set up to be as simple as possible for the casual user. While
+this ease of use will always be present, 'hooks', i.e. preprocessor directives,
+are required in cfortran.h so that some of the following 'inefficiencies' can
+be eliminated if they cause difficulties:
+
+o cfortran.h contains a few small routines for string manipulation. These
+routines are declared static and are included and compiled in all source code
+which uses cfortran.h. Hooks should be provided in cfortran.h to create an
+object file of these routines, allowing cfortran.h to merely prototypes
+these routines in the application source code. This is the only 'problem' which
+afflicts both halves of cfortran.h. The remaining discussion refers to the C
+calls FORTRAN half only.
+
+o Similar to the above routines, cfortran.h generates code for a 'wrapper'
+routine for each FUNCTION exported from FORTRAN. Again cfortran.h needs
+preprocessor directives to create a single object file of these routines,
+and to merely prototype them in the applications.
+
+o Libraries often contain hundreds of routines. While the preprocessor makes
+quick work of generating the required interface code from cfortran.h and the
+application.h's, it may be convenient for very large stable libraries to have
+final_application.h's which already contain the interface code, i.e. these
+final_application.h's would not require cfortran.h. [The convenience can be
+imagined for the VAX VMS CC compiler which has a fixed amount of memory for
+preprocessor directives. Not requiring cfortran.h, with its hundreds of
+directives, could help prevent this compiler from choking on its internal
+limits quite so often.]
+
+With a similar goal in mind, cfortran.h defines 100's of preprocessor
+directives. There is always the potential that these will clash with other tags
+in the users code, so final_applications.h, which don't require cfortran.h,
+also provide the solution.
+
+In the same vein, routines with more than 14 arguments can not be interfaced by
+cfortran.h with compilers which limit C macros to 31 arguments. To resolve this
+difficulty, final_application.h's can be created on a compiler without this
+limitation.
+
+Therefore, new machinery is required to do:
+
+application.h + cfortran.h => final_application.h
+
+The following example may help clarify the means and ends:
+
+If the following definition of the HBOOK1 routine, the /*commented_out_part*/,
+is passed through the preprocessor [perhaps #undefing and #defining preprocessor
+constants if creating an application.h for compiler other than that of the
+preprocessor being used, e.g. cpp -Umips -DCRAY ... ] :
+
+#include "cfortran.h"
+PROTOCCALLSFSUB6(HBOOK1,hbook1,INT,STRING,INT,FLOAT,FLOAT,FLOAT)
+/*#define HBOOK1(ID,CHTITLE,NX,XMI,XMA,VMX) \*/
+ CCALLSFSUB6(HBOOK1,hbook1,INT,STRING,INT,FLOAT,FLOAT,FLOAT, \
+ ID,CHTITLE,NX,XMI,XMA,VMX)
+
+A function prototype is produced by the PROTOCCALLSFSUB6(...).
+Interface code is produced, based on the 'variables',
+ID,CHTITLE,NX,XMI,XMA,VMX, which will correctly massage a HBOOK1 call.
+Therefore, adding the #define line:
+
+'prototype code'
+#define HBOOK1(ID,CHTITLE,NX,XMI,XMA,VMX) \
+ 'interface code'(ID,CHTITLE,NX,XMI,XMA,VMX)
+
+which is placed into final_application.h.
+
+The only known limitation of the above method does not allow the 'variable'
+names to include B1,B2,...,B9,BA,BB,...
+
+Obviously the machinery to automatically generate final_applications.h from
+cfortran.h and applications.h needs more than just some preprocessor
+directives, but a fairly simple unix shell script should be sufficient. Any
+takers?
+
+
+
+V Machine Dependencies of cfortran.h
+------------------------------------
+
+Porting cfortran.h applications, e.g. the hbook.h and cstring.c mentioned
+above, to other machines is trivial since they are machine independent. Porting
+cfortran.h requires a solid knowledge of the new machines C preprocessor, and
+its FORTRAN argument passing mechanisms. Logically cfortran.h exists as two
+halves, a "C CALLS FORTRAN" and a "FORTRAN CALLS C" utility. In some cases it
+may be perfectly reasonable to port only 'one half' of cfortran.h onto a new
+system.
+
+
+The lucky programmer porting cfortran.h to a new machine, must discover the
+FORTRAN argument passing mechanisms. A safe starting point is to assume that
+variables and arrays are simply passed by reference, but nothing is guaranteed.
+Strings, and n-dimensional arrays of strings are a different story. It is
+doubtful that any systems do it quite like VAX VMS does it, so that a UNIX or
+f2c versions may provide an easier starting point.
+
+
+cfortran.h uses and abuses the preprocessor's ## operator. Although the ##
+operator does not exist in many compilers, many kludges do. cfortran.h uses
+/**/ with no space allowed between the slashes, '/', and the macros or tags
+to be concatenated. e.g.
+#define concat(a,b) a/**/b /* works*/
+main()
+{
+ concat(pri,ntf)("hello"); /* e.g. */
+}
+N.B. On some compilers without ##, /**/ may also not work. The author may be
+able to offer alternate kludges.
+
+
+
+VI Bugs in vendors C compilers and other curiosities
+----------------------------------------------------
+
+1. ULTRIX xxxxxx 4.3 1 RISC
+
+Condolences to long suffering ultrix users!
+DEC supplies a working C front end for alpha/OSF, but not for ultrix.
+
+From K&R ANSI C p. 231:
+ ultrix> cat cat.c
+ #define cat(x, y) x ## y
+ #define xcat(x,y) cat(x,y)
+ cat(cat(1,2),3)
+ xcat(xcat(1,2),3)
+ ultrix> cc -E cat.c
+ 123 <---- Should be: cat(1,2)3
+ 123 <---- Correct.
+ ultrix>
+
+The problem for cfortran.h, preventing use of -std and -std1:
+ ultrix> cat c.c
+ #define cat(x, y) x ## y
+ #define xcat(x,y) cat(x,y)
+ #define AB(X) X+X
+ #define C(E,F,G) cat(E,F)(G)
+ #define X(E,F,G) xcat(E,F)(G)
+ C(A,B,2)
+ X(A,B,2)
+ ultrix> cc -std1 -E c.c
+ 2+2
+ AB (2) <---- ?????????????
+ ultrix>
+ ultrix> cc -std0 -E c.c
+ 2+2
+ AB(2) <---- ?????????????
+ ultrix>
+
+Due to further ultrix preprocessor problems,
+for all definitions of definitions with arguments,
+cfortran.h >= 3.0 includes the arguments and recommends the same,
+even though it is not required by ANSI C.
+e.g. Users are advised to do
+ #define fcallsc(UN,LN) orig_fcallsc(UN,LN)
+instead of
+ #define fcallsc orig_fcallsc
+since ultrix fails to properly preprocess the latter example.
+CRAY used to (still does?) occasionally trip up on this problem.
+
+
+2. ConvexOS convex C210 11.0 convex
+
+In a program with a C main, output to LUN=6=* from Fortran goes into
+$pwd/fort.6 instead of stdout. Presumably, a magic incantation can be called
+from the C main in order to properly initialize the Fortran I/O.
+
+
+3. SunOS 5.3 Generic_101318-69 sun4m sparc
+
+The default data and code alignments produced by cc, gcc and f77 are compatible.
+If deviating from the defaults, consistent alignment options must be used
+across all objects compiled by cc and f77. [Does gcc provide such options?]
+
+
+4. SunOS 5.3 Generic_101318-69 sun4m sparc with cc: SC3.0.1 13 Jul 1994
+ or equivalently
+ ULTRIX 4.4 0 RISC using cc -oldc
+ are K&R C preprocessors that suffer from infinite loop macros, e.g.
+
+ zedy03> cat src.c
+ #include "cfortran.h"
+ PROTOCCALLSFFUN1(INT,FREV,frev, INTV)
+ #define FREV(A1) CCALLSFFUN1( FREV,frev, INTV, A1)
+ /* To avoid the problem, deletete these ---^^^^--- spaces. */
+ main() { static int a[] = {1,2}; FREV(a); return EXIT_SUCCESS; }
+
+ zedy03> cc -c -Xs -v -DMAX_PREPRO_ARGS=31 -D__CF__KnR src.c
+ "src.c", line 4: FREV: actuals too long
+ "src.c", line 4: FREV: actuals too long
+ .... 3427 more lines of the same message
+ "src.c", line 4: FREV: actuals too long
+ cc : Fatal error in /usr/ccs/lib/cpp
+ Segmentation fault (core dumped)
+
+
+5. Older sun C compilers
+
+To link to f77 objects, older sun C compilers require the math.h macros:
+
+#define RETURNFLOAT(x) { union {double _d; float _f; } _kluge; \
+ _kluge._f = (x); return _kluge._d; }
+#define ASSIGNFLOAT(x,y) { union {double _d; float _f; } _kluge; \
+ _kluge._d = (y); x = _kluge._f; }
+
+Unfortunately, in at least some copies of the sun math.h, the semi-colon
+for 'float _f;' is left out, leading to compiler warnings.
+
+The solution is to correct math.h, or to change cfortran.h to #define
+RETURNFLOAT(x) and ASSIGNFLOAT(x,y) instead of including math.h.
+
+
+6. gcc version 2.6.3 and probably all other versions as well
+
+Unlike all other C compilers supported by cfortran.h,
+'gcc -traditional' promotes to double all functions returning float
+as demonstrated bu the following example.
+
+/* m.c */
+#include <stdio.h>
+int main() { FLOAT_FUNCTION d(); float f; f = d(); printf("%f\n",f); return 0; }
+
+/* d.c */
+float d() { return -123.124; }
+
+burow[29] gcc -c -traditional d.c
+burow[30] gcc -DFLOAT_FUNCTION=float m.c d.o && a.out
+0.000000
+burow[31] gcc -DFLOAT_FUNCTION=double m.c d.o && a.out
+-123.124001
+burow[32]
+
+Thus, 'gcc -traditional' is not supported by cfortran.h.
+Support would require the same RETURNFLOAT, etc. macro machinery
+present in old sun math.h, before sun gave up the same promotion.
+
+
+7. CRAY
+
+At least some versions of the t3e and t3d C preprocessor are broken
+in the fashion described below.
+At least some versions of the t90 C preprocessor do not have this problem.
+
+On the CRAY, all Fortran names are converted to uppercase.
+Generally the uppercase name is also used for the macro interface
+created by cfortran.h.
+
+For example, in the following interface,
+EASY is both the name of the macro in the original C code
+and EASY is the name of the resulting function to be called.
+
+#define EASY(A,B) CCALLSFSUB2(EASY,easy, PINT, INTV, A, B)
+
+The fact that a macro called EASY() expands to a function called EASY()
+is not a problem for a working C preprocessor.
+From Kernighan and Ritchie, 2nd edition, p.230:
+
+ In both kinds of macro, the replacement token sequence is repeatedly
+ rescanned for more identifiers. However, once a given identifier has been
+ replaced in a given expansion, it is not replaced if it turns up again during
+ rescanning; instead it is left unchanged.
+
+Unfortunately, some CRAY preprocessors are broken and don't obey the above rule.
+A work-around is for the user to NOT use the uppercase name
+of the name of the macro interface provided by cfortran.h. For example:
+
+#define Easy(A,B) CCALLSFSUB2(EASY,easy, PINT, INTV, A, B)
+
+Luckily, the above work-around is not required since the following
+work-around within cfortran.h also circumvents the bug:
+
+ /* (UN), not UN, is required in order to get around CRAY preprocessor bug.*/
+ #define CFC_(UN,LN) (UN) /* Uppercase FORTRAN symbols. */
+
+Aside: The Visual C++ compiler is happy with UN, but barfs on (UN),
+ so either (UN) causes nonstandard C/C++ or Visual C++ is broken.
+
+
+VII History and Acknowledgements
+--------------------------------
+
+1.0 - Supports VAX VMS using C 3.1 and FORTRAN 5.4. Oct. '90.
+1.0 - Supports Silicon Graphics w. Mips Computer 2.0 f77 and cc. Feb. '91.
+ [Port of C calls FORTRAN half only.]
+1.1 - Supports Mips Computer System 2.0 f77 and cc. Mar. '91.
+ [Runs on at least: Silicon Graphics IRIX 3.3.1
+ DECstations with Ultrix V4.1]
+1.2 - Internals made simpler, smaller, faster, stronger. May '91.
+ - Mips version works on IBM RS/6000, this is now called the unix version.
+1.3 - UNIX and VAX VMS versions are merged into a single cfortran.h. July '91.
+ - C can help manipulate (arrays of) strings in FORTRAN common blocks.
+ - Dimensions of string arrays arguments can be explicit.
+ - Supports Apollo DomainOS 10.2 (sys5.3) with f77 10.7 and cc 6.7.
+
+2.0 - Improved code generation machinery creates K&R or ANSI C. Aug. '91.
+ - Supports Sun, CRAY. f2c with vcc on VAX Ultrix.
+ - cfortran.h macros now require routine and COMMON block names in both
+ upper and lower case. No changes required to applications though.
+ - PROTOCCALLSFSUBn is eliminated, with no loss to cfortran.h performance.
+ - Improved tools and guidelines for naming C routines called by FORTRAN.
+2.1 - LOGICAL correctly supported across all machines. Oct. '91.
+ - Improved support for DOUBLE PRECISION on the CRAY.
+ - HP9000 fully supported.
+ - VAX Ultrix cc or gcc with f77 now supported.
+2.2 - SHORT, i.e. INTEGER*2, and BYTE now supported. Dec. '91.
+ - LOGICAL_STRICT introduced. More compact and robust internal tables.
+ - typeV and typeVV for type = BYTE, DOUBLE, FLOAT, INT, LOGICAL, LONG,SHORT.
+ - FORTRAN passing strings and NULL pointer to C routines improved.
+2.3 - Extraneous arguments removed from many internal tables. May '92.
+ - Introduce pseudo argument type SIMPLE for user defined types.
+ - LynxOS using f2c supported. (Tested with LynxOS 2.0 386/AT.)
+2.4 - Separation of internal C and Fortran compilation directives. Oct. '92.
+ - f2c and NAG f90 supported on all machines.
+2.5 - Minor mod.s to source and/or doc for HP9000, f2c, and NAG f90. Nov. '92.
+2.6 - Support external procedures as arguments with type ROUTINE. Dec. '92.
+2.7 - Support Alpha VMS. Support HP9000 f77 +ppu Jan. '93.
+ - Support arrays with up to 7 dimensions.
+ - Minor mod. of Fortran NULL to C via (P)STRING.
+ - Specify the type of ROUTINE passed from Fortran to C [ANSI C requirement.]
+ - Macros never receive a null parameter [RS/6000 requirement.]
+2.8 - PSTRING for Fortran calls C no longer provides escape to pass April'93.
+ NULL pointer nor to pass address of original string.
+ PNSTRING introduced with old PSTRING's behavior.
+ PPSTRING introduced to always pass original address of string.
+ - Support Alpha/OSF.
+ - Document that common blocks used in C should be declared AND defined.
+
+3.0 - Automagic handling of ANSI ## versus K&R /**/ preprocessor op. March'95.
+ - Less chance of name space collisions between cfortran.h and other codes.
+ - SIMPLE macros, supporting user defined types, have changed names.
+3.1 - Internal macro name _INT not used. Conflicted with IRIX 5.3. May '95.
+ - SunOS, all versions, should work out of the box.
+ - ZTRINGV_ARGS|F(k) may no longer point to a PDOUBLE or PFLOAT argument.
+ - ConvexOS 11.0 supported.
+3.2 - __hpux no longer needs to be restricted to MAX_PREPRO_ARGS=31. Oct. '95.
+ - PSTRING bug fixed.
+ - ZTRINGV_ARGS|F(k) may not point to a PBYTE,PINT,PLONG or PSHORT argument.
+ - (P)ZTRINGV machinery improved. Should lead to fewer compiler warnings.
+ (P)ZTRINGV no longer limits recursion or the nesting of routines.
+ - SIMPLE macros, supporting user defined types, have changed slightly.
+3.3 - Supports PowerStation Fortran with Visual C++. Nov. '95.
+ - g77 should work using f2cFortran, though no changes made for it.
+ - (PROTO)CCALLSFFUN10 extended to (PROTO)CCALLSFFUN14.
+ - FCALLSCFUN10 and SUB10 extended to FCALLSCFUN14 and SUB14.
+3.4 - C++ supported, Dec. '95.
+ but it required the reintroduction of PROTOCCALLSFSUBn for users.
+ - HP-UX f77 +800 supported.
+3.5 - Absoft UNIX Fortran supported. Sept.'96.
+3.6 - Minor corrections to cfortran.doc. Oct. '96.
+ - Fixed bug for 15th argument. [Thanks to Tom Epperly at Aspen Tech.]
+ - For AbsoftUNIXFortran, obey default of prepending _C to COMMON BLOCK name.
+ - Fortran calling C with ROUTINE argument fixed and cleaned up.
+3.7 - Circumvent IBM and HP "null argument" preprocessor warning. Oct. '96
+3.8 - (P)STRINGV and (P)ZTRINGV can pass a 1- or 2-dim. char array. Feb. '97
+ (P)ZTRINGV thus effectively also provides (P)ZTRING.
+ - (P)ZTRINGV accepts a (char *) pointer.
+3.9 - Bug fixed for *VVVVV. May '97
+ - f2c: Work-around for strange underscore-dependent naming feature.
+ - NEC SX-4 supported.
+ - CRAY: LOGICAL conversion uses _btol and _ltob from CRAY's fortran.h.
+ - CRAY: Avoid bug of some versions of the C preprocessor.
+ - CRAY T3E: FORTRAN_REAL introduced.
+
+4.0 - new/delete now used for C++. malloc/free still used for C. Jan. '98
+ - FALSE no longer is defined by cfortran.h .
+ - Absoft Pro Fortran for MacOS supported.
+4.1 - COMMA and COLON no longer are defined by cfortran.h . April'98
+ - Bug fixed when 10th arg. or beyond is a string.
+ [Rob Lucchesi of NASA-Goddard pointed out this bug.]
+ - CCALLSFSUB/FUN extended from 14 to 27 arguments.
+ - Workaround SunOS CC 4.2 cast bug. [Thanks to Savrak SAR of CERN.]
+4.2 - Portland Group needs -DpgiFortran . [Thank George Lai of NASA.] June '98
+4.3 - (PROTO)CCALLSFSUB extended from 20 to 27 arguments. July '98
+
+
+['Support' implies these and more recent releases of the respective
+ OS/compilers/linkers can be used with cfortran.h.
+ Earlier releases may also work.]
+
+
+Acknowledgements:
+- CERN very generously sponsored a week in 1994 for me to work on cfortran.h.
+- M.L.Luvisetto (Istituto Nazionale Fisica Nucleare - Centro Nazionale
+ Analisi Fotogrammi, Bologna, Italy) provided all the support for the port to
+ the CRAY. Marisa's encouragement and enthusiasm was also much appreciated.
+- J.Bunn (CERN) supported the port to PowerStation Fortran with Visual C++.
+- Paul Schenk (UC Riverside, CERN PPE/OPAL) in June 1993 extended cfortran.h 2.7
+ to have C++ call Fortran. This was the starting point for full C++ in 3.4.
+- Glenn P.Davis of University Corp. for Atmospheric Research (UCAR) / Unidata
+ supported the NEC SX-4 port and helped understand the CRAY.
+- Tony Goelz of Absoft Corporation ported cfortran.h to Absoft.
+- Though cfortran.h has been created in my 'copious' free time, I thank
+ NSERC for their generous support of my grad. student and postdoc years.
+- Univ.Toronto, DESY, CERN and others have provided time on their computers.
+
+
+THIS PACKAGE, I.E. CFORTRAN.H, THIS DOCUMENT, AND THE CFORTRAN.H EXAMPLE
+PROGRAMS ARE PROPERTY OF THE AUTHOR WHO RESERVES ALL RIGHTS. THIS PACKAGE AND
+THE CODE IT PRODUCES MAY BE FREELY DISTRIBUTED WITHOUT FEES, SUBJECT TO THE
+FOLLOWING RESTRICTIONS:
+- YOU MUST ACCOMPANY ANY COPIES OR DISTRIBUTION WITH THIS (UNALTERED) NOTICE.
+- YOU MAY NOT RECEIVE MONEY FOR THE DISTRIBUTION OR FOR ITS MEDIA
+ (E.G. TAPE, DISK, COMPUTER, PAPER.)
+- YOU MAY NOT PREVENT OTHERS FROM COPYING IT FREELY.
+- YOU MAY NOT DISTRIBUTE MODIFIED VERSIONS WITHOUT CLEARLY DOCUMENTING YOUR
+ CHANGES AND NOTIFYING THE AUTHOR.
+- YOU MAY NOT MISREPRESENTED THE ORIGIN OF THIS SOFTWARE, EITHER BY EXPLICIT
+ CLAIM OR BY OMISSION.
+
+THE INTENT OF THE ABOVE TERMS IS TO ENSURE THAT THE CFORTRAN.H PACKAGE NOT BE
+USED FOR PROFIT MAKING ACTIVITIES UNLESS SOME ROYALTY ARRANGEMENT IS ENTERED
+INTO WITH ITS AUTHOR.
+
+THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
+EXPRESSED OR IMPLIED. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST
+OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. THE AUTHOR IS NOT RESPONSIBLE
+FOR ANY SUPPORT OR SERVICE OF THE CFORTRAN.H PACKAGE.
+
+ Burkhard Burow
+ burow@desy.de
+
+P.S. Your comments and questions are welcomed and usually promptly answered.
+
+VAX VMS and Ultrix, Alpha, OSF, Silicon Graphics (SGI), DECstation, Mips RISC,
+Sun, CRAY, Convex, IBM RS/6000, Apollo DomainOS, HP, LynxOS, f2c, NAG, Absoft,
+NEC SX-4, PowerStation and Visual C++ are registered trademarks of their
+respective owners.
+
+/* end: cfortran.doc */