\chapter{FREE FIELD INPUT}
This chapter describes the free field input system supported in SUPES.  This
software was developed because it was recognized that most codes written
within the Engineering Sciences Directorate have very similar command input
requirements.  The SUPES free field input system consolidates the
development and maintenance of command parsing code into a single set of
reliable software.  This utility provides a uniform command syntax across
application codes to the end user, and minimizes the burden of command
parsing on the applications programmer.

The design requirements which are imposed on the SUPES free field input
system are as follows:
\begin{enumerate}
\item Input must follow a natural syntax which encourages readability.

\item The system must be applicable to both batch and interactive command
input modes.

\item The software must be written in ANSI FORTRAN~\cite{ansi}.

\item The interface to the applications program must be clear and
flexible.
\end{enumerate}

Version 2 of the SUPES free field reader differs from version 1 in the
following areas:
\begin{enumerate}
\item An interface has been provided to allow character strings to be input
to the free field reader in addition to reading from files. This allows the
applications programmer to perform more sophisticated string parsing than
would be possible when reading only from a file.

\item Whole, real numbers (e.g., 12.3E3) will translate to both INTEGER and
REAL values if the absolute value of the number is not greater than
1.0E9.

\item Quoted strings are allowed. This makes the free field reader more
compatible with the standard FORTRAN free field input. No interpretation of
characters (except for internal quotes) is performed within a quoted string.

\end{enumerate}

\section{Keyword/Value Input System}
This section describes the basic characteristics of the SUPES free field
input system.  SUPES addresses the first two phases of command processing;
it obtains a record from the input stream, and parses the record into
logical components.  Interpretation of the data in the final phase of
command processing is left to the applications program.

SUPES provides a keyword/value input structure which encourages a verb
oriented command language.  The hallmark of this input style is the concept
of ``verbs'' (or ``keywords'') which indicate how a command is to be
interpreted.  Since keywords allow each command to be self-contained, input
lines need not follow a rigid order.  This results in highly readable input
data.  For example, the command ``YOUNGS MODULUS = 30.E6'' has a very clear
meaning.  The verb oriented style can be contrasted with standard FORTRAN
list-directed I/O which requires the application code to know precisely what
to expect before reading a line of input.

The SUPES free field input system has a very simple, yet versatile syntax.
Input records are broken into ``fields''.  Each field is categorized
according to its contents as: null, character, real, or integer.  Note that
these four categories form a hierarchy where each subsequent category is a
more specific subset of the previous one.  For example, ``5.2345E3'' is a
real field because it can be interpreted as a REAL value as well as a valid
CHARACTER string, but does not constitute a valid INTEGER format.

There are just four syntax markers in SUPES: field separators which delimit
data fields, a quote character which encloses literal strings, a comment
indicator which allows a comment to be appended to command lines, and a
continuation indicator which causes consecutive input records to be
logically joined.

An application program need not use all of the information returned for
each field.  A default value (blank or zero) is returned when a valid value
is not specified for a given field.  On the other hand, the application code
can easily detect that the user has not explicitly specified a value so that
a more meaningful default can be assumed, or so that the user can be
prompted to supply more information.


\section{Syntax Rules} \label{sec:syntax}
The syntax rules for the SUPES free field input structure are listed below.
This syntax describes how input records/strings are parsed into data fields.  Both
the end user and the applications programmer should clearly understand these
few rules.
\begin{enumerate}
\item A data field is any sequence of data characters within an input line.  A
   data field is broken by (does not include) any non-data character or the
   end of the input line.  A non-data character is a field separator, a
   space, a comment indicator, or a continuation indicator.  Any other
   character is a data character.

\item A field separator is a comma (,), an equal sign (=), or a series of one
   or more spaces not adjacent to another separator.

\item A dollar sign (\$) indicates a comment.  All characters after and
   including the comment indicator are ignored.

\item An asterisk ($*$) indicates that the next input record/string will be
treated as a continuation of the current line.  All characters after and
including the continuation indicator on the current line are ignored.
Multiple records/strings that are ''joined'' by continuation indicators
are treated as a single logical record.

\item A null field does not contain any data characters.  A null field can be
   defined explicitly only by a field separator (spaces cannot act as a
   field separator for an explicit null field).  Fields which are not
   defined on the input line are implicitly null.

\item \label{itm:case} Lowercase letters not contained in a quoted string
                       are converted to uppercase.  All
                       other non-printable ASCII characters are converted
                       to spaces.

