Annotation of 43BSDReno/share/doc/ps1/04.pascal/puman4.n, revision 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.