BSD 4_1_snap development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Sat, 20 Oct 1979 13:33:10 +0000 (05:33 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Sat, 20 Oct 1979 13:33:10 +0000 (05:33 -0800)
Work on file usr/doc/f77

Synthesized-from: CSRG/cd1/4.1.snap

usr/doc/f77 [new file with mode: 0644]

diff --git a/usr/doc/f77 b/usr/doc/f77
new file mode 100644 (file)
index 0000000..6f8b7ec
--- /dev/null
@@ -0,0 +1,2007 @@
+.de XX
+.ne 3
+.sp .3
+.ti -1i
+.ta 1i
+\\$1   \c
+..
+.EQ
+delim $$
+.EN
+.ND "1 August 1978"
+.RP
+.TL
+A Portable Fortran 77 Compiler
+.AU
+S. I. Feldman
+.AU
+P. J. Weinberger
+.AI
+.MH
+.AB
+.LP
+The Fortran language has just been revised.
+The new language, known as Fortran 77,
+became an official American National Standard on April 3, 1978.
+We report here on a compiler and run-time system for the new extended language.
+This is believed to be the first complete Fortran 77 system to be implemented.
+This compiler is designed to be portable,
+to be correct and complete,
+and to generate code compatible with calling sequences produced by C compilers.
+In particular, this Fortran is quite usable on
+.UX
+systems.
+In this paper, we describe the language compiled,
+interfaces between procedures,
+and file formats assumed by the I/O system.
+An appendix describes the Fortran 77 language.
+.AE
+.CS 9 10 19 0 0 8
+.NH 0
+INTRODUCTION
+.PP
+The Fortran language has just been revised.
+The new language, known as Fortran 77, became an official American National Standard [1] on April 3, 1978.
+for the language, known as Fortran 77, is about to be published.
+Fortran 77 supplants 1966 Standard Fortran [2].
+We report here on a compiler and run-time system for the new extended language.
+The compiler and computation library were written by SIF, the I/O system by PJW.
+We believe ours to be the first complete Fortran 77 system to be implemented.
+This compiler is designed to be portable to a number of different machines,
+to be correct and complete,
+and to generate code compatible with calling sequences produced
+by compilers for the C language [3].
+In particular,
+it is in use on
+.UX
+systems.
+Two families of C compilers are in use at Bell Laboratories,
+those based on D. M. Ritchie's PDP-11 compiler[4]
+and those based on S. C. Johnson's portable C compiler [5].
+This Fortran compiler can drive the second passes of either family.
+In this paper, we describe the language compiled,
+interfaces between procedures,
+and file formats assumed by the I/O system.
+We will describe implementation details in companion papers.
+.PP
+.NH 2
+Usage
+.PP
+At present, versions of the compiler run on and compile for the PDP-11,
+the VAX-11/780,
+and the Interdata 8/32
+.UX
+systems.
+The command to run the compiler is
+.DS C
+f\|77  \fIflags  file . . .\fR
+.DE
+.B f\|77
+is a general-purpose command for compiling and loading Fortran and Fortran-related files.
+EFL [6] and Ratfor [7] source files will be preprocessed before being presented to the Fortran compiler.
+C and assembler source files will be compiled by the appropriate programs.
+Object files will be loaded.
+(The
+.B f\|77
+and
+.B cc
+commands cause slightly different loading sequences to be generated,
+since Fortran programs need a few extra libraries and a different startup routine
+than do C programs.)
+The following file name suffixes are understood:
+.DS I
+ .f    Fortran source file
+ .e    EFL source file
+ .r    Ratfor source file
+ .c    C source file
+ .s    Assembler source file
+ .o    Object file
+.DE
+The following flags are understood:
+.in +1i
+.XX \(miS
+Generate assembler output for each source file, but do not assemble it.
+Assembler output for a source file
+.B x.f,
+.B x.e,
+.B x.r,
+or
+.B x.c
+is put on file
+\fBx.s\fR.
+.XX \(mic
+Compile but do not load.
+Output for
+.B x.f,
+.B x.e,
+.B x.r,
+.B x.c,
+or
+.B x.s
+is put on file
+.B x.o.
+.XX \(mim
+Apply the M4 macro preprocessor to each EFL or Ratfor source file before using the appropriate compiler.
+.XX \(mif
+Apply the EFL or Ratfor processor to all
+relevant files, and leave the output from
+.B x.e
+or
+.B x.r
+on
+.B x.f.
+Do not compile the resulting Fortran program.
+.XX \(mip
+Generate code to produce usage profiles.
+.XX "\(mio \fIf\fR"
+Put executable module on file
+.I f.
+(Default is
+\fBa.out\fR).
+.XX \(miw
+Suppress all warning messages.
+.XX \(miw66
+Suppress warnings about Fortran 66 features used.
+.XX \(miO
+Invoke the C object code optimizer.
+.XX \(miC
+Compile code the checks that subscripts are within array bounds.
+.XX \(mionetrip
+Compile code that performs every
+.B do
+loop at least once.
+(see Section 2.10).
+.XX \(miU
+Do not convert upper case letters to lower case.
+The default is to convert Fortran programs to lower case.
+.XX \(miu
+Make the default type of a variable
+.B undefined.
+(see Section 2.3).
+.XX \(miI2
+On machines which support short integers,
+make the default integer constants and variables short.
+(\fB\(miI4\fR is the standard value of this option).  (see Section 2.14).
+All logical quantities will be short.
+.XX \(miE
+The remaining characters in the argument are used as an EFL flag argument.
+.XX \(miR
+The remaining characters in the argument are used as a Ratfor flag argument.
+.XX \(miF
+Ratfor and and EFL source programs are pre-processed into Fortran files,
+but those files are not compiled or removed.
+.in -1i
+.LP
+Other flags,
+all library names (arguments beginning \fB\(mil\fR),
+and any names not ending with one of the understood suffixes are passed to the loader.
+.NH 2
+Documentation Conventions
+.PP
+In running text, we write Fortran keywords and other literal strings in boldface lower case.
+Examples will be presented in lightface lower case.
+Names representing a class of values will be printed in italics.
+.NH 2
+Implementation Strategy
+.PP
+The compiler and library are written entirely in C.
+The compiler  generates C compiler intermediate code.
+Since there are C compilers running on a variety of machines,
+relatively small changes will make this Fortran compiler generate code for any of them.
+Furthermore, this approach guarantees that the resulting programs are compatible with C usage.
+The runtime computational library is complete.
+The mathematical functions are computed to at least 63 bit precision.
+The runtime I/O library makes use of D. M. Ritchie's Standard C I/O package [8]
+for transferring data.
+With the few exceptions described below, only documented calls are used,
+so it should be relatively easy to modify to run on other operating
+systems.
+.NH 1
+LANGUAGE EXTENSIONS
+.PP
+Fortran 77 includes almost all of Fortran 66 as a subset.
+We describe the differences briefly in the Appendix.
+The most important additions are a character string data type,
+file-oriented input/output statements, and random access I/O.
+Also, the language has been cleaned up considerably.
+.PP
+In addition to implementing the language specified in the new Standard,
+our compiler implements a few extensions described in this section.
+Most are useful additions to the language.
+The remainder are extensions
+to make it easier to communicate with C procedures
+or to permit compilation of
+old (1966 Standard) programs.
+.NH 2
+Double Complex Data Type
+.IP
+The new type
+.B "double complex"
+is defined.
+Each datum is represented by a pair of double precision real variables.
+A double complex version of every
+.B complex
+built-in function is provided.
+The specific function names begin with \fBz\fR instead of \fBc\fR.
+.NH 2
+Internal Files
+.IP
+The Fortran 77 standard introduces ``internal files'' (memory arrays), but
+restricts their use to formatted sequential I/O statements.
+Our I/O system also permits internal files to be used
+in direct and unformatted reads and writes.
+.NH 2
+Implicit Undefined statement
+.IP
+Fortran 66 has a fixed rule that the type of a variable that does not appear in a type statement
+is
+.B integer
+if its first letter is
+\fBi, j, k, l, m\fR or \fBn\fR,
+and
+.B real
+otherwise.
+Fortran 77 has an
+.B implicit
+statement for overriding this rule.
+As an aid to good programming practice, we permit an additional type,
+.B undefined.
+The statement
+.DS
+implicit undefined(a-z)
+.DE
+turns off the automatic data typing mechanism,
+and the compiler will issue a diagnostic for each variable that is used but does
+not appear in a type statement.
+Specifying the
+.B \(miu
+compiler flag is equivalent to beginning each procedure with this statement.
+.NH 2
+Recursion
+.IP
+Procedures may call themselves, directly or through a chain of other procedures.
+.NH 2
+Automatic Storage
+.IP
+Two new keywords are recognized,
+.B static
+and
+.B automatic.
+These keywords may appear as ``types'' in type statements and in
+.B implicit
+statements.
+Local variables are static by default;
+there is exactly one copy of the datum, and its value is retained between calls.
+There is one copy of each variable declared
+.B automatic
+for each invocation of the procedure.
+Automatic variables may not appear in
+.B equivalence,
+.B data,
+or
+.B save
+statements.
+.NH 2
+Source Input Format
+.IP
+The Standard expects input to the compiler to be in 72 column format:
+except in comment lines,
+the first five characters are the statement number, the next is the continuation character,
+and the next sixty-six are the body of the line.
+(If there are fewer than seventy-two characters on a line, the compiler pads it with blanks;
+characters after the seventy-second are ignored).
+.IP
+In order to make it easier to type Fortran programs,
+our compiler also accepts input in variable length lines.
+An ampersand (``&'') in the first position of a line indicates a continuation
+line; the remaining characters form the body of the line.
+A tab character in one of the first six positions of a line signals the
+end of the statement number and continuation part of the line;
+the remaining characters form the body of the line.
+A tab elsewhere on the line is treated as another kind of blank by the
+compiler.
+.IP
+In the Standard, there are only 26 letters \(em Fortran is a one-case language.
+Consistent with ordinary
+.UX
+system usage, our compiler expects lower case input.
+By default, the compiler converts all upper case characters to lower case except those inside character constants.
+However, if the
+.B \(miU
+compiler flag is specified, upper case letters are not transformed.
+In this mode, it is possible to specify external names with upper case letters in them,
+and to have distinct variables differing only in case.
+Regardless of the setting of the flag,
+keywords will only be recognized in lower case.
+.NH 2
+Include Statement
+.IP
+The statement
+.DS
+include \(fmstuff\|\(fm
+.DE
+is replaced by the contents of the file
+.B stuff.
+\fBinclude\fRs may be nested to a reasonable depth, currently ten.
+.NH 2
+Binary Initialization Constants
+.IP
+A
+.B logical,
+.B real,
+or
+.B integer
+variable may be initialized in a
+.B data
+statement
+by a binary constant, denoted by a letter followed by a quoted string.
+If the letter is \fBb\fR, the string is binary, and only zeroes and ones are permitted.
+If the letter is \fBo\fR, the string is octal, with digits \fB0\(mi7\fR.
+If the letter is \fBz\fR or \fBx\fR, the string is hexadecimal, with digits \fB0\(mi9\fR, \fBa\(mif\fR.
+Thus, the statements
+.DS
+integer a(3)
+data a / b\(fm1010\(fm, o\(fm12\(fm, z\(fma\(fm /
+.DE
+initialize all three elements of
+.B a
+to ten.
+.NH 2
+Character Strings
+.IP
+For compatibility with C usage, the following backslash escapes are recognized:
+.DS
+\en    newline
+\et    tab
+\eb    backspace
+\ef    form feed
+\e0    null
+\e\(fm apostrophe (does not terminate a string)
+\e"    quotation mark (does not terminate a string)
+\e\e   \e
+\e\fIx\fR      \fIx\fR,  where \fIx\fR is any other character
+.DE
+Fortran 77 only has one quoting character, the apostrophe.
+Our compiler and I/O system recognize
+both the apostrophe ( \(fm ) and the double-quote ( " ).
+If a string begins with one variety of quote mark, the other may be embedded within it
+without using the repeated quote or backslash escapes.
+.IP
+Every unequivalenced scalar local character variable and every character string constant is aligned
+on an
+.B integer
+word boundary.
+Each character string constant appearing outside a
+.B data
+statement is followed by a
+null character to ease communication with C routines.
+.NH 2
+Hollerith
+.IP
+Fortran 77 does not have the old Hollerith (\fIn\|\fBh\fR)
+notation,
+though the new Standard recommends implementing the old Hollerith feature
+in order to improve compatibility with old programs.
+In our compiler, Hollerith data may be used in place of character string constants,
+and may also be used to initialize non-character variables in
+.B data
+statements.
+.NH 2
+Equivalence Statements
+.IP
+As a very special and peculiar case,
+Fortran 66 permits an element of a multiply-dimensioned array to be represented by
+a singly-subscripted reference in
+.B equivalence
+statements.
+Fortran 77 does not permit this usage, since
+subscript lower bounds may now be different from 1.
+Our compiler permits single subscripts in
+.B equivalence
+statements,
+under the interpretation that all missing subscripts are equal to 1.
+A warning message is printed for each such incomplete subscript.
+.NH 2
+One-Trip DO Loops
+.IP
+The Fortran 77 Standard requires that the range of a
+.B do
+loop not be performed
+if the initial value is already past the limit value,
+as in
+.DS
+do 10 i = 2, 1
+.DE
+The 1966 Standard stated that the effect of such a statement was undefined,
+but it was common practice that the range of a
+.B do
+loop would be performed
+at least once.
+In order to accommodate old programs, though they were in violation of the 1966 Standard,
+the
+.B \(mionetrip
+compiler flag causes non-standard loops to be generated.
+.NH 2
+Commas in Formatted Input
+.IP
+The I/O system attempts to be more lenient than the
+Standard when it seems worthwhile.
+When doing a formatted read of non-character variables,
+commas may be used as value separators in the input record,
+overriding the field lengths given in the format statement.
+Thus,
+the format
+.DS
+(i10, f20.10, i4)
+.DE
+will read the record
+.DS
+\(mi345,.05e\(mi3,12
+.DE
+correctly.
+.NH 2
+Short Integers
+.IP
+On machines that support halfword integers,
+the compiler accepts declarations of type
+.B integer\(**2.
+(Ordinary integers follow the Fortran rules about occupying the same
+space as a REAL variable; they are assumed to be of C type
+.B "long int" ;
+halfword integers are of C type
+.B "short int" .)
+An expression involving only objects of type
+.B integer\(**2
+is of that type.
+Generic functions return short or long integers depending on the actual types of their arguments.
+If a procedure is compiled using the
+.B \(miI2
+flag, all small integer constants will be
+of type
+.B integer\(**2.
+If the precision of an integer-valued intrinsic function is not determined by the generic function rules,
+one will be chosen that returns the prevailing length
+(\fBinteger\(**2\fR when the \fB\(miI2\fR command flag is in effect).
+When the
+.B \(miI2
+option is in effect, all quantities of type
+.B logical
+will be short.
+Note that these short integer and logical quantities do not obey the standard rules for storage association.
+.NH 2
+Additional Intrinsic Functions
+.IP
+This compiler supports all of the intrinsic functions specified in the Fortran 77 Standard.
+In addition, there are functions for performing bitwise Boolean operations
+(
+.B or,
+.B and,
+.B xor,
+and
+.B not)
+and for accessing the
+.UX
+command arguments
+(
+.B getarg
+and
+.B iargc
+).
+.NH 1
+VIOLATIONS OF THE STANDARD
+.PP
+We know only thre ways in which our Fortran system violates the new standard:
+.NH 2
+Double Precision Alignment
+.IP
+The Fortran standards (both 1966 and 1977)
+permit
+.B common
+or
+.B equivalence
+statements to force a double precision quantity onto an odd word boundary,
+as in the following example:
+.DS I
+real a(4)
+double precision b,c
+.sp .5
+equivalence (a(1),b), (a(4),c)
+.DE
+Some machines (e.g., Honeywell 6000, IBM 360) require that double precision quantities be on double word boundaries;
+other machines (e.g., IBM 370), run inefficiently if this alignment rule is not observed.
+It is possible to tell which equivalenced and common variables suffer from a forced odd
+alignment, but every double precision argument would have to be assumed on a bad boundary.
+To load such a quantity on some machines,
+it would be necessary to use separate operations to move the upper and lower halves
+into the halves of an aligned temporary, then to load that double precision temporary; the reverse would be
+needed to store a result.
+We have chosen to require that all double precision real and complex quantities
+fall on even word boundaries on machines with corresponding hardware requirements,
+and to issue a diagnostic if the source code demands a violation of the rule.
+.NH 2
+Dummy Procedure Arguments
+.IP
+If any argument of a procedure is of type character,
+all dummy procedure arguments of that procedure must be declared
+in an
+.B external
+statement.
+This requirement arises as a subtle corollary of the way we represent character string arguments
+and of the one-pass nature of the compiler.
+A warning is printed if a dummy procedure is not declared
+.B external.
+Code is correct if there are no
+.B character
+arguments.
+.NH 2
+T and TL Formats
+.IP
+The implementation of the
+.B t
+(absolute tab)
+and
+.B tl
+(leftward tab)
+format codes
+is defective.
+These codes allow rereading or rewriting part of the
+record which has already been processed.
+(Section 6.3.2 in the Appendix.)
+The implementation uses seeks,
+so if the unit is not one which allows seeks,
+such as a terminal,
+the program is in error.
+(People who can make a case for using
+.B tl
+should let us know.)
+A benefit of the implementation chosen is
+that there is no upper limit on the length of
+a record,
+nor is it necessary to predeclare any record
+lengths except where specifically required
+by Fortran or the operating system.
+.NH 1
+INTER-PROCEDURE INTERFACE
+.PP
+To be able to write C procedures that call or are called by Fortran procedures,
+it is necessary to know the conventions for procedure names,
+data representation,
+return values,
+and argument lists that the compiled code obeys.
+.NH 2
+Procedure Names
+.PP
+On
+.UX
+systems,
+the name of a common block or a Fortran procedure
+has an underscore appended to it by the compiler
+to distinguish it from a C procedure or external variable
+with the same user-assigned name.
+Fortran library procedure names have embedded underscores to avoid clashes
+with user-assigned subroutine names.
+.NH 2
+Data Representations
+.PP
+The following is a table of corresponding Fortran and C declarations:
+.KS
+.TS
+center;
+c c
+l l.
+Fortran        C
+.sp .5
+integer\(**2 x short int x;
+integer x      long int x;
+logical x      long int x;
+real x float x;
+double precision x     double x;
+complex x      struct { float r, i; } x;
+double complex x       struct { double dr, di; } x;
+character\(**6 x       char x[6];
+.TE
+.KE
+(By the rules of Fortran,
+.B integer,
+.B logical,
+and
+.B real
+data occupy the same amount of memory).
+.NH 2
+Return Values
+.PP
+A function of type
+.B integer,
+.B logical,
+.B real,
+or
+.B "double precision"
+declared as a C function that returns the corresponding type.
+A
+.B complex
+or
+.B "double complex"
+function is equivalent to a C routine
+with an additional
+initial argument that points to the place where the return value is to be stored.
+Thus,
+.DS
+complex function f( . . . )
+.DE
+is equivalent to
+.DS
+f_(temp, . . .)
+struct { float r, i; } \(**temp;
+ . . .
+.DE
+.DE
+A character-valued function is equivalent to a C routine with
+two extra initial arguments:
+a data address and a length.
+Thus,
+.DS
+character\(**15 function g( . . . )
+.DE
+is equivalent to
+.DS
+g_(result, length, . . .)
+char result[ ];
+long int length;
+ . . .
+.DE
+and could be invoked in C by
+.DS
+char chars[15];
+ . . .
+g_(chars, 15L, . . . );
+.DE
+Subroutines are invoked as if they were \fBinteger\fR-valued functions
+whose value specifies which alternate return to use.
+Alternate return arguments (statement labels) are not passed to the function,
+but are used to do an indexed branch in the calling procedure.
+(If the subroutine has no entry points with alternate return arguments,
+the returned value is undefined.)
+The statement
+.DS
+call nret(\(**1, \(**2, \(**3)
+.DE
+is treated exactly as if it were the computed
+.B goto
+.DS
+goto (1, 2, 3),  nret( )
+.DE
+.NH 2
+Argument Lists
+.PP
+All Fortran arguments are passed by address.
+In addition,
+for every argument that is of type character or
+that is a dummy procedure,
+an argument giving the length of the value is passed.
+(The string lengths are
+.B "long int"
+quantities passed by value).
+The order of arguments is then:
+.DS
+Extra arguments for complex and character functions
+Address for each datum or function
+A \fBlong int\fR for each character or procedure argument
+.DE
+Thus, the call in
+.DS
+external f
+character\(**7 s
+integer b(3)
+ . . .
+call sam(f, b(2), s)
+.DE
+is equivalent to that in
+.DS
+int f();
+char s[7];
+long int b[3];
+ . . .
+sam_(f, &b[1], s, 0L, 7L);
+.DE
+Note that the first element of a C array always has subscript zero,
+but Fortran arrays begin at 1 by default.
+Fortran arrays are stored in column-major order, C arrays are stored in row-major order.
+.NH 1
+FILE FORMATS
+.NH 2
+Structure of Fortran Files
+.PP
+Fortran requires four kinds of external files:
+sequential formatted and unformatted,
+and direct formatted and unformatted.
+On
+.UX
+systems,
+these are all implemented as ordinary files
+which are assumed to have the proper
+internal structure.
+.PP
+Fortran I/O is based on ``records''.
+When a direct file is opened in a Fortran program,
+the record length of the records must be given,
+and this is used by the Fortran I/O system to
+make the file look as if it is made up of records
+of the given length.
+In the special case that the record length is given
+as 1,
+the files are not considered to be divided into records,
+but are treated as byte-addressable byte strings;
+that is,
+as ordinary
+.UX
+file system files.
+(A read or write request on such a file keeps consuming bytes until
+satisfied, rather than being restricted to a single record.)
+.PP
+The peculiar requirements on sequential unformatted files
+make it unlikely that they will ever be read or written by any means except Fortran I/O statements.
+Each record is preceded and followed by
+an integer containing the record's length in bytes.
+.PP
+The Fortran I/O system breaks sequential formatted files
+into records while reading by using each newline
+as a record separator.
+The result of reading off the end of a record is undefined according to the Standard.
+The I/O system is permissive and
+treats the record as being extended by blanks.
+On output,
+the I/O system will write a newline at the end of each
+record.
+It is also possible for programs to write newlines
+for themselves.
+This is an error,
+but the only effect will be that the single record
+the user thought he wrote will be treated as
+more than one record when being read or
+backspaced over.
+.NH 2
+Portability Considerations
+.PP
+The Fortran I/O system uses only the facilities of the
+standard C I/O library,
+a widely available and fairly portable package,
+with the following two nonstandard features:
+The I/O system needs to know whether a file
+can be used for direct I/O,
+and whether or not it is possible to backspace.
+Both of these facilities are implemented
+using the
+.B fseek
+routine,
+so there is a routine
+.B canseek
+which determines if
+.B fseek
+will have the desired effect.
+Also, the
+.B inquire
+statement provides the user
+with the ability to find out if two files are the
+same,
+and to get the name of an already opened file
+in a form which would enable the program to reopen
+it.
+(The
+.UX
+operating system implementation attempts to determine the full pathname.)
+Therefore there are two routines which
+depend on facilities of the operating system
+to provide these two services.
+In any case,
+the I/O system
+runs on the PDP-11, VAX-11/780, and Interdata 8/32
+.UX
+systems.
+.NH 2
+Pre-Connected Files and File Positions
+.PP
+Units 5, 6, and 0 are preconnected when the program starts.
+Unit 5 is connected to the standard input,
+unit 6 is connected to the standard output,
+and unit 0 is connected to the standard error unit.
+All are connected for sequential formatted I/O.
+.PP
+All the other units are also preconnected when execution
+begins.
+Unit
+.I n
+is connected to a file named \fBfort.\fIn\fR.
+These files need not exist,
+nor will they be created unless their units are used
+without first executing an
+.B open.
+The default connection is for sequential formatted I/O.
+.PP
+The Standard does not specify where a file which has been explicitly \fBopen\fRed
+for sequential I/O is initially positioned.
+In fact,
+the I/O system attempts to position the file at the end,
+so a
+.B write
+will append to the file and a
+.B read
+will result in an end-of-file indication.
+To position a file to its beginning,
+use a
+.B rewind
+statement.
+The preconnected units
+0, 5, and 6 are positioned as they come
+from the program's parent process.
+.SG
+.SH
+REFERENCES
+.LP
+.IP 1.
+\fISigplan Notices \fB11\fR, No.3 (1976),
+as amended in X3J3 internal documents through ``/90.1''.
+.IP 2.
+\fIUSA Standard FORTRAN, USAS X3.9-1966\fR,
+New York: United States of America Standards Institute, March 7, 1966.
+Clarified in
+\fIComm. ACM \fB12,\fR 289 (1969)
+and
+\fIComm. ACM \fB14, \fR 628 (1971).
+.IP 3.
+B. W. Kernighan and D. M. Ritchie,
+.I
+The C Programming Language,
+.R
+Englewood Cliffs: Prentice-Hall (1978).
+.IP 4.
+D. M. Ritchie, private communication.
+.IP 5.
+S. C. Johnson,
+``A Portable Compiler: Theory and Practice'',
+Proc. 5th ACM Symp. on Principles of Programming Languages
+(January 1978).
+.IP 6.
+S. I. Feldman,
+``An Informal Description of EFL'',
+internal memorandum.
+.IP 7.
+B. W. Kernighan,
+``RATFOR \(em A Preprocessor for a Rational Fortran'',
+.I
+Bell Laboratories Computing Science Technical Report #55,
+.R
+(January 1977).
+.IP 8.
+D. M. Ritchie, private communication.
+.bp
+.SH
+APPENDIX.  Differences Between Fortran 66 and Fortran 77
+.PP
+The following is a very brief description of the differences
+between the 1966 [2] and the 1977 [1] Standard languages.
+We assume that the reader is familiar with Fortran 66.
+We do not pretend to be complete, precise,
+or unbiased,
+but plan to describe what we feel are the most important aspects of the new language.
+At present the only current information on the 1977 Standard is in publications of the X3J3 Subcommittee
+of the
+American National Standards Institute.
+The following information is from the ``/92'' document.
+This draft Standard is written in English rather than a meta-language, but it is forbidding
+and legalistic.
+No tutorials or textbooks are available yet.
+.NH 0
+Features Deleted from Fortran 66
+.NH 2
+Hollerith
+.IP
+All notions of ``Hollerith''
+(\fIn\|\fBh\fR)
+as data
+have been officially removed, although our compiler, like almost all in the foreseeable future,
+will continue to support this archaism.
+.NH 2
+Extended Range
+.IP
+In Fortran 66, under a set of very restrictive and rarely-understood conditions, it is permissible
+to jump out of the range of a
+.B do
+loop, then jump back into it.
+Extended range has been removed in the Fortran 77 language.
+The restrictions are so special, and the implementation of extended range is so unreliable in many compilers,
+that this change really counts as no loss.
+.NH 1
+Program Form
+.NH 2
+Blank Lines
+.IP
+Completely blank lines are now legal comment lines.
+.NH 2
+Program and Block Data Statements
+.IP
+A main program may now begin with a statement that gives that program an external name:
+.DS
+program work
+.DE
+Block data procedures may also have names.
+.DS
+block data stuff
+.DE
+There is now a rule that only
+.I one
+unnamed
+block data procedure may appear in a program.
+(This rule is not enforced by our system.)
+The Standard does not specify the effect of the program and block data names,
+but they are clearly intended to aid conventional loaders.
+.NH 2
+ENTRY Statement
+.IP
+Multiple entry points are now legal.
+Subroutine and function subprograms may have additional entry points,
+declared by an
+.B entry
+statement with an optional argument list.
+.DS
+entry extra(a, b, c)
+.DE
+Execution begins at the first statement following the
+.B entry
+line.
+All variable declarations must precede all executable statements in the procedure.
+If the procedure begins with a
+.B subroutine
+statement,
+all entry points are subroutine names.
+If it begins with a
+.B function
+statement, each entry is a function entry point,
+with type determined by the type declared for the entry name.
+If any entry is a character-valued function,
+then all entries must be.
+In a function, an entry name of the same type as that where control entered
+must be assigned a value.
+Arguments do not retain their values between calls.
+(The ancient trick of calling one entry point with a large number of arguments
+to cause the procedure to ``remember'' the locations of those arguments,
+then invoking an entry with just a few arguments for later calculation,
+is still illegal.
+Furthermore, the trick doesn't work in our implementation,
+since arguments are not kept in static storage.)
+.NH 2
+DO Loops
+.IP
+.B do
+variables and range parameters may now be of integer, real, or double precision types.
+(The use of floating point
+.B do
+variables is very dangerous
+because of the possibility of unexpected roundoff,
+and we strongly recommend against their use).
+The action of the
+.B do
+statement is now defined for all values of the
+.B do
+parameters.
+The statement
+.DS
+do 10 i = l, u, d
+.DE
+performs
+$ max (0^,^ left floor ( u - l ) / d^ right floor )$
+iterations.
+The
+.B do
+variable has a predictable value when exiting a loop:
+the value at the time a
+.B goto
+or
+.B return
+terminates the loop;
+otherwise
+the value that failed the limit test.
+.NH 2
+Alternate Returns
+.IP
+In a
+.B subroutine
+or subroutine
+.B entry
+statement,
+some of the arguments may be noted by an asterisk, as in
+.DS
+subroutine s(a, \(**, b, \(**)
+.DE
+The meaning of the ``alternate returns'' is described in section 5.2 of the Appendix.
+.NH 1
+Declarations
+.NH 2
+CHARACTER Data Type
+.IP
+One of the biggest improvements to the language is the addition of a character-string data type.
+Local and
+common character variables must have a length denoted by a constant expression:
+.DS
+character\(**17 a, b(3,4)
+character\(**(6+3) c
+.DE
+If the length is omitted entirely, it is assumed equal to 1.
+A character string argument may have a constant length,
+or the length may be declared to be the same as that of the corresponding actual argument at run time
+by a statement like
+.DS
+character\(**(\(**) a
+.DE
+(There is an intrinsic function
+.B len
+that returns the actual length of a character string).
+Character arrays and common blocks containing character variables must be packed:
+in an array of character variables, the first character of one element must follow the last character of
+the preceding element, without holes.
+.NH 2
+IMPLICIT Statement
+.IP
+The traditional implied declaration rules still hold:
+a variable whose name begins with
+\fBi, j, k, l, m,\fR or \fBn\fR is of type
+.B integer,
+other variables are of type
+.B real,
+unless otherwise declared.
+This general rule may be overridden with an
+.B implicit
+statement:
+.DS
+implicit real(a-c,g), complex(w-z), character\(**(17) (s)
+.DE
+declares that variables whose name begins with an
+\fBa ,b, c,\fR
+or
+\fBg\fR
+are
+.B real,
+those beginning with
+\fBw, x, y,\fR
+or
+\fBz\fR
+are assumed
+.B complex,
+and so on.
+It is still poor practice to depend on implicit typing, but this statement is an industry standard.
+.NH 2
+PARAMETER Statement
+.IP
+It is now possible to give a constant a symbolic name, as in
+.DS
+parameter (x=17, y=x/3, pi=3.14159d0, s=\(fmhello\(fm)
+.DE
+The type of each parameter name is governed by the same implicit and explicit rules as for a variable.
+The right side of each equal sign must be a constant expression
+(an expression made up of constants, operators, and already defined parameters).
+.NH 2
+Array Declarations
+.IP
+Arrays may now have as many as seven dimensions.
+(Only three were permitted in 1966).
+The lower bound of each dimension may be declared
+to be other than 1 by
+using a colon.
+Furthermore, an adjustable array bound may be an integer expression involving constants,
+arguments, and variables in
+.B common.
+.DS
+real a(\(mi5:3, 7, m:n), b(n+1:2\(**n)
+.DE
+The upper bound on the last dimension of an array argument may be denoted by an asterisk
+to indicate that the upper bound is not specified:
+.DS
+integer a(5, \(**),  b(\(**), c(0:1, \(mi2:\(**)
+.DE
+.NH 2
+SAVE Statement
+.IP
+A poorly known rule of Fortran 66 is that local variables in a procedure do not necessarily retain their values between
+invocations of that procedure.
+At any instant in the execution of a program,
+if a common block is declared neither in the currently executing procedure
+nor in any of the procedures in the chain of callers,
+all of the variables in that common block also become undefined.
+(The only exceptions are variables that have been defined in a
+.B data
+statement and never changed).
+These rules permit overlay and stack implementations for the affected variables.
+Fortran 77 permits one to specify that certain variables and common blocks are to retain their
+values between invocations.
+The declaration
+.DS
+save a, /b/, c
+.DE
+leaves the values of the variables
+.B a
+and
+.B c
+and all of the contents of common block
+.B b
+unaffected by a return.
+The simple declaration
+.DS
+save
+.DE
+has this effect on all variables and common blocks in the procedure.
+A common block must be \fBsave\fRd in every procedure in which it is declared if the desired effect is to occur.
+.NH 2
+INTRINSIC Statement
+.IP
+All of the functions specified in the Standard are in a single category,
+``intrinsic functions'', rather than being divided into ``intrinsic'' and ``basic external'' functions.
+If an intrinsic function is to be passed to another procedure, it must be declared
+.B intrinsic.
+Declaring it
+.B external
+(as in Fortran 66) causes a function other than the built-in one to be passed.
+.NH 1
+Expressions
+.NH 2
+Character Constants
+.IP
+Character string constants are marked by strings surrounded by apostrophes.
+If an apostrophe is to be included in a constant, it is repeated:
+.DS
+ \(fmabc\(fm
+ \(fmain\(fm\(fmt\(fm
+.DE
+There are no null (zero-length) character strings in Fortran 77.
+Our compiler has two different quotation marks, `` \(fm ''' and `` " ''.
+(See Section 2.9 in the main text.)
+.NH 2
+Concatenation
+.IP
+One new operator has been added, character string concatenation, marked by a double slash
+(``//'').
+The result of a concatenation is the string containing the characters of the left operand followed by the characters of
+the right operand.
+The strings
+.DS
+ \(fmab\(fm // \(fmcd\(fm
+ \(fmabcd\(fm
+.DE
+are equal.
+The strings being concatenated must be of constant length in all concatenations
+that are not the right sides of assignments.
+(The only concatenation expressions in which a
+character string declared adjustable with a ``\(**(\(**)'' modifier
+or a substring denotation with nonconstant position values may appear
+are the right sides of assignments).
+.NH 2
+Character String Assignment
+.IP
+The left and right sides of a character assignment may not share storage.
+(The assumed implementation of character assignment is to copy characters from the right to the left side.)
+If the left side is longer than the right, it is padded with blanks.
+If the left side is shorter than the right, trailing characters are discarded.
+.NH 2
+Substrings
+.IP
+It is possible to extract a substring of a character variable or character array element, using the colon notation:
+.DS
+a(i,\|j) (m:n)
+.DE
+is the string of $(n-m+1)$ characters beginning at the
+$m sup th$ character of the character array element $a sub ij$.
+Results are undefined unless $m<=n$.
+Substrings may be used on the left sides of assignments and as procedure actual arguments.
+.NH 2
+Exponentiation
+.IP
+It is now permissible to raise real quantities to complex powers,
+or complex quantities to real or complex powers.
+(The principal part of the logarithm is used).
+Also, multiple exponentiation is now defined:
+.DS
+a\(**\(**b\(**\(**c = a \(**\(** (b\(**\(**c)
+.DE
+.NH 2
+Relaxation of Restrictions
+.IP
+Mixed mode expressions are now permitted.
+(For instance,
+it is permissible to combine integer and complex quantities in an expression.)
+.IP
+Constant expressions are permitted where a constant is allowed,
+except in
+.B data
+statements.
+(A constant expression is made up of explicit constants and
+\fBparameter\fRs
+and the Fortran operators,
+except for exponentiation to a floating-point power).
+An adjustable dimension may now be an integer expression involving constants,
+arguments, and variables in
+B common..
+.IP
+Subscripts may now be general integer expressions;
+the old
+$c v +- c'$
+rules have been removed.
+.B do
+loop bounds may be general integer, real, or double precision expressions.
+Computed
+.B goto
+expressions and I/O unit numbers may be general integer expressions.
+.NH 1
+Executable Statements
+.NH 2
+IF-THEN-ELSE
+.IP
+At last, the
+if-then-else
+branching structure has been added to Fortran.
+It is called a ``Block If''.
+A Block If begins with a statement of the form
+.DS
+if ( . . . ) then
+.DE
+and ends with an
+.DS
+end if
+.DE
+statement.
+Two other new statements may appear in a Block If.
+There may be several
+.DS
+else if(. . .) then
+.DE
+statements,
+followed by at most one
+.DS
+else
+.DE
+statement.
+If the logical expression in the Block If statement is true, the statements following it up to the
+next
+.B elseif,
+.B else,
+or
+.B endif
+are executed.
+Otherwise, the next
+.B elseif
+statement in the group is executed.
+If none of the
+.B elseif
+conditions are true, control passes to the statements following the
+.B else
+statement, if any.
+(The
+.B else
+must follow all \fBelseif\fRs in a Block If.
+Of course, there may be Block Ifs embedded inside of other Block If structures).
+A
+case
+construct may be rendered
+.DS
+if (s .eq. \(fmab\(fm) then
+ . . .
+else if (s .eq. \(fmcd\(fm) then
+ . . .
+else
+ . . .
+end if
+.DE
+.NH 2
+Alternate Returns
+.IP
+Some of the arguments of a subroutine call may be statement labels preceded by an asterisk, as in
+.DS
+call joe(j, \(**10, m, \(**2)
+.DE
+A
+.B return
+statement may have an integer expression, such as
+.DS
+return k
+.DE
+If the entry point has
+$n$
+alternate return (asterisk) arguments
+and if $1<=k<=n$, the return is followed by a branch to the corresponding statement label;
+otherwise the usual return to the statement following the
+.B call
+is executed.
+.NH 1
+Input/Output
+.NH 2
+Format Variables
+.IP
+A format may be the value of a character expression (constant or otherwise),
+or be stored in a character array, as in
+.DS
+write(6, \(fm(i5)\(fm) x
+.DE
+.NH 2
+END=, ERR=, and IOSTAT= Clauses
+.IP
+A
+.B read
+or
+.B write
+statement may contain
+.B end=,
+.B err=,
+and
+.B iostat=
+clauses, as in
+.DS
+write(6, 101, err=20, iostat=a(4))
+read(5, 101, err=20, end=30, iostat=x)
+.DE
+Here 5 and 6 are the
+.I units
+on which the I/O is done,
+101 is the statement number of the associated format,
+20 and 30 are statement numbers,
+and
+.B a
+and
+.B x
+are integers.
+If an error occurs during I/O,
+control returns to the program at statement 20.
+If the end of the file is reached,
+control returns to the program at statement 30.
+In any case, the variable referred to in
+the
+.B iostat=
+clause is given a value when
+the I/O statement finishes.
+(Yes, the value is assigned to the name on the right side of the equal sign.)
+This value is zero if all went well,
+negative for end of file,
+and some positive value for errors.
+.NH 2
+Formatted I/O
+.NH 3
+Character Constants
+.IP
+Character constants in formats are copied literally to the output.
+Character constants cannot be read into.
+.DS
+write(6,\(fm(i2,\(fm\(fm isn\(fm\(fm\(fm\(fmt \(fm\(fm,i1)\(fm) 7, 4
+.DE
+produces
+.DS
+ 7 isn\(fmt 4
+.DE
+Here the format is the character constant
+.DS
+(i2,\(fm isn\(fm\(fmt \(fm,i1)
+.DE
+and the character constant
+.DS
+ isn\(fmt
+.DE
+is copied into the output.
+.NH 3
+Positional Editing Codes
+.IP
+.B t,
+.B tl,
+.B tr,
+and
+.B x
+codes
+control where the
+next character is in the record.
+\fBtr\fIn\fR
+or
+\fIn\fBx\fR
+specifies that the next character is
+$n$ to the right of the current position.
+\fBtl\fIn\fR
+specifies that the next character is
+$n$ to the left of the current position,
+allowing parts of the record to be reconsidered.
+\fBt\fIn\fR
+says that the next character is to be character
+number $n$ in the record.
+(See section 3.4 in the main text.)
+.NH 3
+Colon
+.IP
+A colon in the format terminates the I/O operation
+if there are no more data items in the I/O list,
+otherwise it has no effect.
+In the fragment
+.DS
+x=\(fm("hello", :, " there", i4)\(fm
+write(6, x) 12
+write(6, x)
+.DE
+the first
+.B write
+statement prints
+\fBhello there 12\fR,
+while the second only prints
+\fBhello\fR.
+.NH 3
+Optional Plus Signs
+.IP
+According to the Standard,
+each implementation has the option of putting
+plus signs in front of non-negative
+numeric output.
+The
+.B sp
+format code may be used to make the optional plus
+signs actually appear for all subsequent items
+while the format is active.
+The
+.B ss
+format code guarantees that the I/O system will not
+insert the optional plus signs,
+and the
+.B s
+format code restores the default behavior of
+the I/O system.
+(Since we never put out optional plus signs,
+.B ss
+and
+.B s
+codes have the same effect in our implementation.)
+.NH 3
+Blanks on Input
+.IP
+Blanks in numeric input fields,
+other than leading blanks
+will be ignored following a
+.B bn
+code in a format
+statement,
+and will be treated as zeros following a
+.B bz
+code in a format statement.
+The default for a unit may be changed by using
+the
+.B open
+statement.
+(Blanks are ignored by default.)
+.NH 3
+Unrepresentable Values
+.IP
+The Standard requires that if a numeric item
+cannot be represented in the form required by a format code,
+the output field must be filled with asterisks.
+(We think this should have been an option.)
+.NH 3
+Iw.m
+.IP
+There is a new integer output code,
+\fBi\fIw.m.\fR
+It is the same as
+\fBi\fIw\fR,
+except that there will be at least $m$
+digits in the output field,
+including,
+if necessary,
+leading zeros.
+The case \fBi\fR$w.0$ is special,
+in that if the value being printed is 0,
+the output field is
+entirely blank.
+\fBi\fIw\fB.1\fR
+is the same as
+\fBi\fIw\fR.
+.NH 3
+Floating Point
+.IP
+On input, exponents may start with the letter
+\fBE, D, e, \fRor \fBd.\fR
+All have the same meaning.
+On output we always use \fBe\fR.
+The
+.B e
+and
+.B d
+format codes also have identical meanings.
+A leading zero before the decimal point in
+.B e
+output
+without a scale factor is optional with the
+implementation.
+(We do not print it.)
+There is a
+\fBg\fIw.d\fR
+format code which is the same as
+\fBe\fIw.d\fR
+and
+\fBf\fIw.d\fR
+on input,
+but which chooses
+.B f
+or
+.B e
+formats for output depending.
+on the size of the number and of $d$.
+.NH 3
+``A'' Format Code
+.IP
+A codes are used for character values.
+\fBa\fIw\fR
+use a field width of $w$,
+while a plain
+.B a
+uses the length of the character item.
+.NH 2
+Standard Units
+.IP
+There are default formatted input and output units.
+The statement
+.DS
+read 10, a, b
+.DE
+reads from the standard unit using format statement 10.
+The default unit may be explicitly specified by an asterisk, as in
+.DS
+read(\(**, 10) a,b
+.DE
+Similarly, the standard output units is specified by a
+.B print
+statement or an asterisk unit:
+.DS
+print 10
+write(\(**, 10)
+.DE
+.NH 2
+List-Directed Formatting
+.IP
+List-directed I/O is a
+kind of free form input for sequential I/O.
+It is invoked by using an asterisk as the
+format identifier, as in
+.DS
+read(6, \(**) a,b,c
+.DE
+.IP
+On input,
+values are separated by strings of blanks
+and possibly a comma.
+Values,
+except for character strings,
+cannot contain blanks.
+End of record counts as a blank,
+except in character strings,
+where it is ignored.
+Complex constants are given as two real constants
+separated by a comma and enclosed in parentheses.
+A null input field,
+such as between two consecutive commas,
+means the corresponding variable in the
+I/O list is not changed.
+Values may be preceded by repetition counts,
+as in
+.DS
+4\(**(3.,2.)  2\(**, 4\(**\(fmhello\(fm
+.DE
+which stands for 4 complex constants, 2 null values,
+and 4 string constants.
+.IP
+For output, suitable formats are chosen for
+each item.
+The values of character strings are printed;
+they are not enclosed in quotes, so they cannot be read back
+using list-directed input.
+.NH 2
+Direct I/O
+.IP
+A file connected for direct access consists of
+a set of equal-sized records each of which is
+uniquely identified by a positive integer.
+The records may be written or read in any order,
+using direct access I/O statements.
+.IP
+Direct access
+.B read
+and
+.B write
+statements
+have an extra argument,
+.B rec=,
+which gives the record number to be read or written.
+.DS
+read(2, rec=13, err=20) (a(i), i=1, 203)
+.DE
+reads the thirteenth record into the array
+.B a.
+.IP
+The size of the records must be given by an
+.B open
+statement
+(see below).
+Direct access files may be connected for either formatted
+or unformatted I/O.
+.NH 2
+Internal Files
+.IP
+Internal files are character string objects,
+such as variables or substrings,
+or arrays of type character.
+In the former cases there is only a single record
+in the file,
+in the latter case each array element is a record.
+The Standard includes only sequential
+formatted I/O on internal files.
+(I/O is not a very precise term to use here,
+but internal files are dealt with using
+.B read
+and
+.B write).
+There is no list-directed I/O on internal files.
+Internal files are used by giving the name of the
+character object in place of the unit number, as in
+.DS
+character\(**80 x
+read(5,"(a)") x
+read(x,"(i3,i4)") n1,n2
+.DE
+which reads a card image into
+.B x
+and then reads
+two integers from the front of it.
+A sequential
+.B read
+or
+.B write
+always starts at the beginning
+of an internal file.
+.IP
+(We also support a compatible extension, direct I/O on internal files.
+This is like direct I/O on external files,
+except that the number of records in the file cannot be
+changed.)
+.NH 2
+OPEN, CLOSE, and INQUIRE Statements
+.IP
+These statements are used to connect and disconnect
+units and files,
+and to gather information about units and files.
+.NH 3
+OPEN
+.IP
+The
+.B open
+statement is used to connect a file with a
+unit,
+or to alter some properties of the connection.
+The following is a minimal example.
+.DS
+open(1, file=\(fmfort.junk\(fm)
+.DE
+.B open
+takes a variety of arguments with meanings described below.
+.EQ
+delim off
+.EN
+.RS
+.      \" macros here
+.de HP
+.RT
+.if !\\(IP .nr IP +1
+.sp \\n(PDu
+.ne 3v
+.in +\\n(PIu
+.ti -\\n(PIu
+\fB\\$1\fR\ \c
+..
+.de P1
+.KS
+.nf
+.in +.3i
+.ta .3i .6i .9i 1.2i 1.5i 1.8i
+.sp
+..
+.de P2
+.fi
+.in -.3i
+.sp
+.KE
+..
+.de TH
+.RT
+.sp \\n(PDu
+.ne 3v
+\fB\\$1\\$2\\$3\\$4\\$5\\$6\fR\ \c
+..
+.      \" end of macros
+.HP unit=
+a small non-negative integer which is the unit to
+which the file is to be connected.
+We allow,
+at the time of this writing,
+0 through 9.
+If this parameter is the first one in the
+.B open
+statement,
+the
+.B unit=
+can be omitted.
+.HP iostat=
+is the same as in
+.B read
+or
+.B write.
+.HP err=
+is the same as in
+.B read
+or
+.B write.
+.HP file=
+a character expression,
+which when stripped of trailing blanks,
+is the name of the file to be connected to the unit.
+The filename should not be given if the
+.B status=scratch.
+.HP status=
+one of
+.B old,
+.B new,
+.B scratch,
+or
+.B unknown.
+If this parameter is not given,
+.B unknown
+is assumed.
+If
+.B scratch
+is given,
+a temporary file will be created.
+Temporary files are destroyed at the end of execution.
+If
+.B new
+is given,
+the file will be created if it doesn't exist,
+or truncated if it does.
+The meaning of
+.B unknown
+is processor dependent;
+our system treats it as synonymous with
+.B old.
+.HP access=
+.B sequential
+or
+.B direct,
+depending on whether the file is
+to be opened for sequential or direct I/O.
+.HP form=
+.B formatted
+or
+.B unformatted.
+.HP recl=
+a positive integer specifying the record length of
+the direct access file being opened.
+We measure all record lengths in bytes.
+On
+.UX
+systems a record length of 1 has the special meaning explained
+in section 5.1 of the text.
+.HP blank=
+.B null
+or
+.B zero.
+This parameter has meaning only for formatted I/O.
+The default value is
+.B null.
+.B zero
+means that blanks,
+other than leading blanks,
+in numeric input fields are to be treated as zeros.
+.RE
+.IP
+Opening a new file on a unit which is already connected
+has the effect of first closing the old file.
+.NH 3
+CLOSE
+.IP
+.B close
+severs the connection between a unit and a file.
+The unit number must be given.
+The optional parameters are
+.B iostat=
+and
+.B err=
+with
+their usual meanings,
+and
+.B status=
+either
+.B keep
+or
+.B delete.
+Scratch files cannot be kept,
+otherwise
+.B keep
+is the default.
+.B delete
+means the file will be removed.
+A simple example is
+.DS
+close(3, err=17)
+.DE
+.NH 3
+INQUIRE
+.IP
+The
+.B inquire
+statement gives information about
+a unit
+(``inquire by unit'')
+or a file (``inquire by file'').
+Simple examples are:
+.DS
+inquire(unit=3, namexx)
+inquire(file=\(fmjunk\(fm, number=n, exist=l)
+.DE
+.RS
+.HP file=
+a character variable specifies the file the
+.B inquire
+is about.
+Trailing blanks in the file name are ignored.
+.HP unit=
+an integer variable specifies the unit the
+.B inquire
+is about.
+Exactly one of
+.B file=
+or
+.B unit=
+must be used.
+.HP "iostat=, err="
+are as before.
+.HP exist=
+a logical variable.
+The logical variable is set to
+.B ".true."
+if the file or unit
+exists and is set to
+.B ".false."
+otherwise.
+.HP opened=
+a logical variable.
+The logical variable is set to
+.B ".true."
+if the file
+is connected to a unit or if the unit is connected
+to a file,
+and it is set to
+.B ".false."
+otherwise.
+.HP number=
+an integer variable to which is assigned the
+number of the unit connected to the file,
+if any.
+.HP named=
+a logical variable to which is assigned
+.B ".true."
+if
+the file has a name,
+or
+.B ".false."
+otherwise.
+.HP name=
+a character variable to which is assigned the name
+of the file (inquire by file) or the name of the
+file connected to the unit (inquire by unit).
+The name will be the full name of the file.
+.HP access=
+a character variable to which will be assigned
+the value
+.B \(fmsequential\(fm
+if the connection is for
+sequential I/O,
+.B \(fmdirect\(fm
+if the connection is for direct I/O.
+The value becomes undefined if there is no connection.
+.HP sequential=
+a character variable to which is assigned the
+value
+.B \(fmyes\(fm
+if the file could be connected for
+sequential I/O,
+.B \(fmno\(fm
+if the file could not be connected for sequential I/O,
+and
+.B \(fmunknown\(fm
+if we can't tell.
+.HP direct=
+a character variable to which is assigned the value
+.B \(fmyes\(fm
+if the file could be connected for direct I/O,
+.B\(fmno\(fm
+if the file could not be connected for direct
+I/O,
+and
+.B \(fmunknown\(fm
+if we can't tell.
+.HP form=
+a character variable to which is assigned the value
+.B \(fmformatted\(fm
+if the file is connected for formatted I/O,
+or
+.B \(fmunformatted\(fm
+if the file is connected for unformatted
+I/O.
+.HP formatted=
+a character variable to which is assigned the value
+.B \(fmyes\(fm
+if the file could be connected for formatted I/O,
+.B \(fmno\(fm
+if the file could not be connected for formatted I/O,
+and
+.B \(fmunknown\(fm
+if we can't tell.
+.HP unformatted=
+a character variable to which is assigned the value
+.B \(fmyes\(fm
+if
+the file could be connected for unformatted I/O,
+.B \(fmno\(fm
+if the file could not be connected for unformatted I/O,
+and
+.B \(fmunknown\(fm
+if we can't tell.
+.HP recl=
+an integer variable to which is assigned the record length
+of the records in the file if the file is connected
+for direct access.
+.HP nextrec=
+an integer variable to which is assigned one more
+than the number of the the last record read from a file connected
+for direct access.
+.HP blank=
+a character variable to which is assigned the value
+.B \(fmnull\(fm
+if null blank control is in effect for the file
+connected for formatted I/O,
+.B \(fmzero\(fm
+if blanks are being converted to zeros and
+the file is connected for formatted I/O.
+.RE
+.PP
+.I "The gentle reader"
+will remember that the people who wrote the standard
+probably weren't thinking of his needs.
+Here is an example.
+The declarations are omitted.
+.DS
+open(1, file="/dev/console")
+.DE
+On a
+.UX
+system this statement opens the console for formatted sequential
+I/O.
+An
+.B inquire
+statement for either unit 1 or file "/dev/console"
+would reveal that the file exists, is connected to unit 1,
+has a name, namely "/dev/console",
+is opened for sequential I/O,
+could be connected for sequential I/O,
+could not be connected for direct I/O (can't seek),
+is connected for formatted I/O,
+could be connected for formatted I/O,
+could not be connected for unformatted I/O
+(can't seek),
+has neither a record length nor a next record number,
+and is ignoring blanks in numeric fields.
+.PP
+In the
+.UX
+system environment,
+the only way to discover what permissions you have
+for a file is to open it and try to read and write it.
+The
+.B err=
+parameter will return system error numbers.
+The
+.B inquire
+statement does not give a way of determining permissions.