\item A numeric field is a data field which adheres to an ANSI FORTRAN numeric
   format.  A numeric field cannot be longer than 32 characters.  A numeric
   field always defines a REAL (floating point) value; it also defines an
   INTEGER (fixed point) value if it adheres to a legal INTEGER format.

\item A quoted string is a data field in which the quote (') character is
the first nonblank character. An internal quote is indicated with 2
consecutive quote characters. If an end quote character is not included,
then the remainder of the record (excluding any trailing blanks) is treated
as part of the quoted string. Within a quoted string, no character
conversion to uppercase is performed. Delimiters (other than quotes) are
treated as part of the string. Interpretation of data to numeric data will
be performed, if possible.

\item A data field which does not begin with the quote character, but has a
quote internal to the field (e.g., MOM'S) is not considered a quoted string.
In this case, the internal quote is not a special character.

\item The maximum length of an input record (FREFLD only) is 132 characters.
Input strings to FFISTR may be any length.
\end{enumerate}

Some important points which are not obvious from the above rules are noted
below.
\begin{itemize}
\item Spaces have no significance except when they act a field separator.

\item Only the first occurrence of a comment or continuation character is
  significant; subsequent characters are considered part of the comment.

\item A blank line has no data fields.

\item If no data characters appear after the last field separator, the field
  after that separator will not be counted.
\end{itemize}

\section{Free Field Input Routines}

The user interface to the SUPES free field input system consists of two
subroutines: FREFLD and FFISTR. Both routines perform parsing functions of
strings. The main difference is that FFREFLD gets its input from a FORTRAN
I/O unit while FFISTR gets its input from a character string. In fact,
FREFLD uses FFISTR to perform parsing functions once FREFLD has read a
record.

\subsection{External Input Routine (FREFLD)}\label{sec:frefld}

Input is prompted for, read, and echoed via FREFLD
using specified I/O units.  FREFLD returns the parsed data field values
defined on the next input record and any continuation records.  All I/O is
accomplished via the utility routine GETINP, which is documented further in
section~\ref{sec:getinp}, while the parsing is performed by FFISTR.

The arguments to FREFLD are prescribed below.
\begin{verbatim}
      CALL FREFLD( KIN, KOUT, PROMPT, MFIELD, IOSTAT, NFIELD, KVALUE,
     *             CVALUE, IVALUE, RVALUE )
\end{verbatim}

\begin{argy}{KIN}{INTEGER}{Read Only}
Unit from which to read input.  If zero, read from the
standard input device (terminal or batch deck) and echo
to the standard output device (terminal or batch log).
If non-zero, the caller is responsible for opening/closing this unit.
\end{argy}

\begin{argy}{KOUT}{INTEGER}{Read Only}
Unit to which to echo input.  If zero, do not echo other
than to the standard output device as described above.
If non-zero, the caller is responsible for opening/closing this unit.
\end{argy}

\begin{argy}{PROMPT}{CHARACTER$*$($*$)}{Read Only}
Prompt string.  This string will be used to prompt for
data from an interactive terminal and/or will be written
as a prefix to the input line for echo.  If the string
`AUTO' is specified, a prompt of the form `   n: ',
where ``n'' is the current input line number (only lines
read under the AUTO feature are counted), will be
generated.
\end{argy}

\begin{argy}{MFIELD}{INTEGER}{Read Only}
Maximum number of data fields to be returned.
The dimensions of each of the output
arrays described below must be greater than of equal to this number.
\end{argy}

\begin{argy}{IOSTAT}{INTEGER}{Write Only}
ANSI FORTRAN I/O status:\\
\begin{tabular}{llll}
IOSTAT &$<$ & 0 & End of File\\
IOSTAT & =  & 0 & Normal\\
IOSTAT &$>$ & 0 & Error
\end{tabular}
\end{argy}

\begin{argy}{NFIELD}{INTEGER}{Write Only}
Number of data fields found on this logical record.  If this value is less
than MFIELD, the excess fields are implicitly defined as null fields.  If
this value is greater than MFIELD, the extra data fields are ignored.
\end{argy}

\begin{argy}{KVALUE}{INTEGER Array}{Write Only}
Translation states of the data fields.  The value of
each element of this array is interpreted as follows:

\begin{tabular}{|cp{9 cm}|} \hline \hline
KVALUE & \multicolumn{1}{c|}{Meaning}\\ \hline
-1 & This is a null field.\\
0 & This is a non-numeric field; only CVALUE
contains a specified value.\\
1 & This is a REAL numeric field; CVALUE and
RVALUE contain specified values.\\
2 & This is an INTEGER numeric field; CVALUE,
RVALUE, and IVALUE contain specified values.\\ \hline \hline
\end{tabular}

The dimension of this array must be at least MFIELD.
\end{argy}

\begin{argy}{CVALUE}{CHARACTER$*$($*$) Array}{Write Only}
Character values of the data fields.  The data will be
left-justified and either blank-filled or truncated.
The value in this array is set blank for a null field.
The dimension of this array must be at least MFIELD.
The character element size may be any value set by the
caller.
\end{argy}

\begin{argy}{IVALUE}{INTEGER Array}{Write Only}
Integer values of the data fields.  The value in this
array is set to zero for a null or non-INTEGER field.
The dimension of this array must be at least MFIELD.
\end{argy}

\begin{argy}{RVALUE}{REAL Array}{Write Only}
Floating-point values of the data fields.  The value in
this array is set to zero for a null or non-REAL field.
The dimension of this array must be at least MFIELD.
\end{argy}

\subsection{Internal Input Routine (FFISTR)}\label{sec:ffistr}

Internal input (i.e., a character string) is parsed via FFISTR using
character strings supplied through FFISTR's argument list.  FFISTR returns
the parsed data field values defined in the input string. If a string
contains a continuation character, a flag is returned to the user indicating
that another string should be supplied to complete the logical record.
The arguments to FFISTR are prescribed below.
\begin{verbatim}
      CALL FFISTR( LINE, MFIELD, IDCONT, NFIELD, KVALUE,
     *             CVALUE, IVALUE, RVALUE )
\end{verbatim}

\begin{argy}{LINE}{CHARACTER$*$($*$)}{Read Only}
Input string. This argument contains the data to be parsed.
\end{argy}

\begin{argy}{MFIELD}{INTEGER}{Read Only}
Maximum number of data fields to be returned.
The dimensions of each of the output
arrays described below must be greater than of equal to this number.
\end{argy}

\begin{argy}{IDCONT}{INTEGER}{Read and Write}
Continuation flag. 0 means no continuation. On input, this flag indicates
if the previous string contained a continuation indicator. In this case, the
current string will be treated as part of the same logical record as the
previous string.
\end{argy}

\begin{argy}{NFIELD}{INTEGER}{Write Only}
Number of data fields found on this logical record.  If this value is less
than MFIELD, the excess fields are implicitly defined as null fields.  If
this value is greater than MFIELD, the extra data fields are ignored.
\end{argy}

\begin{argy}{KVALUE}{INTEGER Array}{Write Only}
Translation states of the data fields.  The value of
each element of this array is interpreted as follows:

\begin{tabular}{|cp{9 cm}|} \hline \hline
KVALUE & \multicolumn{1}{c|}{Meaning}\\ \hline
-1 & This is a null field.\\
0 & This is a non-numeric field; only CVALUE
contains a specified value.\\
1 & This is a REAL numeric field; CVALUE and
RVALUE contain specified values.\\
2 & This is an INTEGER numeric field; CVALUE,
RVALUE, and IVALUE contain specified values.\\ \hline \hline
\end{tabular}

The dimension of this array must be at least MFIELD.
\end{argy}

\begin{argy}{CVALUE}{CHARACTER$*$($*$) Array}{Write Only}
Character values of the data fields.  The data will be
left-justified and either blank-filled or truncated.
The value in this array is set blank for a null field.
The dimension of this array must be at least MFIELD.
The character element size may be any value set by the
caller.
\end{argy}

\begin{argy}{IVALUE}{INTEGER Array}{Write Only}
Integer values of the data fields.  The value in this
array is set to zero for a null or non-INTEGER field.
The dimension of this array must be at least MFIELD.
\end{argy}

\begin{argy}{RVALUE}{REAL Array}{Write Only}
Floating-point values of the data fields.  The value in
this array is set to zero for a null or non-REAL field.
The dimension of this array must be at least MFIELD.
\end{argy}


\subsection{Basic Examples}

The following examples illustrate the operation of the SUPES free field
input system.

INPUT RECORDS:\\
\begin{verbatim}
verb, 1 2. * continue on next line
key=5
\end{verbatim}

Results returned from FREFLD:\\
NFIELD = 5

\begin{tabular}{|ccccc|} \hline \hline
I    &  KVALUE(I) &       CVALUE(I)  &        RVALUE(I)   &  IVALUE(I)\\\hline
   1   &      0 &\verb*"VERB            " & 0.000E+00 & 0\\
   2   &      2 &\verb*"1               " & 1.00     & 1\\
   3   &      2 &\verb*"2.              " & 2.00     & 2\\
   4   &      0 &\verb*"KEY             " & 0.000E+00 & 0\\
   5   &      2 &\verb*"5               " & 5.00     & 5\\ \hline \hline
\end{tabular}

INPUT RECORD:
\begin{verbatim}
$ this is a comment line
\end{verbatim}

Results returned from FREFLD:\\
NFIELD = 0

\begin{tabular}{|ccccc|} \hline \hline
I    &  KVALUE(I)  &      CVALUE(I)    &     RVALUE(I) &    IVALUE(I)\\\hline
1 &-1 &\verb*"                "  &    0.000E+00 & 0\\
2 &-1 &\verb*"                "  &    0.000E+00 & 0\\
3 &-1 &\verb*"                "  &    0.000E+00 & 0\\
4 &-1 &\verb*"                "  &    0.000E+00 & 0\\
5 &-1 &\verb*"                "  &    0.000E+00 & 0\\ \hline \hline
\end{tabular}

INPUT RECORD:
\begin{verbatim}
10,,
\end{verbatim}

Results returned from FREFLD:\\
NFIELD =    2

\begin{tabular}{|ccccc|} \hline \hline
I    &  KVALUE(I) &       CVALUE(I)       &   RVALUE(I)   &  IVALUE(I)\\\hline
1  &  2  &\verb*"10              "  &     10.0     &  10\\
2  & -1  &\verb*"                "  &    0.000E+00 &  0\\
3  & -1  &\verb*"                "  &    0.000E+00 &  0\\
4  & -1  &\verb*"                "  &    0.000E+00 &  0\\
5  & -1  &\verb*"                "  &    0.000E+00 &  0\\ \hline \hline
\end{tabular}

INPUT RECORD:
\begin{verbatim}
'Quoted strings', '5 ', '$*,=''"' $ rest is comment
\end{verbatim}

Results returned from FREFLD:\\
NFIELD =    3

\begin{tabular}{|ccccc|} \hline \hline
I    &  KVALUE(I) &       CVALUE(I)       &   RVALUE(I)   &  IVALUE(I)\\\hline
1  &  0  &\verb*"Quoted strings  "  &    0.000E+00 &  0\\
2  &  2  &\verb*"5               "  &     50.0     &  50\\
3  &  0  &\verb*+$*,='"          +  &    0.000E+00 &  0\\
4  & -1  &\verb*"                "  &    0.000E+00 &  0\\
5  & -1  &\verb*"                "  &    0.000E+00 &  0\\ \hline \hline
\end{tabular}

INPUT RECORD:
\begin{verbatim}
quotes's
\end{verbatim}

Results returned from FREFLD:\\
NFIELD =    1

\begin{tabular}{|ccccc|} \hline \hline
I    &  KVALUE(I) &       CVALUE(I)       &   RVALUE(I)   &  IVALUE(I)\\\hline
1 &   0  &\verb*"QUOTES'S        "  &    0.000E+00 &  0\\
2 &  -1  &\verb*"                "  &    0.000E+00 &  0\\
3 &  -1  &\verb*"                "  &    0.000E+00 &  0\\
4 &  -1  &\verb*"                "  &    0.000E+00 &  0\\
5 &  -1  &\verb*"                "  &    0.000E+00 &  0\\ \hline \hline
\end{tabular}

\section{Utility Routines}
The three routines described in this section, together with the FORTRAN
extension library routines EXREAD and EXUPCS, are the only externals called
by FREFLD and FFISTR. Application programs built on top of FREFLD and FFISTR
may find further use for these routines.


\subsection{Get Literal Input Line (GETINP)}\label{sec:getinp}
All I/O for FREFLD is done through this subroutine.  This routine was
intentionally separated from FREFLD so that the caller can obtain an
unmodified line of input (such as a problem title) via the same I/O stream.
Applications which require a more complex syntax than SUPES provides (e.g.,
algebraic operations) may find GETINP advantageous.

There are four modes of operation of GETINP depending upon the specification
of the I/O units KIN and KOUT.  Each of these modes, which are summarized in
the following table, may be useful to various applications.

\begin{tabular}{|cccc|} \hline \hline
     KIN        &KOUT    &Source  &Echo\\\hline
        0       &0       &Standard Input  &Standard Output\\
        0       &M       &Standard Input  &Standard Output and File (M)\\
     N         &M       &File (N)        &File (M)\\
        N       &0       &File (N)        &none \\ \hline \hline
\end{tabular}

The arguments to GETINP are prescribed below.

\verb+CALL GETINP( KIN, KOUT, PROMPT, LINE, IOSTAT )+

\begin{argy}{KIN}{INTEGER}{Read Only}
Unit from which to read input.  If zero, read from the
standard input device (terminal or batch deck) and echo
to the standard output device (terminal or batch log).
non-zero, the caller is responsible for opening/closing this unit.
\end{argy}

\begin{argy}{KOUT}{INTEGER}{Read Only}
Unit to which to echo input.  If zero, do not echo other
than to the standard output device as described above.
If non-zero, the caller is responsible for opening/closing this unit.
\end{argy}

\begin{argy}{PROMPT}{CHARACTER$*$($*$)}{Read Only}
Prompt string.  This string will be used to prompt for
data from an interactive terminal and/or will be written
as a prefix to the input line for echo.  If the string
`AUTO' is specified, a prompt of the form `   n: ',
where "n" is the current input line number (only lines
read under the AUTO feature are counted), will be
generated.
\end{argy}

\begin{argy}{LINE}{CHARACTER$*$($*$)}{Write Only}
Line of input.  This string will be blank-filled or
truncated, if necessary.  The length of the string is
set by the caller, but should not exceed 132.
\end{argy}

\begin{argy}{IOSTAT}{INTEGER}{Write Only}
ANSI FORTRAN I/O status:\\
\begin{tabular}{cccl}
IOSTAT &$<$ & 0 & End of File\\
IOSTAT &=   & 0 & Normal\\
IOSTAT &$>$ & 0 & Error\\
\end{tabular}
\end{argy}

\subsection{Strip Leading/Trailing Blanks (STRIPB)}\label{sec:stripb}
This routine is called by FREFLD and FFISTR from several locations.  It may
be useful to other applications as well.  Note that STRIPB does not modify
nor copy the input string, but simply returns the location of the first and
last non- blank characters.  If a substring is passed, these locations are
relative to the beginning of the substring.  For example, if the substring
STRING(N:) is passed to STRIPB, STRING(ILEFT+N-1:IRIGHT+N-1) would represent
the result.

The arguments to STRIPB are prescribed below.

\verb+CALL STRIPB( STRING, ILEFT, IRIGHT )+

\begin{argy}{STRING}{CHARACTER$*$($*$)}{Read Only}
Any character string.
\end{argy}

\begin{argy}{ILEFT}{INTEGER}{Write Only}
Relative index of the first non-blank character in
STRING.  ILEFT = LEN(STRING) + 1 if STRING = ` '.
\end{argy}

\begin{argy}{IRIGHT}{INTEGER}{Write Only}
Relative index of the last non-blank character in
STRING.  IRIGHT = 0 if STRING = ` '.
\end{argy}

\subsection{Process Quoted String (QUOTED)}\label{sec:quoted}
This routine is called by FFISTR to remove the delimiting quotes from a
quoted string. It also converts any repeated quotes into single quotes.
(This is a common method for indicating internal quotes.)

The arguments to QUOTED are prescribed below.

\verb+CALL QUOTED ( STRING, ILEFT, IRIGHT )+

\begin{argy}{STRING}{CHARACTER$*$($*$)}{Read and Write}
Any character string. On output, the first and last quotes are removed, and
internal (repeated) quotes are converted to single quotes. If the trailing
quote is omitted, then the remainder of the input record (excluding trailing
blanks) is considered part of the quoted string.
\end{argy}

\begin{argy}{ILEFT}{INTEGER}{Write Only}
Relative index of the first character in the string. This is always the
location of the first character inside the leading quote.
\end{argy}

\begin{argy}{IRIGHT}{INTEGER}{Write Only}
Relative index of the last character in
STRING.  IRIGHT = 0 if the quoted string is null.
\end{argy}
