|
|
1.1 ! root 1: .\" Copyright (c) 1980 Regents of the University of California. ! 2: .\" All rights reserved. The Berkeley software License Agreement ! 3: .\" specifies the terms and conditions for redistribution. ! 4: .\" ! 5: .\" @(#)f77.ms 5.4 (Berkeley) 4/28/86 ! 6: .\" ! 7: .rm CM ! 8: .hw name-list ! 9: .de XX ! 10: .ne 3 ! 11: .sp .3 ! 12: .ti -0.8i ! 13: .ta 0.8i ! 14: \\$1 \c ! 15: .. ! 16: .\" ! 17: .\" Nh macro - same as NH but also saves heading for table of contents ! 18: .\" Nh usage: Nh level string, e.g.: .Nh 2 "Short Integers" ! 19: .de Nh ! 20: .NH \\$1 ! 21: \\$2 ! 22: .XS ! 23: .if '2'\\$1' .ti .25i ! 24: .if '3'\\$1' .ti .5i ! 25: \\*(SN \\$2 ! 26: .XE ! 27: .IP ! 28: .. ! 29: .EQ ! 30: delim $$ ! 31: .EN ! 32: .ND "" ! 33: .\".RP ! 34: .TL ! 35: A Portable Fortran 77 Compiler ! 36: .AU ! 37: S. I. Feldman ! 38: .AU ! 39: P. J. Weinberger ! 40: .AI ! 41: Bell Laboratories ! 42: Murray Hill, New Jersey 07974 ! 43: .AU ! 44: J. Berkman ! 45: .AI ! 46: University of California ! 47: Berkeley, CA 94720 ! 48: .AB ! 49: The Fortran language has been revised. ! 50: The new language, known as\p ! 51: Fortran 77, ! 52: became an official American National Standard on April 3, 1978. ! 53: We report here on a compiler and run-time system for the new extended language. ! 54: It is believed to be the first complete Fortran 77 system to be implemented. ! 55: This compiler is designed to be portable, ! 56: to be correct and complete, ! 57: and to generate code compatible with calling sequences produced by C compilers. ! 58: In particular, this Fortran is quite usable on ! 59: .UX ! 60: systems. ! 61: In this paper, we describe the language compiled, ! 62: interfaces between procedures, ! 63: and file formats assumed by the \s-1I/O\s0 system. ! 64: Appendix A describes the Fortran 77 language extensions. ! 65: .PP ! 66: This is a standard Bell Laboratories ! 67: document reproduced with minor modifications ! 68: to the text. ! 69: The Bell Laboratory's appendix ! 70: on ``Differences Between Fortran 66 and Fortran 77'' ! 71: has been changed to Appendix A, ! 72: and a local appendix has been added. ! 73: Appendix B contains ! 74: a list of Fortran 77 references ! 75: (some from the original Bell document ! 76: and some added at Berkeley). ! 77: .sp 2 ! 78: .LP ! 79: Revised September, 1985 ! 80: .AE ! 81: .LP ! 82: .CS 9 10 19 0 0 8 ! 83: .\" the Table of Contents uses pages 2 and 3, ! 84: .\" hence the document begins at page 4. ! 85: .pn 4 ! 86: .EH 'PS1:2-%''A Portable Fortran 77 Compiler' ! 87: .OH 'A Portable Fortran 77 Compiler''PS1:2-%' ! 88: .bp ! 89: .NH 0 ! 90: INTRODUCTION ! 91: .XS ! 92: \*(SN Introduction ! 93: .XE ! 94: .LP ! 95: The Fortran language has been revised. ! 96: The new language, known as Fortran 77, ! 97: became an official American National Standard [1] on April 3, 1978. ! 98: Fortran 77 supplants 1966 Standard Fortran [2]. ! 99: We report here on a compiler and run-time system for the new extended language. ! 100: The compiler and computation library were written by S.I.F., the \s-1I/O\s0 system by P.J.W. ! 101: We believe ours to be the first complete Fortran 77 system to be implemented. ! 102: This compiler is designed to be portable to a number of different machines, ! 103: to be correct and complete, ! 104: and to generate code compatible with calling sequences produced ! 105: by compilers for the C language [3]. ! 106: In particular, ! 107: it is in use on ! 108: \s-1UNIX\s0 ! 109: systems. ! 110: Two families of C compilers are in use at Bell Laboratories, ! 111: those based on D. M. Ritchie's \s-1PDP-11\s0 compiler [4] ! 112: and those based on S. C. Johnson's portable C compiler [5]. ! 113: This Fortran compiler can drive the second passes of either family. ! 114: In this paper, we describe the language compiled, ! 115: interfaces between procedures, ! 116: and file formats assumed by the \s-1I/O\s0 system. ! 117: We will describe implementation details in companion papers. ! 118: .Nh 2 Usage ! 119: At present, versions of the compiler run on and compile ! 120: for the \s-1PDP-11\s0, ! 121: the \s-1VAX-11/780\s0, ! 122: and the Interdata 8/32 ! 123: \s-1UNIX\s0 ! 124: systems. ! 125: The command to run the compiler is ! 126: .DS ! 127: f\|77 \fIflags file . . .\fR ! 128: .DE ! 129: .B f\|77 ! 130: is a general-purpose command for compiling and loading Fortran and Fortran-related files. ! 131: \s-1EFL\s0 [6] and Ratfor [7] source files will be preprocessed before being presented to the Fortran compiler. ! 132: C and assembler source files will be compiled by the appropriate programs. ! 133: Object files will be loaded. ! 134: (The ! 135: .B f\|77 ! 136: and ! 137: .B cc ! 138: commands cause slightly different loading sequences to be generated, ! 139: since Fortran programs need a few extra libraries and a different startup routine ! 140: than do C programs.) ! 141: The following file name suffixes are understood: ! 142: .DS ! 143: \f3.f\f1 Fortran source file ! 144: \f3.F\f1 Fortran source file ! 145: \f3.e\f1 \s-1EFL\s0 source file ! 146: \f3.r\f1 Ratfor source file ! 147: \f3.c\f1 C source file ! 148: \f3.s\f1 Assembler source file ! 149: \f3.o\f1 Object file ! 150: .DE ! 151: .IP ! 152: Arguments whose names end with \f3.f\f1 are taken to be ! 153: Fortran 77 source programs; ! 154: they are compiled, and ! 155: each object program is left on the file in the current directory ! 156: whose name is that of the source with \f3.o\f1 substituted ! 157: for \f3.f\f1. ! 158: .IP ! 159: Arguments whose names end with \f3.F\f1 ! 160: are also taken to be Fortran 77 source programs; these are first ! 161: processed by the C preprocessor before being compiled by \fBf77\fP. ! 162: .IP ! 163: Arguments whose names end with \f3.r\f1 or \f3.e\f1 ! 164: are taken to be Ratfor or \s-1EFL\s0 ! 165: source programs, respectively; these are first transformed by the ! 166: appropriate preprocessor, then compiled by \fBf77\fP. ! 167: .IP ! 168: In the same way, ! 169: arguments whose names end ! 170: with \f3.c\f1 or \f3.s\f1 ! 171: are taken to be C or assembly source programs ! 172: and are compiled or assembled, producing a \f3.o\f1 file. ! 173: .IP ! 174: The following flags are understood: ! 175: .in +0.8i ! 176: .XX \(mi\f3c\f1 ! 177: Compile but do not load. ! 178: Output for ! 179: .B x.f , ! 180: .B x.F , ! 181: .B x.e , ! 182: .B x.r , ! 183: .B x.c , ! 184: or ! 185: .B x.s ! 186: is put on file ! 187: .B x.o . ! 188: .XX \(mi\f3d\f1 ! 189: Used in debugging the compiler. ! 190: .XX \(mi\f3g\f1 ! 191: Have the compiler produce additional ! 192: symbol table information for \fIdbx(1)\fR. ! 193: This flag is incompatible with \(mi\f3O\f1. ! 194: See section 1.4 for more details. ! 195: .XX \(mi\f3i2\f1 ! 196: On machines which support short integers, ! 197: make the default integer constants and variables short ! 198: (see section 2.14). ! 199: (\fB\(mii4\fR is the standard value of this option). ! 200: All logical quantities will be short. ! 201: .XX \(mi\f3m\f1 ! 202: Apply the M4 macro preprocessor ! 203: to each \s-1EFL\s0 or Ratfor source file ! 204: before using the appropriate compiler. ! 205: .XX "\(mi\f3o\f1 \fIfile\fR" ! 206: Put executable module on file ! 207: .I file . ! 208: (Default is \fBa.out\fR). ! 209: .ne 6 ! 210: .XX \(mi\f3onetrip\f1\ or\ \(mi\f31\f1 ! 211: .br ! 212: Compile code that performs every ! 213: .B do ! 214: loop at least once ! 215: (see section 2.12). ! 216: .XX \(mi\f3p\f1 ! 217: Generate code to produce usage profiles. ! 218: .XX \(mi\f3pg\f1 ! 219: Generate code in the manner of \fB\(mip\fR, but invoke a run-time ! 220: recording mechanism that keeps more extensive statistics. ! 221: See ! 222: .I gprof (1). ! 223: .XX \(mi\f3q\f1 ! 224: Suppress printing of file names and program unit names during compilation. ! 225: .XX \(mi\f3r8\f1 ! 226: Treat all floating point variables, ! 227: constants, functions and intrinsics ! 228: as double precision and all complex ! 229: quantities as double complex. See section 2.17. ! 230: .XX \(mi\f3u\f1 ! 231: Make the default type of a variable ! 232: .B undefined ! 233: (see section 2.3). ! 234: .XX \(mi\f3v\f1 ! 235: Print the version number of the compiler and the name of each pass. ! 236: .XX \(mi\f3w\f1 ! 237: Suppress all warning messages. ! 238: .XX \(mi\f3w66\f1 ! 239: Suppress warnings about Fortran 66 features used. ! 240: .XX \(mi\f3C\f1 ! 241: Compile code that checks that subscripts are within array bounds. ! 242: For multi-dimensional arrays, only the equivalent linear subscript is ! 243: checked. ! 244: .XX \(mi\fBD\fP\fIname=def\fR ! 245: .XX \(mi\fBD\fP\fIname\fR ! 246: Define the ! 247: .I name ! 248: to the C preprocessor, as if by `#define'. If no definition is given, the name ! 249: is defined as "1". (\fB.F\fR files only). ! 250: .XX \(mi\f3E\f1\fIstr\fR ! 251: Use the string \fIstr\fR as an ! 252: \s-1EFL\s0 option in processing \f3.e\f1 files. ! 253: .XX \(mi\f3F\f1 ! 254: Ratfor, \s-1EFL\s0, and \f3.F\f1 source files ! 255: are pre-processed into \f3.f\f1 files, ! 256: and those \f3.f\f1 files are left on the disk without being compiled. ! 257: .XX \(mi\fBI\fP\fIdir\fR ! 258: `#include' files whose names do not begin with `/' are always sought ! 259: first in the directory of the \fIfile\fR ! 260: argument, then in directories named in \fB\(miI\fR ! 261: options, then in directories on a standard list. (\fB.F\fR files only). ! 262: .XX \(mi\f3N\f1[\fBqxscn\fR]\fInnn\f1 ! 263: .br ! 264: Make static tables in the compiler bigger. The compiler will complain ! 265: if it overflows its tables and suggest you apply one or more of these ! 266: flags. These flags have the following meanings: ! 267: .RS ! 268: .IP \fBq\fP ! 269: Maximum number of equivalenced variables. Default is 150. ! 270: .IP \fBx\fP ! 271: Maximum number of external names (common block names, subroutine and ! 272: function names). Default is 200. ! 273: .IP \fBs\fP ! 274: Maximum number of statement numbers. Default is 401. ! 275: .IP \fBc\fP ! 276: Maximum depth of nesting for control statements (e.g. DO loops). Default is ! 277: 20. ! 278: .IP \fBn\fP ! 279: Maximum number of identifiers. Default is 1009. ! 280: .RE ! 281: .XX \(mi\f3O\f1 ! 282: Invoke the object code optimizer. ! 283: Incompatible with \(mi\f3g\f1. ! 284: .XX \(mi\f3R\f1\fIstr\fR ! 285: Use the string \fIstr\fR as a Ratfor option ! 286: in processing \f3.r\f1 files. ! 287: .XX \(mi\f3U\f1 ! 288: Do not convert upper case letters to lower case. ! 289: The default is to convert Fortran programs to lower case ! 290: except within character string constants. ! 291: .XX \(mi\f3S\f1 ! 292: Generate assembler output for each source file, but do not assemble it. ! 293: Assembler output for a source file ! 294: .B x.f , ! 295: .B x.F , ! 296: .B x.e , ! 297: .B x.r , ! 298: or ! 299: .B x.c ! 300: is put on file ! 301: .B x.s . ! 302: .in -0.8i ! 303: .IP ! 304: Other flags, ! 305: all library names (arguments beginning \fB\(mil\fR), ! 306: and any names not ending with one of the understood suffixes are passed ! 307: to the loader. ! 308: .Nh 2 Documentation\ Conventions ! 309: In running text, we write Fortran keywords and other literal strings in boldface lower case. ! 310: Examples will be presented in lightface lower case. ! 311: Names representing a class of values will be printed in italics. ! 312: .Nh 2 Implementation\ Strategy ! 313: The compiler and library are written entirely in C. ! 314: The compiler generates C compiler intermediate code. ! 315: Since there are C compilers running on a variety of machines, ! 316: relatively small changes will make this Fortran compiler generate code for any of them. ! 317: Furthermore, this approach guarantees that the resulting programs are compatible with C usage. ! 318: The runtime computational library is complete. ! 319: The runtime \s-1I/O\s0 library makes use of D. M. Ritchie's Standard C \s-1I/O\s0 package [8] ! 320: for transferring data. ! 321: With the few exceptions described below, only documented calls are used, ! 322: so it should be relatively easy to modify to run on other operating ! 323: systems. ! 324: .Nh 2 Debugging\ Aids ! 325: A memory image is sometimes ! 326: written to a file \fBcore\fP in the current directory ! 327: upon abnormal termination for errors caught by the \fBf77\fP libraries, ! 328: user calls to \fBabort\fP, and certain signals (see \fBsigvec\fP\|(2) ! 329: in the \fI\s-1UNIX\s0 Programmer's Manual\fP). ! 330: \fBCore\fP is normally created only if ! 331: the \fB\(mig\fP flag was specified to \fBf77\fP during loading.\(dg ! 332: .FS ! 333: \(dgSpecify \fB\(mig\fP when loading with \fBcc\fP or \fBf77\fP; ! 334: specify \fB\(milg\fP as a library ! 335: when using \fBld\fP directly. ! 336: .FE ! 337: The source-level debugger ! 338: .I dbx (1) ! 339: may be used with the executable and the ! 340: .B core ! 341: file to examine the image and ! 342: determine what went wrong. ! 343: .IP ! 344: In the event that it is necessary to override this default behavior, ! 345: the user may set the environment variable \fBf77_dump_flag\fP. ! 346: If \fBf77_dump_flag\fP is set to a value beginning ! 347: with \fBn\fP, a \fBcore\fP file is not produced regardless of whether ! 348: \fB\(mig\fP was specified at compile time, ! 349: and if the value begins with \fBy\fP, ! 350: dumps are produced even if \fB\(mig\fP was not specified. ! 351: .NH 1 ! 352: LANGUAGE EXTENSIONS ! 353: .XS ! 354: \*(SN Language Extensions ! 355: .XE ! 356: .LP ! 357: Fortran 77 includes almost all of Fortran 66 as a subset. ! 358: We describe the differences briefly in Appendix A. ! 359: The most important additions are a character string data type, ! 360: file-oriented input/output statements, and random access \s-1I/O\s0. ! 361: Also, the language has been cleaned up considerably. ! 362: .LP ! 363: In addition to implementing the language specified in the new Standard, ! 364: our compiler implements a few extensions described in this section. ! 365: Most are useful additions to the language. ! 366: The remainder are extensions ! 367: to make it easier to communicate with C procedures ! 368: or to permit compilation of ! 369: old (1966 Standard) programs. ! 370: .Nh 2 Double\ Complex\ Data\ Type ! 371: The new type ! 372: .B "double complex" ! 373: is defined. ! 374: Each datum is represented by a pair of double precision real values. ! 375: The statements ! 376: .DS ! 377: z1 = ( 0.1d0, 0.2d0 ) ! 378: z2 = dcmplx( dx, dy ) ! 379: .DE ! 380: assign double complex values to \fBz1\fP and \fBz2\fP. ! 381: The double precision values which constitute the double complex ! 382: value may be isolated by using \fBdreal\fP or \fBdble\fP for the ! 383: real part and \fBimag\fP or \fBdimag\fP for the ! 384: imaginary part. ! 385: To compute the double complex conjugate of a double complex value, ! 386: use \fBconjg\fP or \fBdconjg\fP. ! 387: The other \fBdouble complex\fP intrinsic functions may be ! 388: accessed using their generic names or specific names. ! 389: The generic names are: \fBabs\fP, \fBsqrt\fP, \fBexp\fP, ! 390: \fBlog\fP, \fBsin\fP, and \fBcos\fP. ! 391: The specific names are the same as the generic names preceded by ! 392: either \fBcd\fP or \fBz\fP, e.g. you may code \fBsqrt\fP, ! 393: \fBzsqrt\fP or \fBcdsqrt\fP to compute the square root of a double ! 394: complex value. ! 395: .Nh 2 Internal\ Files ! 396: The Fortran 77 standard introduces ``internal files'' (memory arrays), but ! 397: restricts their use to formatted sequential \s-1I/O\s0 statements. ! 398: Our \s-1I/O\s0 system also permits internal files to be used ! 399: in formatted direct reads and writes and list directed sequential read and ! 400: writes. ! 401: .Nh 2 Implicit\ Undefined\ Statement ! 402: Fortran 66 has a fixed rule that the type of a variable that does not appear in a type statement ! 403: is ! 404: .B integer ! 405: if its first letter is ! 406: \fBi, j, k, l, m\fR or \fBn\fR, ! 407: and ! 408: .B real ! 409: otherwise. ! 410: Fortran 77 has an ! 411: .B implicit ! 412: statement for overriding this rule. ! 413: As an aid to good programming practice, we permit an additional type, ! 414: .B undefined. ! 415: The statement ! 416: .DS ! 417: implicit undefined(a-z) ! 418: .DE ! 419: turns off the automatic data typing mechanism, ! 420: and the compiler will issue a diagnostic for each variable that is used but does ! 421: not appear in a type statement. ! 422: Specifying the ! 423: .B \(miu ! 424: compiler flag is equivalent to beginning each procedure with this statement. ! 425: .Nh 2 Recursion ! 426: Procedures may call themselves, ! 427: directly or through a chain of other procedures. ! 428: Since Fortran variables are by default ! 429: .B static , ! 430: it is often necessary to use the ! 431: .B automatic ! 432: storage extension to prevent unexpected results ! 433: from recursive functions. ! 434: .Nh 2 Automatic\ Storage ! 435: Two new keywords are recognized, ! 436: .B static ! 437: and ! 438: .B automatic. ! 439: These keywords may appear as ``types'' in type statements and in ! 440: .B implicit ! 441: statements. ! 442: Local variables are static by default; ! 443: there is only one instance of the variable. ! 444: For variables declared ! 445: .B automatic, ! 446: there is a separate instance of the variable for each ! 447: invocation of the procedure. ! 448: Automatic variables may not appear in ! 449: .B equivalence, ! 450: .B data, ! 451: or ! 452: .B save ! 453: statements. ! 454: Neither type of variable is guaranteed to retain its value between ! 455: calls to a subprogram (see the \fBsave\fP statement in Appendix A). ! 456: .Nh 2 Source\ Input\ Format ! 457: The Standard expects input to the compiler to be in 72-column format: ! 458: except in comment lines, ! 459: the first five characters are the statement number, the next is the continuation character, ! 460: and the next 66 are the body of the line. ! 461: (If there are fewer than 72 characters on a line, the compiler pads it with blanks; ! 462: characters after the seventy-second are ignored.) ! 463: .IP ! 464: In order to make it easier to type Fortran programs, ! 465: our compiler also accepts input in variable length lines. ! 466: An ampersand ``&'' in the first position of a line indicates a continuation ! 467: line; the remaining characters form the body of the line. ! 468: A tab character in one of the first six positions of a line signals the ! 469: end of the statement number and continuation part of the line; ! 470: the remaining characters form the body of the line. ! 471: A tab elsewhere on the line is treated as another kind of blank by the ! 472: compiler. ! 473: .IP ! 474: In the Standard, there are only 26 letters \(em Fortran is a one-case language. ! 475: Consistent with ordinary ! 476: \s-1UNIX\s0 ! 477: system usage, our compiler expects lower case input. ! 478: By default, the compiler converts all upper case characters to lower case except those inside character constants. ! 479: However, if the ! 480: .B \(miU ! 481: compiler flag is specified, upper case letters are not transformed. ! 482: In this mode, it is possible to specify external names with upper case letters in them, ! 483: and to have distinct variables differing only in case. ! 484: If \(mi\f3U\f1 is specified, ! 485: keywords will only be recognized in lower case. ! 486: .Nh 2 Include\ Statement ! 487: The statement ! 488: .DS ! 489: include \(fmstuff\|\(fm ! 490: .DE ! 491: is replaced by the contents of the file ! 492: .B stuff ; ! 493: .B include ! 494: statements may be nested to a reasonable depth, currently ten. ! 495: .Nh 2 Binary\ Initialization\ Constants ! 496: A variable may be initialized in a ! 497: .B data ! 498: statement ! 499: by a binary constant, denoted by a letter followed by a quoted string. ! 500: If the letter is \fBb\fR, the string is binary, and only zeroes and ones are permitted. ! 501: If the letter is \fBo\fR, the string is octal, with digits \fB0\(mi7\fR. ! 502: If the letter is \fBz\fR or \fBx\fR, the string is hexadecimal, with digits \fB0\(mi9\fR, \fBa\(mif\fR. ! 503: Thus, the statements ! 504: .DS ! 505: integer a(3) ! 506: data a / b\(fm1010\|\(fm, o\(fm12\|\(fm, z\(fma\|\(fm / ! 507: .DE ! 508: initialize all three elements of ! 509: .B a ! 510: to ten. ! 511: .Nh 2 Character\ Strings ! 512: For compatibility with C usage, the following backslash escapes are recognized: ! 513: .DS ! 514: \f3\en\f1 newline ! 515: \f3\et\f1 tab ! 516: \f3\eb\f1 backspace ! 517: \f3\ef\f1 form feed ! 518: \f3\e0\f1 null ! 519: \f3\e\(fm\f1 apostrophe (does not terminate a string) ! 520: \f3\e"\f1 quotation mark (does not terminate a string) ! 521: \f3\e\e\f1 \e ! 522: \f3\e\fP\fIx\fR \fIx\fR, where \fIx\fR is any other character ! 523: .DE ! 524: Fortran 77 only has one quoting character, the apostrophe. ! 525: Our compiler and \s-1I/O\s0 system recognize ! 526: both the apostrophe `` \(fm '' and the double-quote `` " ''. ! 527: If a string begins with one variety of quote mark, the other may be embedded within it ! 528: without using the repeated quote or backslash escapes. ! 529: .IP ! 530: Each character string constant appearing outside a ! 531: .B data ! 532: statement is followed by a ! 533: null character to ease communication with C routines. ! 534: .Nh 2 Hollerith ! 535: Fortran 77 does not have the old Hollerith ``\fIn\fP\|\fBh\fR'' ! 536: notation, ! 537: though the new Standard recommends implementing the old Hollerith feature ! 538: in order to improve compatibility with old programs. ! 539: In our compiler, Hollerith data may be used in place of character string constants, ! 540: and may also be used to initialize non-character variables in ! 541: .B data ! 542: statements. ! 543: .Nh 2 Equivalence\ Statements ! 544: As a very special and peculiar case, ! 545: Fortran 66 permits an element of a multiply-dimensioned array to be represented by ! 546: a singly-subscripted reference in ! 547: .B equivalence ! 548: statements. ! 549: Fortran 77 does not permit this usage, since ! 550: subscript lower bounds may now be different from 1. ! 551: Our compiler permits single subscripts in ! 552: .B equivalence ! 553: statements, ! 554: under the interpretation that all missing subscripts are equal to 1. ! 555: A warning message is printed for each such incomplete subscript. ! 556: .Nh 2 One-Trip\ \s-1DO\s0\ Loops ! 557: The Fortran 77 Standard requires that the range of a ! 558: .B do ! 559: loop not be performed ! 560: if the initial value is already past the limit value, ! 561: as in ! 562: .DS ! 563: do 10 i = 2, 1 ! 564: .DE ! 565: The 1966 Standard stated that the effect of such a statement was undefined, ! 566: but it was common practice that the range of a ! 567: .B do ! 568: loop would be performed ! 569: at least once. ! 570: In order to accommodate old programs, though they were in violation of the 1966 Standard, ! 571: the ! 572: .B \(mionetrip ! 573: or ! 574: .B \(mi1 ! 575: compiler flags causes non-standard loops to be generated. ! 576: .Nh 2 Commas\ in\ Formatted\ Input ! 577: The \s-1I/O\s0 system attempts to be more lenient than the ! 578: Standard when it seems worthwhile. ! 579: When doing a formatted read of non-character variables, ! 580: commas may be used as value separators in the input record, ! 581: overriding the field lengths given in the format statement. ! 582: Thus, ! 583: the format ! 584: .DS ! 585: (i10, f20.10, i4) ! 586: .DE ! 587: will read the record ! 588: .DS ! 589: \(mi345,.05e\(mi3,12 ! 590: .DE ! 591: correctly. ! 592: .Nh 2 Short\ Integers ! 593: On machines that support halfword integers, ! 594: the compiler accepts declarations of type ! 595: .B integer\(**2. ! 596: (Ordinary integers follow the Fortran rules about occupying the same ! 597: space as a real variable; they are assumed to be of C type ! 598: .B "long int" ; ! 599: halfword integers are of C type ! 600: .B "short int" .) ! 601: An expression involving only objects of type ! 602: .B integer\(**2 ! 603: is of that type. ! 604: Generic functions return short or long integers depending on the actual types of their arguments. ! 605: If a procedure is compiled using the ! 606: .B \(mii2 ! 607: flag, all small integer constants will be ! 608: of type ! 609: .B integer\(**2. ! 610: If the precision of an integer-valued intrinsic function is not determined by the generic function rules, ! 611: one will be chosen that returns the prevailing length ! 612: (\fBinteger\(**2\fR when the \fB\(mii2\fR command flag is in effect). ! 613: When the ! 614: .B \(mii2 ! 615: option is in effect, all quantities of type ! 616: .B logical ! 617: will be short. ! 618: Note that these short integer and logical quantities do not obey the standard rules for storage association. ! 619: .Nh 2 Additional\ Intrinsic\ Functions ! 620: This compiler supports all of the ! 621: intrinsic functions specified in the Fortran 77 Standard. ! 622: In addition, there are built-in functions ! 623: for performing bitwise logical and boolean operations on ! 624: integer and logical values ! 625: (\fBor\fR, \fBand\fR, \fBxor\fR, \fBnot\fR, \fBlshift\fP, and \fBrshift\fP), ! 626: and intrinsic functions for \fBdouble complex\fP values (see section 2.1). ! 627: The \fBf77\fP library contains many other functions, such as accessing ! 628: the \s-1UNIX\s0 command arguments (\fBgetarg\fR and \fBiargc\fR) ! 629: and environment (\fBgetenv\fR). ! 630: See \fBintro\fP(3f) and \fBbit\fP(3f) in the \fI\s-1UNIX\s0 ! 631: Programmer's Manual\fP ! 632: for more information. ! 633: .Nh 2 Namelist\ \s-1I/O\s0 ! 634: Namelist \s-1I/O\s0 provides an easy way to input and output information without ! 635: formats. ! 636: Although not part of the standard, namelist \s-1I/O\s0 was part of many ! 637: Fortran 66 systems and is a common extension to Fortran 77 systems. ! 638: .IP ! 639: Variables and arrays to be used in namelist \s-1I/O\s0 are declared as part of ! 640: a namelist in a \fBnamelist\fP statement, e.g.: ! 641: .DS ! 642: character str\(**12 ! 643: logical flags(20) ! 644: complex c(2) ! 645: real arr1(2,3), arr2(0:3,4) ! 646: namelist /basic/ arr1, arr2, key, str, c /flglst/ key, flags ! 647: .DE ! 648: This defines two namelists: list \fBbasic\fP consists of variables ! 649: \fBkey\fP and \fBstr\fP and arrays \fBarr1\fP, \fBarr2\fP, ! 650: and \fBc\fP; list \fBflglst\fP consists of variable \fBkey\fP and ! 651: array \fBflags\fP. ! 652: A namelist can include variables and arrays of any type, and ! 653: a variable or array may be in several different namelists. ! 654: However dummy arguments and array elements may not be in a namelist. ! 655: A namelist name may be used in external sequential \fBread\fP, \fBwrite\fP ! 656: and \fBprint\fP statements wherever a format could be used. ! 657: .IP ! 658: In a namelist \fBread\fP, column one of each data record is ignored. ! 659: The data begins with an ampersand in column 2 followed by ! 660: the namelist name and a blank. ! 661: Then there is a sequence of value assignments separated by commas ! 662: and finally an ``&end''. ! 663: A simple example of input data corresponding to namelist \fBbasic\fP is: ! 664: .DS ! 665: \ &basic key=5, str=\(fmhi there\(fm &end ! 666: .DE ! 667: .EQ ! 668: delim off ! 669: .EN ! 670: For compatibility with other systems, dollar signs ! 671: may be used instead of the ampersands: ! 672: .DS ! 673: \ $basic key=5, str=\(fmhi there\(fm $end ! 674: .DE ! 675: .IP ! 676: .EQ ! 677: delim $$ ! 678: .EN ! 679: A value assignment in the data record must be one of three forms. ! 680: The simplest is a variable name followed by an equal sign ! 681: followed by a data value which is assigned to that variable, ! 682: e.g. ``key=5''. ! 683: The second form consists of an array name followed by ``='' ! 684: followed by one or more values to be assigned to the array, ! 685: e.g.: ! 686: .DS ! 687: c=(1.1,\-2.9),(\-1.8e+10,14.0e\-3) ! 688: .DE ! 689: assigns values to c(1) and c(2) in the complex array c. ! 690: .IP ! 691: As in other \fBread\fP statements, values are assigned in the order of the ! 692: array in memory, i.e. column-major order for two dimensional arrays. ! 693: Multiple copies of a value may be represented by a repetition count ! 694: followed by an asterisk followed by the value; e.g. ``3*55.4'' is the ! 695: same as ``55.4, 55.4, 55.4''. ! 696: It is an error to specify more values than the array can hold; ! 697: if less are specified, only that number of elements of the array ! 698: are changed. ! 699: The third form of a value assignment is a subscripted variable ! 700: name followed by ``='' followed by a value or values, ! 701: e.g.: ``arr2(0,4)=15.2''. ! 702: Only integer constant subscripts may be used. ! 703: The correct number of subscripts must be used and the subscripts ! 704: must be legal. ! 705: This form is the same as the form with an array name except the ! 706: array is filled starting at the named element. ! 707: .IP ! 708: In all three forms, the variable or array name must be declared ! 709: in the namelist. The form of the data values is the same as in ! 710: list directed input except that in namelist \s-1I/O\s0, ! 711: character strings in the data must be enclosed in apostrophes or ! 712: double quotes, and ! 713: repetition counts must be followed by data values. ! 714: .IP ! 715: One use of namelist input is to read in a list of options or flags. ! 716: For example: ! 717: .DS ! 718: logical flags(14) ! 719: namelist /pars/ flags, iters, xlow, xhigh, xinc ! 720: data flags/14*.false./ ! 721: ! 722: 10 read(5,pars,end=900) ! 723: print pars ! 724: call calc( xlow, xhigh, xinc, flags, iters ) ! 725: go to 10 ! 726: 900 continue ! 727: end ! 728: .DE ! 729: could be run with the following data (each record begins with a space): ! 730: .DS ! 731: \ &pars iters=10, xlow=0.0, xhigh=1.0, xinc=0.1 &end ! 732: \ &pars xinc=0.2, ! 733: \ \ \ flags(2)=2*.true., flags(8)=.true. &end ! 734: \ &pars xlow=2.0, xhigh=8.0 &end ! 735: .DE ! 736: The program reads parameters for the run from the first data set ! 737: and computes using them. ! 738: Then it loops and each successive set of namelist input data ! 739: specifies only those data items which need to be changed. ! 740: Note the second data set sets the $2 sup nd$, $3 sup rd$, ! 741: and $8 sup th$ elements in the array \fBflags\fP to \fB.true.\fP. ! 742: .IP ! 743: When a namelist name is used in a \fBwrite\fP or \fBprint\fP statement, ! 744: all the values in the namelist are output together with their names. ! 745: For example the \fBprint\fP in the program above prints the following: ! 746: .DS ! 747: \ &pars flags= f, f, f, f, f, f, f, f, f, f, f, f, f, f, iters= ! 748: \ 10, xlow= 0., xhigh= 1.00000, xinc= 0.100000 ! 749: \ &end ! 750: \ &pars flags= f, t, t, f, f, f, f, t, f, f, f, f, f, f, iters= ! 751: \ 10, xlow= 0., xhigh= 1.00000, xinc= 0.200000 ! 752: \ &end ! 753: \ &pars flags= f, t, t, f, f, f, f, t, f, f, f, f, f, f, iters= ! 754: \ 10, xlow= 2.00000, xhigh= 8.00000, xinc= 0.200000 ! 755: \ &end ! 756: .DE ! 757: .IP ! 758: Each line begins with a space so that namelist output can be used as input to ! 759: a namelist \fBread\fP. ! 760: The default is to use ampersands in namelist \fBprint\fP and ! 761: \fBwrite\fP. ! 762: However, dollar signs will be used if the last preceding namelist \fBread\fP ! 763: data set used dollar signs. ! 764: The character to be used is stored as the first character of the common ! 765: block \fBnamelistkey\fP. ! 766: .Nh 2 Automatic\ Precision\ Increase ! 767: The \(mi\fBr8\fP flag allows a user to run a program with increased ! 768: precision without changing any of the program source, ! 769: i.e. it allows a user to take a program coded in ! 770: single precision and compile and execute it as if it had ! 771: been coded in double precision. ! 772: The option extends the precision of all single precision real ! 773: and complex constants, variables, external functions, and intrinsic functions. ! 774: For example, the source: ! 775: .DS ! 776: implicit complex(c) ! 777: real last ! 778: intrinsic sin, csin ! 779: data last/0.3/ ! 780: ! 781: x = 0.1 ! 782: y = sqrt(x)+sqrt(last) ! 783: c1 = (0.1,0.2) ! 784: c2 = sqrt(c1) ! 785: x = real(i) ! 786: y = aimag(c1) ! 787: call fun(sin,csin) ! 788: .DE ! 789: is compiled under this flag as if it had been written as: ! 790: .DS ! 791: implicit double precision (a-b,d-h,o-z), double complex(c) ! 792: double precision last ! 793: intrinsic dsin, cdsin ! 794: data last/0.3d0/ ! 795: ! 796: x = 0.1d0 ! 797: y = sqrt(x)+sqrt(last) ! 798: c1 = (0.1d0,0.2d0) ! 799: c2 = sqrt(c1) ! 800: x = dreal(i) ! 801: y = dimag(c1) ! 802: call fun(dsin,cdsin) ! 803: .DE ! 804: When the \(mi\fBr8\f flag is invoked, ! 805: the calls using the generic name \fBsqrt\fP will refer to a different ! 806: specific function since the types of the arguments have changed. ! 807: This option extends the precision of all single precision \fBreal\fP ! 808: and \fBcomplex\fP variables and functions, ! 809: including those declared \fBreal\(**4\fP and \fBcomplex\(**8\fP. ! 810: .IP ! 811: In order to successfully use this flag to increase precision, ! 812: the entire program including ! 813: all the subroutines and functions it calls must be recompiled. ! 814: Programs which use dynamic memory allocation or ! 815: use equivalence or common statements to associate variables of different types ! 816: may have to be changed by hand. ! 817: Similar caveats apply to the sizes of records ! 818: in unformatted \s-1I/O\s0. ! 819: .Nh 2 Characters\ and\ Integers ! 820: A character constant of integer length or less ! 821: may be assigned to an integer variable. ! 822: Individual bytes are packed into ! 823: the integer in the native byte order. ! 824: The character constant is padded with blanks ! 825: to the width of the integer during the assignment. ! 826: Use of this feature is deprecated; ! 827: it is intended only as a porting aid ! 828: for extended Fortran 66 programs. ! 829: Note that the intrinsic ! 830: .B ichar ! 831: function behaves as the standard requires, ! 832: converting only single bytes to integers. ! 833: .NH 1 ! 834: VIOLATIONS OF THE STANDARD ! 835: .XS ! 836: \*(SN Violations of the Standard ! 837: .XE ! 838: .LP ! 839: We know only a few ways in which our Fortran system violates the new standard: ! 840: .Nh 2 Double\ Precision\ Alignment ! 841: The Fortran Standards (both 1966 and 1977) ! 842: permit ! 843: .B common ! 844: or ! 845: .B equivalence ! 846: statements to force a double precision quantity onto an odd word boundary, ! 847: as in the following example: ! 848: .DS I ! 849: real a(4) ! 850: double precision b,c ! 851: .sp .5 ! 852: equivalence (a(1),b), (a(4),c) ! 853: .DE ! 854: Some machines (e.g., Honeywell 6000, \s-1IBM 360\s0) require that double precision quantities be on double word boundaries; ! 855: other machines (e.g., \s-1IBM 370\s0), run inefficiently if this alignment rule is not observed. ! 856: It is possible to tell which equivalenced and common variables suffer from a forced odd ! 857: alignment, but every double precision argument would have to be assumed on a bad boundary. ! 858: To load such a quantity on some machines, ! 859: it would be necessary to use separate operations to move the upper and lower halves ! 860: into the halves of an aligned temporary, then to load that double precision temporary; the reverse would be ! 861: needed to store a result. ! 862: We have chosen to require that all double precision real and complex quantities ! 863: fall on even word boundaries on machines with corresponding hardware requirements, ! 864: and to issue a diagnostic if the source code demands a violation of the rule. ! 865: .Nh 2 Dummy\ Procedure\ Arguments ! 866: If any argument of a procedure is of type character, ! 867: all dummy procedure arguments of that procedure must be declared ! 868: in an ! 869: .B external ! 870: statement. ! 871: This requirement arises as a subtle corollary of the way we represent character string arguments ! 872: and of the one-pass nature of the compiler. ! 873: A warning is printed if a dummy procedure is not declared ! 874: .B external. ! 875: Code is correct if there are no ! 876: .B character ! 877: arguments. ! 878: .Nh 2 T\ and\ TL\ Formats ! 879: The implementation of the ! 880: .B t ! 881: (absolute tab) ! 882: and ! 883: .B tl ! 884: (leftward tab) ! 885: format codes ! 886: is defective. ! 887: These codes allow rereading or rewriting part of the ! 888: record which has already been processed ! 889: (section 6.3.2 in Appendix A). ! 890: The implementation uses seeks, ! 891: so if the unit is not one which allows seeks, ! 892: such as a terminal, ! 893: the program is in error. ! 894: A benefit of the implementation chosen is ! 895: that there is no upper limit on the length of ! 896: a record, ! 897: nor is it necessary to predeclare any record ! 898: lengths except where specifically required ! 899: by Fortran or the operating system. ! 900: .Nh 2 Carriage\ Control ! 901: The Standard leaves as implementation dependent which logical unit(s) ! 902: are treated as ``printer'' files. ! 903: In this implementation there is no printer file and ! 904: thus by default, no carriage control is recognized on formatted output. ! 905: This can be changed using \fBform=\|\(fmprint\|\(fm\fP in the ! 906: \fBopen\fP statement ! 907: for a unit, or by using the \fBfpr\fP(1) filter for output; see [9]. ! 908: .Nh 2 Assigned\ Goto ! 909: The optional ! 910: .I list ! 911: associated with an assigned ! 912: .B goto ! 913: statement is not checked against the actual assigned value during execution. ! 914: .NH 1 ! 915: INTER-PROCEDURE INTERFACE ! 916: .XS ! 917: \*(SN Inter-Procedure Interface ! 918: .XE ! 919: .LP ! 920: To be able to write C procedures that call or are called by Fortran procedures, ! 921: it is necessary to know the conventions for procedure names, ! 922: data representation, ! 923: return values, ! 924: and argument lists that the compiled code obeys. ! 925: .Nh 2 Procedure\ Names ! 926: On ! 927: \s-1UNIX\s0 ! 928: systems, ! 929: the name of a common block or a Fortran procedure ! 930: has an underscore appended to it by the compiler ! 931: to distinguish it from a C procedure or external variable ! 932: with the same user-assigned name. ! 933: Fortran built-in procedure names have embedded underscores to avoid clashes ! 934: with user-assigned subroutine names. ! 935: .Nh 2 Data\ Representations ! 936: The following is a table of ! 937: corresponding Fortran and C declarations: ! 938: .KS ! 939: .TS ! 940: center; ! 941: l l ! 942: l l. ! 943: .B ! 944: Fortran C ! 945: .R ! 946: .sp .5 ! 947: integer\(**2 x short int x; ! 948: integer x long int x; ! 949: logical x long int x; ! 950: real x float x; ! 951: double precision x double x; ! 952: complex x struct { float r, i; } x; ! 953: double complex x struct { double dr, di; } x; ! 954: character\(**6 x char x[6]; ! 955: .TE ! 956: .KE ! 957: (By the rules of Fortran, ! 958: .B integer, ! 959: .B logical, ! 960: and ! 961: .B real ! 962: data occupy the same amount of memory.) ! 963: .Nh 2 Arrays ! 964: The first element of a C array always has subscript zero, ! 965: while Fortran arrays begin at 1 by default. ! 966: Fortran arrays are stored in column-major order in contiguous storage, ! 967: C arrays are stored in row-major order. ! 968: Many mathematical libraries have subroutines which transpose a two dimensional ! 969: matrix, e.g. \fBf01crf\fP in the \fB\s-1NAG\s0\fP library and ! 970: \fBvtran\fP in the \fB\s-1IMSL\s0\fP library. ! 971: These may be used to transpose a two-dimensional array stored in C in row-major ! 972: order to Fortran column-major order or vice-versa. ! 973: .Nh 2 Return\ Values ! 974: A function of type ! 975: .B integer, ! 976: .B logical, ! 977: .B real, ! 978: or ! 979: .B "double precision" ! 980: declared as a C function returns the corresponding type. ! 981: A ! 982: .B complex ! 983: or ! 984: .B "double complex" ! 985: function is equivalent to a C routine ! 986: with an additional ! 987: initial argument that points to the place where the return value is to be stored. ! 988: Thus, ! 989: .DS ! 990: complex function f( . . . ) ! 991: .DE ! 992: is equivalent to ! 993: .DS ! 994: f_(temp, . . .) ! 995: struct { float r, i; } \(**temp; ! 996: . . . ! 997: .DE ! 998: A character-valued function is equivalent to a C routine with ! 999: two extra initial arguments: a data address and a length. ! 1000: Thus, ! 1001: .DS ! 1002: character\(**15 function g( . . . ) ! 1003: .DE ! 1004: is equivalent to ! 1005: .DS ! 1006: g_(result, length, . . .) ! 1007: char result[ ]; ! 1008: long int length; ! 1009: . . . ! 1010: .DE ! 1011: and could be invoked in C by ! 1012: .DS ! 1013: char chars[15]; ! 1014: . . . ! 1015: g_(chars, 15L, . . . ); ! 1016: .DE ! 1017: Subroutines are invoked as if they were \fBinteger\fR-valued functions ! 1018: whose value specifies which alternate return to use. ! 1019: Alternate return arguments (statement labels) are not passed to the function, ! 1020: but are used to do an indexed branch in the calling procedure. ! 1021: (If the subroutine has no entry points with alternate return arguments, ! 1022: the returned value is undefined.) ! 1023: The statement ! 1024: .DS ! 1025: call nret(\(**1, \(**2, \(**3) ! 1026: .DE ! 1027: is treated exactly as if it were the computed ! 1028: .B goto ! 1029: .DS ! 1030: goto (1, 2, 3), nret( ) ! 1031: .DE ! 1032: .Nh 2 Argument\ Lists ! 1033: All Fortran arguments are passed by address. ! 1034: In addition, ! 1035: for every argument that is of type character or ! 1036: that is a dummy procedure, ! 1037: an argument giving the length of the value is passed. ! 1038: (The string lengths are ! 1039: .B "long int" ! 1040: quantities passed by value.) ! 1041: The order of arguments is then: ! 1042: .DS ! 1043: Extra arguments for complex and character functions ! 1044: Address for each datum or function ! 1045: A \fBlong int\fR for each character or procedure argument ! 1046: .DE ! 1047: Thus, the call in ! 1048: .DS ! 1049: external f ! 1050: character\(**7 s ! 1051: integer b(3) ! 1052: . . . ! 1053: call sam(f, b(2), s) ! 1054: .DE ! 1055: is equivalent to that in ! 1056: .DS ! 1057: int f(); ! 1058: char s[7]; ! 1059: long int b[3]; ! 1060: . . . ! 1061: sam_(f, &b[1], s, 0L, 7L); ! 1062: .DE ! 1063: .Nh 2 System\ Interface ! 1064: To run a Fortran program, the system invokes a small C program which ! 1065: first initializes signal handling, then calls \fBf_init\fP to initialize ! 1066: the Fortran \s-1I/O\s0 library, then calls your Fortran main program, ! 1067: and then calls \fBf_exit\fP to close any Fortran files opened. ! 1068: .IP ! 1069: \fBf_init\fP initializes Fortran units 0, 5, and 6 to standard error, ! 1070: standard input, and standard output respectively. ! 1071: It also calls \fBsetlinebuf\fP to initiate line buffering ! 1072: of standard error. ! 1073: If you are using Fortran subroutines which may do \s-1I/O\s0 ! 1074: and you have a C main program, ! 1075: call \fBf_init\fP before calling the Fortran subroutines. ! 1076: Otherwise, Fortran units 0, 5, and 6 will be connected to files ! 1077: \fBfort.0\fP, \fBfort.5\fP, and \fBfort.6\fP, ! 1078: and error messages from the \fBf77\fP libraries will be written ! 1079: to \fBfort.0\fP instead of to standard error. ! 1080: If your C program terminates by calling the C function \fBexit\fP, ! 1081: all files are automatically closed. ! 1082: If there are Fortran scratch files to be deleted, first call \fBf_exit\fP. ! 1083: \fBF_init\fP and \fBf_exit\fP do not have any arguments. ! 1084: .IP ! 1085: The \fB\(mid\fP flag will show what libraries are used in loading Fortran ! 1086: programs. ! 1087: .NH 1 ! 1088: FILE FORMATS ! 1089: .XS ! 1090: \*(SN File Formats ! 1091: .XE ! 1092: .Nh 2 Structure\ of\ Fortran\ Files ! 1093: Fortran requires four kinds of external files: ! 1094: sequential formatted and unformatted, ! 1095: and direct formatted and unformatted. ! 1096: On ! 1097: \s-1UNIX\s0 ! 1098: systems, ! 1099: these are all implemented as ordinary files ! 1100: which are assumed to have the proper ! 1101: internal structure. ! 1102: .IP ! 1103: Fortran \s-1I/O\s0 is based on \f2records\f1. ! 1104: When a direct file is opened in a Fortran program, ! 1105: the record length of the records must be given, ! 1106: and this is used by the Fortran \s-1I/O\s0 system to ! 1107: make the file look as if it is made up of records ! 1108: of the given length. ! 1109: In the special case that the record length is given ! 1110: as 1, ! 1111: the files are not considered to be divided into records, ! 1112: but are treated as byte-addressable byte strings; ! 1113: that is, ! 1114: as ordinary ! 1115: \s-1UNIX\s0 ! 1116: file system files. ! 1117: (A read or write request on such a file keeps consuming bytes until ! 1118: satisfied, rather than being restricted to a single record.) ! 1119: .IP ! 1120: The peculiar requirements on sequential unformatted files ! 1121: make it unlikely that they will ever be read or written by any means except Fortran \s-1I/O\s0 statements. ! 1122: Each record is preceded and followed by ! 1123: an integer containing the record's length in bytes. ! 1124: .IP ! 1125: The Fortran \s-1I/O\s0 system breaks sequential formatted files ! 1126: into records while reading by using each newline ! 1127: as a record separator. ! 1128: The result of reading off the end of a record is undefined according to the Standard. ! 1129: The \s-1I/O\s0 system is permissive and ! 1130: treats the record as being extended by blanks. ! 1131: On output, ! 1132: the \s-1I/O\s0 system will write a newline at the end of each ! 1133: record. ! 1134: It is also possible for programs to write newlines ! 1135: for themselves. ! 1136: This is an error, ! 1137: but the only effect will be that the single record ! 1138: the user thought he wrote will be treated as ! 1139: more than one record when being read or ! 1140: backspaced over. ! 1141: .Nh 2 Portability\ Considerations ! 1142: The Fortran \s-1I/O\s0 system uses only the facilities of the ! 1143: standard C \s-1I/O\s0 library, ! 1144: a widely available and fairly portable package, ! 1145: with the following two nonstandard features: ! 1146: the \s-1I/O\s0 system needs to know whether a file ! 1147: can be used for direct \s-1I/O\s0, ! 1148: and whether or not it is possible to backspace. ! 1149: Both of these facilities are implemented ! 1150: using the ! 1151: .B fseek ! 1152: routine, ! 1153: so there is a routine ! 1154: .B canseek ! 1155: which determines if ! 1156: .B fseek ! 1157: will have the desired effect. ! 1158: Also, the ! 1159: .B inquire ! 1160: statement provides the user ! 1161: with the ability to find out if two files are the ! 1162: same, ! 1163: and to get the name of an already opened file ! 1164: in a form which would enable the program to reopen ! 1165: it. ! 1166: Therefore there are two routines which ! 1167: depend on facilities of the operating system ! 1168: to provide these two services. ! 1169: In any case, ! 1170: the \s-1I/O\s0 system ! 1171: runs on the \s-1PDP-11\s0, \s-1VAX-11/780\s0, and Interdata 8/32 ! 1172: \s-1UNIX\s0 ! 1173: systems. ! 1174: .Nh 2 Logical\ Units\ and\ Files ! 1175: Fortran logical unit numbers may be any integer between 0 and 99. ! 1176: The number of simultaneously open files is currently limited to 48. ! 1177: .IP ! 1178: Units 5, 6, and 0 are connected before the program begins to ! 1179: standard input, standard output, and standard error respectively. ! 1180: .IP ! 1181: If an unit is opened explicitly by an \fBopen\fP statement with ! 1182: a \fBfile=\fP keyword, then the file name is the name from ! 1183: the \fBopen\fP statement. ! 1184: Otherwise, the default file name corresponding to unit \fIn\fP is ! 1185: \fBfort.\fP\fIn\fP. ! 1186: If there is an environment variable whose name is the same as ! 1187: the tail of the file name after periods are deleted, ! 1188: then the contents of that environment variable ! 1189: are used as the name of the file. ! 1190: See [9] for details. ! 1191: .IP ! 1192: The default connection for all units is for sequential formatted \s-1I/O\s0. ! 1193: The Standard does not specify where a file which has been explicitly ! 1194: \fBopen\fRed ! 1195: for sequential \s-1I/O\s0 is initially positioned. ! 1196: The \s-1I/O\s0 system will position the file at the beginning. ! 1197: Therefore a ! 1198: .B write ! 1199: will destroy any data already in the file, but a ! 1200: .B read ! 1201: will work reasonably. ! 1202: To position a file to its end, ! 1203: use a \fBread\fP loop, or the system dependent function \fBfseek\fP. ! 1204: The preconnected units ! 1205: 0, 5, and 6 are positioned as they come ! 1206: from the program's parent process. ! 1207: .bp ! 1208: .SH ! 1209: APPENDIX A: Differences Between Fortran 66 and Fortran 77 ! 1210: .XS ! 1211: Appendix A. Differences Between Fortran 66 and Fortran 77 ! 1212: .XE ! 1213: .LP ! 1214: The following is a very brief description of the differences ! 1215: between the 1966 [2] and the 1977 [1] Standard languages. ! 1216: We assume that the reader is familiar with Fortran 66. ! 1217: We do not pretend to be complete, precise, ! 1218: or unbiased, ! 1219: but plan to describe what we feel are the most important aspects of the new language. ! 1220: The best current information on the 1977 Standard is in publications of the ! 1221: \s-1X3J3\s0 Subcommittee of the ! 1222: American National Standards Institute, and ! 1223: the \s-1ANSI\s0 X3.9-1978 document, the official description of the language. ! 1224: The Standard is written in English rather than a meta-language, ! 1225: but it is forbidding and legalistic. ! 1226: A number of tutorials and textbooks ! 1227: are available ! 1228: (see Appendix B). ! 1229: .NH 0 ! 1230: Features Deleted from Fortran 66 ! 1231: .XS ! 1232: \*(SN Features Deleted from Fortran 66 ! 1233: .XE ! 1234: .Nh 2 Hollerith ! 1235: All notions of ``Hollerith'' ! 1236: (\fIn\fP\|\fBh\fR) ! 1237: as data ! 1238: have been officially removed, although our compiler, like almost all in the foreseeable future, ! 1239: will continue to support this archaism. ! 1240: .Nh 2 Extended\ Range\ of\ DO ! 1241: .IP ! 1242: In Fortran 66, under a set of very restrictive and rarely-understood conditions, it is permissible ! 1243: to jump out of the range of a ! 1244: .B do ! 1245: loop, then jump back into it. ! 1246: Extended range has been removed in the Fortran 77 language. ! 1247: The restrictions are so special, and the implementation of extended range is so unreliable in many compilers, ! 1248: that this change really counts as no loss. ! 1249: .NH 1 ! 1250: Program Form ! 1251: .XS ! 1252: \*(SN Program Form ! 1253: .XE ! 1254: .Nh 2 Blank\ Lines ! 1255: Completely blank lines are now legal comment lines. ! 1256: .Nh 2 Program\ and\ Block\ Data\ Statements ! 1257: A main program may now begin with a statement that gives that program an external name: ! 1258: .DS ! 1259: program work ! 1260: .DE ! 1261: Block data procedures may also have names. ! 1262: .DS ! 1263: block data stuff ! 1264: .DE ! 1265: There is now a rule that only ! 1266: .I one ! 1267: unnamed ! 1268: block data procedure may appear in a program. ! 1269: (This rule is not enforced by our system.) ! 1270: The Standard does not specify the effect of the program and block data names, ! 1271: but they are clearly intended to aid conventional loaders. ! 1272: .Nh 2 ENTRY\ Statement ! 1273: Multiple entry points are now legal. ! 1274: Subroutine and function subprograms may have additional entry points, ! 1275: declared by an ! 1276: .B entry ! 1277: statement with an optional argument list. ! 1278: .DS ! 1279: entry extra(a, b, c) ! 1280: .DE ! 1281: Execution begins at the first statement following the ! 1282: .B entry ! 1283: line. ! 1284: All variable declarations must precede all executable statements in the procedure. ! 1285: If the procedure begins with a ! 1286: .B subroutine ! 1287: statement, ! 1288: all entry points are subroutine names. ! 1289: If it begins with a ! 1290: .B function ! 1291: statement, each entry is a function entry point, ! 1292: with type determined by the type declared for the entry name. ! 1293: If any entry is a character-valued function, ! 1294: then all entries must be. ! 1295: In a function, an entry name of the same type as that where control entered ! 1296: must be assigned a value. ! 1297: Arguments do not retain their values between calls. ! 1298: (The ancient trick of calling one entry point with a large number of arguments ! 1299: to cause the procedure to ``remember'' the locations of those arguments, ! 1300: then invoking an entry with just a few arguments for later calculation, ! 1301: is still illegal. ! 1302: Furthermore, the trick doesn't work in our implementation, ! 1303: since arguments are not kept in static storage.) ! 1304: .Nh 2 \s-1DO\s0\ Loops ! 1305: .B do ! 1306: variables and range parameters may now be of integer, real, or double precision types. ! 1307: (The use of floating point ! 1308: .B do ! 1309: variables is very dangerous ! 1310: because of the possibility of unexpected roundoff, ! 1311: and we strongly recommend against their use.) ! 1312: The action of the ! 1313: .B do ! 1314: statement is now defined for all values of the ! 1315: .B do ! 1316: parameters. ! 1317: The statement ! 1318: .DS ! 1319: do 10 i = l, u, d ! 1320: .DE ! 1321: performs ! 1322: $ max (0^,^ left floor ( u - l + d ) / d^ right floor )$ ! 1323: iterations. ! 1324: The ! 1325: .B do ! 1326: variable has a predictable value when exiting a loop: ! 1327: the value at the time a ! 1328: .B goto ! 1329: or ! 1330: .B return ! 1331: terminates the loop; ! 1332: otherwise ! 1333: the value that failed the limit test. ! 1334: .Nh 2 Alternate\ Returns ! 1335: In a ! 1336: .B subroutine ! 1337: or subroutine ! 1338: .B entry ! 1339: statement, ! 1340: some of the arguments may be noted by an asterisk, as in ! 1341: .DS ! 1342: subroutine s(a, \(**, b, \(**) ! 1343: .DE ! 1344: The meaning of the ``alternate returns'' is described ! 1345: in section 5.2 of Appendix A. ! 1346: .NH 1 ! 1347: Declarations ! 1348: .XS ! 1349: \*(SN Declarations ! 1350: .XE ! 1351: .Nh 2 CHARACTER\ Data\ Type ! 1352: One of the biggest improvements to the language is the addition of a character-string data type. ! 1353: Local and ! 1354: common character variables must have a length denoted by a constant expression: ! 1355: .DS ! 1356: character\(**17 a, b(3,4) ! 1357: character\(**(6+3) c ! 1358: .DE ! 1359: If the length is omitted entirely, it is assumed equal to 1. ! 1360: A character string argument may have a constant length, ! 1361: or the length may be declared to be the same as that of the corresponding actual argument at run time ! 1362: by a statement like ! 1363: .DS ! 1364: character\(**(\(**) a ! 1365: .DE ! 1366: (There is an intrinsic function ! 1367: .B len ! 1368: that returns the actual length of a character string.) ! 1369: Character arrays and common blocks containing character variables must be packed: ! 1370: in an array of character variables, the first character of one element must follow the last character of ! 1371: the preceding element, without holes. ! 1372: .Nh 2 IMPLICIT\ Statement ! 1373: The traditional implied declaration rules still hold: ! 1374: a variable whose name begins with ! 1375: \fBi, j, k, l, m,\fR or \fBn\fR is of type ! 1376: \f3integer\f1; ! 1377: other variables are of type ! 1378: .B real, ! 1379: unless otherwise declared. ! 1380: This general rule may be overridden with an ! 1381: .B implicit ! 1382: statement: ! 1383: .DS ! 1384: implicit real(a-c,g), complex(w-z), character\(**(17) (s) ! 1385: .DE ! 1386: declares that variables whose name begins with an ! 1387: \fBa ,b, c,\fR ! 1388: or ! 1389: \fBg\fR ! 1390: are ! 1391: .B real, ! 1392: those beginning with ! 1393: \fBw, x, y,\fR ! 1394: or ! 1395: \fBz\fR ! 1396: are assumed ! 1397: .B complex, ! 1398: and so on. ! 1399: It is still poor practice to depend on implicit typing, but this statement is an industry standard. ! 1400: .Nh 2 PARAMETER\ Statement ! 1401: It is now possible to give a constant a symbolic name, as in ! 1402: .DS ! 1403: character str\(**(\(**) ! 1404: parameter (x=17, y=x/3, pi=3.14159d0, str=\(fmhello\(fm) ! 1405: .DE ! 1406: The type of each parameter name is governed ! 1407: by the same implicit and explicit rules as for a variable. ! 1408: Symbolic names for \fBcharacter\fP constants may be declared with ! 1409: an implied length ``(\(**)''. ! 1410: The right side of each equal sign must be a constant expression ! 1411: (an expression made up of constants, operators, and already defined parameters). ! 1412: .Nh 2 Array\ Declarations ! 1413: Arrays may now have as many as seven dimensions. ! 1414: (Only three were permitted in 1966.) ! 1415: The lower bound of each dimension may be declared ! 1416: to be other than 1 by ! 1417: using a colon. ! 1418: Furthermore, an adjustable array bound may be an integer expression involving constants, ! 1419: arguments, and variables in ! 1420: .B common. ! 1421: .DS ! 1422: real a(\(mi5:3, 7, m:n), b(n+1:2\(**n) ! 1423: .DE ! 1424: The upper bound on the last dimension of an array argument may be denoted by an asterisk ! 1425: to indicate that the upper bound is not specified: ! 1426: .DS ! 1427: integer a(5, \(**), b(\(**), c(0:1, \(mi2:\(**) ! 1428: .DE ! 1429: .Nh 2 SAVE\ Statement ! 1430: A little known rule of Fortran 66 is that variables in a procedure do ! 1431: not necessarily retain their values between invocations of that procedure. ! 1432: This rule permits overlay and stack implementations for the affected variables. ! 1433: In Fortran 77, three types of variables automatically keep there values: ! 1434: variables in blank common, ! 1435: variables defined in \fBdata\fP statements and never changed, and ! 1436: variables in named common blocks which have not become undefined. ! 1437: At any instant in the execution of a program, ! 1438: if a named common block is declared neither in the currently executing procedure ! 1439: nor in any of the procedures in the chain of callers, ! 1440: all of the variables in that common block become undefined. ! 1441: Fortran 77 permits one to specify that certain variables and common blocks are ! 1442: to retain their values between invocations. ! 1443: The declaration ! 1444: .DS ! 1445: save a, /b/, c ! 1446: .DE ! 1447: leaves the values of the variables ! 1448: .B a ! 1449: and ! 1450: .B c ! 1451: and all of the contents of common block ! 1452: .B b ! 1453: unaffected by an exit from the procedure. ! 1454: The simple declaration ! 1455: .DS ! 1456: save ! 1457: .DE ! 1458: has this effect on all variables and common blocks in the procedure. ! 1459: A common block must be \fBsave\fRd in every procedure in which it is declared ! 1460: if the desired effect is to occur. ! 1461: .Nh 2 INTRINSIC\ Statement ! 1462: All of the functions specified in the Standard are in a single category, ! 1463: ``intrinsic functions'', rather than being divided into ``intrinsic'' and ``basic external'' functions. ! 1464: If an intrinsic function is to be passed to another procedure, it must be declared ! 1465: .B intrinsic. ! 1466: Declaring it ! 1467: .B external ! 1468: (as in Fortran 66) causes a function other than the built-in one to be passed. ! 1469: .NH 1 ! 1470: Expressions ! 1471: .XS ! 1472: \*(SN Expressions ! 1473: .XE ! 1474: .Nh 2 Character\ Constants ! 1475: Character string constants are marked by strings surrounded by apostrophes. ! 1476: If an apostrophe is to be included in a constant, it is repeated: ! 1477: .DS ! 1478: \(fmabc\(fm ! 1479: \(fmain\(fm\(fmt\(fm ! 1480: .DE ! 1481: Although null (zero-length) character strings are not allowed in the ! 1482: standard Fortran, they may be used with \fBf77\fP. ! 1483: Our compiler has two different quotation marks, `` \(fm '' and `` " ''. ! 1484: (See section 2.9 in the main text.) ! 1485: .Nh 2 Concatenation ! 1486: One new operator has been added, ! 1487: character string concatenation, marked by a double slash ! 1488: ``//''. ! 1489: The result of a concatenation ! 1490: is the string containing the characters ! 1491: of the left operand followed by the characters of ! 1492: the right operand. ! 1493: The character expressions ! 1494: .DS ! 1495: \(fmab\(fm // \(fmcd\(fm ! 1496: \(fmabcd\(fm ! 1497: .DE ! 1498: are equal. ! 1499: .IP ! 1500: Dummy arguments of type character may be declared with implied ! 1501: lengths: ! 1502: .DS ! 1503: subroutine s ( a, b ) ! 1504: character a\(**(\(**), b\(**(\(**) ! 1505: .DE ! 1506: Such dummy arguments may be used in concatenations in assign statements: ! 1507: .DS ! 1508: s = a // b ! 1509: .DE ! 1510: but not in other contexts. For example: ! 1511: .DS ! 1512: if( a // b .eq. \(fmabc\(fm ) key = 1 ! 1513: call sub( a // b ) ! 1514: .DE ! 1515: are legal statements if ``a'' and ``b'' are dummy arguments ! 1516: declared with explicit lengths, or if they are not arguments. ! 1517: These are illegal if they are declared with implied lengths. ! 1518: .Nh 2 Character\ String\ Assignment ! 1519: The left and right sides of a character assignment may not share storage. ! 1520: (The assumed implementation of character assignment is to copy characters from the right to the left side.) ! 1521: If the left side is longer than the right, it is padded with blanks. ! 1522: If the left side is shorter than the right, trailing characters are discarded. ! 1523: Since the two sides of a character assignment must be disjoint, the ! 1524: following are illegal: ! 1525: .DS ! 1526: str = \(fm\ \(fm // str ! 1527: str = str(2:) ! 1528: .DE ! 1529: These are not flagged as errors during compilation or execution, ! 1530: however the result is undefined. ! 1531: .Nh 2 Substrings ! 1532: It is possible to extract a substring of a character variable or character ! 1533: array element, using the colon notation: ! 1534: .DS ! 1535: a(i,\|j) (m:n) ! 1536: .DE ! 1537: is the string of $(n-m+1)$ characters beginning at the ! 1538: $m sup th$ character of the character array element $a sub ij$. ! 1539: Results are undefined unless $m<=n$. ! 1540: Substrings may be used on the left sides of assignments and as procedure actual arguments. ! 1541: .Nh 2 Exponentiation ! 1542: It is now permissible to raise real quantities to complex powers, ! 1543: or complex quantities to real or complex powers. ! 1544: (The principal part of the logarithm is used.) ! 1545: Also, multiple exponentiation is now defined: ! 1546: .DS ! 1547: a\(**\(**b\(**\(**c is equivalent to a \(**\(** (b\(**\(**c) ! 1548: .DE ! 1549: .Nh 2 Relaxation\ of\ Restrictions ! 1550: Mixed mode expressions are now permitted. ! 1551: (For instance, ! 1552: it is permissible to combine integer and complex quantities in an expression.) ! 1553: .IP ! 1554: Constant expressions are permitted where a constant is allowed, ! 1555: except in ! 1556: .B data ! 1557: statements ! 1558: and ! 1559: .B format ! 1560: statements. ! 1561: (A constant expression is made up of explicit constants and ! 1562: \fBparameter\fRs ! 1563: and the Fortran operators, ! 1564: except for exponentiation to a floating-point power.) ! 1565: An adjustable dimension may now be an integer expression involving constants, ! 1566: arguments, and variables in ! 1567: .B common. ! 1568: .IP ! 1569: Subscripts may now be general integer expressions; ! 1570: the old ! 1571: $c v +- c'$ ! 1572: rules have been removed. ! 1573: .B do ! 1574: loop bounds may be general integer, real, or double precision expressions. ! 1575: Computed ! 1576: .B goto ! 1577: expressions and \s-1I/O\s0 unit numbers may be general integer expressions. ! 1578: .NH 1 ! 1579: Executable Statements ! 1580: .XS ! 1581: \*(SN Executable Statements ! 1582: .XE ! 1583: .Nh 2 IF-THEN-ELSE ! 1584: At last, the ! 1585: if-then-else ! 1586: branching structure has been added to Fortran. ! 1587: It is called a ``Block If\|''. ! 1588: A Block If begins with a statement of the form ! 1589: .DS ! 1590: if ( . . . ) then ! 1591: .DE ! 1592: and ends with an ! 1593: .DS ! 1594: end if ! 1595: .DE ! 1596: statement. ! 1597: Two other new statements may appear in a Block If. ! 1598: There may be several ! 1599: .DS ! 1600: else if (. . .) then ! 1601: .DE ! 1602: statements, ! 1603: followed by at most one ! 1604: .DS ! 1605: else ! 1606: .DE ! 1607: statement. ! 1608: If the logical expression in the Block If statement is true, ! 1609: the statements following it up to the next ! 1610: .B "else if", ! 1611: .B else, ! 1612: or ! 1613: .B "end if" ! 1614: are executed. ! 1615: Otherwise, the next ! 1616: .B "else if" ! 1617: statement in the group is executed. ! 1618: If none of the ! 1619: .B "else if" ! 1620: conditions are true, control passes to the statements following the ! 1621: .B else ! 1622: statement, if any. ! 1623: (The ! 1624: .B else ! 1625: block must follow all ! 1626: .B "else if" ! 1627: blocks in a Block If. ! 1628: Of course, there may be Block Ifs embedded inside of other Block If structures.) ! 1629: A case construct may be rendered: ! 1630: .DS ! 1631: if (s .eq. \(fmab\(fm) then ! 1632: . . . ! 1633: else if (s .eq. \(fmcd\(fm) then ! 1634: . . . ! 1635: else ! 1636: . . . ! 1637: end if ! 1638: .DE ! 1639: .Nh 2 Alternate\ Returns ! 1640: Some of the arguments of a subroutine call may be statement labels preceded by an asterisk, as in: ! 1641: .DS ! 1642: call joe(j, \(**10, m, \(**2) ! 1643: .DE ! 1644: A ! 1645: .B return ! 1646: statement may have an integer expression, such as: ! 1647: .DS ! 1648: return k ! 1649: .DE ! 1650: If the entry point has ! 1651: $n$ ! 1652: alternate return (asterisk) arguments ! 1653: and if $1<=k<=n$, the return is followed by a branch to the corresponding statement label; ! 1654: otherwise the usual return to the statement following the ! 1655: .B call ! 1656: is executed. ! 1657: .NH 1 ! 1658: Input/Output ! 1659: .XS ! 1660: \*(SN Input/Output ! 1661: .XE ! 1662: .Nh 2 Format\ Variables ! 1663: A format may be the value of a character expression (constant or otherwise), ! 1664: or be stored in a character array, as in: ! 1665: .DS ! 1666: write(6, \(fm(i5)\(fm) x ! 1667: .DE ! 1668: .Nh 2 END=,\ ERR=,\ and\ IOSTAT=\ Clauses ! 1669: A ! 1670: .B read ! 1671: or ! 1672: .B write ! 1673: statement may contain ! 1674: .B end=, ! 1675: .B err=, ! 1676: and ! 1677: .B iostat= ! 1678: clauses, as in: ! 1679: .DS ! 1680: write(6, 101, err=20, iostat=a(4)) ! 1681: read(5, 101, err=20, end=30, iostat=x) ! 1682: .DE ! 1683: Here 5 and 6 are the ! 1684: .I units ! 1685: on which the \s-1I/O\s0 is done, ! 1686: 101 is the statement number of the associated format, ! 1687: 20 and 30 are statement numbers, ! 1688: and ! 1689: .B a ! 1690: and ! 1691: .B x ! 1692: are integer variables. ! 1693: If an error occurs during \s-1I/O\s0, ! 1694: control returns to the program at statement 20. ! 1695: If the end of the file is reached, ! 1696: control returns to the program at statement 30. ! 1697: In any case, the variable referred to in ! 1698: the ! 1699: .B iostat= ! 1700: clause is given a value when ! 1701: the \s-1I/O\s0 statement finishes. ! 1702: (Yes, the value is assigned to the name on the right side of the equal sign.) ! 1703: This value is zero if all went well, ! 1704: negative for end of file, ! 1705: and some positive value for errors. ! 1706: .Nh 2 Formatted\ \s-1I/O\s0 ! 1707: .NH 3 ! 1708: Character Constants ! 1709: .IP ! 1710: Character constants in formats are copied literally to the output. ! 1711: .IP ! 1712: A format may be specified as a character constant within the ! 1713: .B read ! 1714: or ! 1715: .B write ! 1716: statement. ! 1717: .DS ! 1718: write(6,\|\(fm(i2,\|\(fm\|\(fm isn\|\(fm\|\(fm\|\(fm\|\(fm\|t \|\(fm\|\(fm,i1)\|\(fm) 7, 4 ! 1719: .DE ! 1720: produces ! 1721: .DS ! 1722: 7 isn\|\(fm\|t 4 ! 1723: .DE ! 1724: In the example above, the format is the character constant ! 1725: .DS ! 1726: (i2,\|\(fm isn\|\(fm\|\(fmt \|\(fm,i1) ! 1727: .DE ! 1728: and the embedded character constant ! 1729: .DS ! 1730: isn\|\(fmt ! 1731: .DE ! 1732: is copied into the output. ! 1733: .IP ! 1734: The example could have been written more legibly by taking advantage ! 1735: of the two types of quote marks. ! 1736: .DS ! 1737: write(6,\|\(fm(i2," isn\|\(fm\|\|\(fm\|t ",i1)\|\(fm) 7, 4 ! 1738: .DE ! 1739: However, the double quote is not standard Fortran 77. ! 1740: .IP ! 1741: The standard does not allow reading into character constants or ! 1742: Hollerith fields. ! 1743: In order to facilitate running older programs, the Fortran \s-1I/O\s0 library ! 1744: allows reading into Hollerith fields; however this is a practice to be ! 1745: avoided. ! 1746: .NH 3 ! 1747: Positional Editing Codes ! 1748: .IP ! 1749: .B t, ! 1750: .B tl, ! 1751: .B tr, ! 1752: and ! 1753: .B x ! 1754: codes ! 1755: control where the ! 1756: next character is in the record. ! 1757: \fBtr\fIn\fR ! 1758: or ! 1759: \fIn\fBx\fR ! 1760: specifies that the next character is ! 1761: $n$ to the right of the current position. ! 1762: \fBtl\fIn\fR ! 1763: specifies that the next character is ! 1764: $n$ to the left of the current position, ! 1765: allowing parts of the record to be reconsidered. ! 1766: \fBt\fIn\fR ! 1767: says that the next character is to be character ! 1768: number $n$ in the record. ! 1769: (See section 3.3 in the main text.) ! 1770: .NH 3 ! 1771: Colon ! 1772: .IP ! 1773: A colon in the format terminates the \s-1I/O\s0 operation ! 1774: if there are no more data items in the \s-1I/O\s0 list, ! 1775: otherwise it has no effect. ! 1776: In the fragment ! 1777: .DS ! 1778: x=\(fm("hello", :, " there", i4)\(fm ! 1779: write(6, x) 12 ! 1780: write(6, x) ! 1781: .DE ! 1782: the first ! 1783: .B write ! 1784: statement prints ! 1785: .DS ! 1786: hello there 12 ! 1787: .DE ! 1788: while the second only prints ! 1789: .DS ! 1790: hello ! 1791: .DE ! 1792: .NH 3 ! 1793: Optional Plus Signs ! 1794: .IP ! 1795: According to the Standard, ! 1796: each implementation has the option of putting ! 1797: plus signs in front of non-negative ! 1798: numeric output. ! 1799: The ! 1800: .B sp ! 1801: format code may be used to make the optional plus ! 1802: signs actually appear for all subsequent items ! 1803: while the format is active. ! 1804: The ! 1805: .B ss ! 1806: format code guarantees that the \s-1I/O\s0 system will not ! 1807: insert the optional plus signs, ! 1808: and the ! 1809: .B s ! 1810: format code restores the default behavior of ! 1811: the \s-1I/O\s0 system. ! 1812: (Since we never put out optional plus signs, ! 1813: .B ss ! 1814: and ! 1815: .B s ! 1816: codes have the same effect in our implementation.) ! 1817: .NH 3 ! 1818: Blanks on Input ! 1819: .IP ! 1820: Blanks in numeric input fields, ! 1821: other than leading blanks, ! 1822: will be ignored following a ! 1823: .B bn ! 1824: code in a format ! 1825: statement, ! 1826: and will be treated as zeros following a ! 1827: .B bz ! 1828: code in a format statement. ! 1829: The default for a unit may be changed by using ! 1830: the ! 1831: .B open ! 1832: statement. ! 1833: (Blanks are ignored by default.) ! 1834: .NH 3 ! 1835: Unrepresentable Values ! 1836: .IP ! 1837: The Standard requires that if a numeric item ! 1838: cannot be represented in the form required by a format code, ! 1839: the output field must be filled with asterisks. ! 1840: (We think this should have been an option.) ! 1841: .NH 3 ! 1842: Iw.m ! 1843: .IP ! 1844: There is a new integer output code, ! 1845: \fBi\fIw.m.\fR ! 1846: It is the same as ! 1847: \fBi\fIw\fR, ! 1848: except that there will be at least $m$ ! 1849: digits in the output field, ! 1850: including, ! 1851: if necessary, ! 1852: leading zeros. ! 1853: The case \fBi\fR$w.0$ is special, ! 1854: in that if the value being printed is 0, ! 1855: the output field is ! 1856: entirely blank. ! 1857: \fBi\fIw\fB.1\fR ! 1858: is the same as ! 1859: \fBi\fIw\fR. ! 1860: .NH 3 ! 1861: Floating Point ! 1862: .IP ! 1863: On input, exponents may start with the letter ! 1864: \fBE, D, e, \fRor \fBd.\fR ! 1865: All have the same meaning. ! 1866: On output we always use \fBe\fR or \fBd\fR. ! 1867: The ! 1868: .B e ! 1869: and ! 1870: .B d ! 1871: format codes also have identical meanings. ! 1872: A leading zero before the decimal point in ! 1873: .B e ! 1874: output ! 1875: without a scale factor is optional with the ! 1876: implementation. ! 1877: There is a ! 1878: \fBg\fIw.d\fR ! 1879: format code which is the same as ! 1880: \fBe\fIw.d\fR ! 1881: and ! 1882: \fBf\fIw.d\fR ! 1883: on input, ! 1884: but which chooses ! 1885: .B f ! 1886: or ! 1887: .B e ! 1888: formats for output depending ! 1889: on the size of the number and of $d$. ! 1890: .NH 3 ! 1891: ``A'' Format Code ! 1892: .IP ! 1893: The ! 1894: .B a ! 1895: code is used for character data. ! 1896: \fBa\fIw\fR ! 1897: uses a field width of $w$, ! 1898: while a plain ! 1899: .B a ! 1900: uses the length of the internal character item. ! 1901: .Nh 2 Standard\ Units ! 1902: There are default formatted input and output units. ! 1903: The statement ! 1904: .DS ! 1905: read 10, a, b ! 1906: .DE ! 1907: reads from the standard unit using format statement 10. ! 1908: The default unit may be explicitly specified by an asterisk, as in ! 1909: .DS ! 1910: read(\(**, 10) a, b ! 1911: .DE ! 1912: Similarly, the standard output unit is specified by a ! 1913: .B print ! 1914: statement or an asterisk unit: ! 1915: .DS ! 1916: print 10 ! 1917: write(\(**, 10) ! 1918: .DE ! 1919: .Nh 2 List-Directed\ \s-1I/O\s0 ! 1920: List-directed \s-1I/O\s0 is a ! 1921: kind of free form input for sequential \s-1I/O\s0. ! 1922: It is invoked by using an asterisk as the ! 1923: format identifier, as in ! 1924: .DS ! 1925: read(6, \(**) a,b,c ! 1926: .DE ! 1927: .IP ! 1928: On input, ! 1929: values are separated by strings of blanks ! 1930: and possibly a comma. ! 1931: On \s-1UNIX\s0, tabs may be used ! 1932: interchangeably with blanks as separators. ! 1933: Values, ! 1934: except for character strings, ! 1935: cannot contain blanks. ! 1936: End of record counts as a blank, ! 1937: except in character strings, ! 1938: where it is ignored. ! 1939: Complex constants are given as two real constants ! 1940: separated by a comma and enclosed in parentheses. ! 1941: A null input field, ! 1942: such as between two consecutive commas, ! 1943: means the corresponding variable in the ! 1944: \s-1I/O\s0 list is not changed. ! 1945: Values may be preceded by repetition counts, ! 1946: as in ! 1947: .DS ! 1948: 4\(**(3.,2.) 2\(**, 4\(**\|\(fm\|hello\|\(fm ! 1949: .DE ! 1950: which stands for 4 complex constants, 2 null values, ! 1951: and 4 string constants. ! 1952: .IP ! 1953: The Fortran standard requires data being read into \fBcharacter\fP variables ! 1954: by a list-directed read to be enclosed in quotes. ! 1955: In our system, the quotes are optional for strings which do not start with ! 1956: a digit or quote and do not contain separators. ! 1957: .IP ! 1958: For output, suitable formats are chosen for ! 1959: each item. ! 1960: The values of character strings are printed; ! 1961: they are not enclosed in quotes. ! 1962: According to the standard, ! 1963: they could not be read back ! 1964: using list-directed input. ! 1965: However much of this data could be read back in with list-directed ! 1966: \s-1I/O\s0 on our system. ! 1967: .Nh 2 Direct\ \s-1I/O\s0 ! 1968: A file connected for direct access consists of ! 1969: a set of equal-sized records each of which is ! 1970: uniquely identified by a positive integer. ! 1971: The records may be written or read in any order, ! 1972: using direct access \s-1I/O\s0 statements. ! 1973: .IP ! 1974: Direct access ! 1975: .B read ! 1976: and ! 1977: .B write ! 1978: statements ! 1979: have an extra argument, ! 1980: .B rec=, ! 1981: which gives the record number to be read or written. ! 1982: .DS ! 1983: read(2, rec=13, err=20) (a(i), i=1, 203) ! 1984: .DE ! 1985: reads the thirteenth record into the array ! 1986: .B a. ! 1987: .IP ! 1988: The size of the records must be given by an ! 1989: .B open ! 1990: statement ! 1991: (see below). ! 1992: Direct access files may be connected for either formatted ! 1993: or unformatted \s-1I/O\s0. ! 1994: .Nh 2 Internal\ Files ! 1995: Internal files are character string objects, ! 1996: such as variables or substrings, ! 1997: or arrays of type character. ! 1998: In the former cases there is only a single record ! 1999: in the file; ! 2000: in the latter case each array element is a record. ! 2001: The Standard includes only sequential ! 2002: formatted \s-1I/O\s0 on internal files. ! 2003: (\s-1I/O\s0 is not a very precise term to use here, ! 2004: but internal files are dealt with using ! 2005: .B read ! 2006: and ! 2007: .B write.) ! 2008: Internal files are used by giving the name of the ! 2009: character object in place of the unit number, as in ! 2010: .DS ! 2011: character\(**80 x ! 2012: read(5,\(fm(a)\(fm) x ! 2013: read(x,\(fm(i3,i4)\(fm) n1,n2 ! 2014: .DE ! 2015: which reads a character string into ! 2016: .B x ! 2017: and then reads ! 2018: two integers from the front of it. ! 2019: A sequential ! 2020: .B read ! 2021: or ! 2022: .B write ! 2023: always starts at the beginning ! 2024: of an internal file. ! 2025: .IP ! 2026: We also support two extensions of the standard. The first is ! 2027: direct \s-1I/O\s0 on internal files. ! 2028: This is like direct \s-1I/O\s0 on external files, ! 2029: except that the number of records in the file cannot be ! 2030: changed. ! 2031: In this case a record is a single element of an array of character strings. ! 2032: The second extension is list-directed \s-1I/O\s0 on internal files. ! 2033: .Nh 2 OPEN,\ CLOSE,\ and\ INQUIRE\ Statements ! 2034: These statements are used to connect and disconnect ! 2035: units and files, ! 2036: and to gather information about units and files. ! 2037: .NH 3 ! 2038: OPEN ! 2039: .IP ! 2040: The ! 2041: .B open ! 2042: statement is used to connect a file with a ! 2043: unit, ! 2044: or to alter some properties of the connection. ! 2045: The following is a minimal example. ! 2046: .DS ! 2047: open(1, file=\(fmfort.junk\(fm) ! 2048: .DE ! 2049: .B open ! 2050: takes a variety of arguments with meanings described below. ! 2051: .EQ ! 2052: delim off ! 2053: .EN ! 2054: . \" macros here ! 2055: .de HP ! 2056: .RT ! 2057: .if !\\(IP .nr IP +1 ! 2058: .sp \\n(PDu ! 2059: .ne 3v ! 2060: .in +\\n(PIu ! 2061: .ti -\\n(PIu ! 2062: \fB\\$1\fR\ \c ! 2063: .. ! 2064: .de P1 ! 2065: .KS ! 2066: .nf ! 2067: .in +.3i ! 2068: .ta .3i .6i .9i 1.2i 1.5i 1.8i ! 2069: .sp ! 2070: .. ! 2071: .de P2 ! 2072: .fi ! 2073: .in -.3i ! 2074: .sp ! 2075: .KE ! 2076: .. ! 2077: .de TH ! 2078: .RT ! 2079: .sp \\n(PDu ! 2080: .ne 3v ! 2081: \fB\\$1\\$2\\$3\\$4\\$5\\$6\fR\ \c ! 2082: .. ! 2083: . \" end of macros ! 2084: .RS ! 2085: .HP unit= ! 2086: an integer between 0 and 99 inclusive which is the unit to ! 2087: which the file is to be connected (see section 5.3 in the text). ! 2088: If this parameter is the first one in the ! 2089: .B open ! 2090: statement, ! 2091: the ! 2092: .B unit= ! 2093: can be omitted. ! 2094: .HP iostat= ! 2095: is the same as in ! 2096: .B read ! 2097: or ! 2098: .B write. ! 2099: .HP err= ! 2100: is the same as in ! 2101: .B read ! 2102: or ! 2103: .B write. ! 2104: .HP file= ! 2105: a character expression, ! 2106: which when stripped of trailing blanks, ! 2107: is the name of the file to be connected to the unit. ! 2108: The file name should not be given if the ! 2109: .B status=\(fmscratch\(fm. ! 2110: .HP status= ! 2111: one of ! 2112: .B \(fmold\(fm, ! 2113: .B \(fmnew\(fm, ! 2114: .B \(fmscratch\(fm, ! 2115: or ! 2116: .B \(fmunknown\(fm. ! 2117: If this parameter is not given,\p ! 2118: .B \(fmunknown\(fm ! 2119: is assumed. ! 2120: The meaning of ! 2121: .B \(fmunknown\(fm ! 2122: is processor dependent; ! 2123: our system will create the file if it doesn't exist. ! 2124: If ! 2125: .B \(fmscratch\(fm ! 2126: is given, ! 2127: a temporary file will be created. ! 2128: Temporary files are destroyed at the end of execution. ! 2129: If ! 2130: .B \(fmnew\(fm ! 2131: is given, the file must not exist. ! 2132: It will be created for both reading and writing. ! 2133: If ! 2134: .B \(fmold\(fm ! 2135: is given, it is an error for the file not to exist. ! 2136: .HP access= ! 2137: .B \(fmsequential\(fm ! 2138: or ! 2139: .B \(fmdirect\(fm, ! 2140: depending on whether the file is ! 2141: to be opened for sequential or direct \s-1I/O\s0. ! 2142: .HP form= ! 2143: .B \(fmformatted\(fm ! 2144: or ! 2145: .B \(fmunformatted\(fm. ! 2146: On ! 2147: \s-1UNIX\s0 ! 2148: systems, ! 2149: .B form=\(fmprint\(fm ! 2150: implies ! 2151: .B \(fmformatted\(fm ! 2152: with vertical format control. ! 2153: (See section 3.4 of the text). ! 2154: .HP recl= ! 2155: a positive integer specifying the record length of ! 2156: the direct access file being opened. ! 2157: We measure all record lengths in bytes. ! 2158: On ! 2159: \s-1UNIX\s0 ! 2160: systems a record length of 1 has the special meaning explained ! 2161: in section 5.1 of the text. ! 2162: .HP blank= ! 2163: .B \(fmnull\(fm ! 2164: or ! 2165: .B \(fmzero\(fm. ! 2166: This parameter has meaning only for formatted \s-1I/O\s0. ! 2167: The default value is ! 2168: .B \(fmnull\(fm. ! 2169: .B \(fmzero\(fm ! 2170: means that blanks, ! 2171: other than leading blanks, ! 2172: in numeric input fields are to be treated as zeros. ! 2173: .RE ! 2174: .IP ! 2175: Opening a new file on a unit which is already connected ! 2176: has the effect of first closing the old file. ! 2177: .NH 3 ! 2178: CLOSE ! 2179: .IP ! 2180: .B close ! 2181: severs the connection between a unit and a file. ! 2182: The unit number must be given. ! 2183: The optional parameters are ! 2184: .B iostat= ! 2185: and ! 2186: .B err= ! 2187: with ! 2188: their usual meanings, ! 2189: and ! 2190: .B status= ! 2191: either ! 2192: .B \(fmkeep\(fm ! 2193: or ! 2194: .B \(fmdelete\(fm. ! 2195: For scratch files the default is ! 2196: .B \(fmdelete\(fm; ! 2197: otherwise ! 2198: .B \(fmkeep\(fm ! 2199: is the default. ! 2200: .B \(fmdelete\(fm ! 2201: means the file will be removed. ! 2202: A simple example is ! 2203: .DS ! 2204: close(3, err=17) ! 2205: .DE ! 2206: .NH 3 ! 2207: INQUIRE ! 2208: .IP ! 2209: The ! 2210: .B inquire ! 2211: statement gives information about ! 2212: a unit ! 2213: (``inquire by unit'') ! 2214: or a file (``inquire by file''). ! 2215: Simple examples are: ! 2216: .DS ! 2217: inquire(unit=3, name=xx) ! 2218: inquire(file=\(fm\|junk\|\(fm, number=n, exist=l) ! 2219: .DE ! 2220: .RS ! 2221: .HP file= ! 2222: a character variable specifies the file the ! 2223: .B inquire ! 2224: is about. ! 2225: Trailing blanks in the file name are ignored. ! 2226: .HP unit= ! 2227: an integer variable specifies the unit the ! 2228: .B inquire ! 2229: is about. ! 2230: Exactly one of ! 2231: .B file= ! 2232: or ! 2233: .B unit= ! 2234: must be used. ! 2235: .HP "iostat=, err=" ! 2236: are as before. ! 2237: .HP exist= ! 2238: a logical variable. ! 2239: The logical variable is set to ! 2240: .B ".true." ! 2241: if the file or unit ! 2242: exists and is set to ! 2243: .B ".false." ! 2244: otherwise. ! 2245: .HP opened= ! 2246: a logical variable. ! 2247: The logical variable is set to ! 2248: .B ".true." ! 2249: if the file ! 2250: is connected to a unit or if the unit is connected ! 2251: to a file, ! 2252: and it is set to ! 2253: .B ".false." ! 2254: otherwise. ! 2255: .HP number= ! 2256: an integer variable to which is assigned the ! 2257: number of the unit connected to the file, ! 2258: if any. ! 2259: .HP named= ! 2260: a logical variable to which is assigned ! 2261: .B ".true." ! 2262: if ! 2263: the file has a name, ! 2264: or ! 2265: .B ".false." ! 2266: otherwise. ! 2267: .HP name= ! 2268: a character variable to which is assigned the name ! 2269: of the file (inquire by file) or the name of the ! 2270: file connected to the unit (inquire by unit). ! 2271: .HP access= ! 2272: a character variable to which will be assigned ! 2273: the value ! 2274: .B \(fmsequential\(fm ! 2275: if the connection is for ! 2276: sequential \s-1I/O\s0, ! 2277: .B \(fmdirect\(fm ! 2278: if the connection is for direct \s-1I/O\s0, ! 2279: .B \(fmunknown\(fm ! 2280: if not connected. ! 2281: .HP sequential= ! 2282: a character variable to which is assigned the ! 2283: value ! 2284: .B \(fmyes\(fm ! 2285: if the file could be connected for ! 2286: sequential \s-1I/O\s0, ! 2287: .B \(fmno\(fm ! 2288: if the file could not be connected for sequential \s-1I/O\s0, ! 2289: and ! 2290: .B \(fmunknown\(fm ! 2291: if we can't tell. ! 2292: .HP direct= ! 2293: a character variable to which is assigned the value ! 2294: .B \(fmyes\(fm ! 2295: if the file could be connected for direct \s-1I/O\s0, ! 2296: .B \(fmno\(fm ! 2297: if the file could not be connected for direct ! 2298: \s-1I/O\s0, and ! 2299: .B \(fmunknown\(fm ! 2300: if we can't tell. ! 2301: .HP form= ! 2302: a character variable to which is assigned the value ! 2303: .B \(fmunformatted\(fm ! 2304: if the file is connected for unformatted \s-1I/O\s0, ! 2305: .B \(fmformatted\(fm ! 2306: if the file is connected for formatted \s-1I/O\s0, ! 2307: .B \(fmprint\(fm ! 2308: for formatted \s-1I/O\s0 with vertical format control, or ! 2309: .B \(fmunknown\(fm ! 2310: if not connected. ! 2311: .HP formatted= ! 2312: a character variable to which is assigned the value ! 2313: .B \(fmyes\(fm ! 2314: if the file could be connected for formatted \s-1I/O\s0, ! 2315: .B \(fmno\(fm ! 2316: if the file could not be connected for formatted \s-1I/O\s0, ! 2317: and ! 2318: .B \(fmunknown\(fm ! 2319: if we can't tell. ! 2320: .HP unformatted= ! 2321: a character variable to which is assigned the value ! 2322: .B \(fmyes\(fm ! 2323: if ! 2324: the file could be connected for unformatted \s-1I/O\s0, ! 2325: .B \(fmno\(fm ! 2326: if the file could not be connected for unformatted \s-1I/O\s0, ! 2327: and ! 2328: .B \(fmunknown\(fm ! 2329: if we can't tell. ! 2330: .HP recl= ! 2331: an integer variable to which is assigned the record length ! 2332: of the records in the file if the file is connected ! 2333: for direct access. ! 2334: .HP nextrec= ! 2335: an integer variable to which is assigned one more ! 2336: than the number of the the last record read from a file connected ! 2337: for direct access. ! 2338: .HP blank= ! 2339: a character variable to which is assigned the value ! 2340: .B \(fmnull\(fm ! 2341: if null blank control is in effect for the file ! 2342: connected for formatted \s-1I/O\s0, ! 2343: .B \(fmzero\(fm ! 2344: if blanks are being converted to zeros and ! 2345: the file is connected for formatted \s-1I/O\s0. ! 2346: .RE ! 2347: .IP ! 2348: For information on file permissions, ownership, etc., ! 2349: use the Fortran library routines \fBstat\fP and \fBaccess\fP. ! 2350: .IP ! 2351: For further discussion of the \s-1UNIX\s0 Fortran \s-1I/O\s0 system ! 2352: see ``Introduction to the f77 I/O Library'' [9]. ! 2353: .bp ! 2354: .SH ! 2355: APPENDIX B: References and Bibliography ! 2356: .XS ! 2357: Appendix B. References and Bibliography ! 2358: .XE ! 2359: .LP ! 2360: .sp ! 2361: .B ! 2362: References ! 2363: .R ! 2364: .IP 1. 3 ! 2365: \f2American National Standard Programming Language \s-1FORTRAN\s0, ! 2366: \s-1ANSI\s0 X3.9-1978\f1. ! 2367: New York: American National Standards Institute, 1978. ! 2368: .IP 2. ! 2369: \f2\s-1USA\s0 Standard \s-1FORTRAN\s0, \s-1USAS X\s03.9-1966\f1. ! 2370: New York: United States of America Standards Institute, 1966. ! 2371: Clarified in \f2Comm. \s-1ACM\s0\f1 12:289 (1969) ! 2372: and \f2Comm. \s-1ACM\s0\f1 14:628 (1971). ! 2373: .IP 3. ! 2374: Kernighan, B. W., and D. M. Ritchie. \f2The C Programming Language.\f1 ! 2375: Englewood Cliffs: Prentice-Hall, 1978. ! 2376: .IP 4. ! 2377: Ritchie, D. M. Private communication. ! 2378: .IP 5. ! 2379: Johnson, S. C. ``A Portable Compiler: Theory and Practice,'' ! 2380: \f2Proceedings of Fifth \s-1ACM\s0 Symposium on ! 2381: Principles of Programming Languages\f1. 1978. ! 2382: .IP 6. ! 2383: Feldman, S. I. ``An Informal Description of \s-1EFL\s0,'' ! 2384: internal memorandum. ! 2385: .IP 7. ! 2386: Kernighan, B. W. ``\s-1RATFOR\s0\(emA Preprocessor for ! 2387: Rational Fortran,'' \f2Bell Laboratories Computing Science ! 2388: Technical Report #55\f1. 1977. ! 2389: .IP 8. ! 2390: Ritchie, D. M. Private communication. ! 2391: .IP 9. ! 2392: Wasley, D. L. ``Introduction to the f77 I/O Library'', ! 2393: \fI\s-1UNIX\s0 Programmer's Manual, Volume 2c\fR. ! 2394: .sp ! 2395: .LP ! 2396: .B ! 2397: Bibliography ! 2398: .R ! 2399: .LP ! 2400: The following books or documents describe aspects of Fortran 77. ! 2401: This list cannot pretend to be complete. ! 2402: Certainly no particular endorsement is implied. ! 2403: .IP 1. 3 ! 2404: Brainerd, Walter S., et al. \f2Fortran 77 Programming.\f1 ! 2405: Harper Row, 1978. ! 2406: .IP 2. ! 2407: Day, A. C. \f2Compatible Fortran.\f1 Cambridge University Press, 1979. ! 2408: .IP 3. ! 2409: Dock, V. Thomas. \f2Structured Fortran IV Programming.\f1 West, 1979. ! 2410: .IP 4. ! 2411: Feldman, S. I. ``The Programming Language \s-1EFL\s0,'' ! 2412: \f2Bell Laboratories Technical Report\f1. ! 2413: June 1979. ! 2414: .IP 5. ! 2415: Hume, J. N., and R. C. Holt. \f2Programming Fortran 77.\f1 ! 2416: Reston, 1979. ! 2417: .IP 6. ! 2418: Katzan, Harry, Jr. \f2Fortran 77.\f1 Van Nostrand-Reinhold, 1978. ! 2419: .IP 7. ! 2420: Meissner, Loren P., and Organick, Elliott I. \f2Fortran 77 Featuring ! 2421: Structured Programming\f1, Addison-Wesley, 1979. ! 2422: .IP 8. ! 2423: Merchant, Michael J. \f2\s-1ABC\s0's of Fortran Programming.\f1 ! 2424: Wadsworth, 1979. ! 2425: .IP 9. ! 2426: Page, Rex, and Richard Didday. \f2Fortran 77 for Humans.\f1 ! 2427: West, 1980. ! 2428: .IP 10. ! 2429: Wagener, Jerrold L. \f2Principles of Fortran 77 Programming.\f1 ! 2430: Wiley, 1980. ! 2431: .\" want Table of Contents to begin on page 2 hence must expand body ! 2432: .\" of .TC macro to enable us to get handle on page number. ! 2433: .pn 2 ! 2434: .bp ! 2435: .PX
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.