home *** CD-ROM | disk | FTP | other *** search
- Path: j.cc.purdue.edu!mentor.cc.purdue.edu!purdue!bu.edu!att!linac!pacific.mps.ohio-state.edu!zaphod.mps.ohio-state.edu!wuarchive!uunet!papaya.bbn.com!rsalz
- From: rsalz@bbn.com (Rich Salz)
- Newsgroups: comp.sources.unix
- Subject: v23i057: Line oriented macro processor, Part07/09
- Message-ID: <3032@litchi.bbn.com>
- Date: 29 Nov 90 17:44:15 GMT
- Organization: BBN Systems and Technologies, Cambridge MA
- Lines: 1836
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Darren New <new@ee.udel.edu>
- Posting-number: Volume 23, Issue 57
- Archive-name: lome/part07
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 6 (of 9)."
- # Contents: LOME/LOME.scm LOME/SCMTestP.scm PPL/PPL.doc TFS/TFSUnix.c
- # Wrapped by new@estelle.ee.udel.edu on Tue Aug 14 16:10:01 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'LOME/LOME.scm' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'LOME/LOME.scm'\"
- else
- echo shar: Extracting \"'LOME/LOME.scm'\" \(9447 characters\)
- sed "s/^X//" >'LOME/LOME.scm' <<'END_OF_FILE'
- XFILE: LOME.scm
- XThis is the SCM source file for the LOME program.
- X THIS IS NOT COMPLETE AND PROBABLY WON'T BE FOR SOME TIME!
- X I'LL PROBABLY FINISH THIS ONLY WHEN I FIND A MACHINE WHERE I NEED LOME
- X WHICH DOESN'T HAVE A REASONABLE C COMPILER. AND PROBABLY NOT THEN
- X EITHER.
- X
- XBEGIN PROGRAM
- XBEGIN MAIN ROUTINE
- X
- X. The following parameters may be changed to allow larger or smaller progs.
- X
- XNUMDATA 01 0 00 30. Allow up to thirty pushes on the user stack.
- XNUMDATA 02 0 00 15. Allow up to fifteen nested macros.
- XNUMDATA 10 0 03 00. Start output on stream 3.
- X
- X. The data near the bottom of the cell-space is organised thus:
- X. PTR[01] = number of pushes to user stack
- X. PTR[02] = number of nested macros
- X. PTR[05] = bottom of user-managed stack
- X. PTR[06] = first address past user-managed stack
- X. = bottom of macro call stack.
- X. PTR[07] = first address past macro call stack
- X. = address of first macro.
- X. PTR[08] = first address past last macro
- X. = beginning of dynamically allocated memory
- X. PTR[10] = root of dictionary tree.
- X. VAL[10] = current output stream
- X. VAL[11] = macro input stream
- X. PTR[11] = head of free space chain
- X. PTR[12] = head of input stream stack (stream #'s in VAL's)
- X. VAL[20] to VAL[49] = parameter line.
- X
- X
- X
- X
- X. Here we read the initial macro definition file until we get a
- X. blank line or an EOF
- X
- XLABEL 01. Read next line of MDef file
- XVAL A = 1 + 0.
- XGET BUFF A.
- XTO 03 IF FLG A EQ 0.
- XLABEL 02. Many places go to here to issue error
- XPTR B = 6 + 0. really 10
- XGET B = MEM B. get current output stream
- XMESSAGE UEOF TO B.
- XSTOP A.
- XLABEL 03. See if empty line
- XVAL A = INPUT.
- XTO 01 IF VAL A NE 0.
- X
- X. Here we have found the first blank line. Read the next line and
- X. store its contents in the val fields at offsets 20 thru 49
- X
- XVAL A = 1 + 0.
- XGET BUFF A.
- XTO 02 IF FLG A NE 0.
- XPTR B = 3 * 6. We expect 30 characters.
- XVAL B = PTR B. We need PTR B below.
- XPTR A = 2 * 6. Which is really 20.
- XPTR B = 8 + 0. Which is mem[0].
- XMOV PTR B BY A. Which is mem[20].
- XLABEL 04. read next char of parameter line
- XVAL A = INPUT.
- XTO 05 IF VAL A EQ 0.
- XPTR A = 0 + 0.
- XFLG A = 0.
- XPUT MEM B = A.
- XMOV PTR B BY 1.
- XVAL B = B - 1.
- XTO 04.
- XLABEL 05. found end of parameter line
- XTO 02 IF VAL B NE 0. Issue UEOF for parameter line wrong length
- XFLG B = 0.
- XPTR A = 8 + 0. Which is mem[0]
- XMOV PTR A BY 5. See start of code
- XMOV PTR A BY 2. Pointing at mem[7]
- XPUT MEM A = B. Store pointer to start of macros
- X
- X
- X
- X. At this point, we are ready to start reading macro bodies.
- X. The macros are stored in contiguous memory locations.
- X. At this point in the code, PTR B points to the place to start
- X. storing the macro definitions.
- X. The first cell of each macro contains:
- X. VAL = number of chars in the header minus placeholders and EOL
- X. = minimum length of line which will match this header.
- X. PTR = address of this cell in the next macro.
- X. ??? FLG = 0 if more macros after this, 1 if not (PTR not valid).
- X. This is followed by the text of the header line, processed.
- X. The escape characters have been removed and any BEOL and comment have
- X. been removed. Each FLG field is one of
- X. FLG = 0 for a normal or escaped character,
- X. FLG = 1 for a placeholder character, or
- X. FLG = 2 for end-of-line (BEOL or real EOL).
- X. PTR = ??????????????
- X. The header line is followed by the macro body lines.
- X. FLG = 0 if the VAL should be inserted into the constructed line
- X. FLG = 1 if the VAL contains 0 - 9 as a function number and PTR
- X. contains 0 - 11 (0-9,C,F).
- X. FLG = 2 if the VAL contains 0 for EOL.
- X. FLG = 3 if the FLG=2 cell immediately before this was the last line
- X. of this macro body.
- X. PTR = ??????????????
- X
- XPTR A = 2 * 6.
- XPTR C = 8 + 0.
- XMOV PTR C BY A. Point to parameter line
- XGET E = MEM C. VAL E = escape character
- XMOV PTR C BY 1.
- XGET F = MEM C. VAL F = placeholder character
- XMOV PTR C BY 1.
- XGET G = MEM C. VAL G = HEOL character
- XMOV PTR C BY 3.
- XGET H = MEM C. VAL H = digit zero
- XMOV PTR C BY 6. C points to param[16]
- XMOV PTR C BY 4. C points to param[20]
- XGET I = MEM C. VAL I = space character
- XMOV PTR C BY 2.
- XGET J = MEM C.
- XVAL J = J - H. VAL J = 0 discard blank lines, = 1 keep blank lines
- XMOV PTR C BY 1.
- XGET K = MEM C.
- XVAL K = K - H. VAL K = 0 discard leading space, = 1 keep leading space
- X
- XPTR A = 2 * 6.
- XPTR C = 8 + 0.
- XMOV PTR C BY A. Point to parameter line
- XMOV PTR C BY 3.
- XGET L = MEM C. VAL L = substitution character
- XMOV PTR C BY 1.
- XGET M = MEM C. VAL M = BEOL character
- XMOV PTR C BY 5.
- XGET N = MEM C. VAL N = file operation character
- XMOV PTR C BY 1.
- XGET O = MEM C. VAL O = control operation character
- X
- X. Here we use
- X. PTR B to point to the start of the macro header,
- X. VAL B to hold the min length of matching line,
- X. VAL C to hold number of chars added to line so far,
- X. PTR C to point to the current location,
- X. VAL A to hold input character,
- X. REG D to hold built cell to be stored,
- X
- XLABEL 06. Read next macro header line
- XDEBUG.
- XPTR C = B + 0.
- XVAL B = 0 + 0.
- XVAL C = 0 + 0.
- XVAL A = 1 + 0.
- XGET BUFF A.
- XTO 22 IF FLG A NE 0. @$@$ CHANGE THIS TO READ SOURCES
- XVAL D = 0 + 0.
- XFLG D = 0.
- XPTR D = 0 + 0.
- XPUT MEM C = D.
- XMOV PTR C BY 1.
- XTO 98 IF PTR C EQ 9. full memory?
- X
- XLABEL 07. process next char of macro header
- XVAL A = INPUT.
- XTO 08 IF VAL K NE 0. if leading space not being discarded
- XTO 08 IF VAL A NE I. if char read was not space
- XTO 08 IF VAL C NE 0. if other characters are on the line
- XTO 07. skip this character
- XLABEL 08. not a leading space to be discarded
- XTO 10 IF VAL A NE E. if input not an escape character
- XVAL A = INPUT. it was an escape, so read next char
- XTO 11 IF VAL A EQ 0. but at end of line, so ignore it
- XLABEL 09. go here to add a regular character
- XVAL D = A + 0. set up cell to match normal character
- XFLG D = 0. normal char
- XPTR D = B + 0. point back to beginning of header
- XPUT MEM C = D. store it
- XMOV PTR C BY 1. bump pointer
- XTO 98 IF PTR C EQ 9. full memory?
- XVAL B = B + 1. need to match it
- XVAL C = C + 1. stored it.
- XTO 07.
- XLABEL 10. input not an escape char
- XTO 11 IF VAL A EQ G. if HEOL found
- XTO 11 IF VAL A EQ 0. if EOL found
- XTO 09 IF VAL A NE F. jump if not placeholder char
- XVAL D = A + 0.
- XFLG D = 1. placeholder character
- XPTR D = B + 0. point back to header
- XPUT MEM C = D. store it
- XMOV PTR C BY 1. bump pointer
- XTO 98 IF PTR C EQ 9. full memory?
- XVAL C = C + 1. stored it.
- XTO 07.
- XLABEL 11. end of macro header line found.
- XVAL D = 0 + 0.
- XFLG D = 2.
- XPTR D = B + 0.
- XPUT MEM C = D.
- XMOV PTR C BY 1.
- XTO 98 IF PTR C EQ 9. full memory?
- X
- X. Now we must read in the macro body, stoping when we get two BEOLs at
- X. the start of a line.
- X
- XLABEL 12. to here to read macro body line.
- X. PTR B still header, PTR C still next free
- XVAL A = 1 + 0.
- XGET BUFF A.
- XTO 02 IF FLG A NE 0.
- XVAL C = 0 + 0. to count chars on line
- XLABEL 13. to here for each char of macro body line
- XVAL A = INPUT.
- XFLG D = 0. assume normal char until known otherwise
- XVAL D = A + 0.
- XPTR D = 0 + 0.
- XTO 20 IF VAL A EQ 0. if end of line
- XTO 19 IF VAL A EQ M. if BEOL
- XTO 15 IF VAL A NE E. if not escape
- XVAL A = INPUT.
- XVAL D = A + 0.
- XTO 20 IF VAL A EQ 0. escape, then EOL
- XLABEL 14. insert D into macro body line
- XPUT MEM C = D.
- XMOV PTR C BY 1.
- XTO 98 IF PTR C EQ 9. full memory?
- XVAL C = C + 1.
- XTO 13.
- XLABEL 15. not escape or EOL or BEOL
- XTO 14 IF VAL A NE L. if not substitution char, insert it
- XVAL A = INPUT. get next char
- XTO 16 IF VAL A NE O. if not control operation character
- XVAL D = 9 + 2. 11 means control operation
- XTO 18.
- XLABEL 16. substitution, but not control op
- XTO 17 IF VAL A NE N. if not file operation character
- XVAL D = 9 + 1. 10 means file operation
- XTO 18.
- XLABEL 17. substitution, but not control op or file op
- XVAL D = A - H. D = 0..9 (H is '0')
- XLABEL 18. finish building substitution cell
- XPTR D = VAL D. so we can do LT comparisons
- XTO 97 IF PTR D LT 0. issue SUBS error if too small
- XPTR A = 6 + 1. set PTR A to 11
- XTO 97 IF PTR A LT D. issue SUBS error if too big
- XVAL A = INPUT. read individual code
- XVAL D = A - H. convert individual code to 0..9
- XFLG D = 1. substitution flag
- XTO 14. go insert it
- XLABEL 19. found an unescaped BEOL
- XTO 20 IF VAL C NE 0. not at start of line, so treat as normal EOL
- XVAL A = INPUT. see if followed by another BEOL
- XTO 20 IF VAL A NE M. nope, handle as normal EOL
- XFLG D = 3. mark end of macro (for skip -1)
- XPUT MEM C = D.
- XMOV PTR C BY 1.
- XTO 98 IF PTR C EQ 9. full memory?
- XFLG D = 0.
- XVAL D = 0 + 0.
- XPTR D = C + 0.
- XPUT MEM B = D. store forward pointer
- XPTR B = C + 0. and skip forward
- XPTR C = 8 + 0. point C at mem[7].
- XMOV PTR C BY 5.
- XMOV PTR C BY 2.
- XVAL B = 0 + 0.
- XFLG B = 0.
- XPUT MEM C = B. point end-of-macro pointer here.
- XTO 06. read next macro header
- X
- XLABEL 20. insert end-of-line marker if appropriate
- XTO 21 IF VAL C NE 0. if anything on line,
- XTO 21 IF VAL J EQ 1. or we want to keep blank lines
- XTO 12. otherwise forget it.
- XLABEL 21. insert end-of-line marker
- XFLG D = 2. insert EOL character
- XVAL D = 0 + 0.
- XPTR D = 0 + 0.
- XPUT MEM C = D.
- XMOV PTR C BY 1.
- XVAL C = C + 1. keep track of chars on line
- XTO 98 IF PTR C EQ 9. full memory?
- XTO 12. read next line
- X
- XLABEL 22. go here to read and translate source file.
- XDEBUG. dump memory for inspection
- XTO 99.
- X
- XLABEL 97. output a SUBS message to current output stream
- XPTR A = 6 + 0.
- XGET A = MEM A.
- XMESSAGE SUBS TO A.
- XSTOP A.
- X
- XLABEL 98. output a FULL message to current output stream
- XPTR A = 6 + 0. really 10
- XGET A = MEM A. get current output stream
- XMESSAGE FULL TO A.
- XSTOP A.
- X
- XLABEL 99.
- X
- XEND MAIN ROUTINE
- XEND PROGRAM
- X
- X
- END_OF_FILE
- if test 9447 -ne `wc -c <'LOME/LOME.scm'`; then
- echo shar: \"'LOME/LOME.scm'\" unpacked with wrong size!
- fi
- # end of 'LOME/LOME.scm'
- fi
- if test -f 'LOME/SCMTestP.scm' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'LOME/SCMTestP.scm'\"
- else
- echo shar: Extracting \"'LOME/SCMTestP.scm'\" \(9624 characters\)
- sed "s/^X//" >'LOME/SCMTestP.scm' <<'END_OF_FILE'
- XThis is a test program to make sure that your SCM macros are correct. It
- Xshould be compiled and executed. Execute it with SCMTestD on stream one.
- XOutput to stream two will consist of error messages and explainations. It
- Xuses a brute-force approach to testing the macros: it reads a line from the
- Xinput file that contains an error message, it checks that an operation had
- Xan intended effect, and if it does, it skips past code that outputs the
- Xline that was read. You should make sure that the I/O routines work first.
- XAlso, check manually that BEGIN PROGRAM, BEGIN MAIN ROUTINE, END PROGRAM,
- Xand END MAIN ROUTINE do what you want. Also, BEGIN SUBROUTINE and END
- XSUBROUTINE should be checked manually.
- X
- XBEGIN PROGRAM.
- X
- XBEGIN SUBROUTINE F.
- XVAL B = 1 + 0.
- XGET BUFF B. 4
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XEND SUBROUTINE F.
- X
- XBEGIN SUBROUTINE S.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 002
- XTO 03 IF FLG 1 EQ 1.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 03.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 003
- XTO 05 IF FLG 1 EQ 2.
- XTO 04.
- XLABEL 05.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 04.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 004
- XTO 06 IF FLG 1 NE 1.
- XTO 07.
- XLABEL 06.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 07.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 005
- XTO 08 IF FLG 1 NE 2.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 08.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 006
- XTO 09 IF VAL 1 EQ 1.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 09.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 007
- XTO 10 IF VAL 1 EQ 2.
- XTO 11.
- XLABEL 10.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 11.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 008
- XTO 12 IF VAL 1 NE 1.
- XTO 13.
- XLABEL 12.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 13.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 009
- XTO 14 IF VAL 1 NE 2.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 14.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 010
- XTO 15 IF PTR 1 EQ 1.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 15.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 011
- XTO 16 IF PTR 1 EQ 2.
- XTO 17.
- XLABEL 16.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 17.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 012
- XTO 18 IF PTR 1 NE 1.
- XTO 19.
- XLABEL 18.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 19.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 013
- XTO 20 IF PTR 1 NE 2.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 20.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 014
- XTO 21 IF PTR 1 LT 2.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 21.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 015
- XTO 22 IF PTR 2 LT 1.
- XTO 23.
- XLABEL 22.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 23.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 016
- XTO 24 IF PTR 1 LT 1.
- XTO 25.
- XLABEL 24.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 25.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 017
- XFLG A = 1.
- XTO 26 IF FLG A EQ 1.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 26.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 018
- XVAL A = PTR 3.
- XTO 27 IF VAL A EQ 3.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 27.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 019
- XPTR A = VAL 2.
- XTO 28 IF PTR A EQ 2.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 28.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 020
- XFLG A = 1.
- XVAL A = 2 + 0.
- XPTR A = VAL 3.
- XTO 29 IF FLG A EQ 1.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 29.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 021
- XTO 30 IF VAL A EQ 2.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 30.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 022
- XFLG A = 1.
- XPTR A = 2 + 0.
- XVAL A = PTR 3.
- XTO 31 IF FLG A EQ 1.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 31.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 023
- XTO 32 IF PTR A EQ 2.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 32.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 024
- XFLG A = 1.
- XPTR A = 3 + 0.
- XVAL A = 2 + 0.
- XFLG A = 0.
- XTO 33 IF VAL A EQ 2.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 33.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 025
- XTO 34 IF PTR A EQ 3.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 34.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 026
- XFLG E = 0.
- XPTR E = VAL 0.
- XVAL E = 1 + 3.
- XTO 35 IF VAL E EQ 4.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 35.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 027
- XTO 36 IF PTR E EQ 0.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 36.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 028
- XTO 37 IF FLG E EQ 0.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 37.
- X
- XEND SUBROUTINE S.
- X
- XBEGIN SUBROUTINE Q.
- XVAL B = 1 + 0.
- XGET BUFF B. X 032
- XFLG A = 0.
- XVAL A = 0 + 0.
- XPTR A = 1 + 2.
- XTO 41 IF FLG A EQ 0.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 41.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 033
- XTO 42 IF VAL A EQ 0.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 42.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 034
- XTO 43 IF PTR A EQ 3.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 43.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 035
- XVAL A = 0 + 0.
- XFLG A = 0.
- XPTR A = 1 - 3.
- XTO 44 IF FLG A EQ 0.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 44.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 036
- XTO 45 IF VAL A EQ 0.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 45.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 037
- XPTR A = A + 3.
- XTO 46 IF PTR A EQ 1.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 46.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 038
- XPTR A = 0 + 0.
- XFLG A = 0.
- XVAL A = 1 - 3.
- XTO 47 IF FLG A EQ 0.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 47.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 039
- XTO 48 IF PTR A EQ 0.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 48.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 040
- XVAL A = A + 3.
- XTO 49 IF VAL A EQ 1.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 49.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 041
- XVAL A = 0 + 0.
- XFLG A = 0.
- XPTR A = 3 * 3.
- XPTR D = VAL 9.
- XTO 50 IF PTR A EQ D.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 50.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 042
- XTO 51 IF VAL A EQ 0.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 51.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 043
- XTO 52 IF FLG A EQ 0.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 52.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 044
- XVAL C = 0 + 0.
- XFLG C = 0.
- XPTR A = VAL 6.
- XPTR C = A / 2.
- XTO 53 IF PTR C EQ 3.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 53.
- X
- XEND SUBROUTINE Q.
- X
- XBEGIN SUBROUTINE R.
- X
- XCALL Q. make sure nested calls work
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 045
- XTO 54 IF VAL C EQ 0.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 54.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 046
- XTO 55 IF VAL C EQ 0.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 55.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 047
- XPTR A = VAL 7.
- XPTR C = A / 2.
- XTO 56 IF PTR C EQ 3.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 56.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 048
- XPTR A = VAL 7.
- XPTR A = 0 - A.
- XPTR C = A / 2.
- XPTR C = 0 - C.
- XTO 57 IF PTR C EQ 3.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 57.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 049
- XPTR A = VAL 7.
- XPTR D = 0 - 2.
- XPTR C = A / D.
- XPTR C = 0 - C.
- XTO 58 IF PTR C EQ 3.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 58.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 050
- XPTR A = VAL 7.
- XPTR A = 0 - A.
- XPTR D = 0 - 2.
- XPTR C = A / D.
- XTO 59 IF PTR C EQ 3.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 59.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 051
- XPTR D = VAL 4.
- XPTR A = 0 - 2.
- XPTR C = 2 * A.
- XPTR C = 0 - C.
- XTO 60 IF PTR C EQ D.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 60.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 052
- XPTR D = VAL 4.
- XPTR A = 0 - 2.
- XPTR C = A * 2.
- XPTR C = 0 - C.
- XTO 61 IF PTR C EQ D.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 61.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 053
- XPTR D = VAL 4.
- XPTR A = 0 - 2.
- XPTR C = A * A.
- XTO 62 IF PTR C EQ D.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 62.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 054
- XVAL C = 0 - 6.
- XTO 63 IF VAL C EQ 6.
- XTO 64.
- XLABEL 63.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 64.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 055
- XTO 65 IF VAL C NE 6.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 65.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 056
- XPTR C = 0 - 3.
- XTO 66 IF PTR C EQ 3.
- XTO 67.
- XLABEL 66.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 67.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 057
- XTO 68 IF PTR C NE 3.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 68.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 058
- XTO 69 IF PTR C LT 3.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 69.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 059
- XTO 70 IF PTR 3 LT C.
- XTO 71.
- XLABEL 70.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 71.
- X
- XEND SUBROUTINE R.
- X
- X
- XBEGIN MAIN ROUTINE.
- XVAL B = 1 + 0.
- XGET BUFF B. 1
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XVAL B = 1 + 0.
- XGET BUFF B. 2
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XVAL B = 1 + 0.
- XGET BUFF B. 3
- XVAL W = 2 + 0.
- XPUT BUFF W.
- X
- XCALL F.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. X 001
- XTO 02.
- XLABEL 01.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 02.
- X
- XCALL S.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. 5
- XVAL W = 2 + 0.
- XPUT BUFF W.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. 6
- XVAL D = INPUT. '6'
- XVAL E = INPUT. '.'
- XVAL F = INPUT. ' '
- XVAL G = INPUT. 'D'
- XVAL H = INPUT. 'O'
- XVAL I = INPUT. 'G'
- XVAL J = INPUT. eol
- XVAL B = 1 + 0.
- XGET BUFF B. X 029
- XTO 38 IF VAL J EQ 0.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 38.
- X
- XOUTPUT = VAL D. '6'
- XOUTPUT = VAL E. '.'
- XOUTPUT = VAL F. ' '
- XOUTPUT = VAL I. 'G'
- XOUTPUT = VAL H. 'O'
- XOUTPUT = VAL H. 'O'
- XOUTPUT = VAL G. 'D'
- XOUTPUT = VAL J. eol
- XVAL W = 2 + 0.
- XPUT BUFF W.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. 7
- XVAL W = 2 + 0.
- XPUT BUFF W.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. 8
- XVAL D = INPUT. '7'
- XVAL E = INPUT. '.'
- XVAL F = INPUT. ' '
- XVAL G = INPUT. '0'
- XVAL H = INPUT. eol
- XVAL B = 1 + 0.
- XGET BUFF B. X 030
- XTO 39 IF VAL H EQ 0.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 39.
- X
- XOUTPUT = VAL D. '7'
- XOUTPUT = VAL E. '.'
- XOUTPUT = VAL F. ' '
- XVAL J = G + 0.
- XOUTPUT = VAL J. '0'
- XOUTPUT = VAL F. ' '
- XVAL J = G + 1.
- XOUTPUT = VAL J. '1'
- XOUTPUT = VAL F.
- XVAL J = G + 2.
- XOUTPUT = VAL J. '2'
- XOUTPUT = VAL F.
- XVAL J = G + 3.
- XOUTPUT = VAL J. '3'
- XOUTPUT = VAL F.
- XVAL J = G + 4.
- XOUTPUT = VAL J. '4'
- XOUTPUT = VAL F.
- XVAL J = G + 5.
- XOUTPUT = VAL J. '5'
- XOUTPUT = VAL F.
- XVAL J = G + 6.
- XOUTPUT = VAL J. '6'
- XOUTPUT = VAL F.
- XVAL J = G + 7.
- XOUTPUT = VAL J. '7'
- XOUTPUT = VAL F.
- XVAL J = G + 8.
- XOUTPUT = VAL J. '8'
- XOUTPUT = VAL F.
- XVAL J = G + 9.
- XOUTPUT = VAL J. '9'
- XOUTPUT = VAL F.
- XOUTPUT = VAL H.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. 9
- XVAL W = 2 + 0.
- XPUT BUFF W.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. 10
- XVAL D = INPUT. '1'
- XVAL G = INPUT. '0'
- XVAL E = INPUT. '.'
- XVAL F = INPUT. ' '
- XVAL G = INPUT. '0'
- XVAL H = INPUT. eol
- XVAL B = 1 + 0.
- XGET BUFF B. X 031
- XTO 40 IF VAL H EQ 0.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- XLABEL 40.
- X
- XOUTPUT = VAL D. '1'
- XOUTPUT = VAL G. '0'
- XOUTPUT = VAL E. '.'
- XOUTPUT = VAL F. ' '
- XVAL I = PTR 0.
- XVAL J = G + I.
- XOUTPUT = VAL J. '0'
- XOUTPUT = VAL F. ' '
- XVAL I = PTR 1.
- XVAL J = G + I.
- XOUTPUT = VAL J. '1'
- XOUTPUT = VAL F.
- XVAL I = PTR 2.
- XVAL J = G + I
- XOUTPUT = VAL J. '2'
- XOUTPUT = VAL F.
- XVAL I = PTR 3.
- XVAL J = G + I
- XOUTPUT = VAL J. '3'
- XOUTPUT = VAL H.
- XVAL W = 2 + 0.
- XPUT BUFF W.
- X
- XCALL R.
- X
- XVAL B = 1 + 0.
- XGET BUFF B. 99
- XVAL W = 2 + 0.
- XPUT BUFF W.
- X
- XEND MAIN ROUTINE.
- XEND PROGRAM.
- X
- END_OF_FILE
- if test 9624 -ne `wc -c <'LOME/SCMTestP.scm'`; then
- echo shar: \"'LOME/SCMTestP.scm'\" unpacked with wrong size!
- fi
- # end of 'LOME/SCMTestP.scm'
- fi
- if test -f 'PPL/PPL.doc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'PPL/PPL.doc'\"
- else
- echo shar: Extracting \"'PPL/PPL.doc'\" \(13126 characters\)
- sed "s/^X//" >'PPL/PPL.doc' <<'END_OF_FILE'
- X.rm 75
- X.rm 70
- X.po 2
- X.he 'PPL.Doc'Portability Library Specs'Darren New'
- X.fo ' Page #' 'Printed % '
- X.pl 63
- X.nj
- X.ce 4
- XThis documentation and all accompanying files
- XCopyright 1986, 1990 Darren New.
- XAll Rights Reserved.
- XSee README for distribution permissions.
- X
- XThis file documents the proposed "Portable Programmer's Library",
- Xhereinafter referred to as "PPL" or "PL".
- X
- XThe Portable Programmer's Library is a set of functions written in portable
- XC intended to allow programmers to port their utilities and applications
- Xbetween different machines with no changes to their source. The PPL
- Xacheives this goal by relying on a small number of programmer-supplied
- Xfunctions that must be rewritten for each type of "host" computer. At the
- Xlowest level, these functions handle such tasks as memory allocation, error
- Xrecovery, I/O to "standard input" and "standard output", and command-line
- Xargument parsing. At the next higher level, these functions provide such
- Xservices as screen updates and file and directory access. All other
- Xfunctions are built on top of these low-level routines. Many of the more
- Xsophisticated routines (e.g., file requesters, menus) have equivalent
- Xroutines in the PPL implemented in terms of lower-level routines. These can
- Xbe overwridden by the host implementation to allow conformance with
- Xalready-existant host capabilities.
- X
- XThe PPL includes several subsystems which are sorted according to
- Xfunctionality. Each subsystem has its own header file, named after the
- Xsubsystem, which includes all of the other header files for that subsystem.
- XSince the syntax for subdirectories may vary, these header files are
- Xassumed to be somewhere accessable without subdirectories, and the
- Xindividual header files lie in subdirectories; thus, the programmer need
- Xonly edit one header file for each subsystem. The subsystems, which are
- Xdocumented in more detail in their own documentation file, include the
- Xfollowing:
- X
- X.nf
- XHOST - The lowest level routines. These change between machines. These
- Xare actually several of these, one for each subsystem and one for all
- Xsubsystems combined. The basic routines are stored in a subdirectory called
- XPPL.
- X
- XUTIL - The Utility Subsystem. These parse command-line templates and
- Xdo other utility-oriented processing. These also handle date and time
- Xarithmetic, list processing, sorting, and regular expression matching.
- X
- XUIS - The User Interface Subsystem. This includes windowing, menus,
- Xand special key handling.
- X
- XTFS - The Text File Subsystem. This includes routines to handle
- Xopening, closing, creating, destroying, reading, and writing of ASCII
- Xformat files. Files created by the TFS of one host should be readable by
- Xthe TFS of other hosts.
- X
- XBFS - The Binary File Subsystem. This includes routines to handle
- Xopening, closing, creating, destroying, reading, and writing of binary
- X(non_ASCII) files. These files are byte-addressable and dynamically sized
- X(esentially like UNIX files).
- X
- XKFS - The Keyed File Subsystem. This includes routines to handle
- Xopening, closing, creating, destroying, reading, and writing of
- XKey/Sequential files. These files can have records inserted, deleted, and
- Xsorted on several keys, and can also be accessed sequentially. Most of what
- Xyou need for the file interface to a simple database is here.
- X
- XFNS - File Name Subsystem. This includes routines for HOST-specific
- Xfilenames, directory access, protection changing, and so on. Use of
- Xthis library will not make your program non-portable if care is used, but
- Xthe user of you application will be aware of the syntax of host file names
- Xand so on.
- X
- XHIS - Host Interface Subsystem. This includes routines for date and
- Xtime handling, host-syntax "system" calls, and other miscellaneous routines
- Xthat may need to be changed from machine to machine. Check the header file
- Xto determine which routines are portable and which are not.
- X
- XPNS - Portable Name Subsystem. This includes routines for allowing
- Xportable filenames and "system" functions such as starting other commands
- Xand changing access permissions on files. It includes essentially
- Xeverything that the FNS and HIS do; however, it is more difficult for the
- Xprogrammer to use. It is designed to prevent the user from needing to learn
- Xabout the host filename syntax, how to copy or rename files on the host,
- Xand so on. It essentially gives the functionality of a small shell by using
- Xmenu-driven utilities. It also includes routines for translating host-style
- Xfilenames to portable filenames and back again, as well as routines for
- Xgiving the user a choice of filenames and returning which filename the user
- Xchose.
- X
- XTLS - Threaded Language Subsystem. This implements the threaded
- Xlanguage called "2OL", which stands for "Second Order Language".
- X
- XMXS - The Mutual Exclusion Subsystem. This includes routines for
- Xcommunicating between concurrent tasks, especially locking other concurrent
- Xtasks out of critical sections. This also contains simple routines for
- Xasynchronous user-generated interrupt handling.
- X
- XACS - The Application Configuration Subsystem. This includes routines
- Xfor creating and saving configuration information in a portable and
- Xextendable way.
- X
- XTIS - The Telecommunication Interface Subsystem. This includes
- Xroutines for portable access to computers other than the one the program is
- Xrunning on. Note this Subsystem works best if the computer being contacted
- Xis also running an application based on the TIS.
- X
- X.fi
- X.ce
- X***************************************************************
- X
- XNote that only shorts and longs are actually used by PortLib routines.
- XShorts are pretty much assumed to be at least 16 bits long. Chars are
- Xpretty much assumed to be 8 bits long, and longs are pretty much assumed to
- Xbe long enough to reference anything in the system. Where parameters are
- Xdeclared int, it is assumed that only arguments that could fit in a short
- Xare passed. These parameters are declared int instead of short simply to
- Xease the burden of the caller by allowing uncast integers to be passed. In
- Xmost cases (I hope all), parameters are declared as short and only shorts
- Xare passed.
- X
- XAlso, the naming conventions for external data are as follows: constant
- Xvalues such as NULL, TRUE, and so on are all caps. Constant values that are
- Xused as flags to individual routines are all small letters prefixed by the
- Xinitials of the subsystem in which they appear (e.g., PLsev_normal,
- XUIScolor_notice). Routine names (functions or macros that look like
- Xfunctions) are mixed upper/lower case and are prefixed by their subsystem
- Xinitials in all caps (e.g., PLClrErr, UISMakeWindow). General typedefs
- X(like bool, str, etc.) are all lower case. Specific typedefs (UISwindow)
- Xshould be lower case with the subsystem initials prepended in upper case.
- XFor compatibility, assert(), fault(), and bomb() are all lower case.
- X
- X.fi
- X.ce
- X***************************************************************
- X
- XThe HOST Subsystem includes routines to allow easy implementation of each
- Xof the above subsystems. There are, however, a set of HOST routines that
- Xwould be required for every application using the PPL. The organization of
- Xthis subsystem is described here. The functionality required is divided as
- Xfollows:
- X
- XMachine Parameters - In PPL.h is a set of parameters that should be
- Xset to match the host computer before the first compilation of the rest of
- Xthe PPL. These parameters include such things as the maximum amount of
- Xmemory that can be allocated contiguously (for segmented machines), the
- Xmaximum size a single I/O, the most efficient declaration for array
- Xindicies, and so on.
- X
- XMemory Functions - Functions to allocate and deallocate dynamic
- Xmemory, similarly to malloc() and free().
- X
- XStandard I/O Functions - Functions to read and write "standard I/O"
- Xstreams for utilities; these are normally not found in user-level
- Xapplications, but rather only in programs which a programmer would be
- Xusing. Interfacing to the user is the task of the UIS.
- X
- XError Functions - Functions to diagnose and correct errors detected by
- Xother HOST subsystems. This allows for portable error handling.
- X
- XCommand Argument Functions - These access command-line arguments in a
- Xportable way. Note that in order to implement this, the HOST subsystem
- Xactually contains the main() function, which must eventually call DoIt();
- XDoIt() is the "main program" of all PPL-based programs.
- X
- XDebug Functions - These allow for portable debugging statements, not
- Xnecessarily for portable debugging. In the worst case (the host implements
- Xnone of these), all these statements are designed to be macro'ed out.
- X
- XStatus Functions - These allow the programmer to post status messages
- Xfor debugging purposes or for keeping the user awake. These also include
- Xfunctions for delaying and for beeping or flashing.
- X
- XFor more explicit documentation of these routines, please see the
- XHOST subsystem header files.
- X
- X
- X.fi
- X.ce
- X***************************************************************
- X.ce
- XINSTALLATION ON YOUR COMMODORE AMIGA COMPUTER
- X
- XThe organization of the development system is as follows. The root for
- Xall directories is "PPLDIR:" on the Amiga. Upon installation on your
- Xparticular machine, you should make the directory that is to be the
- Xroot and then add to your Startup-Sequence a command to assign this
- Xdirectory to PPLDIR:. You should also assign "INCLUDE:" to be the
- Xdirectory where you want compressed header files to go and "CH:" to be
- Xthe directory where you want uncompressed header files to go. You
- Xshould then unpack the zoo files using the `x//' parameter to cause
- Xthe files to go into the correct directories. Edit the MakeHead.Amiga
- Xfiles to set the first couple of lines correctly for your machine.
- XExecute the FixMake.Amiga script in each subdirectory in order to
- Xrebuild the Makefile.Amiga and Makefile.Unix files. Note that you may
- Xneed to change ld.Amiga to set the correct flags or whatever. On my
- XAmiga, I have renamed `lmk' to be `make' and have written the
- Xfollowing script and put it in s:lmk:
- X
- X.nf
- X .key name
- X .bra {
- X .ket }
- X if exists Makefile
- X make {name}
- X else
- X if exists FixMake.Amiga
- X execute FixMake.Amiga
- X make -f Makefile.Amiga {name}
- X endif
- X endif
- X
- X.fi
- X
- XBy doing this, the command `lmk' will recreate the Makefile and then
- Xmake the program. In each subsystem, the default target will build the
- Xsubsystem. The target `clean' will remove most of the leftovers, while
- X`zap' will remove everything about the subsystem except the source.
- XThe target `test' (if available) will run regression tests on the
- Xsubsystem. If the regression tests fail, check the output: you may
- Xjust have a different encoding of characters or a byte-order
- Xdifference or something like that.
- X
- X.nf
- XThe correct order for making these programs is as follows:
- X 1) PPL
- X 2) BFS, TFS
- X 3) VMS, LOME, UIS
- X
- X.fi
- X.ce
- X***************************************************************
- X.ce
- XINSTALLATION ON YOUR UNIX-BASED COMPUTER
- X
- XThe organization of the development system is as follows. The root for
- Xall directories is "$PPLDIR" under Unix. The current sources assume
- Xthe use of GCC under SunOS 4.x. Upon installation on your particular
- Xmachine, you should make the directory that is to be the root and then
- Xadd to your .cshrc file a command to setenv PPLDIR to the full path of
- Xthat directory. You should then unpack the zoo files using the `x//'
- Xparameter to cause the files to go into the correct directories. You
- Xshould also create directories called "$PPLDIR/CH" and
- X"$PPLDIR/Headers" to hold header files. Edit the MakeHead.Unix file to
- Xset the first couple of lines correctly for your machine. Execute the
- XFixMake.Unix script in each subdirectory in order to rebuild the
- XMakefile.Amiga and Makefile.Unix files. Note that you may need to
- Xchange ld.Unix to set the correct flags or whatever.
- X
- XUnder Unix, I have the following lines in my .cshrc:
- X
- X.nf
- Xsetenv PPLDIR ~/PPLstuff
- Xalias lmk 'source FixMake.Unix && make -f Makefile.Unix \!* |& \
- X tee make.err'
- X
- X.fi
- X
- XBy doing this, the command `lmk' will recreate the Makefile and then
- Xmake the program. In each subsystem, the default target will build the
- Xsubsystem. The target `clean' will remove most of the leftovers, while
- X`zap' will remove everything about the subsystem except the source.
- XThe target `test' (if available) will run regression tests on the
- Xsubsystem. If the regression tests fail, check the output: you may
- Xjust have a different encoding of characters or a byte-order
- Xdifference or something like that.
- X
- X.nf
- XThe correct order for making these programs is as follows:
- X 1) PPL
- X 2) BFS, TFS
- X 3) VMS, LOME, UIS
- X
- X.fi
- X.ce
- X***************************************************************
- X.ce
- XINSTALLATION ON A CURRENTLY-UNSUPPORTED PLATFORM
- X
- XUnpack as above. If you don't have `make,' go buy it. Otherwise, you
- Xwill have to build everything by hand, which is not impossible but is
- Xinconvenient. Look at all the files that have `Amiga' or `Unix' in
- Xtheir name and modify them to work under your machine and OS. Package
- Xup the changes and send them to me. Thank you!
- X
- X
- END_OF_FILE
- if test 13126 -ne `wc -c <'PPL/PPL.doc'`; then
- echo shar: \"'PPL/PPL.doc'\" unpacked with wrong size!
- fi
- # end of 'PPL/PPL.doc'
- fi
- if test -f 'TFS/TFSUnix.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'TFS/TFSUnix.c'\"
- else
- echo shar: Extracting \"'TFS/TFSUnix.c'\" \(10504 characters\)
- sed "s/^X//" >'TFS/TFSUnix.c' <<'END_OF_FILE'
- X/* :ts=4:
- X * TFSUnix.c
- X * Portable Programmer's Library Text File Subsystem Code File
- X * Copyright 1988 Darren New. All Rights Reserved.
- X *
- X * Started: 26-Feb-88 DHN
- X * LastMod: 13-Jul-90 DHN
- X *
- X * Version One for Unix -- Simple, just to get running
- X * This uses access() because it's simple and there, even
- X * tho I know this is wrong under SUID programs.
- X *
- X */
- X
- X#include "PPL.h"
- X#include "TFS.h"
- X
- X#include "stdio.h"
- X#include "fcntl.h"
- X
- X/* Why this isn't in stdio.h I'll never understand */
- Xextern int fclose(FILE *);
- Xextern long tell(int);
- Xextern long ftell(FILE *);
- Xextern long fseek(FILE *, long, int);
- Xextern int fgetc(FILE *);
- Xextern int fwrite(char *, int, int, FILE *);
- X
- X#define MAXTFS 15 /* max # TFSfiles open at once */
- X
- XHIDDEN struct { /* one open file */
- X str name;
- X FILE * fhand;
- X str modes;
- X } ftab[MAXTFS];
- X
- XHIDDEN bool TFShbi = FALSE; /* has been init */
- XHIDDEN short TFSfree; /* number of free ftab entries */
- X
- X
- X#define HND (handle - 1) /* for convenience */
- X
- X
- Xvoid TFSInit()
- X{
- X inx i;
- X assert(TFShbi == FALSE);
- X TFShbi = TRUE;
- X for (i = 0; i < MAXTFS; i++)
- X ftab[i].name = ftab[i].modes = NULL;
- X TFSfree = MAXTFS;
- X PLErrClr();
- X }
- X
- Xbool TFSHasBeenInit()
- X{
- X return TFShbi;
- X }
- X
- Xvoid TFSTerm()
- X{
- X int i;
- X assert(TFShbi);
- X for (i = 0; i < MAXTFS; i++) {
- X if (ftab[i].modes != NULL) {
- X fclose(ftab[i].fhand);
- X PLFreeMem(ftab[i].modes);
- X PLFreeMem(ftab[i].name);
- X }
- X }
- X TFSfree = 0;
- X TFShbi = FALSE;
- X PLErrClr();
- X }
- X
- X
- XTFSfile TFSOpen(fname, mode)
- X str fname;
- X str mode;
- X{
- X
- X /**** NOTE THIS MUST BE CHANGED TO REMEMBER NAMES IN FULL LENGTH
- X OR RELATIVE TO A LOCK OR DIRECTORY! ****/
- X
- X /**** Also note that this takes advantage of some of the restrictions
- X on mode combinations; e.g., R excludes W, W excludes P, ... ****/
- X
- X long flock, fhand;
- X bool mL, mC, mT, mA, mR, mW, mP, mD;
- X long t; /* temp value */
- X inx i;
- X
- X#define setup(a,b) {a = (NULL != strchr(mode, b));}
- X
- X assert(TFShbi);
- X#if CHKARGS
- X if (fname == NULL || mode == NULL || *fname == EOS || *mode == EOS ||
- X BIGFNAME <= strlen(fname) ) {
- X PLErrSet(PLerr_badarg);
- X return 0;
- X }
- X#endif
- X
- X setup(mL, 'L'); setup(mC, 'C'); setup(mT, 'T');
- X setup(mA, 'A'); setup(mR, 'R'); setup(mW, 'W');
- X setup(mP, 'P'); setup(mD, 'D');
- X
- X#if CHKARGS
- X if ( (mR && mW) || (mP && !mR && !mC) || (mW && !mA && !mT) ||
- X (mA && mT) || (mA && !mW) || (mT && !mW) ) {
- X PLErrSet(PLerr_badarg);
- X return 0;
- X }
- X#endif
- X
- X if (TFSfree == 0 && ! mL) {
- X PLErrSet(PLerr_oores);
- X return 0;
- X }
- X
- X if (mL) { /* just check for access */
- X if (!mC) { /* not creating */
- X flock = access(fname, F_OK);
- X if (flock == -1) { /* directories inaccessible */
- X OSerr = errno;
- X if (OSerr == EACCES || OSerr == EISDIR || OSerr == ENOTDIR ||
- X OSerr == EPERM || OSerr == ETXTBSY)
- X PLErrSet(PLerr_permit);
- X else
- X PLErrSet(PLerr_exist);
- X return 0;
- X }
- X flock = access(fname, F_OK + mR ? R_OK : W_OK);
- X if (flock == -1) { /* file inaccessible */
- X OSerr = errno;
- X if (OSerr == EACCES || OSerr == EISDIR || OSerr == ENOTDIR ||
- X OSerr == EPERM || OSerr == ETXTBSY)
- X PLErrSet(PLerr_permit);
- X else
- X PLErrSet(PLerr_exist);
- X return 0;
- X }
- X }
- X else { /* creating */
- X char * dirname;
- X char * slash;
- X /* check simple case first */
- X if (-1 != access(fname, F_OK + W_OK))
- X return 1;
- X /* Difficult case: build name of parent dir */
- X dirname = PLStrDup(fname);
- X slash = dirname + 1;
- X if (NULL == strchr(dirname, '/'))
- X strcpy(dirname, ".");
- X else {
- X while (NULL != strchr(slash, '/'))
- X slash = strchr(slash, '/');
- X *(slash+1) = '\0';
- X }
- X flock = access(dirname, F_OK);
- X if (flock == -1) { /* see if dest dir exists */
- X OSerr = errno;
- X PLErrSet(PLerr_exist);
- X PLFreeMem(dirname);
- X return 0;
- X }
- X flock = access(dirname, F_OK + W_OK);
- X if (flock == -1) { /* see if dest dir is writable */
- X OSerr = errno;
- X PLErrSet(PLerr_permit);
- X PLFreeMem(dirname);
- X return 0;
- X }
- X flock = access(fname, F_OK + W_OK);
- X if (flock == -1 && errno != ENOENT) {
- X /* see if dest file exists and writable */
- X OSerr = errno;
- X PLErrSet(PLerr_permit);
- X PLFreeMem(dirname);
- X return 0;
- X }
- X else {
- X /* otherwise, must be good */
- X errno = 0;
- X PLFreeMem(dirname);
- X return 1;
- X }
- X }
- X }
- X
- X /* Here, we are not just looking. In this case, it is easiest to
- X simply try to do the operation and see if it fails. */
- X
- X t = mR ? O_RDONLY : O_WRONLY;
- X t += mC ? O_CREAT : 0;
- X t += mT ? O_TRUNC : 0;
- X t += mA ? O_APPEND : 0;
- X
- X fhand = open(fname, t, 0666);
- X if (fhand < 0) {
- X OSerr = errno;
- X switch (errno) {
- X default:
- X PLErrSet(PLerr_opsysF); break;
- X case EACCES:
- X case EEXIST:
- X case EISDIR:
- X case ENOTDIR:
- X case EROFS:
- X PLErrSet(PLerr_permit); break;
- X case EDQUOT:
- X case EMFILE:
- X case ENFILE:
- X case ENOSPC:
- X case ENOSR:
- X PLErrSet(PLerr_oores); break;
- X case EFAULT:
- X case ENAMETOOLONG:
- X PLErrSet(PLerr_param); break;
- X case EOPNOTSUPP:
- X PLErrSet(PLerr_unsup); break;
- X case ENOENT:
- X PLErrSet(PLerr_exist); break;
- X }
- X return 0;
- X }
- X if (mP && tell(fhand) < 0) {
- X close(fhand);
- X PLErrSet(PLerr_unsup);
- X return 0;
- X }
- X for (i = 0; i < MAXTFS && ftab[i].modes; i++)
- X ;
- X ftab[i].fhand = fdopen(fhand, mR ? "rt" : (mA ? "at" : "wt"));
- X if (ftab[i].fhand == NULL) {
- X close(fhand);
- X PLErrSet(PLerr_oores);
- X return 0;
- X }
- X ftab[i].modes = PLStrDup(mode);
- X ftab[i].name = PLStrDup(fname);
- X
- X return (TFSfile) (i + 1);
- X }
- X
- Xbool TFSClose(handle)
- X TFSfile handle;
- X{
- X int err;
- X assert(TFShbi);
- X#if CHKARGS
- X if (HND < 0 || MAXTFS <= HND || ftab[HND].modes == NULL) {
- X PLErrSet(PLerr_badarg);
- X return FALSE;
- X }
- X#endif
- X assert(ftab[HND].fhand != NULL);
- X assert(ftab[HND].name != NULL);
- X assert(ftab[HND].modes != NULL);
- X
- X err = fclose(ftab[HND].fhand);
- X PLFreeMem((ptr) ftab[HND].modes);
- X PLFreeMem((ptr) ftab[HND].name);
- X ftab[HND].name = ftab[HND].modes = NULL;
- X if (err == 0) {
- X PLErrClr();
- X return TRUE;
- X }
- X else {
- X PLErrSet(PLerr_opsysF);
- X return FALSE;
- X }
- X }
- X
- Xbool TFSDestroy(handle)
- X TFSfile handle;
- X{
- X char fn[BIGFNAME];
- X bool flag;
- X int err;
- X
- X assert(TFShbi);
- X#if CHKARGS
- X if (HND < 0 || MAXTFS <= HND || ftab[HND].modes == NULL) {
- X PLErrSet(PLerr_badarg);
- X return FALSE;
- X }
- X#endif
- X strcpy(fn, ftab[HND].name);
- X flag = (NULL != strchr(ftab[HND].modes, 'D'));
- X
- X fclose(ftab[HND].fhand);
- X PLFreeMem(ftab[HND].name);
- X PLFreeMem(ftab[HND].modes);
- X ftab[HND].modes = NULL;
- X
- X if (flag) {
- X err = unlink(fn); /* permission checked during open */
- X if (err == -1) {
- X OSerr = errno;
- X PLErrSet(PLerr_permit);
- X return FALSE;
- X }
- X else {
- X PLErrClr();
- X return TRUE;
- X }
- X }
- X else {
- X PLErrSet(PLerr_badarg);
- X return FALSE;
- X }
- X }
- X
- X/* @$@$
- XTFSInfo() - Determine file parameters. This may return various
- Xparameters about the given file. The description of the information
- Xreturned is given in the TFS.h file.
- X*/
- X
- X
- Xshort TFSRead(handle, buf)
- X TFSfile handle;
- X str buf;
- X{
- X inx i; /* index into buffer */
- X int c; /* read character */
- X long l; /* length of record read */
- X
- X assert(TFShbi);
- X assert(buf != NULL);
- X#if CHKARGS
- X if (HND < 0 || MAXTFS <= HND || ftab[HND].modes == NULL) {
- X PLErrSet(PLerr_badarg);
- X return S -1;
- X }
- X if (NULL == strchr(ftab[HND].modes, 'R')) {
- X PLErrSet(PLerr_badarg);
- X return S -1;
- X }
- X#endif
- X i = 0;
- X do {
- X errno = 0;
- X c = fgetc(ftab[HND].fhand);
- X l = (c == EOF) ? (ferror(ftab[HND].fhand) ? -1 : 0) : 1;
- X /* l is what read() would have returned */
- X if (0 < l)
- X buf[i++] = c;
- X } while (0 < l && i < BIGLINE && c != '\n');
- X
- X /* printf("l=%d, i=%d, c=%d, buf[0]=%c\n", l, i, c, buf[0]); */
- X if (l == -1) {
- X OSerr = errno;
- X PLErrSet(PLerr_opsysF);
- X buf[0] = EOS;
- X return S -1;
- X }
- X if (i == BIGLINE && c != '\n') { /* line overflow */
- X buf[--i] = EOS;
- X while (0 < i && isspace(buf[i-1]))
- X buf[--i] = EOS;
- X while (EOF != (c = fgetc(ftab[HND].fhand)) && c != '\n')
- X /* flush rest of line */;
- X PLErrSet(PLerr_overflow);
- X assert(strlen(buf) < BIGLINE);
- X return S -1;
- X }
- X if (l == 0) { /* end of file */
- X if (i == 0) {
- X buf[0] = EOS;
- X PLErrSet(PLerr_eod);
- X return S -1;
- X }
- X else {
- X buf[i++] = c = '\n';
- X /* and fall thru */
- X }
- X }
- X if (c == '\n') { /* end of line */
- X if (i == BIGLINE)
- X i -= 1;
- X buf[i] = EOS;
- X while (0 < i && isspace(buf[i-1]))
- X buf[--i] = EOS;
- X PLErrClr();
- X assert(strlen(buf) < BIGLINE);
- X return S i;
- X }
- X
- X assert(0); /* you can't get here */
- X return 0;
- X }
- X
- X
- Xbool TFSWrite(handle, buf)
- X TFSfile handle;
- X str buf;
- X{
- X int i; /* must be able to handle negative numbers */
- X
- X assert(buf != NULL);
- X#if CHKARGS
- X if (HND < 0 || MAXTFS <= HND || ftab[HND].modes == NULL) {
- X PLErrSet(PLerr_badarg);
- X return FALSE;
- X }
- X if (NULL == strchr(ftab[HND].modes, 'W')) {
- X PLErrSet(PLerr_badarg);
- X return FALSE;
- X }
- X if (BIGIO <= strlen(buf)) {
- X PLErrSet(PLerr_badarg);
- X return FALSE;
- X }
- X#endif
- X
- X clearerr(ftab[HND].fhand);
- X i = strlen(buf);
- X while (0 < i && isspace(buf[i - 1]))
- X i -= 1;
- X if ( ( (0 < i) && (i != fwrite(buf, 1, i, ftab[HND].fhand)) ) ||
- X 1 != fwrite("\n", 1, 1, ftab[HND].fhand)) {
- X OSerr = errno;
- X PLErrSet(PLerr_opsysF);
- X return FALSE;
- X }
- X PLErrClr();
- X return TRUE;
- X }
- X
- Xlong TFSNote(handle)
- X TFSfile handle;
- X{
- X long retval;
- X#if CHKARGS
- X if (HND < 0 || MAXTFS <= HND || ftab[HND].modes == NULL) {
- X PLErrSet(PLerr_badarg);
- X return -1L;
- X }
- X if (NULL == strchr(ftab[HND].modes, 'P') ||
- X NULL == strchr(ftab[HND].modes, 'R')) {
- X PLErrSet(PLerr_badarg);
- X return -1L;
- X }
- X#endif
- X
- X retval = ftell(ftab[HND].fhand);
- X if (retval == -1) {
- X OSerr = errno;
- X PLErrSet(PLerr_opsysF);
- X return 0L;
- X }
- X else {
- X PLErrClr();
- X return retval + 1L;
- X }
- X }
- X
- Xbool TFSPoint(handle, pos)
- X TFSfile handle;
- X TFSnote pos;
- X{
- X long newpos;
- X#if CHKARGS
- X if (HND < 0 || MAXTFS <= HND || ftab[HND].modes == NULL) {
- X PLErrSet(PLerr_badarg);
- X return -1L;
- X }
- X if (pos <= 0L || NULL == strchr(ftab[HND].modes, 'P') ||
- X NULL == strchr(ftab[HND].modes, 'R')) {
- X PLErrSet(PLerr_badarg);
- X return -1L;
- X }
- X#endif
- X
- X newpos = fseek(ftab[HND].fhand, pos - 1L, 0);
- X if (newpos == -1L) {
- X OSerr = errno;
- X PLErrSet(PLerr_opsysF);
- X return FALSE;
- X }
- X else {
- X PLErrClr();
- X return TRUE;
- X }
- X }
- X
- X
- END_OF_FILE
- if test 10504 -ne `wc -c <'TFS/TFSUnix.c'`; then
- echo shar: \"'TFS/TFSUnix.c'\" unpacked with wrong size!
- fi
- # end of 'TFS/TFSUnix.c'
- fi
- echo shar: End of archive 6 \(of 9\).
- cp /dev/null ark6isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 9 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- --- Darren New --- Grad Student --- CIS --- Univ. of Delaware ---
-
- exit 0 # Just in case...
- --
- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
- Use a domain-based address or give alternate paths, or you may lose out.
-