home *** CD-ROM | disk | FTP | other *** search
Text File | 1979-01-10 | 51.1 KB | 2,005 lines |
- .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.
- .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.
-