% Master File: project-doc.tex
% Document Type: LaTeX
% Document Previewer: xdvi -margins 1.5
\documentclass{article}
%\documentstyle[12pt]{article}

\addtolength{\textheight}{0.5in}
\addtolength{\topmargin}{-0.25in}
\addtolength{\textwidth}{1.0in}
\addtolength{\oddsidemargin}{-0.5in}
\thispagestyle{empty}
\title{%article title
Project-File Format
}
\author{Robert K. Moniot}
\date{\today}

\newcommand{\OMIT}[1]{}

%\pagestyle{headings}

%\pagestyle{myheadings}\markright{%article running head
%}

\newcommand{\Line}[2]{\makebox[0pt][r]{#1: }\ \texttt{#2}\\}

\begin{document}

\maketitle

\section{Introduction}
This is a description of {\tt ftnchek} project-file format, version P3
(for {\tt ftnchek} versions 2.11 and later).  This description is
intended for those who want to write programs or scripts that make use
of the information in project files for other purposes.
This document was written fairly hastily, but care has been taken that
to make sure it is accurate, even if perhaps it is not very clear or
well-organized.

This document is {\em not} intended to describe how to use project
files when checking Fortran programs.  If that is what you are
interested in, see the {\tt ftnchek} documentation.

The description is based on the following sample program.  Line
numbers are added for reference.
\vspace{2ex}

		% Original source follows \end{document} in this file
\noindent
\Line{1}{C Program used as example in project-file documentation.}
\Line{2}{C These comments are mainly to make the program not start on line 1.}
\Line{3}{\ \ \ \ \ \ PROGRAM CALC}
\Line{4}{\ \ \ \ \ \ INCLUDE 'projcom.f'}
Including file projcom.f \\
\Line{1}{\ \ \ \ \ \ DOUBLE PRECISION BETA}
\Line{2}{\ \ \ \ \ \ COMMON IOTA, GAMMA(3), BETA}
Resuming file projex.f \\
\Line{5}{\ \ \ \ \ \ READ(*,*) NUM}
\Line{6}{\ \ \ \ \ \ IOTA = NUM*NUM}
\Line{7}{\ \ \ \ \ \ CALL SUMUP(NUM,GAMMA)}
\Line{8}{\ \ \ \ \ \ WRITE(*,*) IOTA, (GAMMA(I),I=1,3)}
\Line{9}{\ \ \ \ \ \ END}
\Line{10}{\ \ \ \ \ \ SUBROUTINE SUMUP(M,XRAY)}
\Line{11}{\ \ \ \ \ \ DIMENSION XRAY(M)}
\Line{12}{\ \ \ \ \ \ XRAY(1) = 1.0}
\Line{13}{\ \ \ \ \ \ DO 10 I=2,M}
\Line{14}{\ \ \ \ \ \ \ \  XRAY(I) = XRAY(I-1)+I}
\Line{15}{\ 10\ \ \ CONTINUE}
\Line{16}{\ \ \ \ \ \ RETURN}
\Line{17}{\ \ \ \ \ \ ENTRY SUMDOWN(M,XRAY)}
\Line{18}{\ \ \ \ \ \ XRAY(M) = 1.0}
\Line{19}{\ \ \ \ \ \ DO 20 I=M-1,1,-1}
\Line{20}{\ \ \ \ \ \ \ \  XRAY(I) = XRAY(I-1)+I}
\Line{21}{\ 20\ \ \ CONTINUE}
\Line{22}{\ \ \ \ \ \ END}

\section{Project files}
A project file (produced when the {\tt -project} option is given) contains
information from only one source file.  A separate project file is
created for each source file, with the extension {\tt .prj} replacing the
source file extension {\tt .f} or {\tt .for}.

The top-level routine in {\tt ftnchek} that is invoked to create a
project file is {\tt proj\_file\_out} in file {\tt project.c}.
Consult that routine to answer any detailed questions not treated
here.

Here is the project file produced by {\tt ftnchek} from the sample
program.  It will be explained line-by-line in the following sections.  Line
numbers have been added for reference.
\vspace{2ex}

		% Original project file follows \end{document} in this file
\noindent
\Line{1}{FTNCHEK\_ P3}
\Line{2}{file projex.f}
\Line{3}{ entries 3}
\Line{4}{ entry CALC class 1 type 12 size 0 flags 1 0 0 0 0 0 0 0}
\Line{5}{ defn}
\Line{6}{ module CALC file projex.f line 3 top 3 class 1 type 12 size 0 flags 1 0 0 0}
\Line{7}{ args 0}
\Line{8}{ end}
\Line{9}{ entry SUMUP class 1 type 10 size 0 flags 1 0 0 0 0 0 0 0}
\Line{10}{ defn}
\Line{11}{ module SUMUP file projex.f line 10 top 10 class 1 type 10 size 0 flags 1 0 0 0}
\Line{12}{ args 2}
\Line{13}{ arg 1 name M}
\Line{14}{ class 0 type 1 size 0 dims 0 elts 1 cblk - cndx 0 same 0 flags 1 0 0 1 0 0 0 0}
\Line{15}{ arg 2 name XRAY}
\Line{16}{ class 0 type 2 size 0 dims 1 elts 0 cblk - cndx 0 same 1 flags 1 1 1 0 1 0 0 0}
\Line{17}{ end}
\Line{18}{ entry SUMDOWN class 1 type 10 size 0 flags 0 0 0 0 0 0 0 0}
\Line{19}{ defn}
\Line{20}{ module SUMUP file projex.f line 17 top 17 class 1 type 10 size 0 flags 1 0 0 0}
\Line{21}{ args 2}
\Line{22}{ arg 1 name M}
\Line{23}{ class 0 type 1 size 0 dims 0 elts 1 cblk - cndx 0 same 0 flags 1 0 0 1 0 0 0 0}
\Line{24}{ arg 2 name XRAY}
\Line{25}{ class 0 type 2 size 0 dims 1 elts 0 cblk - cndx 0 same 1 flags 1 1 1 0 1 0 0 0}
\Line{26}{ end}
\Line{27}{}
\Line{28}{ externals 1}
\Line{29}{ external SUMUP class 1 type 10 size 0 flags 1 0 0 0 0 0 0 0}
\Line{30}{ call}
\Line{31}{ module CALC file projex.f line 7 top 7 class 1 type 10 size 0 flags 0 1 0 0}
\Line{32}{ args 2}
\Line{33}{ arg 1 name NUM}
\Line{34}{ class 0 type 1 size 0 dims 0 elts 1 cblk - cndx 0 same 0 flags 1 1 1 0 0 0 0 0}
\Line{35}{ arg 2 name GAMMA}
\Line{36}{ class 0 type 2 size 0 dims 1 elts 3 cblk \%BLANK cndx 2 same 1 flags 1 1 0 0 1 0 0 0}
\Line{37}{ end}
\Line{38}{}
\Line{39}{ comblocks 1}
\Line{40}{ block \%BLANK class 2 type 11}
\Line{41}{ module CALC file projcom.f line 2 top 4 flags 1 1 0 0}
\Line{42}{ vars 3}
\Line{43}{ var 1 name IOTA}
\Line{44}{ class 0 type 1 size 0 dims 0 elts 1 flags 1 1 0 1 0 0 0 0}
\Line{45}{ var 2 name GAMMA}
\Line{46}{ class 0 type 2 size 0 dims 1 elts 3 flags 1 1 0 0 0 0 0 0}
\Line{47}{ var 3 name BETA}
\Line{48}{ class 0 type 3 size 0 dims 0 elts 1 flags 0 0 0 0 0 0 0 0}
\Line{49}{}

\section{Overall structure}
The project file is a plain text file.  It is line-oriented.  Items
on a line are not organized by columns, but simply separated by blank
spaces.  (In the example above, some lines have been broken for
printing, but they are single lines in the original.  The line numbers
make clear where each line actually begins.)

Throughout the file, lowercase letters are used for project-file
keywords, and uppercase for the names of program identifiers.  File
names retain the case used by the operating system to refer to them.
Most numeric items can have any value greater than or equal to 0, but
flags can only be 0 for false and 1 for true.

The project file consists of four main sections: a {\em preamble}
(lines 1--2), an {\em entries} section (lines 3--27), an {\em
externals} section (lines 28--38), and a {\em common block} section
(lines 39--49).
(These line numbers, and all line numbers in the description below,
refer to this example.  For other instances, all except the preamble
line numbers will vary.)

\section{Preamble}
Line 1 is a magic cookie to identify the file as an {\tt ftnchek}
project file and to indicate the project-file version number
(currently P3).  The {\tt F} is in column 1.
If {\tt ftnchek} reads a project file with a different
version number, it prints an error message and exits.

Line 2 specifies the source file name.  The keyword {\tt file} is
unvarying.

{\em Note:} Subsequent nonblank lines of the file are all indented by one
blank space.

\section{Entries section}
This section (lines 3--27) lists the entry points of all the
subprograms defined in the source file.  The first line of this
section (line 3) has the keyword {\tt entries} and the number of entry
points in the following list.

Then for each of the entry points, there is a sequence of lines as
follows:
\begin{itemize}
  \item {\tt entry} line (lines 4, 9, 19) giving the name of the entry
     point, its storage {\tt class} (subprograms are always class 1),
     its data {\tt type} (see list of {\tt \#define type\_UNDECL} et
     al.\ in {\tt symtab.h}), its type {\tt size} (usually 0 for
     default, but may have other values from, e.g. {\tt INTEGER*8}
     declarations), and {\tt flags}: {\tt used\_flag} (entry is
     referenced in a {\tt CALL} or by use as a function anywhere in
     the file), {\tt set\_flag} (function name is given a value for
     return), {\tt invoked\_as\_func} (used as a function, i.e. in an
     expresssion rather than a {\tt CALL} anywhere in the file), {\tt
     declared\_external} (named in an {\tt EXTERNAL} statement
     anywhere in the file), {\tt library\_module} (processed in {\tt
     -library} mode).  There are three additional values (all 0) to
     allow for future flags.  This information comes from the {\tt
     Gsymtab} entry (in {\tt symtab.h}) for the entry point.

  \item {\tt defn} line (lines 5, 10, 19) with just the keyword {\tt
  defn}.

  \item {\tt module} line (lines 6, 11, 20) giving name of subprogram
     containing the entry point, the {\tt file} name (can be different from
     line 2 if include files are used), {\tt line} number of entry point in
     source file, line number in {\tt top}-level file (this will be the same
     if not in an include file, otherwise it is where the outermost
     {\tt INCLUDE} statement is located), storage {\tt class}, data
     {\tt type} and type {\tt size} of
     module (meanings as in {\tt entry} line, should be the same
     values), and {\tt flags} {\tt is\_defn}, {\tt is\_call}, {\tt
     external\_decl}, {\tt actual\_arg} identifying the nature of the
     definition ({\tt is\_defn} is always 1, and the other flags 0 for
     entry definitions).  This information comes from the {\tt
     ArgListHeader} (defined in {\tt symtab.h}) for this entry-point
     definition.

  \item {\tt args} line (lines 7, 12, 21) giving the number of
     arguments (parameters) of this entry point.  This line is the
     beginning of a series (lines 7--8, 12--17, 21--26) terminated by
     an {\tt end} line.  For each argument there are two lines:

  \begin{itemize}

    \item {\tt arg} line (lines 13, 15, 22, 24) giving the position in
    the argument sequence and the {\tt name} of the actual argument.

    \item {\tt class} line (lines 14, 16, 23, 25) giving the storage
        {\tt class} (see list of {\tt \#define class\_VAR} et al.\ in
        {\tt symtab.h} for definitions), data {\tt type}, type {\tt
        size}, number of array {\tt dims} (0 for scalars), and number
        of array elements {\tt elts} (1 for scalars).  Next come {\tt
        cblk}, {\tt cndx}, and {\tt same} which are useful only for
        actual arguments.  For dummy arguments they are always {\tt
        -}, {\tt 0}, and the argument's position in the argument list,
        respectively.  Last come the {\tt flags} {\tt is\_lvalue}
        (always 1 for dummy arguments), {\tt set\_flag} (variable is
        assigned or otherwise possibly modified, e.g.\ by being passed
        to a subroutine), {\tt assigned\_flag} (variable is on left
        side of an assignment statement), {\tt used\_before\_set}
        (value is used before being possibly assigned) , {\tt
        array\_var} (variable is an array or array element), {\tt
        array\_element} (variable is an array element), {\tt
        declared\_external} (argument is declared in an {\tt EXTERNAL}
        statement), and {\tt active\_do\_var} (variable is the index
        of a {\tt DO} loop, and call is within the range of that {\tt
        DO}; always 0 for dummy arguments).  This
        information is taken from the {\tt
        ArgListElement} entry (defined in {\tt symtab.h}) for the
        argument.

  \end{itemize}

  \item {\tt end} line (lines 8, 17,26) marking the end of the list of
	arguments for the entry point.

\end{itemize}

A blank line (line 27) marks the end of the entries section.

\section{Externals section}
This section (lines 28--38) lists the external references made from
the subprograms in the source file.  It is very similar in form to the
entries section (in fact they are produced by the same code, differing
only in that the keyword {\tt entry} is used instead of {\tt defn} to mark
successive externals.
The first line of this section (line 28) has the keyword {\tt
externals} and the number of external references in the following
list.

This number counts \emph{separate} references to an external; that is,
a given external can occur several times if it is referenced several
times.  However, if the external reference is resolved by a subprogram
defined within the same source file, only one instance (or none in
{\tt -library} mode) of a reference to that external is retained for
the project file.  If you want all the references to each external to
be retained, compile {\tt ftnchek} with the macro {\tt PROJ\_KEEPALL}
defined, or split the source file into separate files, one file for
each subprogram.

For each of the external references, there is a sequence of lines as
follows.
\begin{itemize}

  \item {\tt external} line (line 29) giving the name of the external
     and other information the same as described above for {\tt entry} lines
     in the {\tt entries} section.

  \item {\tt call} line (line 30) with just the keyword {\tt call}.

  \item {\tt module} line (line 31) giving the name of the subprogram
     containing the external reference, and other information as
     described above for {\tt module} lines in the {\tt entries} section.
     The difference is that for  externals, the flag {\tt
     is\_defn} is 0, and one of {\tt is\_call}, {\tt external\_decl},
     or {\tt actual\_arg} will be 1 to indicate how the external was
     referenced.  Here {\tt is\_call} signifies an actual {\tt
     CALL} or the use of a function in an expression, {\tt
     external\_decl} means the reference is in an {\tt EXTERNAL}
     declaration, and {\tt actual\_arg} means the reference was
     generated by passing the external as an actual argument to a
     subprogram.

  \item {\tt args} line (line 32) giving the number of actual
     arguments of this external reference.  This line is the beginning
     of a series (lines 32--37) terminated by an {\tt end} line.  For
     each argument there are two lines:

  \begin{itemize}

    \item {\tt arg} line (lines 33, 35) giving the position in the
	argument sequence and the name (or text if an expression) of
	the actual argument.  (The text may be incomplete if longer
	than a limit {\tt MAXEXPRTEXT} set in {\tt ftnchek.h}.)

    \item {\tt class} line (lines 34, 36) giving the storage class and
        other information about the actual argument, as described
        above for {\tt class} lines for dummy arguments in the entries
        section.  The differences are that for actual arguments that
        are common variables, {\tt cblk} gives the name of the common
        block containing the actual argument (the special indicator
        {\tt -} signifies that the variable is not in common) and {\tt
        cndx} the position in common (counting from 1 by variables,
        not by storage location).  This index is 0 for variables that
        are not in common.  Next is {\tt same} which gives the
        position in the argument list of an argument that is aliased
        to this one (equals its own index if no aliasing).

  \end{itemize}

  \item {\tt end} line (line 37) marking the end of the list of
	arguments for the entry point.

\end{itemize}

A blank line (line 38) marks the end of the entries section.


\section{Common block section}
This section (lines 39--49) lists common block declarations in the
source file.

If there are multiple subprograms in the source file declaring the
same common block, all of the declarations are retained, unless the
project file is created in {\tt -library} mode, in which case only one
instance of a declaration is retained.

The first line (line 39) of this section has the keyword {\tt
comblocks} and the  number of common block declarations retained
from the source file.  (This will be just one instance of
each block if the project file was created in library
mode, otherwise the number will be the sum of all
declarations of all blocks.)


Then for each of the entry points, there is a sequence of lines as
follows:
\begin{itemize}

  \item {\tt block} line (line 40) giving the block name, storage {\tt
	class} (always 2) and data {\tt type} (always 11).  This
	information comes from the {\tt Gsymtab} entry for the block.

  \item {\tt module} line (line 41) giving the name of the subprogram
	declaring the block, the {\tt file} name, and location
	information.  As the example illustrates, if the declaration
	is in an include file, the {\tt file} name on this line is the
	include file containing the common declaration and the {\tt
	line} number is the line of the declaration within the include
	file, while the {\tt top} line number is the location of the
	{\tt INCLUDE} statement in the top-level source file.  After
	the location information there are flags {\tt any\_used}
	(any variable in the block is used), {\tt any\_set} (any
	variable in the block is possibly assigned), {\tt saved} (the block is
	named in a {\tt SAVE} statement), and one placeholder value
	for a possible future flag (always 0).  This information comes
	from the {\tt ComListHeader} for the block declaration.

  \item {\tt vars} line (line 42) giving the number of variables in
	the block.  An array counts as a single variable.  This line
	is the beginning of a series (lines 43--48).  Unlike its
	counterparts in the entries and externals sections, this
	series is \emph{not} terminated by an {\tt end} line.  For
	each argument there are two lines:

  \begin{itemize}

	\item {\tt var} line giving the position in the block and the
            {\tt name} of the variable.

	\item {\tt class} line giving the storage {\tt class} (always
	    0), data {\tt type}, and {\tt size}, number of array
	    dimensions {\tt dims} and elements {\tt elts}, and
	    {\tt flags} {\tt used} (value is  used), {\tt set}
	    (variable is assigned or otherwise possibly modified),
	    {\tt  used\_before\_set} (value is used before being
	    possibly assigned), {\tt assigned} (variable
	    is on left side of an assignment statement), and four
	    placeholding zeroes for possible future flags.  This
	    information is from the {\tt ComListElement} entry
	    for the variable.

  \end{itemize}

\end{itemize}
The last line (line 49) of the common block section is blank.  This is
the last line of the project file.

\end{document}

			Original source of projex.f

C Program used as example in project-file documentation.
C These comments are mainly to make the program not start on line 1.
      PROGRAM CALC
      INCLUDE 'projcom.f'
      READ(*,*) NUM
      IOTA = NUM*NUM
      CALL SUMUP(NUM,GAMMA)
      WRITE(*,*) IOTA, (GAMMA(I),I=1,3)
      END
      SUBROUTINE SUMUP(M,XRAY)
      DIMENSION XRAY(M)
      XRAY(1) = 1.0
      DO 10 I=2,M
         XRAY(I) = XRAY(I-1)+I
 10   CONTINUE
      RETURN
      ENTRY SUMDOWN(M,XRAY)
      XRAY(M) = 1.0
      DO 20 I=M-1,1,-1
         XRAY(I) = XRAY(I-1)+I
 20   CONTINUE
      END


		Original projex.prj file

FTNCHEK_ P3
file projex.f
 entries 3
 entry CALC class 1 type 12 size 0 flags 1 0 0 0 0 0 0 0
 defn
 module CALC file projex.f line 3 top 3 class 1 type 12 size 0 flags 1 0 0 0
 args 0
 end
 entry SUMUP class 1 type 10 size 0 flags 1 0 0 0 0 0 0 0
 defn
 module SUMUP file projex.f line 10 top 10 class 1 type 10 size 0 flags 1 0 0 0
 args 2
 arg 1 name M
 class 0 type 1 size 0 dims 0 elts 1 cblk - cndx 0 same 0 flags 1 0 0 1 0 0 0 0
 arg 2 name XRAY
 class 0 type 2 size 0 dims 1 elts 0 cblk - cndx 0 same 1 flags 1 1 1 0 1 0 0 0
 end
 entry SUMDOWN class 1 type 10 size 0 flags 0 0 0 0 0 0 0 0
 defn
 module SUMUP file projex.f line 17 top 17 class 1 type 10 size 0 flags 1 0 0 0
 args 2
 arg 1 name M
 class 0 type 1 size 0 dims 0 elts 1 cblk - cndx 0 same 0 flags 1 0 0 1 0 0 0 0
 arg 2 name XRAY
 class 0 type 2 size 0 dims 1 elts 0 cblk - cndx 0 same 1 flags 1 1 1 0 1 0 0 0
 end

 externals 1
 external SUMUP class 1 type 10 size 0 flags 1 0 0 0 0 0 0 0
 call
 module CALC file projex.f line 7 top 7 class 1 type 10 size 0 flags 0 1 0 0
 args 2
 arg 1 name NUM
 class 0 type 1 size 0 dims 0 elts 1 cblk - cndx 0 same 0 flags 1 1 1 0 0 0 0 0
 arg 2 name GAMMA
 class 0 type 2 size 0 dims 1 elts 3 cblk %BLANK cndx 2 same 1 flags 1 1 0 0 1 0 0 0
 end

 comblocks 1
 block %BLANK class 2 type 11
 module CALC file projcom.f line 2 top 4 flags 1 1 0 0
 vars 3
 var 1 name IOTA
 class 0 type 1 size 0 dims 0 elts 1 flags 1 1 0 1 0 0 0 0
 var 2 name GAMMA
 class 0 type 2 size 0 dims 1 elts 3 flags 1 1 0 0 0 0 0 0
 var 3 name BETA
 class 0 type 3 size 0 dims 0 elts 1 flags 0 0 0 0 0 0 0 0

