Annotation of 43BSDReno/share/doc/ps1/04.pascal/puman4.n, revision 1.1.1.1

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: .\"    @(#)puman4.n    6.2 (Berkeley) 5/7/86
                      6: .\"
                      7: .if !\n(xx \{\
                      8: .so tmac.p \}
                      9: .nr H1 3
                     10: .if n 'ND
                     11: .NH
                     12: Input/output
                     13: .PP
                     14: This section describes features of the Pascal input/output environment,
                     15: with special consideration of the features peculiar to an
                     16: interactive implementation.
                     17: .NH 2
                     18: Introduction
                     19: .PP
                     20: Our first sample programs, in section 2, used the file
                     21: .I output .
                     22: We gave examples there of redirecting the output to a file and to the line
                     23: printer using the shell.
                     24: Similarly, we can read the input from a file or another program.
                     25: Consider the following Pascal program which is similar to the program
                     26: .I cat 
                     27: (1).
                     28: .LS
                     29: % \*bpix -l kat.p <primes\fR
                     30: .so katout
                     31: %
                     32: .LE
                     33: Here we have used the shell's syntax to redirect the program input from
                     34: a file in
                     35: .I primes
                     36: in which we had placed the output of our prime number program of section 2.6.
                     37: It is also possible to
                     38: `pipe' input to this program much as we piped input
                     39: to the line printer daemon
                     40: .I lpr
                     41: (1)
                     42: before.
                     43: Thus, the same output as above would be produced by
                     44: .LS
                     45: % \*bcat primes | pix -l kat.p\fR
                     46: .LE
                     47: .PP
                     48: All of these examples use the shell to control the input and output
                     49: from files.
                     50: One very simple way to associate Pascal files with named
                     51: .UX
                     52: files is to place the file name in the
                     53: .B program
                     54: statement.
                     55: For example, suppose we have previously created the file
                     56: .I data.
                     57: We then use it as input to another version of a listing program.
                     58: .LS
                     59: % \*bcat data\fR
                     60: .so data
                     61: % \*bpix -l copydata.p\fR
                     62: .so copydataout
                     63: %
                     64: .LE
                     65: By mentioning the file
                     66: .I data
                     67: in the
                     68: .B program
                     69: statement, we have indicated that we wish it
                     70: to correspond to the
                     71: .UX
                     72: file
                     73: .I data .
                     74: Then, when we
                     75: `reset(data)',
                     76: the Pascal system opens our file `data' for reading.
                     77: More sophisticated, but less portable, examples of using
                     78: .UX
                     79: files will be given in sections 4.5 and 4.6.
                     80: There is a portability problem even with this simple example.
                     81: Some Pascal systems attach meaning to the ordering of the file in the
                     82: .B program
                     83: statement file list.
                     84: .UP
                     85: does not do so.
                     86: .NH 2
                     87: Eof and eoln
                     88: .PP
                     89: An extremely common problem encountered by new users of Pascal, especially
                     90: in the interactive environment offered by
                     91: .UX ,
                     92: relates to the definitions of
                     93: .I eof
                     94: and
                     95: .I eoln .
                     96: These functions are supposed to be defined at the beginning of execution of
                     97: a Pascal program, indicating whether the input device is at the end of a
                     98: line or the end of a file.
                     99: Setting
                    100: .I eof
                    101: or
                    102: .I eoln
                    103: actually corresponds to an implicit read in which the input is
                    104: inspected, but no input is ``used up''.
                    105: In fact, there is no way the system can know whether the input is
                    106: at the end-of-file or the end-of-line unless it attempts to read a line from it.
                    107: If the input is from a previously created file,
                    108: then this reading can take place without run-time action by the user.
                    109: However, if the input is from a terminal, then the input
                    110: is what the user types.\*(dg
                    111: If the system were to do an initial read
                    112: automatically at the beginning of program execution,
                    113: and if the input were a terminal,
                    114: the user would have to type some input before execution could begin.
                    115: .FS
                    116: \*(dgIt is not possible to determine whether the input is
                    117: a terminal, as the input may appear to be a file but actually be a
                    118: .I pipe,
                    119: the output of a program which is reading from the terminal.
                    120: .FE
                    121: This would make it impossible for the program to begin by prompting
                    122: for input or printing a herald.
                    123: .PP
                    124: .UP
                    125: has been designed so that an initial read is not necessary.
                    126: At any given time, the Pascal system may or may not know whether the
                    127: end-of-file or end-of-line conditions are true.
                    128: Thus, internally, these functions can have three values \-
                    129: true, false, and ``I don't know yet; if you ask me I'll have to
                    130: find out''.
                    131: All files remain in this last, indeterminate state until the Pascal
                    132: program requires a value for
                    133: .I eof
                    134: or
                    135: .I eoln
                    136: either explicitly or implicitly, e.g. in a call to
                    137: .I read .
                    138: The important point to note here is that if you force the Pascal
                    139: system to determine whether the input is at the end-of-file or the end-of-line,
                    140: it will be necessary for it to attempt to read from the input.
                    141: .PP
                    142: Thus consider the following example code
                    143: .LS
                    144: \*bwhile not\fP eof \*bdo\fP \*bbegin\fP
                    145:     write('number, please? ');
                    146:     read(i);
                    147:     writeln('that was a ', i: 2)
                    148: \*bend\fP
                    149: .LE
                    150: At first glance, this may be appear to be a correct program
                    151: for requesting, reading and echoing numbers.
                    152: Notice, however, that the
                    153: .B while
                    154: loop asks whether
                    155: .I eof
                    156: is true
                    157: .I before
                    158: the request is printed.
                    159: This will force the Pascal system to decide whether the input is at the
                    160: end-of-file.
                    161: The Pascal system will give no messages;
                    162: it will simply wait for the user to type a line.
                    163: By producing the desired prompting before testing
                    164: .I eof,
                    165: the following code avoids this problem:
                    166: .LS
                    167: write('number, please ?');
                    168: \*bwhile not\fP eof \*bdo\fP \*bbegin\fP
                    169:     read(i);
                    170:     writeln('that was a ', i:2);
                    171:     write('number, please ?')
                    172: \*bend\fP
                    173: .LE
                    174: The user must still type a line before the
                    175: .B while
                    176: test is completed, but the prompt will ask for it.
                    177: This example, however, is still not correct.
                    178: To understand why, it is first necessary to know, as we will discuss below,
                    179: that there is a blank character at the end of each line in a Pascal text
                    180: file.
                    181: The
                    182: .I read
                    183: procedure, when reading integers or real numbers,
                    184: is defined so that,
                    185: if there are only blanks left in the file,
                    186: it will return a zero value and set the end-of-file condition.
                    187: If, however, there is a number remaining in the file, the end-of-file
                    188: condition will not be set even if it is the last number, as
                    189: .I read
                    190: never reads the blanks after the number, and there is always at least
                    191: one blank.
                    192: Thus the modified code will still put out a spurious
                    193: .LS
                    194: that was a 0
                    195: .LE
                    196: at the end of a session with it when the end-of-file is reached.
                    197: The simplest way to correct the problem in this example is to use the procedure
                    198: .I readln
                    199: instead of
                    200: .I read
                    201: here.
                    202: In general, unless we test the end-of-file condition both before and
                    203: after calls to
                    204: .I read
                    205: or
                    206: .I readln ,
                    207: there will be inputs for which our program will attempt
                    208: to read past end-of-file.
                    209: .NH 2
                    210: More about eoln
                    211: .PP
                    212: To have a good understanding of when
                    213: .I eoln
                    214: will be true it is necessary to know that in any file
                    215: there is a special character indicating end-of-line,
                    216: and that, in effect, the Pascal system always reads one character ahead of the 
                    217: Pascal
                    218: .I read
                    219: commands.\*(dg
                    220: .FS
                    221: \*(dgIn Pascal terms,
                    222: `read(ch)'
                    223: corresponds to
                    224: `ch := input^; get(input)'
                    225: .FE
                    226: For instance,
                    227: in response to `read(ch)',
                    228: the system sets
                    229: .I ch
                    230: to the current input character and gets the next input character.
                    231: If the current input character is the last character of the line,
                    232: then the next input character from the file is the new-line character,
                    233: the normal
                    234: .UX
                    235: line separator.
                    236: When the read routine gets the new-line character,
                    237: it replaces that character by a blank
                    238: (causing every line to end with a blank)
                    239: and sets
                    240: .I eoln
                    241: to true.
                    242: .I Eoln
                    243: will be true as soon as we read the last character of the line and
                    244: .B before
                    245: we read the blank character corresponding to the end of line.
                    246: Thus it is almost always a mistake to write a program which deals with
                    247: input in the following way:
                    248: .LS
                    249: read(ch);
                    250: \*bif\fP eoln \*bthen\fP
                    251:     \fIDone with line\fP
                    252: \*belse\fP
                    253:     \fINormal processing\fP
                    254: .LE
                    255: as this will almost surely have the effect of ignoring the last character
                    256: in the line.
                    257: The `read(ch)' belongs as part of the normal processing.
                    258: .PP
                    259: Given this framework, it is not hard to explain the function of a
                    260: .I readln
                    261: call, which is defined as:
                    262: .LS
                    263: \*bwhile not\fP eoln \*bdo\fP
                    264:     get(input);
                    265: get(input);
                    266: .LE
                    267: This advances the file until the blank corresponding to the end-of-line
                    268: is the current input symbol and then discards this blank.
                    269: The next character available from
                    270: .I read
                    271: will therefore be the first character of the next line,
                    272: if one exists.
                    273: .NH 2
                    274: Output buffering
                    275: .PP
                    276: A final point about Pascal input-output must be noted here.
                    277: This concerns the buffering of the file
                    278: .I output .
                    279: It is extremely inefficient for the Pascal system to send each character
                    280: to the user's terminal as the program generates it for output;
                    281: even less efficient if the output is the input of another
                    282: program such as the line printer daemon
                    283: .I lpr
                    284: (1).
                    285: To gain efficiency, the Pascal system ``buffers'' the output characters
                    286: (i.e. it saves them in memory until the buffer is full and then emits
                    287: the entire buffer in one system interaction.)
                    288: However, to allow interactive prompting to work as in the example given
                    289: above, this prompt must be printed before the Pascal system waits for a
                    290: response.
                    291: For this reason, Pascal normally prints all the output which has
                    292: been generated for the file
                    293: .I output
                    294: whenever
                    295: .HP
                    296: .RS
                    297: .IP 1)
                    298: A
                    299: .I writeln
                    300: occurs, or
                    301: .IP 2)
                    302: The program reads from the terminal, or
                    303: .IP 3)
                    304: The procedure
                    305: .I message
                    306: or
                    307: .I flush
                    308: is called.
                    309: .RE
                    310: .LP
                    311: Thus, in the code sequence
                    312: .ne 5
                    313: .LS
                    314: \*bfor\fP i := 1 to 5 \*bdo begin\fP
                    315:     write(i: 2);
                    316:     \fICompute a lot with no output\fP
                    317: \*bend;\fP
                    318: writeln
                    319: .LE
                    320: the output integers will not print until the
                    321: .I writeln
                    322: occurs.
                    323: The delay can be somewhat disconcerting, and you should be aware 
                    324: that it will occur.
                    325: By setting the
                    326: .B b
                    327: option to 0 before the
                    328: .B program
                    329: statement by inserting a comment of the form
                    330: .LS
                    331: (*$b0*)
                    332: .LE
                    333: we can cause
                    334: .I output
                    335: to be completely unbuffered, with a corresponding horrendous degradation
                    336: in program efficiency.
                    337: Option control in comments is discussed in section 5.
                    338: .NH 2
                    339: Files, reset, and rewrite
                    340: .PP
                    341: It is possible to use extended forms of the built-in functions
                    342: .I reset
                    343: and
                    344: .I rewrite
                    345: to get more general associations of
                    346: .UX
                    347: file names with Pascal file variables.
                    348: When a file other than
                    349: .I input
                    350: or
                    351: .I output
                    352: is to be read or written, then the reading or writing must be preceded
                    353: by a
                    354: .I reset
                    355: or
                    356: .I rewrite
                    357: call.
                    358: In general, if the Pascal file variable has never been used before,
                    359: there will be no
                    360: .UX
                    361: filename associated with it.
                    362: As we saw in section 2.9,
                    363: by mentioning the file in the
                    364: .B program
                    365: statement,
                    366: we could cause a
                    367: .UX
                    368: file with the same name as the Pascal variable to be associated with it.
                    369: If we do not mention a file in the
                    370: .B program
                    371: statement and use it for the first time with the statement
                    372: .LS
                    373: reset(f)
                    374: .LE
                    375: or
                    376: .LS
                    377: rewrite(f)
                    378: .LE
                    379: then the Pascal system will generate a temporary name of the form
                    380: `tmp.x'
                    381: for some character `x',
                    382: and associate this
                    383: .UX
                    384: file name name with the Pascal file.
                    385: The first such generated name will be `tmp.1'
                    386: and the names continue by incrementing their last character through the
                    387: .SM ASCII
                    388: set.
                    389: The advantage of using such temporary files is that they are automatically
                    390: .I remove d
                    391: by the Pascal system as soon as they become inaccessible.
                    392: They are not removed, however, if a runtime error causes termination
                    393: while they are in scope.
                    394: .PP
                    395: To cause a particular
                    396: .UX
                    397: pathname to be associated with a Pascal file variable
                    398: we can give that name in the
                    399: .I reset
                    400: or
                    401: .I rewrite
                    402: call, e.g. we could have associated the Pascal file
                    403: .I data
                    404: with the file
                    405: `primes'
                    406: in our example in section 3.1 by doing:
                    407: .LS
                    408: reset(data, 'primes')
                    409: .LE
                    410: instead of a simple
                    411: .LS
                    412: reset(data)
                    413: .LE
                    414: In this case it is not essential to mention `data'
                    415: in the program statement, but it is still a good idea
                    416: because is serves as an aid to program documentation.
                    417: The second parameter to
                    418: .I reset
                    419: and
                    420: .I rewrite
                    421: may be any string value, including a variable.
                    422: Thus the names of 
                    423: .UX
                    424: files to be associated with Pascal file variables can be read
                    425: in at run time.
                    426: Full details on file name/file variable associations are given in
                    427: section A.3.
                    428: .NH 2
                    429: Argc and argv
                    430: .PP
                    431: Each
                    432: .UX
                    433: process receives a variable
                    434: length sequence of arguments each of which is a variable length
                    435: character string.
                    436: The built-in function
                    437: .I argc
                    438: and the built-in procedure
                    439: .I argv
                    440: can be used to access and process these arguments.
                    441: The value of the function
                    442: .I argc
                    443: is the number of arguments to the process.
                    444: By convention,
                    445: the arguments are treated as an array,
                    446: and indexed from 0 to
                    447: .I argc \-1,
                    448: with the zeroth argument being the name of the program being executed.
                    449: The rest of the
                    450: arguments are those passed to the command on the command line.
                    451: Thus, the command
                    452: .LS
                    453: % \*bobj  /etc/motd  /usr/dict/words hello\fR
                    454: .LE
                    455: will invoke the program in the file
                    456: .I obj
                    457: with
                    458: .I argc
                    459: having a value of 4.
                    460: The zeroth element accessed by
                    461: .I argv
                    462: will be `obj', the first `/etc/motd', etc.
                    463: .PP
                    464: Pascal does not provide variable size arrays, nor does it allow
                    465: character strings of varying length.
                    466: For this reason,
                    467: .I argv
                    468: is a procedure and has the syntax
                    469: .LS
                    470: argv(i, a)
                    471: .LE
                    472: where
                    473: .I i
                    474: is an integer and
                    475: .I a
                    476: is a string variable.
                    477: This procedure call assigns the (possibly truncated or blank padded)
                    478: .I i \|'th
                    479: argument of the current process to the string variable
                    480: .I a .
                    481: The file manipulation routines
                    482: .I reset
                    483: and
                    484: .I rewrite
                    485: will strip trailing blanks from their optional second arguments
                    486: so that this blank padding is not a problem in the usual case
                    487: where the arguments are file names.
                    488: .PP
                    489: We are now ready to give a
                    490: Berkeley
                    491: Pascal program `kat',
                    492: based on that given in section 3.1 above,
                    493: which can be used with the same syntax as the
                    494: .UX
                    495: system program
                    496: .I cat
                    497: (1).
                    498: .LS
                    499: % \*bcat kat.p\fR
                    500: .so kat3.p
                    501: %
                    502: .LE
                    503: Note that the
                    504: .I reset
                    505: call to the file
                    506: .I input
                    507: here, which is necessary for a clear program,
                    508: may be disallowed on other systems.
                    509: As this program deals mostly with
                    510: .I argc
                    511: and
                    512: .I argv
                    513: and
                    514: .UX
                    515: system dependent considerations,
                    516: portability is of little concern.
                    517: .PP
                    518: If this program is in the file `kat.p', then we can do
                    519: .LS
                    520: % \*bpi kat.p\fR
                    521: % \*bmv obj kat\fR
                    522: % \*bkat primes\fR
                    523: .so kat2out
                    524: % \*bkat\fR
                    525: .so katscript
                    526: %
                    527: .LE
                    528: Thus we see that, if it is given arguments, `kat' will,
                    529: like
                    530: .I cat,
                    531: copy each one in turn.
                    532: If no arguments are given, it copies from the standard input.
                    533: Thus it will work as it did before, with
                    534: .LS
                    535: % \*bkat < primes\fR
                    536: .LE
                    537: now equivalent to
                    538: .LS
                    539: % \*bkat primes\fR
                    540: .LE
                    541: although the mechanisms are quite different in the two cases.
                    542: Note that if `kat' is given a bad file name, for example:
                    543: .LS
                    544: % \*bkat xxxxqqq\fR
                    545: .so xxxxqqqout
                    546: %
                    547: .LE
                    548: it will give a diagnostic and a post-mortem control flow backtrace
                    549: for debugging.
                    550: If we were going to use `kat', we might want to translate it
                    551: differently, e.g.:
                    552: .LS
                    553: % \*bpi -pb kat.p\fR
                    554: % \*bmv obj kat\fR
                    555: .LE
                    556: Here we have disabled the post-mortem statistics printing, so
                    557: as not to get the statistics or the full traceback on error.
                    558: The
                    559: .B b
                    560: option will cause the system to block buffer the input/output so that
                    561: the program will run more efficiently on large files.
                    562: We could have also specified the
                    563: .B t
                    564: option to turn off runtime tests if that was felt to be a speed hindrance
                    565: to the program.
                    566: Thus we can try the last examples again:
                    567: .LS
                    568: % \*bkat xxxxqqq\fR
                    569: .so xxxxqqqout2
                    570: % \*bkat primes\fR
                    571: .so primes-d
                    572: %
                    573: .LE
                    574: .PP
                    575: The interested reader may wish to try writing a program which
                    576: accepts command line arguments like
                    577: .PI
                    578: does, using
                    579: .I argc
                    580: and
                    581: .I argv
                    582: to process them.

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.