Views
LIB: Run-time library for the LITTLE system (compile time and run time).
by
Paul McJones
—
last modified
2021-03-17 18:44
- History
-
Action Performed by Date and Time Comment Publish Paul McJones 2021-03-17 18:34 No comments.
LIB: Run-time library for the LITTLE system (compile time and run time).
1 .=member intro
2 $ !$&'()*+,-./0123456789:;<=>abcdefghijklmnopqrstuvwxyz^_
3 $ the above line contains, in order of ascii codes, the 56
4 $ characters of the little language, starting in column 7.
5 $
6 $ $$ $$$$$$$$$$ $$$$$$$$$$ $$$$$$$$$$ $$ $$$$$$$$$
7 $ $$ $$$$$$$$$$ $$$$$$$$$$ $$$$$$$$$$ $$ $$$$$$$$$
8 $ $$ $$ $$ $$ $$ $$
9 $ $$ $$ $$ $$ $$ $$
10 $ $$ $$ $$ $$ $$ $$$$$$
11 $ $$ $$ $$ $$ $$ $$$$$$
12 $ $$ $$ $$ $$ $$ $$
13 $ $$ $$ $$ $$ $$ $$
14 $ $$$$$$$$$$ $$$$$$$$$$ $$ $$ $$$$$$$$$$ $$$$$$$$$
15 $ $$$$$$$$$$ $$$$$$$$$$ $$ $$ $$$$$$$$$$ $$$$$$$$$
16 $
17 $ $$ $$$$$$$$$$ $$$$$$$$$$
18 $ $$ $$$$$$$$$$ $$$$$$$$$$
19 $ $$ $$ $$ $$
20 $ $$ $$ $$ $$
21 $ $$ $$ $$$$$$$$$
22 $ $$ $$ $$$$$$$$$
23 $ $$ $$ $$ $$
24 $ $$ $$ $$ $$
25 $ $$$$$$$$$$ $$$$$$$$$$ $$$$$$$$$$
26 $ $$$$$$$$$$ $$$$$$$$$$ $$$$$$$$$
27
28
29
30 $ this software is part of the little programming system.
31 $ address queries and comments to
32 $
33 $ little project
34 $ department of computer science
35 $ new york university
36 $ courant institute of mathematical sciences
37 $ 251 mercer street
38 $ new york, ny 10012
39 $
40 $ this is the run-time library for the little system, and
41 $ is known as 'lib'.
42 $
43 $ the principal authors of the little compiler are
44 $ robert abes, edith deak, richard kenner, david shields
45 $ and aaron stein.
46 $
47 $
1 .=member chars
2 /* little character set and ascii representation
3
4 !$&'()*+,-./0123456789:;<=>abcdefghijklmnopqrstuvwxyz^_
5 the above line contains, in order of ascii codes, the 56
6 characters of the little language, starting in column 7.
7
8 the little language requires 56 distinct characters.
9 these include the 26 upper case letters, the 10 digits,
10 and the following special characters:
11
12 blank
13 = equal sign, assignment symbol
14 + plus
15 - minus
16 * times, asterisk
17 / divide, slash
18 ( left parenthesis
19 ) right parenthesis
20 , comma
21 . period, point
22 ; semicolon
23 : colon
24 $ dollar sign, comment character
25 ^ not
26 & and
27 ! or
28 < less than
29 > greater than
30 ' apostrophe, string delimiter
31 _ underline, break character
32
33 the following table gives the standard ascii encoding
34 for the little character set.
35
36 little character ascii ascii ascii ascii character
37 (hex) (oct) (dec)
38
39 space 20 40 32 space
40 ! or 21 41 33 exclamation mark
41 $ dollar sign 24 44 36 dollar sign
42 & and 26 46 38 ampersand
43 ' apostrophe 27 47 39 apostrophe
44 ( left parenthesis 28 50 40 left parenthesis
45 ) right parenthesis 29 51 41 right parenthesis
46 * asterisk 2a 52 42 asterisk
47 + plus 2b 53 43 plus
48 , comma 2c 54 44 comma
49 - minus 2d 55 45 minus
50 . period 2e 56 46 period
51 / slash 2f 57 47 slant
52 0 digit 0 30 60 48 digit 0
53 1 digit 1 31 61 49 digit 1
54 2 digit 2 32 62 50 digit 2
55 3 digit 3 33 63 51 digit 3
56 4 digit 4 34 64 52 digit 4
57 5 digit 5 35 65 53 digit 5
58 6 digit 6 36 66 54 digit 6
59 7 digit 7 37 67 55 digit 7
60 8 digit 8 38 70 56 digit 8
61 9 digit 9 39 71 57 digit 9
62 : colon 3a 72 58 colon
63 ; semicolon 3b 73 59 semicolon
64 < less than 3c 74 60 less than
65 = equals 3d 75 61 equals
66 > greater than 3e 76 62 greater than
67 a letter a 41 101 65 letter a
68 b letter b 42 102 66 letter b
69 c letter c 43 103 67 letter c
70 d letter d 44 104 68 letter d
71 e letter e 45 105 69 letter e
72 f letter f 46 106 70 letter f
73 g letter g 47 107 71 letter g
74 h letter h 48 110 72 letter h
75 i letter i 49 111 73 letter i
76 j letter j 4a 112 74 letter j
77 k letter k 4b 113 75 letter k
78 l letter l 4c 114 76 letter l
79 m letter m 4d 115 77 letter m
80 n letter n 4e 116 78 letter n
81 o letter o 4f 117 79 letter o
82 p letter p 50 120 80 letter p
83 q letter q 51 121 81 letter q
84 r letter r 52 122 82 letter r
85 s letter s 53 123 83 letter s
86 t letter t 54 124 84 letter t
87 u letter u 55 125 85 letter u
88 v letter v 56 126 86 letter v
89 w letter w 57 127 87 letter w
90 x letter x 58 130 88 letter x
91 y letter y 59 131 89 letter y
92 z letter z 5a 132 90 letter z
93 ^ not 5e 136 94 circumflex
94 _ underline 5f 137 95 underline
95
96 */
97
1 .=member mods
2 $ -- all corrections are to insert mod notice after -- mods.2 --
ldsd 1
ldsd 2 $ ldsd d. shields 20-jun-83
ldsd 3 $
ldsd 4 $ 1. increase oscmax to 512 fo s32.
ldsd 5 $ 2. extend incio to permit tabs, not just blanks, to be used
ldsd 6 $ to delimit keywords for .=member, .=include, except that
ldsd 7 $ directive must start with blank.
ldsd 8 $ decks affected - macros, incio
ldsd 9
ldsc 1
ldsc 2 $ ldsc d. shields 23-jul-82
ldsc 3 $
ldsc 4 $ for s37, allow longer program parameter strings and also change
ldsc 5 $ specification for print file from 'l=sysprint/sysout' to just
ldsc 6 $ 'l=sysprint/'.
ldsc 7 $
ldsc 8 $ decks affected - macros, ltlini
ldsc 9
dso 1
dso 2 $ ldsb d. shields 15-jan-82
dso 3 $
dso 4 $ revise ltlfin to put etim output on standard output not terminal.
dso 5 $ write etim output only if normal termination. writing the output
dso 6 $ to terminal was confusing, especially for unix.
dso 7 $ deck affected - ltlfin (resequenced).
dso 8
dsnc 1
dsnc 2 $ dsnc d. shields 15-dec-81
dsnc 3 $
dsnc 4 $ make the default for 'termp=' be system dependent.
dsnc 5 $ deck affected - ltlini
dsnc 6
dsn 1
dsn 2 $ dsn d. shields 09-dec-81
dsn 3 $
dsn 4 $ 1. support termp=>/> to indicate terminal prompt to be given
dsn 5 $ for interactive input.
dsn 6 $ termp=0 gives no prompting.
dsn 7 $ termp requires new sio procedure promsio(fn,rc,string) to
dsn 8 $ set prompt for file fn to string. provide dummy promsio if
dsn 9 $ this feature not to be supported on a particular implementatio
dsn 10 $ 2. extend plf1 parameter option so that parameter values
dsn 11 $ containing commas can be enclosed in parentheses.
dsn 12 $ decks affected - ltlini, beglio, makf, reados
dsn 13
utsa 1
utsa 2 $ utsa d. shields 29-nov-81 level 81333
utsa 3 $
utsa 4 $ support s47: amdahl uts (universal timesharing system).
utsa 5 $ this implementation runs on s37 architecture using an operating
utsa 6 $ system very close to unix (v7), and uses the ascii character set.
utsa 7 $ note that new decks s47xtr1 and s47errs will need revision for uts
utsa 8
dsm 1
dsm 2 $ dsm d. shields 04-nov-81
dsm 3 $
dsm 4 $ for systems other than s66, have etim write its output to
dsm 5 $ terminal file. also, limit use of remarkl within this library
dsm 6 $ to very serious errors such as 'unable to open listing file'.
dsm 7 $ remarkl is based on s66, and semantics elsewhere not always clear.
dsm 8 $ also, slightly adjust ltlini so all globals in single nameset,
dsm 9 $ hence no need to have nameset with created name ($tlini, etc.).
dsm 10 $ decks affected - ltlini, ltlced, incio, ltlfin.
dsm 11
dsl 1
dsl 2 $ dsl d. shields 21-sep-81
dsl 3 $
dsl 4 $ report fatal error (1010) if unable to open inclusion file.
dsl 5 $ deck affected - incio
dsl 6
dsua 1
dsua 2 $ dsua d. shields 27-jan-81
dsua 3 $
dsua 4 $ adjust iolbamax for s10.
dsua 5 $ deck affected - beglio
dsua 6
dsk 1
dsk 2 $ dsk d. shields 27-oct-80
dsk 3 $
dsk 4 $ 1. fix case folding in conditional assembly processing.
dsk 5 $ 2. add program parameter 'termh' such that title line generated
dsk 6 $ by ltitlr echoed to terminal only if termh=1. make default
dsk 7 $ 'termh=1/0', except for s32, where want 'termh=0/1'.
dsk 8 $ new contlpr entries permit reading and changing termh.
dsk 9 $ contlpr(28, arg) sets arg to termh value
dsk 10 $ contlpr(29, arg) sets termh value to arg
dsk 11 $ 3. permit specification of number of characters in standard
dsk 12 $ output file (unit 2). new program parameter
dsk 13 $ pfcl=0/80 permits specification of characters per line in
dsk 14 $ standard output file (including carriage control column).
dsk 15 $ 'pfcl=0' yields default line length.
dsk 16 $ alternate '80' chosen to assist output to terminal.
dsk 17 $ new contlpr entry permits finding line length
dsk 18 $ contlpr(30,arg) sets arg to line length of standard
dsk 19 $ output file
dsk 20 $ decks affected - macros, ltlini, lcp, incio, makf
dsk 21
plf 1
plf 2 $ plf d. shields 10-oct-80
plf 3 $
plf 4 $ add conditional assembly options to permit varying
plf 5 $ program parameter list formats, as follows
plf 6 $ plf0 comma is separator (default)
plf 7 $ plf1 comma is separator, except when between brackets
plf 8 $ ([ or < at left, ] or > at right). this format
plf 9 $ used for s10, s11 and s32, to permit passing
plf 10 $ fully-qualified file names.
plf 11 $ deck affected - reados
plf 12
dsj 1
dsj 2 $ dsj d. shields 24-sep-80
dsj 3 $
dsj 4 $ add procedure -ltlced- (c-heck e-xpiration d-ate) to check
dsj 5 $ expiration date. expiration causes abnormal termination with
dsj 6 $ code 1009. execution within a month of expiration causes
dsj 7 $ generation of warning message. expiration only checked if
dsj 8 $ -expire- option in ltlgen used when compiling program.
dsj 9 $ deck affected - ltlced (new).
dsj 10
dsi 1
dsi 2 $ dsi d. shields 30-jul-80
dsi 3 $ r. kenner
dsi 4 $
dsi 5 $ 1. fix problem (fr143) in multi-word extraction.
dsi 6 $ 2. correct spelling error in message in prhd.
dsi 7 $ 3. accept mixed case input in ilst (fixing fr137), iget
dsi 8 $ and vnum.
dsi 9 $ 4. fix macro definition for addrl for s37.
dsi 10 $ 5. support up to 20 files for s37.
dsi 11 $ 6. make page limit infinite for s37.
dsi 12 $ 7. change default for term= to 'term=systerm/' for s37.
dsi 13 $
dsi 14 $ * * * new sio procedures - eretsio, ecodsio * * *
dsi 15 $
dsi 16 $ add eretsio(fn, rc, lev) to permit recovery from sio errors.
dsi 17 $ lev is 0 for no return if sio error (prior practice)
dsi 18 $ 1 for terse return
dsi 19 $ 2 for verbose return (issue error messages, etc.)
dsi 20 $ the setting persits across file closes. rc is set zero unless
dsi 21 $ fn is not a valid file number.
dsi 22 $
dsi 23 $ add ecodsio(fn, rc, src) to report system error code.
dsi 24 $ after a call to an sio procedure, ecodsio may be called.
dsi 25 $ rc is set to the value returned in the last sio call, and,
dsi 26 $ if an error has occurred, src is set to a system-dependent
dsi 27 $ value describing which error occurred.
dsi 28 $
dsi 29 $ the standard input and output files are opened with eretsio level
dsi 30 $ 1 (terse return) and 2 (verbose return) respectively.
dsi 31 $
dsi 32 $ decks affected - macros, eexmw, prhd, ilst, iget, vnum, termio,
dsi 33 $ ltlini, makf.
dsi 34
dsh 1
dsh 2 $ dsh d. shields 21-jul-80
dsh 3 $
dsh 4 $ 1. force load of blds if defenv_ss not set.
dsh 5 $ 2. for s32 vms, have getipp and getspp fold arguments.
dsh 6 $ decks affected - ltlini, getipp, getspp.
dsh 7
dsg 1
dsg 2 $ dsg d. shields 11-jul-80
dsg 3 $
dsg 4 $ fix error (fr138) that caused extra blank line at end of
dsg 5 $ standard output file.
dsg 6 $ deck affected - rlse.
dsg 7
dsf 1
dsf 2 $ dsf d. shields 10-jul-80
dsf 3 $ 1. add conditional symbol -unix- for the unix operating system.
dsf 4 $ use iset=unix to obtain unix variant.
dsf 5 $ delete all special env code for initial unix checkout.
dsf 6 $ 2. provide up to 20 files for s32.
dsf 7 $ 3. improve ltlfin, especially for s32.
dsf 8 $ 4. watch for possible sio error on file open. if cannot
dsf 9 $ open standard output (unit 2), issue error message using
dsj 11 $ -remarkl- and terminate with code 1007.
dsf 11 $ decks affected - macros, ltlfin, beglio, ltllio, makf.
dsf 12
dse 1
dse 2 $ dse d. shields 21-apr-80
dse 3 $
dse 4 $ 1. allow up to 16 files for s32 and s37.
dse 5 $ 2. increase line buffer array for s32 and s37.
dse 6 $ 3. add option extime_off to permit support of timing feature,
dse 7 $ but not have times given by default.
dse 8 $ 4. fix error (fr132) that caused null lines to not be written.
dse 9 $ decks affected - macros, ltlini, beglio, flsh.
dse 10
dsd 1
dsd 2 $ dsd d. shields 21-nov-79
dsd 3 $
dsd 4 $ support mixed case in specifying .=include and .=member
dsd 5 $ directives and also for member names.
dsd 6 $ deck affected - incio
dsd 7
dsc 1
dsc 2 $ dsc d. shields 19-nov-79
dsc 3 $
dsc 4 $ 1. change default site name to 'nyu'. also adjust ltitlr
dsc 5 $ to work with names of differing lengths.
dsc 6 $ 2. have ltlini process 'term=' terminal option. this avoids user
dsc 7 $ programs having to open terminal file. this change compatible
dsc 8 $ with existing use of opnterm.
dsc 9 $ 3. change page limit default to 'pfpl=100/0' so that
dsc 10 $ 'pfpl' alone suppresses page limit check.
dsc 11 $ 4. do some initialization in opninc using data statements
dsc 12 $ instead of code.
dsc 13 $ 5. fix bug (fr2.3.124) in detecting conversion errors due
dsc 14 $ to misplaced test in vnum.
dsc 15 $ 6. add code for s10 to ctlc, ctuc.
dsc 16 $ 7. convert sstab in blds for s10 from sixbit to 9 bit.
dsc 17 $ 8. add parameter 'ilib=' to permit explicit naming of inclusion
dsc 18 $ text library. null value selects default library name.
dsc 19 $ 9. if extime enabled to permit timing execution, support
dsc 20 $ program parameter 'etim=1/0' so that time not reported
dsc 21 $ if etim=0.
dsc 22 $ 10. add procedure getapp(s, sl) which returns in string s of max.
dsc 23 $ length sl the full parameter string that invoked the program.
dsc 24 $ the maximum length of this string is getapp_len, which has
dsc 25 $ default length of 128 (240 for s32).
dsc 26 $ decks affected - ltlini, ltitlr, opnterm, incio, ltlfin, blds,
dsc 27 $ ctlc, ctuc, getapp (new).
dsc 28
dsb 1
dsb 2 $ dsb d. shields 10-sep-79
dsb 3 $
dsb 4 $ 1. for s32, support parameter strings up to 300 characters, and
dsb 5 $ individual string parameters up to 64 characters.
dsb 6 $ 2. ignore non-digits in integer parameter strings to avoid
dsb 7 $ generating spurious values during integer conversion.
dsb 8 $ 3. for little i/o, recognize only error levels 1 and 2.
dsb 9 $ level 1 error indicates conversion/truncation error, level 2
dsb 10 $ indicates bad parameters or error on attempting operation.
dsb 11 $ 4. detect sio failure when opening, closing or rewinding file.
dsb 12 $ 5. permit io procedure pcsa to be defined in environment.
dsb 13 $ 6. correct confusion in conditional assembly of ltlterm.
dsb 14 $ decks affected - macros, getipp, getspp, reados, makf, rlse,
dsb 15 $ rwnd, pfin, istr, uinp, uout, ioer, ltlterm.
dsb 16
ldsa 1
ldsa 2 $ ldsa d. shields 02-aug-79
ldsa 3 $
ldsa 4 $ 1. revise text inclusion routines to accept 'upd' argument to
ldsa 5 $ permit direct reading of little source from upd library files
ldsa 6 $ which have sequence information in first eight columns.
ldsa 7 $ 2. revise s10 configuration parameters to reflect use of
ldsa 8 $ 9-bit ascii.
ldsa 9 $ 3. add string search functions as follows.
ldsa 10 $ anyc, anys, blds, brkc, brks, ctlc, ctuc, nayc, nays, rbrc
ldsa 11 $ rbrs, rpld, rple, rspc, rsps, spnc, spns, stlc, stuc
ldsa 12 $ decks affected - incio, new decks for anyc...stuc
ldsa 13
dsz 1
dsz 2 $ dsz d. shields 05 jun 79
dsz 3 $
dsz 4 $ add special entry for subn in monitor package to permit setl
dsz 5 $ system to reset procedure table pointer.
dsz 6 $ deck affected - subn.
dsz 7
dsy 1
dsy 2 $ dsy d. shields 11 apr 79
dsy 3 $
dsy 4 $ fix error (fr2.3.109) that had line pointer wrongly initialized
dsy 5 $ for access get.
dsy 6 $ deck affected - makf.
dsy 7
dsx 1
dsx 2 $ dsx d. shields 01 feb 79
dsx 3 $
dsx 4 $ 1. add check for overflow in floating input (fr2.3.81).
dsx 5 $ 2. correct typos in correction dsw.
dsx 6 $ 3. add deck 'bneqmw' to provide multi word not-equal
dsx 7 $ needed by some asm's.
dsx 8 $ 4. fix getfmt macro to see if operation done (fr2.3.90).
dsx 9 $ 5. fix monitor package to have namesets in right place
dsx 10 $ (fr2.3.91) and have name length correct (fr2.3.92).
dsx 11 $ decks affected - lhdr, setx, subn, beglio, bneqmw.
dsx 12
dsw 1
dsw 2 $ dsw d. shields 30 jan 79
dsw 3 $ 1. correct sizing error in monitor routine setx. this fixes
dsw 4 $ fr2.3.76 and requires mod -dss- in gen be applied also.
dsw 5 $ 2. drop support for s16.
dsw 6 $ 3. add fields for s40 (prime 400).
dsw 7 $ decks affected - macros, beglio, setx.
dsw 8
vax 1
vax 2 $ vax d. shields 21 nov 78 level 78325
vax 3 $ r. kenner
vax 4 $
vax 5 $ add configuration values for s32: dec vax-11/780.
vax 6 $ decks affected - macros, ltlini, ltlregl, begmon, beglio.
vax 7
dsv 1
dsv 2 $ dsv d. shields 25 sep 78
dsv 3 $
dsv 4 $ 1. add code for resident s10 system.
dsv 5 $ 2. redo some standard macros to assume standard values,
dsv 6 $ and then add exceptions for particular implementations.
dsv 7 $ 3. fix reported bug in ltlxtr for s66.
dsv 8 $ decks affected - macros, beglio, ltlxtr.
dsv 9
dsu 1
dsu 2 $ dsu d. shields 20 jun 78
dsu 3 $
dsu 4 $ 1. adjust dimension of iolb for s11.
dsu 5 $ 2. fix bug in lstime so argument initialized.
dsu 6 $ 3. fix size error in vcsmw.
dsu 7 $ 4. fix error in putf.
dsu 8 $ 5. add 'dmp=0/1' option for s66, to permit full memory
dsu 9 $ dump if system forces termination.
dsu 10 $ decks affected - ltlini, lstime, putf, beglio, vcsmw.
dsu 11
dst 1
dst 2 $ dst d. shields 06 jun 78
dst 3 $
dst 4 $ 1. fix grouping problem in ofmi.
dst 5 $ 2. add code to ltlregl for s10.
dst 6 $ 3. change fatrasz for s10.
dst 7 $ decks affected - ltlregl (resequenced), beglio, ofmi.
dst 8
3
4 $ chars d. shields 30 may 78 level 78150
5 $
6 $ include deck chars to describe character set to assist in
7 $ correct translation of source text for new machines.
8 $ correct error in use of cdc character set so that apostrophe
9 $ represented by cdc display code 3b'70' (up arrow).
10 $ decks affected - all (source resequenced).
11
12
13 $ dss d. shields 01 mar 78
14 $ r. kenner
15 $
16 $ 1. fix traceback listing for s37.
17 $ 2. fix error in multi-word not (last word was not left filled).
18 $ 3. keep track of line number of formatted files. on error
19 $ list line number and recent line. line number is number
20 $ of sio operations done since file last positioned at start.
21 $ 4. assign abnormal termination code 1008 for attempt to use
22 $ function not defined/supported by an implementation.
23 $ 5. add conditional assembly option fp to select support
24 $ of floating point (real) operations.
25 $ modify ifme, ofme and ofmf to recognize fp, and report
26 $ error 1008 if called and floating point not supported.
27 $ decks affected - ltlxtr, ioer, notmw, (misc.) io
28
29
30 $ rgb r. gezelter 25 jan 78
31 $
32 $ fix errors in mod rga.
33 $ decks affected - macros, ltlregl, errmw.
34
35
36 $ rga r. gezelter 16 jan 78
37 $
38 $ fix conditional text for s11.
39 $ decks affected - macros, ltlini, gobyerm, ltlregl, ltlterm.
40
41
42 $ dsr d. shields 18 jan 78
43 $
44 $ provide standard for handling previously 'undefined' array
45 $ slices as follows, letting 'ara(lo) to ara(hi)' be model:
46 $
47 $ if lo<=1, there is an error which should be reported.
48 $ if hi>=lo, a slice is to be transmitted as before.
49 $ if hi<(lo-1), there is an error which should be reported.
50 $ if hi=(lo-1), the slice is said to be 'null', and
51 $ no data is to be transmitted.
52 $
53 $ the null slice is consistent with zero-width fields and
54 $ zero-trip do loops, and permits such constructs as
55 $ write f, ptr, ara(1) to ara(ptr);
56 $ where ptr has value zero.
57 $
58 $ the above changes are reflected by making the word count
59 $ parameter to uinp and uout be signed. word count of
60 $ zero is to result for null slice, and a negative word
61 $ count indicates an invalid slice, resulting from lo<=1
62 $ or hi<(lo-1).
63 $ add error message to ioer for invalid array slice.
64 $ decks affected - uinp, uout, ioer.
65
66
67 $ dsq d. shields 05 jan 78
68 $
69 $ 1. fix reported bug in support of -column- and
70 $ -x(negative)- control formats by adding field -lbmax-
71 $ to record true length of coded line.
72 $ 2. slightly improve efficiency for s37 by redefining
73 $ some file attribute fields as byte fields.
74 $ decks affected - beglio, lpin, flsh, putf, gcfp.
75
76
77 $ rke r. kenner 02 jan 78
78 $
79 $ 1. fix errors in conditional text for s37 and selection
80 $ of which routines should be compiled for various machines.
81 $ 2. have -stitlr- clear title before it sets new one.
82 $ 3. add third parameter to -rewisio- calls.
83 $ 4. correct formatting problem in -ltlregl- for s37.
84 $ 5. add -prs3-, -prs4-, and -prs5- to call -prst- with fewer
85 $ parameters.
86 $ 6. fix bug in -trfl- which causes labels not to be printed
87 $ in flow trace and improve format of labels that get printed.
88 $ 7. add missing 'access' statements in the multi-word routines.
89 $ 8. add a -ltlterm- for the s37.
90 $ 9. add new -ltlxtr- and some error routines for s37.
91 $ decks affected - macros, lcp, incio, ltlregl, begmon, trfl,
92 $ prfl, deci, ltlterm, ltlxtr1, ltlfin,
93 $ s37xtr1 (new), s37errs (new)
94
95
96 $ dsp d. shields 08 nov 77
97 $
98 $ revise .e. procedures to handle zero length extracts correctly.
99 $ decks affected - easmw, eexmw.
100
101
102 $ dso d. shields 31 oct 77
103 $ r. kenner
104 $
105 $ 1. add conditional text for s10 (dec 10).
106 $ 2. clean up program initialization (cf ltlini).
107 $ 3. clean up makf, in particular to permit sio to return
108 $ line size.
109 $ 4. clean up lcp, and do more argument checking in contlpr.
110 $ 5. clean up monitor package, recognize program procedure.
111 $ 6. assign an encoding for abnormal termination codes passed
112 $ to ltlfin, for use on s37.
113 $ decks affected - most (source has been resequenced).
114
115
116 $ dsn d. shields 18 oct 77
117 $
118 $ make several fixes and changes to io, as follows.
119 $ 1. do not permit read past end without filestat(,end) check.
120 $ 2. improve error handling.
121 $ 3. do conversion using negative arithmetic to avoid problems
122 $ on twos complement machines.
123 $ 4. simplify makf by having gen do some tests that can be done
124 $ at compile time.
125 $ 5. do not require column for sign position in integer output.
126 $ 6. on s66, no longer attempt to convert integers of more than
127 $ 48 bits (they can only be added and subtracted, anyway.)
128 $ decks affected - almost all from beglio thru endlio, lpin (new
129
130
131 $ rkd r. kenner 31 may 77
132 $
133 $ detected bug - grouping is done before field is blank filled.
134 $ this causes unexpected results.
135 $ fix - move call to -ogrp- in -pfin- to after the filling code.
136 $ deck affected - pfin
137
138
139 $ rkc r. kenner 27 may 77.
140 $
141 $ 1. correct some macros for s16.
142 $ 2. fix slighly conservative test in getipp.
143 $ 3. change data statements in ltllio for ions to executable
144 $ initialization to allow for space saving on s16.
145 $ decks affected - macros, getipp, ltllio.
146
147
148 $ rkb r. kenner 26 may 77.
149 $
150 $ correctly report an error in makf using ioer instead of lcp,
151 $ as s16 does not have lcp.
152 $ decks affected - makf, ioer.
153
154
155 $ dsm d. shields 24 may 77.
156 $
157 $ reported bug - 'writing' flag not reset for reading.
158 $ cause - an elseif in vali should be else.
159 $ deck affected - vali.
160
161
162 $ dsl d. shields 13 may 77
163 $
164 $ 1. make -ignore- level of string access files one, so conversion
165 $ and truncation errors on such files not fatal by default.
166 $ 2. add procedure 7nsigl$io(f,ilev) to set ignore level of file f
167 $ to ilev, to permit user to override default settings.
168 $ decks affected - makf, ioer, sigl(new).
169
170
171 $ dsk d. shields 06 may 77
172 $
173 $ 1. reported bug - on s16, format 'b(7,3)' gives occasional
174 $ erroneous high order bits.
175 $ cause - ofmb was not resetting for high order byte.
176 $ 2. reported bug - -a- input format not working on string file.
177 $ cause - s66 special case did not check for string file.
178 $ 3. reported bug - list input mode bombing on end of file.
179 $ 4. correct code for -b- conversion in case byte width three and
180 $ word size not multiple of three.
181 $ cause - debug trace code inadvertently left in.
182 $ decks affected - ofmb, ifma, ifmb, ilst, pcsa.
183
184
185 $ dsj d. shields 21 apr 77
186 $
187 $ install revised semantics for string access files.
188 $ decks affected - makf, rwnd, istr, ostr, gcfp, pcsa(new), ioer,
189 $ grem (deleted), prem (deleted).
190
191
192 $ dsi d. shields 14 apr 77.
193 $
194 $ 1. make 'line limit exceeded' force abnormal termination.
195 $ 2. support 'erexit' option, conditioned by name erexit, if
196 $ operating system permits processing after adress exception,
197 $ time limit, etc. this involves two procedures. procedure
198 $ 7nerxi$si is called by ltlini to initialize for recovery.
199 $ the recovery is nominally named '7nerxp$si' but is not
200 $ directly referenced. erxp$si should call ltlfin(1,0) to
201 $ indicate abnormal termination.
202 $ 3. ltlfin now calls procedure usratp (user a-bnormal
203 $ t-ermination p-rocedure) in case of abnormal
204 $ termination. usratp should not attempt to continue
205 $ execution.
206 $ decks affected - linelr, ltlini, ltlfin.
207
208
209 $ dsh d. shields 14 mar 77.
210 $
211 $ correct some problems in ofmf in handling of small quantities.
212 $ deck affected - ofmf.
213
214 $ sys16 t. stuart 5 april 1977
215
216 $ 1. redefine numerous constants for the s16 implementation
217 $ 2. correct an extractor macro in deck begmon
218 $ 3. add deck io16 which contains system 16 replacements for some
219 $ i/o procedures
220
221
222
223 $ rka r. kenner 6 april 1977
224 $
225 $ correct two bugs in lio:
226 $ 1. when error 12 (cannot allocate line buffer) occurs, the access
227 $ value for the file must be cleared. otherwise the program
228 $ will not terminate cleanly because -ltllio- will attempt to
229 $ disconnect a file which was not connected.
230 $ 2. there is a bug in -rlse- where the line buffers are moved
231 $ down. this causes spurious error 12's.
232 $ decks affected - makf, rlse.
233
234
235 $ dsg d. shields 14 mar 77.
236 $
237 $ reset -endseenv- before call to getw in istr so can read past
238 $ end marks in file.
239 $ deck affected - istr.
240
241
242 $ dsf d. shields 25 february 1977.
243 $
244 $ 1. fix size error of -printsw- in -flsh-.
245 $ 2. correct retrieval of io parameters in some put procedures
246 $ which inadvertently accessed input parameter list.
247 $ 3. install width parameters for -bl-, -el-, -fl- and -rl-
248 $ formats.
249 $ decks affected - flsh, ofmb, ofme, ofmf, ofmi, ofmr.
250
251
252 $ dse d. shields 31 january 1977.
253 $
254 $ 1. correct error in computation of point position by vnum.
255 $ 2. initialize variable deci_nsd in ltllio.
256 $ decks affected - ltllio, vnum.
257
258
259 $ dsd d. shields 27 january 77.
260 $
261 $ 1. insert missing assignment of -gw- in ofmi.
262 $ 2. use .s. instead of .ch. in some -lcp- string operations.
263
264
265 $ dsc d. shields 26 january 77.
266 $
267 $ 1. make linesize 90 for std. input file for s66.
268 $ 2. correct misplaced test in gcfp.
269 $ 3. correct error processing in makf to use ioer.
270 $ 4. move misplaced declaration in ifma.
271 $ decks affected - gcfp, ltllio, makf, ioer, ifma.
272
273
274 $ dsb d.shields 24 january 77.
275 $
276 $ 1. reported bug - coded line not flushed on rewind.
277 $ fix - include code to write last line in rwnd.
278 $ deck affected - rwnd.
279
280
281 $ dsa d. shields 20 jan 77
282 $
283 $ 1. clear line buffer after -put-, so -column- format works
284 $ correctly.
285 $ 2. install code in ltlfin to time execution.
286 $ 3. drop procedure -exitl- (ltlfin is to be used).
287 $ decks affected - macros, ltllib, ltlfin, exitl(dropped),
288 $ flsh, gcfp.
289
1 .=member begltl
2 $ begin little portion of ltllib
1 .=member macros
2
dsi 35
dsi 36 $ select mc if lower-case characters available.
dsi 37
dsi 38 .+set mc $ assume mixed-case characters available.
dsi 39
dsi 40 .+s66.
dsi 41 .-set mc $ upper case only on s66
dsi 42 ..s66
dsi 43
plf 13 .+set plf0 $ assume commas in parm lists always separators
dsi 44 $ if mixed-case available, default primary case is upper.
dsi 45 $ obtain lower primary case by defining mcl.
dsi 46
3 $ indicate procedures implemented by environment.
4
5 $ since multiword arithmetic temporarily dropped,
6 $ indicate that defined in environment so little
7 $ multiword arithmetic procedueres not compiled.
8 .+set defenv_addmw
9 .+set defenv_submw
10 .+set defenv_mulmw
11 .+set defenv_divmw
12 .+s11.
13 .+set defenv_readsos
plf 14 .-set plf0
plf 15 .+set plf1
14 ..s11
15
dsv 10 .+s10.
dsv 11 .+set defenv_linepack
dsv 12 +* linepack(pa, ua, nc) =
dsv 13 call 6npack$l(pa, 1, ua, 1, nc); **
dsv 14 .+set defenv_readsos
plf 16 .-set plf0
plf 17 .+set plf1
dsv 15 ..s10
utsb 1
utsb 2 .+s32.
utsb 3 .+set s32v $ assume vms.
utsb 4 ..s32
utsb 5
utsb 6 .+s32u.
utsb 7 .+s32.
utsb 8 .-set s32v $ do not want vms.
utsb 9 .+set s32u $ want unix os.
utsb 10 ..s32
utsb 11 .+set mcl $ want primary case to be lower.
utsb 12 ..s32u
vax 8 .+s32.
plf 18 .-set plf0
plf 19 .+set plf1
vax 9 .+set defenv_readsos
vaxa 1 .+set defenv_linepak
utsb 13 .+s32v.
vaxa 2 +* linepak(pa, ua, nc) = $ use interface procedure.
vaxa 3 7npack$li(pa, 1, ua, 1, nc) **
utsb 14 ..s32v
vaxa 4 .+set defenv_ss $ string search procedures defined in environment
vaxb 1 .+set defenv_casmw
vaxb 2 .+set defenv_catmw
vaxb 3 .+set defenv_cexmw
vaxb 4 .+set defenv_ceqmw
vaxb 5 .+set defenv_cinmw
vaxb 6 .+set defenv_vcsmw
vax 10 ..s32
16 .+s37.
mtsa 1 .+set s37cms $ assume cms operating system
mtsa 2
mtsa 3 .+s37mts $ if mts operating system
mtsa 4 .-set s37cms $ reset cms flag
mtsa 5 .+set s37mts $ set mts flag (redundant)
mtsa 6 ..s37mts
mtsa 7
17 .+set defenv_linepak
18 +* linepak(pa, ua, nc) = $ use interface procedure.
19 7npack$li(pa, 1, ua, 1, nc) **
20 .+set defenv_readsos
21 .+set defenv_lstime $ lstime defined by environment.
22 .+set defenv_fbtmw
23 .+set defenv_nbtmw
24 .+set defenv_casmw
25 .+set defenv_catmw
26 .+set defenv_cexmw
27 .+set defenv_ceqmw
28 .+set defenv_cinmw
29 .+set defenv_vcsmw
30 .+set defenv_ersmw
31 ..s37
utsa 9
utsa 10 .+s47.
utsa 11 .-set defenv_linepak
utsa 12 .+set defenv_readsos
utsa 13 .-set defenv_lstime $ lstime defined by environment.
utsa 14 .-set defenv_fbtmw
utsa 15 .-set defenv_nbtmw
utsa 16 .-set defenv_casmw
utsa 17 .-set defenv_catmw
utsa 18 .-set defenv_cexmw
utsa 19 .-set defenv_ceqmw
utsa 20 .-set defenv_cinmw
utsa 21 .-set defenv_vcsmw
utsa 22 .-set defenv_ersmw
utsa 23 ..s47
32
33 .+s66.
34 .+set defenv_linepak
35 +* linepak(pa, ua, nc) = $ use interface procedure.
36 7npack$li(pa, 1, ua, 1, nc) **
37 .+set defenv_lctime
38 .+set defenv_lstime $ lstime defined by environment.
ssa 1 .+set defenv_ss $ string search procedures defined in environment
39 .+set defenv_andmw
40 .+set defenv_iormw
41 .+set defenv_xormw
42 .+set defenv_notmw
43 .+set defenv_fbtmw
44 .+set defenv_nbtmw
45 .+set defenv_casmw
46 .+set defenv_cexmw
47 .+set defenv_catmw
48 .+set defenv_ceqmw
49 .+set defenv_cinmw
50 .+set defenv_vcsmw
51 .+set defenv_ersmw
52 ..s66
53
utsb 15 .+s32u.
dsf 16 $ disable defenv options for initial unix checkout.
dsf 17 .+set defenv_readsos
dsf 18 .-set defenv_linepak
dsf 19$ +* linepak(pa, ua, nc) = $ use interface procedure.
dsf 20$ 7npack$li(pa, 1, ua, 1, nc) **
dsf 21 .-set defenv_ss $ string search procedures defined in environment
dsf 22 .-set defenv_casmw
dsf 23 .-set defenv_catmw
dsf 24 .-set defenv_cexmw
dsf 25 .-set defenv_ceqmw
dsf 26 .-set defenv_cinmw
dsf 27 .-set defenv_vcsmw
utsb 16 ..s32u
dsf 29
54
55 $ end of environment-defined procedure list.
56
57 $ select those procedures which only exist in the environment
58 $ and select which ones exists for each machine.
dsv 16 .+s10.
dsv 17 .+set txtl_env
dsv 18 .+set unpk_env
dsv 19 .+set pack_env
dsv 20 .+set spak_env
dsv 21 ..s10
vaxa 5 .+s32.
vaxa 6 .+set txtl_env,unpk_env,pack_env,spak_env
vaxa 7 ..s32
59 .+s66.
60 .+set txtl_env,unpk_env,pack_env,spak_env
61 ..s66
62 .+s37.
63 .+set txtl_env,unpk_env,pack_env,spak_env
64 ..s37
utsa 24 .+s47.
utsa 25 .-set txtl_env,unpk_env,pack_env,spak_env
utsa 26 ..s47
65
utsb 17 .+s32u.
dsf 31 $ delete special env code for unix checkout.
dsf 32 .-set txtl_env,unpk_env,pack_env,spak_env
utsb 18 ..s32u
dsh 17
utsa 27 .+s47.
utsa 28 .+set mcl $ primary case lower
utsa 29 ..s47
utsa 30
dsi 48
dsi 49 .+mc.
dsi 50 .+mcl. $ if mixed-case to be lower
dsi 51 +* ctpc(x) = ctlc(x) ** $ primary case is lower.
dsi 52 +* stpc(x) = stlc(x) ** $ primary case is lower.
dsi 53 .-mcl.
dsi 54 +* ctpc(x) = ctuc(x) ** $ primary case is upper.
dsi 55 +* stpc(x) = stuc(x) ** $ primary case is upper.
dsi 56 ..mcl
dsi 57 ..mc
dsi 58
66 /*
67 abnormal termination codes.
68 the following codes are used as the second argument to
69 -ltlfin- to indicate type of abnormal termination.
70
71 some implementations may report these codes to the user as
72 and abend or completion code.
73
74 1001 line limit exceeded.
75 1002 bad go to index.
76 1003 inclusion depth too great or inclusion recursion.
77 1004 bad name for cross-reference file.
78 1005 array index out of range.
79 1006 assertion failed.
80 1007 unable to open standard print file.
81 1008 request for undefined/unsupported function
dsj 12 1009 expiration date passed
dsl 7 1010 unable to open inclusion file.
82 1101-1199 math library error n-1100.
83 1201-1299 multiword error n-1200.
84 1301-1399 little input/output error n-1300
85 2000+ reserved for use by machine-dependant environment
86 */
87
90 $ conditional assembly options.
91
92 $ select extime to have ltlfin display execution time.
dse 11 $ extime causes inclusion of code to support execution timing.
dse 12 $ the etim program parameter determines if timings listed.
dse 13 $ select extime_off to have times not listed by default.
vaxa 9 .+set extime
dse 14 .+set extime_off
93 .+s66.
94 .+set extime
exta 1 .-set extime_off
95 ..s66
96
97 $ select wsm3 if word size is multiple of three.
dsv 22 .+s10.
dsv 23 .+set wsm3
dsv 24 ..s10
98 .+s66.
99 .+set wsm3
100 ..s66
101
102 $ select erexit if error exit processing available.
106 .+s66.
107 .+set erexit
smp 1 $ select -smps66- to enable nos support of -smp- execution
smp 2 $ profile.
smp 3 .+set smps66
108 ..s66
109
110 $ select inclseq to use sequencial model of inclusion.
111 $ since all we have now is sequencial model, this is set.
112 .+set inclseq
113
114 +* slen = .len. ** $ length field of sds
115
116 +* sorg = .f. .sl.+1, .so., ** $ origin field of sds
117
118 +* ldcs = (.sl.+.so.) ** $ combined length of sds origin, leng
119
120 +* ws = .ws. ** $ number of bits in machine word
121
122 +* ps = .ps. ** $ number of bits in machine pointer (address)
123
124 +* cs = .cs. ** $ number of bits in character
125
126 +* yes = 1 **
127 +* no = 0 **
128
129 +* cpw = (.ws./.cs.) ** $ characters per machine_word
130
131 +* blankword = $ word of blanks
ldsa 14 .+s10 4r $ 9-bit ascii version
133 .+s11 2r
vax 11 .+s32 4r
135 .+s37 4r
utsa 31 .+s47 4r
dsw 9 .+s40 2r
136 .+s66 10r
137 **
138
139 +* charofdig(d) = $ maps digit to character code
140 (d+1r0) $ if characters in order
141 **
142
143 +* digofchar(c) = $ maps decimal character onto value
144 (c-1r0) $ if characters for digits in order
145 **
146
147 +* sds(n) = .sds. (n) ** $ size of n character string
148
dsv 25 +* letimesz = ws ** $ size of -letime- result.
dsv 26 .+s11 +* letimesz = 32 **
156
157
dsv 27 +* filenamelen = 20 ** $ default maximum file name length.
dsb 17 .+s32 +* filenamelen = 64 **
utsa 32 .+s47 +* filenamelen = 64 **
165
dsv 28 +* filenamelenblanks = 20q **
dsb 18 .+s32.
dsb 19 +* filenamelenblanks =
dsb 20 64q
dsb 21 **
dsb 22 ..s32
utsa 33 .+s47.
utsa 34 +* filenamelenblanks =
utsa 35 64q
utsa 36 **
utsa 37 ..s47
173
174 $ spplen is string program parameter maximum length.
175 +* spplen = 20 **
dsb 23 .+s32 +* spplen = 64 **
utsa 38 .+s47 +* spplen = 64 **
176 $ macros related to user option string processing
177 $ see procedures reados and readsos.
178
179 +* oscmax = 80 ** $ maximum length of option string
ldsd 10 .+s32 +* oscmax = 512 ** $ accept long parameter strings for s32.
ldsc 10 .+s37 +* oscmax = 300 ** $ accept long parameter strings for s37.
utsc 1 .+s47 +* oscmax = 300 ** $ accept long param. strings. uts
dsb 25 +* ospmax = filenamelen ** $ maximum length of strings used for
dsc 29 $ getapp_len is maximum length of string returned by getapp.
dsc 30 $ this cannot exceed maximum length of sds.
dsc 31 +* getapp_len = 128 **
dsc 32 .+s32 +* getapp_len = 240 **
utsa 40 .+s47 +* getapp_len = 240 **
dsc 33
181 $ string parameter codes and values.
183
184
185 +* q3(a,b,c) = a b c**
186 +* macdef(text) = q3(+,*text*,*)**
187 +* macdrop(mname) = macdef(mname=)**
188
dsv 29 +* szmax = 2047 ** $ maximum item size.
198
199 +* wordi(i,arg) = .f. 1+(i-1)*ws, ws, arg **
200 +* lcpns = $ name of lcp nameset.
201 6nlcp$ns
202 **
203
204 $ the output functions to be used in generating print lines
dsw 10 .+s40.
dsw 11 $ change names on s40 to create 4 character unique names
207 +* wordsr = wrdsr ** +* wordlfr = wrdfr **
208 +* intlpr = intpr ** +* octlpr = octpr **
209 +* readsos =rdsos **
dsw 12 ..s40
211 $
212 +* endl = call endlr; ** $ end current line
213 +* textl(s) = call textlr(s); ** $ add string to current line
214 +* intl(i) = call intlr(i);** $ add integer (5 cols) to line
215 +* intlp(i,c) = call intlpr(i,c);** $ add c column integer to li
216 +* octl(i) = call octlr(i); ** $ add octal value to line
217 +* octlp(v,c) = call octlpr(v,c);**$ output v in octal,
218 +* octlv(v) = call octlpr(v,((.fb.v-1)/3+1)); **
219 $ output v as octal, leadnng zeros suppressed
220 +* hexlp(v, c) = call hexlpr(v, c); ** $ output in hex
221 +* wordl(i) = call wordlr(i);** $ add word (00 ends) to line
222 +* wordlf(i) = call wordlfr(i);** $ add full word to line
223 +* charl(c) = call charlr(c); ** $ add chaacter to line
224 +* tintl(s,i) = call tintlr(s,i); ** $ output text and integer
225 +* getlpos(p) = call contlpr(1,p);** $ get currnt line position
226 +* setlpos(p) = call contlpr(2,p);** $ set current line position
227 +* skipl(p) = call contlpr(3,p); ** $
228 +* tabl(p) = call contlpr(4,p); ** $ tab to column -p-
229
230 $ pflen is the length of a print line, including the carriage
231 $ control character. the value of 133 is suggested as this is
232 $ value for s37.
dsk 23 +* pflenmax =
234 133
235 **
236
dsv 30 $ print file parameter initial values.
dsv 31
dsv 32 +* pfdefaultlinelimit = 'pfll=0/' **
dsv 33
dsc 34 +* pfdefaultpagelimit = 'pfpl=100/0' **
vaxc 1 $ for s32, make page limit infinite by default.
vaxc 2 .+s32 +* pfdefaultpagelimit = 'pfpl=0/0' **
dsi 59 $ for s37, make page limit infinite by default.
dsi 60 .+s37 +* pfdefaultpagelimit = 'pfpl=0/0' **
utsa 41 .+s47 +* pfdefaultpagelimit = 'pfpl=0/0' **
dsv 35
dsv 36 +* pfdefaultlinesperpage = 'pflp=60/' **
dsv 37
dsv 38 $ sitename appears as part of standard title line.
dsc 35
dsc 36 +* sitename = 'nyu' **
dsc 37 +* sitenamelen = 3 ** $ length of sitename (cf. ltitlr)
270
271 +* lstimelen = 30 **
272
273 $ memory access procedure names (use with caution).
274 +* memget = 7nmget$li **
275 +* memptr = 7nmptr$li **
276 +* memput = 7nmput$li **
277
338
339 +* wpc = $ words per card
ldsa 15 .+s10 20 $ 80 columns (4*20)
341 .+s11 40 $ 80 column (2*40)
vax 12 .+s32 20 $ 80 columns (4*20)
343 .+s37 20 $ 80 columns (4*20)
utsa 42 .+s47 20 $ 80 columns (4*20)
dsw 13 .+s40 40 $ 80 column (2*40)
344 .+s66 10 $ 90 columns (10*9) 90 for update compile files.
345 **
dsv 41 $ mradix is default machine radix (assume octal).
dsv 42
dsv 43 +* mradix = 3 **
vax 13 .+s32 +* mradix = 4 ** $ use hexadecimal for s32
dsv 44 .+s37 +* mradix = 4 ** $ use hexadecimal for s37
utsa 43 .+s47 +* mradix = 4 ** $ use hexadecimal for s37
dsv 45
dsv 46 $ bwordl lists machine word in appropriate format.
dsv 47 $ bwordlen is number of characters for bwordl.
dsv 48 $ addrl lists machine address in appropriate format.
dsv 49 $ addrlen is length of addrl result.
dsv 50
dsv 51 +* bwordl(w) = octl(w); **
vax 14 .+s32 +* bwordl(w) = hexlp(w, 8); ** $ s32 is hex.
dsv 52 .+s37 +* bwordl(w) = hexlp(w, 8); ** $ s37 is hex.
utsa 44 .+s47 +* bwordl(w) = hexlp(w, 8); ** $ s37 is hex.
dsv 53
dsv 54 +* bwordlen = (ws/3) **
vax 15 .+s32 +* bwordlen = 8 **
dsv 55 .+s37 +* bwordlen = 8 **
utsa 45 .+s47 +* bwordlen = 8 **
dsv 56
dsv 57 +* addrl(w) = octlp(w, 6); **
vax 16 .+s32 +* addrl(w) = hexlp(w, 8); **
dsi 61 .+s37 +* addrl(w) = hexlp(w, 6); **
utsa 46 .+s47 +* addrl(w) = hexlp(w, 6); **
dsv 59
vax 17 +* addrlen = ((ps + mradix - 1) / mradix) **
dsv 62
dsv 63 $ inclusion processing.
dsv 64 $ memnamelenmax is maximum length of member name.
dsv 65 $ inclevmax is maximum depth of inclusion.
dsv 66 $ inclibname is name of standard inclusion library.
dsv 67
dsv 68 +* memnamelenmax = 20 **
dsv 69
dsv 70 +* inclevmax = 6 **
349
350 .-set makfprfi $ print file status in makf (debug).
351
352 $ set fp if floating arithmetic is supported, default is on.
353 .+set fp
354 .+s11.
355 .-set fp
356 ..s11
357
358 +* deciaralen = 40 ** $ length of integer conversion array.
359 +* deci_lsd = 40 **
360
361 $ macros for -little- i/o procedures - mostly, fields of status words
362
dsv 74 $ maxfiles is maximum number of simultaneously open files.
dsv 75
dsv 76 +* maxfiles = 10 **
dsv 77 .+s11 +* maxfiles = 15 **
dsf 36 .+s32 +* maxfiles = 20 **
dsi 62 .+s37 +* maxfiles = 20 **
utsa 47 .+s47 +* maxfiles = 20 **
dse 17
dse 18 $ termfilenumber is unit number for terminal file. since this
dse 19 $ file possibly open on all runs, it is allocated as largest
dse 20 $ possible number.
dse 21 $ incfilenumber is unit number for text inclusion library.
dse 22 $ it is not always needed, and so is allocated in same way as
dse 23 $ term file. note that termfile and include file were added after
dse 24 $ standard input and output file numbers established. they are
dse 25 $ allocated 'at the end' to avoid conflicts with old programs.
dse 26
dse 27 +* termfilenumber = maxfiles **
dse 28 +* incfilenumber = (maxfiles-1) ** $ inclusion file number.
370
371 $ since two's complement machines have a negative value whose
372 $ absolute value is one greater than the value of the largest
373 $ positive integer, integer conversion is done using negative
374 $ values. maxnegint is the value of the smallest negative
375 $ integer.
376
377 +* maxnegint = $ value of smallest negative integer.
378 $ give as bit constants to avoid conversion problems.
379 .+s10 4b'8 0000 0000'
380 .+s11 3b'100000'
vax 18 .+s32 4b'8000 0000'
382 .+s37 4b'8000 0000'
utsa 48 .+s47 4b'8000 0000'
dsw 14 .+s40 4b'8000'
383 .+s66 3b'7777 0000 0000 0000 0000'
384 **
385
386
dsv 78 $ gotoem gives name of error proc for indexed go to error.
dsv 79 +* gotoem = 7ngoto$em **
dsv 80 .+s11 +* gotoem = 6ngoto$m **
goa 1 .+s10 +* gotoem = 6ngoto$m **
394
395 $ codes used for accessv values.
396 +* access_get = 1 **
397 +* access_print = 2 **
398 +* access_put = 3 **
399 +* access_read = 4 **
400 +* access_string = 5 **
401 +* access_write = 6 **
402 +* access_release = 7 **
1 .=member ltlini
2 subr ltlini(c); $ initiate little system.
3 $ initialize little library. c is zero if little alone,
4 $ nonzero if running in presence of host.
5 $ for now, assume little alone.
6 size c(ps); $ case.
7
8 $
9 $ all global variables used by the little library procedures
10 $ not otherwise explicitly defined in their own nameset are
11 $ to be defined here in nameset -lcpns-.
12
dsm 12 nameset lcpns;
13 .+extime size timeon(letimesz);
dsc 38 .+extime size etim(ps); $ on if want execution time reported
15 size inputfilename(.sds. filenamelen); $ input file name.
16 size printfilename(.sds. filenamelen); $ print file name.
dsc 39 size termfilename(.sds. filenamelen); $ terminal file name.
dsc 40 size inclibname(.sds. filenamelen); $ include file name.
dsk 24 size pfl(cs); dims pfl(pflenmax); $ print file line.
18 size pfcol(ps); $ print line column (of next character)
19 data pfcol = 2;
20 size pfline(ps); $ print line number (last line completed)
21 data pfline = 0;
22 size pfpage(ps); $ print file page number.
23 size pflinetotal(ps); $ total lines written on print file.
24 data pflinetotal = 0; $ no lines written at start
25 size pflinelimit(ps); $ print file line limit.
26 size pfpagelimit(ps); $ print file page limit.
27 size pfcarriage(1); $ on to allow carriage control in col. 1.
28 size pflinesperpage(ps); $ lines per print file page.
dsk 25 size pftitle(.sds. pflenmax); $ main print title.
dsk 26 size pfstitle(.sds. pflenmax); $ print file subtitle.
31 size pftitling(1); $ on if titline print file.
32 data pftitling = no;
33 size pfpaging(1); $ on if forming print file pages.
34 data pfpaging = no;
35 size pfpagefield(ps); $ field in title for page number.
36 size pfdatefield(ps); $ field in title for date.
37 size pftermflag(1); $ on to write to terminal file
38 data pftermflag = no; $ default is not to write to term file
39 size pflistflag(1); $ on to write to listing file
40 data pflistflag = yes; $ default is to write to list file
41 size pftermopen(1); $ on if terminal file open
42 data pftermopen = no; $ terminal file is initially closed
43 size dblinelim(ps); $ monitor line limit
44 size dblinect(ps); data dblinect=1; $ line counter
45 size dbstoplist(1); data dbstoplist = no; $ on to stop prin
46 size dblinenum(ps); data dblinenum = 0; $ used to space lines
47 data pfl(1) = 1r ; $ carriage control is initially blank
dsk 27 size pflen(ps); $ length of print line.
dsk 28 data pflen = pflenmax;
dsk 29 size termh(ps); $ on for terminal header.
dsk 30 data termh=yes;
dsn 14 size termprompt(.sds. filenamelen);
dsn 15 data termprompt = '>';
48 end nameset;
49
50 call sysini(0); $ perform necessary system initialization.
51
52 .+extime call letime(timeon); $ get starting time.
smp 4 .+smps66 call 7nsmpi$li; $ to check for -smp- run.
53 call ltlsio(0);
54
dsc 41 .+extime.
dsc 42 $ etim=0 permits suppressing reporting elapsed time if
dsc 43 $ execution time being noted.
dse 29 .-extime_off call getipp(etim, 'etim=1/0'); $ get option
dse 30 .+extime_off call getipp(etim, 'etim=0/1'); $ get option
dsc 45 ..extime
dsc 46
55 $ get names of standard input and print files.
56
57 .+s10.
58 call getspp(inputfilename, 'i=*.ltl/');
59 call getspp(printfilename, 'l=*.lst/');
dsc 47 call getspp(termfilename, 'term=tty:/');
dsc 48 call getspp(inclibname, 'ilib=syslib/');
60 ..s10
61 .+s11.
62 call getspp(inputfilename, 'i=ti:/');
63 call getspp(printfilename, 'l=ti:/');
dsc 49 call getspp(termfilename, 'term=ti:/');
dsc 50 call getspp(inclibname, 'ilib=syslib/');
64 ..s11
utsb 19 .+s32u.
utsb 20 call getspp(inputfilename, 'i=stdin/');
utsb 21 call getspp(printfilename, 'l=stdout/');
utsb 22 call getspp(termfilename, 'term=stderr/');
dsc 52 call getspp(inclibname, 'ilib=syslib/');
utsb 23 ..s32u
utsb 24 .+s32v.
utsb 25 call getspp(inputfilename, 'i=sys$input/');
utsb 26 call getspp(printfilename, 'l=sys$output/');
utsb 27 call getspp(termfilename, 'term=sys$error/');
utsb 28 call getspp(inclibname, 'ilib=syslib/');
utsb 29 ..s32v
mtsa 8 .+s37cms.
66 call getspp(inputfilename, 'i=sysin/');
ldsc 11 call getspp(printfilename, 'l=sysprint/');
dsi 63 call getspp(termfilename, 'term=systerm/');
dsc 54 call getspp(inclibname, 'ilib=syslib/');
mtsa 9 ..s37cms
mtsa 10 .+s37mts.
mtsa 11 call getspp(inputfilename, 'i=*source*/');
mtsa 12 call getspp(printfilename, 'l=*sink*/');
mtsa 13 call getspp(termfilename, 'term=*msink*/');
mtsa 14 call getspp(inclibname, 'ilib=syslib/');
mtsa 15 ..s37mts
utsa 49 .+s47.
utsb 30 call getspp(inputfilename, 'i=stdin/');
utsb 31 call getspp(printfilename, 'l=stdout/');
utsb 32 call getspp(termfilename, 'term=stderr/');
utsa 53 call getspp(inclibname, 'ilib=syslib/');
utsa 54 ..s47
69 .+s66.
dsu 12 nameset 7nerxd$ns; $ for abnormal termination dump.
dsu 13 size atdopt(ws); $ adnormal termination dump option.
dsu 14 data atdopt = 0; $ no dump by default.
dsu 15 end nameset;
dsu 16
dsu 17 call getipp(atdopt, 'dmp=0/1'); $ get termination dump option.
70 call getspp(inputfilename, 'i=input/compile');
71 call getspp(printfilename, 'l=output/list');
dsc 55 call getspp(termfilename, 'term=/term');
dsc 56 call getspp(inclibname, 'ilib=inclib/');
72 ..s66
73
74 $ get parameters of standard print file.
75
76 call getipp(pflinelimit, pfdefaultlinelimit);
77 call getipp(pfpagelimit, pfdefaultpagelimit);
78 call getipp(pflinesperpage, pfdefaultlinesperpage);
dsk 31 call getipp(pflen, 'pfcl=0/80');
dsk 32 if (pflen=0) pflen = pflenmax;
dsk 33 if (pflen>pflenmax) pflen=pflenmax;
79 call getipp(pfcarriage, 'pfcc=1/0');
80 if pflinelimit=0 & pfpagelimit>0 then
81 pflinelimit = pfpagelimit * pflinesperpage;
82 end if;
83
84 dblinelim = pflinelimit*9/10; $ set monitor line limit.
85
dsnc 7 $ get prompting character. the default value is system dependent.
dsnc 8 .+s10 call getspp(termprompt,'termp=*/');
dsnc 9 .+s11 call getspp(termprompt,'termp=>/');
dsnc 10 .+s32u call getspp(termprompt,'termp=:/');
dsnc 11 .+s32v call getspp(termprompt,'termp=>/');
dsnc 12 .+s37 call getspp(termprompt,'termp=>/');
dsnc 13 .+s47 call getspp(termprompt,'termp=:/');
dsnc 14 .+s66 call getspp(termprompt,'termp=>/');
dsna 2 if (termprompt.seq.'0') .len. termprompt=0;
dsna 3
86 call ltllio(0); $ initialize little io.
dsc 57
dsc 58 $ open terminal file if one desired.
dsc 59 if (.len. termfilename) call opnterm(termfilename);
dsk 34 call getipp(termh, 'termh=1/0');
dsk 35 .+s32 call getipp(termh, 'termh=0/1');
dsna 4 .+s47 call getipp(termh, 'termh=0/1');
87
dsh 18 .-defenv_ss.
dsh 19 $ if using library-defined string search primitives, call
dsh 20 $ blds to guarantee that ss namesets initialized.
dsh 21 $ do this by redundant, and harmless, construction of a string set.
dsh 22 call blds(' ', 1);
dsh 23 ..defenv_ss
88 end subr ltlini;
smp 5 .+smps66.
smp 6 subr 7nsmpi$li; $ smp execution initiator.
smp 7 $ retrieve program parameters 'smplo=0/0' and 'smphi=0/0'.
smp 8 $ if either nonzero, initiate smp request to generate
smp 9 $ execution profile. as system will only accept request
smp 10 $ if job origin is 'system origin', issue dayfile
smp 11 $ messages before and after system request.
smp 12 $ smplo is first word address of area to monitor,
smp 13 $ smphi is last word address.
smp 14 size memget(ws);
smp 15 size smplo(ws), smphi(ws);
smp 16 size wd(ws);
smp 17
smp 18 call getipp(smplo, 'smplo=0/0');
smp 19 call getipp(smphi, 'smphi=0/0');
smp 20
smp 21 if (smphi>0) & (smplo(ynow+1)) return; $ if expiration far in the future.
14 $ expiration possible, find common origin for days, then determine
15 $ days left until expiration.
16 yorg = ynow; if (yorg>yexp) yorg = yexp; $ set origin.
17 left = ((yexp-yorg)*365 + dexp) - ((ynow-yorg)*365+dnow);
18 if left <= 0 then $ if expired
19 textl('expired, obtain new copy.'); endl;
21 call ltlfin(1, 1009); $ abnormally terminate.
22 elseif left<30 then $ if expiration approaching, warn user
23 intl(left) textl(' days to expiration.') endl
24 end if;
25 end subr;
1 .=member lcp
2 $ lcp ( l-ittle c-ompiler p-rint -procedures)
3 $
4 $ define the procedures used to generate the compiler list
5 $ file. these procedures perform needed conversions, building up a
6 $ line as array of characters.
7 $
8 +* putcn(c) = $ add character to print line - no check
9 pfl(pfcol) = c; pfcol = pfcol+1;
10 **
11
12 +* addc(c) = $ add character to print line
13 putcn(c); $ add character
14 if (pfcol > pflen) call endlr;
15 **
16
17 subr pagelr; $ begin print file page.
18 access lcpns;
19 size i(ps); $ loop index.
20 size j(ps); $ loop index.
dsk 36 size pflsave(.sds. pflenmax); $ saved print line (for titles).
22 size pflensave(ps); $ saved length of pfl.
23 size pftermsave(1); $ save -pftermflag-
24 size v(ps); $ for converting page number.
25
26 pfpage = pfpage + 1;
27 if (pfpaging = 0) return;
28 pftermsave = pftermflag; pftermflag = no; $ dont write title on t
29 $ if page limit exceeded, suppress further carriage control.
30 if pfpagelimit then
31 if (pfpage > pfpagelimit) pfcarriage = 0;
32 end if;
33 if pftitling then $ if title desired.
34 pflensave = pfcol - 1;
35 slen pflsave = pflensave; sorg pflsave = 1 + .sds. pflensave;
36 do i = 1 to pflensave; .ch. i, pflsave = pfl(i); end do;
37 do i = 1 to slen pftitle; pfl(i) = .ch. i, pftitle; end do;
38 if pfpagefield then $ if page number desired.
39 if (pfpage<0) pfpage = 0;
40 if (pfpage>9999) pfpage = 0;
41 do i = 0 to 4; pfl(pfpagefield+i) = 1r ; end do;
42 j = pfpagefield + 5;
43 v = pfpage;
44 until v = 0;
45 j = j - 1;
46 pfl(j) = charofdig( (v - 10*(v/10)) );
47 v = v / 10;
48 end until;
49 end if;
50 pfcol = slen pftitle+1; call linelr; $ print main title.
51 do i = 1 to slen pfstitle; pfl(i) = .ch. i, pfstitle; end do;
52 pfcol = slen pfstitle + 1; call linelr; $ print sub title.
53 call linelr; $ print blank line after title.
54 do i = 1 to pflensave; pfl(i) = .ch. i, pflsave; end do;
55 pfcol = pflensave + 1;
56 pfl(1) = 1r ;
57 pfline = 3;
58 else
59 pfl(1) = 1r1; $ force start of new page.
60 pfline = 0;
61 end if;
62 pftermflag = pftermsave; $ save terminal flag
63 end subr pagelr;
64 subr etitlr(lin, str, posarg, lenarg); $ enter string into title.
65 $ enter string str in title line beginning at column pos.
66 $ enter len characters, padding with blanks if str if shorter.
67 $ use main title if lin is zero, else use subtitle.
68 access lcpns;
69 size lin(ps); $ line designator.
dsk 37 size posarg(ws); $ specified position to begin insert.
dsk 38 size pos(ws); $ position to insert.
72 size lenarg(ps); $ number of positions to define.
73 size len(ps); $ adjusted length.
dsk 39 size str(.sds. pflenmax); $ string to insert.
75 size lc(ps); $ last column index.
76
77 len = lenarg; if (len = 0) len = slen str;
78 pos = posarg; if (pos<2) pos = 2;
79 lc = pos + len - 1; $ index of last column.
80 if (lc > pflen) return;
81 if lin then $ if subtitle.
82 if (lc > slen pfstitle) slen pfstitle = lc;
83 .s. pos, len, pfstitle = str;
84 else $ if main title.
85 if (lc > slen pftitle) slen pftitle = lc;
86 .s. pos, len, pftitle = str;
87 end if;
88 end subr etitlr;
89 subr ltitlr(tlabel); $ prepare standard little title.
90 access lcpns;
dsk 40 size tlabel(.sds. pflenmax); $ title string.
92 size lstimestr(.sds. lstimelen);
93 size i(ps); $ do loop index
94
95 call contlpr(6, 1); $ set paging on.
96 call contlpr(7, 1); $ enable titling.
dsc 60 call etitlr(0, sitename, pflen-(63+sitenamelen), 0);
98 call etitlr(0, '.little.', pflen-63, 0);
99 $ copy at most first fifteen chars of supplied label.
100 call etitlr(0, tlabel, pflen-55, 15);
101 call etitlr(0, 'page', pflen-8, 0);
102 call contlpr(8, pflen-4); $ set page field.
103 call contlpr(9, pflen-40); $ set date field.
104 pfpage = 0; pfline = pflinesperpage; $ at end of zero page.
105 pfcol = 2; pfl(1) = 1r ;
106 pflinetotal = 0;
dsk 41 if pftermopen & termh then $ write header to terminal file
108 pflistflag = no; pftermflag = yes; $ this goes to terminal fi
109 textl('start ') textl(sitename) textl('.little.')
110 textl(tlabel)
111 call lstime(lstimestr);
una 2 textl(lstimestr) endl
113 pflistflag = yes; pftermflag = no; $ reset to normal
114 end if;
115 end subr ltitlr;
116 subr stitlr(lin, titl); $ enter title or subtitle.
117 size lin(ps); $ zero for main title, else subtitle.
dsk 42 size titl(.sds. pflenmax); $ title string.
119 call etitlr(lin, titl, 2, 60);
120 end subr stitlr;
121 subr linelr; $ end print line.
122 access lcpns;
123 size lastline(1); $ on when limit exceeded.
124 size i(ps); $ loop index.
125 size iocc(ws); $ io completion code.
126
127 if (pfcol<2) pfcol = 2;
128 if (pfcol > (pflen+1)) pfcol = pflen + 1;
129 $ put blank in col 1 if no want carriage control.
130 if (pfcarriage = 0) pfl(1) = 1r ;
131 lastline = no;
132 if pflinelimit ^= 0 & pflistflag then $ check for line limit
133 pflinetotal = pflinetotal + 1;
134 if pflinetotal > pflinelimit then
135 lastline = yes;
136 do i = 1 to 20;
137 pfl(i+1) = .ch. i, 20qline limit exceeded. ;
138 end do;
139 pfcol = 22;
140 end if;
141 end if;
142
143 pfcol = pfcol - 1; $ make true number of columns.
144 if (pflistflag) call putcsio(2, iocc, pfl, 1, pfcol);
145
146 if (pftermflag & pftermopen) $ write line to terminal fil
147 call putcsio(termfilenumber, iocc, pfl, 1, pfcol);
148 pfcol = 2;
149 pfl(1) = 1r ;
150 if lastline then $ note limit exceeded, and abort.
151 call remarkl(' line limit exceeded.');
152 call ltlfin(1, 1001); $ line limit exceeded.
153 end if;
154 end subr linelr;
155 subr endlr; $ end print line.
156 $ end print line. if paging, see if must begin new page.
157 access lcpns;
158 size newpage(1); $ on to begin new page.
159 if (pfpaging = no) then call linelr; return; end if;
160 newpage = no;
161
162 $ if no ouput to list file, dont count lines
163 if pflistflag = no then call linelr; return; end if;
164
165 if pfl(1) = 1r then
166 if (pfline = pflinesperpage) newpage = yes;
167 elseif pfl(1) = 1r1 then newpage = yes;
168 elseif pfl(1) = 1r0 then
169 if pfline >= (pflinesperpage-1) then
170 newpage = yes; pfl(1) = 1r ;
171 else pfline = pfline + 1; end if;
172 elseif pfl(1) = 1r+ then pfline = pfline - 1;
173 end if;
174 if (newpage) call pagelr; $ begin new page
175 call linelr;
176 pfline = pfline+1;
177 end subr endlr;
178 subr contlpr(act, arg); $ control actions for print file.
179 access lcpns;
180 size act(ps); $ action to take.
181 size arg(ws); $ parameter or result.
182 size i(ps); $ loop index.
183 size lstimestr(.sds. lstimelen); $ time-date string.
184
185 $ actions as follows.
186 $ 1 get current position in line.
187 $ 2 set current position in line.
188 $ 3 skip forward pos columns, inserting blanks on way.
189 $ 4 tab to column pos (add blanks on forward tab).
190 $ 5 new page action:
191 $ if pos zero, begin new page.
192 $ if pos not zero, begin new page if less than pos lines
193 $ remain on current page.
194
195 $ 6 set paging mode (if on, pages formed)
196 $ 7 set titling mode (if on, titles cleared).
197 $ 8 set page number field in title line.
198 $ 9 set date field in title line.
199 $ 10 get lines per page.
200 $ 11 set lines per page.
201 $ 12 get page number.
202 $ 13 set page number.
203 $ 14 get line number (within page).
204 $ 15 set line number (within page).
205 $ 16 get number of lines written.
206 $ 17 set number of lines written.
207 $ 18 get line limit.
208 $ 19 set line limit.
209 $ 20 get page limit.
210 $ 21 set page limit.
211 $ 22 get carriage control status.
212 $ 23 set carriage control status.
213 $ 24 get carriage control character.
214 $ 25 set carriage control character.
215 $ 26 set list output control flag.
216 $ 27 set terminal output control flag.
dsk 43 $ 28 get terminal header flag.
dsk 44 $ 29 set terminal header flag.
dsk 45 $ 30 get characters per line.
217
dsk 46 go to l(act) in 1 to 30;
219
220 /l(01)/
221 arg = pfcol; go to ret;
222 /l(02)/
dsk 47 if (arg<1 ! arg>pflen) go to ret;
223 pfcol = arg; go to ret;
224 /l(03)/ $ skip action
225 if (arg<1 ! arg>(pflen-1)) return;
226 if (arg+pfcol >= pflen) then call endlr; return; end if;
227 pfcol = pfcol + arg;
228 do i = 1 to arg; pfl(pfcol-i) = 1r ; end do;
229 go to ret;
230 /l(04)/ $ tab action.
231 if (arg=0) go to ret;
232 if (pfcol >= arg) then
233 pfcol = arg;
234 else
235 while pfcol < arg;
236 pfl(pfcol) = 1r ; pfcol = pfcol + 1;
237 end while;
238 end if;
239 go to ret;
240 /l(05)/ $ page action.
241 if pfpaging then
242 if (arg=0) ! ((arg>0)&((arg+pfline)>pflinesperpage)) then
243 call pagelr;
244 end if;
245 end if;
246 go to ret;
247 /l(06)/
248 pfpaging = (arg ^= 0); go to ret;
249 /l(07)/
250 pftitling = (arg ^= 0);
251 if pftitling then $ if titling, clear titles.
252 sorg pftitle = 1 + .sds. pflen ;
253 slen pftitle = pflen;
254 .s. 1, pflen, pftitle = ' ';
255 pfstitle = pftitle;
256 slen pftitle = 1;
257 .ch. 1, pftitle = 1r1;
258 end if;
259 go to ret;
260 /l(08)/
dsk 48 if (arg<2) go to ret;
261 i = arg + 4; $ index of last column.
262 if (i > pflen) return; $ if out of bounds.
263 pfpagefield = arg; $ set page field.
264 if (slen pftitle < i) slen pftitle = i;
265 go to ret;
266 /l(09)/
dsk 49 if (arg<2) go to ret;
267 i = arg + lstimelen - 1; $ last column index.
268 if (i > pflen) go to ret; $ if out of bounds.
269 pfdatefield = arg;
270 if pfdatefield then $ if date field, get date.
271 call lstime(lstimestr);
272 if (slen pftitle < i) slen pftitle = i;
273 .s. pfdatefield, lstimelen, pftitle = lstimestr;
274 end if;
275 go to ret; $ set date field in title line.
276 /l(10)/
277 arg = pflinesperpage; go to ret;
278 /l(11)/
279 if (arg < 10) go to ret; $ avoid very small pages.
280 pflinesperpage = arg; go to ret;
281 /l(12)/
282 arg = pfpage;
283 if (pfline = pflinesperpage) arg = arg + 1; $ if at end of page
284 go to ret;
285 /l(13)/
286 if (arg > 9999) go to ret; $ avoid too large page number.
287 pfpage = arg; go to ret;
288 /l(14)/ $ get line number of last line completed.
289 arg = pfline; go to ret;
290 /l(15)/ $ set line number of last line completed.
291 pfline = arg; go to ret;
292 /l(16)/ $ get number of lines written.
293 arg = pflinetotal; go to ret;
294 /l(17)/ $ set number of lines written.
295 pflinetotal = arg; go to ret;
296 /l(18)/ $ get line limit.
297 arg = pflinelimit; go to ret;
298 /l(19)/ $ set line limit (zero to suppress limit check).
299 pflinelimit = arg; go to ret;
300 /l(20)/ $ get page limit.
301 arg = pfpagelimit; go to ret;
302 /l(21)/ $ set page limit.
303 pfpagelimit = arg; go to ret;
304 /l(22)/ $ get carriage control condition.
305 arg = pfcarriage; go to ret;
306 /l(23)/ $ set carriage control condition.
307 pfcarriage = (arg ^= 0); go to ret;
308 /l(24)/ $ get carriage control character.
309 arg = pfl(1); go to ret;
310 /l(25)/ $ set carriage control character.
311 pfl(1) = arg; go to ret;
312 /l(26)/ $ set list output control flag.
313 pflistflag = (arg ^= 0); go to ret;
314 /l(27)/ $ set terminal output control flag.
315 pftermflag = (arg ^= 0); go to ret;
dsk 50 /l(28)/ $ get terminal header flag.
dsk 51 arg = termh; go to ret;
dsk 52 /l(29)/ $ set terminal header flag.
dsk 53 termh = (arg ^= 0); go to ret;
dsk 54 /l(30)/ $ get characters per line.
dsk 55 arg = pflen; go to ret;
316 /ret/
317 end subr contlpr;
318 subr textlr(t); $ print string.
319 access lcpns;
dsk 56 size t(.sds. pflenmax); $ string to add.
321 size torg(ps); $ origin of string.
322 size tlen(ps); $ length in characters of string
323 size tpos(ps); $ current position in string
324 size i(ps); $ do loop index
325 tlen = slen t;
326 .+txtl_env.
327 $ if possible, unpack string directly into pfl.
328 if pfcol+tlen <= pflen+1 then $ if can unpack directly.
329 call 7ntxtl$li(pfl, pfcol, t);
330 pfcol = pfcol + tlen;
331 if (pfcol>pflen) call endlr;
332 return;
333 end if;
334 ..txtl_env
335 tpos = sorg t;
336 do i = 1 to tlen; $ print characters in turn
337 tpos = tpos - cs; $ position to next character
338 addc( (.f. tpos, cs, t))
339 end do;
340 end subr textlr;
341 subr charlr(c); $ print character.
342 access lcpns;
343 size c(cs); $ character to add
344 addc(c);
345 end subr charlr;
346 subr octlr(o); $ print octal value
347 access lcpns;
348 size o(ws); $ argument to output
349
350 call octlpr(o, (ws+2)/3);
351 end subr octlr;
352 subr wordlr(wordlarg); $ print word
353 access lcpns;
354 size wordlarg(ws); $ word to output
355 size wordlch(cs); $ character to output
356 size wordlpos(ps); $ position in word
357 size i(ps); $ do loop index
358 $ adds characters in input word-size argument to output line
359 .+unpk_env. $ if possible, unpack directly into pfl.
360 if pfcol+cpw <= pflen+1 then
361 call 7nunpk$li(pfl, pfcol, wordlarg, 1, cpw);
362 pfcol = pfcol + cpw;
363 if (pfcol>pflen) call endlr;
364 return;
365 end if;
366 ..unpk_env
367 wordlpos = (ws+1);
368 while (wordlpos>cs); $ process characters in turn
369 wordlpos = wordlpos - cs;
370 wordlch = .f. wordlpos, cs, wordlarg;
371 addc(wordlch)
372 end while;
373 end subr wordlr;
374 subr wordsr(ara, lo, hi); $ print ara(lo) to ara(hi).
375 size ara(ws); dims ara(2);
376 size lo(ps); $ starting index.
377 size hi(ps); $ ending index.
378 size i(ps); $ loop index.
379 .+unpk_env. $ if possible, unpack directly into pfl.
380 size nc(ps); $ number of characters.
381 nc = (hi-lo+1) * cpw;
382 if pfcol+nc <= pflen+1 then $ if can unpack.
383 call 7nunpk$li(pfl, pfcol, ara, lo, nc);
384 pfcol = pfcol + nc;
385 if (pfcol>pflen) call endlr;
386 return;
387 end if;
388 ..unpk_env
389 do i = lo to hi;
390 call wordlr(ara(i));
391 end do;
392 return;
393 end subr wordsr;
394 subr intlr(intarg); $ print integer value (5 digits).
395 access lcpns;
396 size intarg(ws);
397 call intlpr(intarg, 5);
398 end subr intlr;
399 subr tintlr(s, i); $ print text and integer.
400 $ put blanks before start and after end
401 access lcpns;
402 size s(ws); $ string to label integer
403 size i(ws); $ integer to output
404 addc(1r ) textl(s) textl(' = ') intl(i) addc(1r )
405 end subr tintlr;
406 subr intlpr(vin, cols); $ print integer vin in cols columns.
407 $ intlpr outputs a -cols- column integer value for input integer
408 $ -vin-. a new line is begun if less than -p- columns remain
409 $ on the current line. negative and large numbers are handled
410 $ correctly, as is the integer -0 (peculiar to one's complements
411 $ machines).
412 $
413 access lcpns;
414 size v(ws-1); $ value to print, is nonnegative.
415 size vin (ws); $ value to print
416 size colnow (ps); $ current column being output
417 size ifminus(1); $ set to 'yes' if negative input
418 size cols(ps); $ columns to output
419
420 $ end current line if not room for integer.
421 if (cols < 1 ! cols > pflen) return; $ bad call.
422 if (pfcol+cols > pflen+1) call endlr;
423 colnow = pfcol + cols; $ index of last column defined.
424 ifminus = (vin<0); v = iabs(vin);
425
426 if v<10 then $ if only one digit.
427 colnow = colnow - 1;
428 pfl(colnow) = charofdig(v);
429 v = 0; $ indicate conversion complete.
430 else
431 while v > 0 & colnow > pfcol;
432 colnow = colnow - 1;
433 pfl(colnow) = charofdig(mod(v,10));
434 v = v / 10;
435 end while;
436 end if;
437
438 if ifminus then $ if negative, insert minus sign.
439 if colnow > pfcol then $ if room for minus sign.
440 colnow = colnow - 1; pfl(colnow) = 1r-;
441 else v = 1; end if; $ if not room, force truncation error.
442 end if;
443
444 if (v) pfl(pfcol) = 1r*; $ if truncation.
445
446 do colnow = colnow-1 to pfcol by -1;
447 pfl(colnow) = 1r ; end do;
448
449 pfcol = pfcol + cols; $ set ending position.
450 if pfcol>pflen then $ if defined last char in line, write it.
451 call endlr;
452 end if;
453 end subr intlpr;
454 subr octlpr(w, c); $ print -w- in -c- columns in octal.
455 $ print word -w- in octal in no more than -c- columns.
456 access lcpns;
457 size w(ws); $ word to list
458 size c(ps); $ no. of columns to output
459 size p(ps); $ position in -w- during actual output
460
461 if (c+pfcol > pflen+1) call endlr; $ if need new line.
462 p = c*3 + 1;
463 while p > 1;
464 p = p - 3; $ advance to next digit
465 .+wsm3 putcn(charofdig((.f. p, 3, w)));
466 .-wsm3.
467 if p = (ws/3)*3 + 1
468 then putcn(charofdig((.f. p, ws-(ws/3)*3,w)));
469 else putcn(charofdig((.f. p, 3, w)));
470 end if;
471 ..wsm3
472 end while;
473 end subr octlpr;
474 subr hexlpr(hexarg, c); $ print hexarg in hex using c columns.
475 $ list c hexadecimal digits of hexarg
476
477 access lcpns;
478 size hexarg(ws); $ value to list
479 size i(ps); $ do loop index
480 size c(ps); $ number of digits to list
481 size hextab(ps); dims hextab(16); $ conversion table
482 data hextab = 1r0,1r1,1r2,1r3,1r4,1r5,1r6,1r7,1r8,1r9,1ra,1rb,1rc
483 ,1rd,1re,1rf;
484
485 $ start new line if no room for constant.
486 if (pfcol+c > pflen+1) call endlr;
487 do i = 1 to c;
488 putcn(hextab(.f. (c-i)*4 + 1, 4,hexarg + 1));
489 end do;
490 end subr hexlpr;
491
492 macdrop(addc)
493 macdrop(putcn)
494 $ end of lcp procedures.
1 .=member getapp
2 subr getapp(s, sl); $ get actual parameter string.
3 size s(.sds. getapp_len);
4 size sl(ps); $ maximum length of s.
5 size key(ps), code(ps), ifpres(ps), ifval(ps);
6
7 call reados(5, code, ifpres, ifval, sl, s);
8
9 end subr getapp;
1 .=member getipp
2 subr getipp(pvar, pstr); $ get i-nteger p-rogram p-arameter.
3 size pvar(ws); $ variable to receive value.
4 size pstr(.sds. (2*spplen));
5 size eqpos(ps); $ index of '='.
6 size slpos(ps); $ index of '/'.
7 size p1pos(ps); $ index of start of value field.
8 size p2pos(ps); $ index of end of value field.
9 size ifpres(1); $ set if parameter present.
10 size ifval(1); $ set if value specified.
11 size inval(ws); $ set to numeric value if given.
12 size isval(.sds. spplen); $ set to string value if given.
13 size i(ps); $ loop index.
14 size val(ws); $ numeric value.
15 size plen(ps); $ length of parameter code string.
dsb 26 size d(ws); $ digit during conversion.
16
17 plen = slen pstr;
18 eqpos = '=' .in. pstr; slpos = '/' .in. pstr;
19 if (slpos=0) return;
20 if (eqpos<=1 ! eqpos>=spplen) return;
21
22 call reados(1,(.s. 1, eqpos-1, pstr), ifpres, ifval, inval,isval);
dsh 24 .+s32v.
dsh 25 $ for vax vms, copy arg string and fold to upper case.
dsh 26 size ustr(.sds. (2*spplen));
dsi 64 ustr = .s. 1, eqpos-1, pstr;
dsi 65 call stpc(ustr); $ convert to primary case.
dsi 66 call reados(1,ustr, ifpres, ifval, inval,isval);
dsh 30 ..s32v
23
24 val = 0;
25
26 if ifpres then $ if present.
27 if ifval then $ if value given, use it.
28 pvar = inval;
29 return;
30 else $ if present, no value, take alternate.
31 if (slpos = plen) go to getstandard;
32 p1pos = slpos+1; p2pos = plen;
33 end if;
34 else $ if not given, take standard default.
35 /getstandard/
36 p1pos = eqpos+1; p2pos = slpos-1;
37 end if;
38
39 do i = p1pos to p2pos;
dsb 27 d = digofchar((.ch. i, pstr)); $ get value assuming digit.
dsb 28 if (d<0 ! d>9) cont do; $ ignore if not digit.
dsb 29 val = 10*val + d;
41 end do;
42 pvar = val;
43 return;
44 end subr getipp;
1 .=member getspp
2 subr getspp(pvar, pstr); $ get s-tring p-rogram p-arameter.
3 size pvar(.sds. spplen); $ variable to receive value.
4 size pstr(.sds. (2*spplen));
5 size eqpos(ps); $ index of '='.
6 size slpos(ps); $ index of '/'.
7 size p1pos(ps); $ index of start of value field.
8 size p2pos(ps); $ index of end of value field.
9 size ifpres(1); $ set if parameter present.
10 size ifval(1); $ set if value specified.
11 size inval(ws); $ set to numeric value if given.
12 size isval(.sds. spplen); $ set to string value if given.
13 size i(ps); $ loop index.
14 size val(ws); $ numeric value.
15 size plen(ps); $ length of parameter code string.
16
17 plen = slen pstr;
18 eqpos = '=' .in. pstr; slpos = '/' .in. pstr;
19 if (slpos=0) return;
20 if (eqpos<=1 ! eqpos>=spplen) return;
21
22 isval = '' .pad. spplen;
23
24
25 call reados(3,(.s. 1, eqpos-1, pstr), ifpres, ifval, inval,isval);
dsh 31 .+s32v.
dsh 32 $ for vax vms, copy arg string and fold to upper case.
dsh 33 size ustr(.sds. (2*spplen));
dsi 67 ustr = .s. 1, eqpos-1, pstr;
dsi 68 call stpc(ustr); $ convert to primary case.
dsi 69 call reados(3,ustr, ifpres, ifval, inval,isval);
dsh 37 ..s32v
26
27 val = 0;
28
29 if ifpres then $ if present.
30 if ifval then $ if value given, use it.
dsb 30 i = slen isval;
dsb 31 slen pvar = i;
dsb 32 if i then $ copy value.
dsb 33 sorg pvar = .sds. i + 1;
dsb 34 .s. 1, i, pvar = .s. 1, i, isval;
dsb 35 end if;
32 return;
33 else $ if present, no value, take alternate.
34 if (slpos = plen) go to getstandard;
35 p1pos = slpos+1; p2pos = plen;
36 end if;
37 else $ if not given, take standard default.
38 /getstandard/
39 p1pos = eqpos+1; p2pos = slpos-1;
40 end if;
41
dsb 36 if p2pos >= p1pos then
dsb 37 i = p2pos - p1pos + 1; $ length to set.
dsb 38 slen pvar = i; $ set length.
dsb 39 if i then $ if value to copy.
dsb 40 sorg pvar = .sds. i + 1;
dsb 41 .s. 1, i, pvar = .s. p1pos, i, pstr;
dsb 42 end if;
dsb 43 else
dsb 44 slen pvar = 0;
45 end if;
46 return;
47 end subr getspp;
1 .=member lstime
2 .-defenv_lstime.
3 subr lstime(lst); $ get character time.
4 $ lstime determines characters representing current time.
5 $ for example, the next to last second of 23 march 1976
6 $ is represented as follows:
7 $
8 $ ' tue 23 mar 76 23.59.58 '
9 $
10 $ (123456789a123456789b123456789c) .
11 $
12 size ca(cs); dims ca(2); $ user array of characters.
13 size nca(cs); $ number of characters to enter in ca.
14 size ta(ps); dims ta(8); $ lntime array.
15 size i(cs); $ loop index
16 size lst(.sds. lstimelen); $ time string.
17 size names(sds((12+7)*3)); data names = $ day,month names
18 'sunmontuewedthufrisatjanfebmaraprmayjunjulaugsepoctnovdec';
19 size mpos(ps), dpos(ps); $ month, day positions in names.
20 size n(ps), ndiv10(ps); $ for conversion.
21
22 call lntime(ta); $ get numeric times.
dsu 18 lst = '' .pad. lstimelen; $ intialize string.
24 $ convert desired integers in lca.
25 mpos = 3*ta(2) + 18; $ names index of start of month name.
26 ta(2) = ta(1) - 1900; $ get last two digits of year.
27 do i = 14 to 26 by 3; $ convert needed integers.
28 n = ta(i/3-2); ndiv10 = n/10;
29 .ch. i, lst = charofdig(ndiv10);
30 .ch. i+1, lst = charofdig((n - 10*ndiv10));
31 end do;
32 dpos = (ta(8)-1)*3; $ position for day of week.
33 do i = 1 to 3;
34 .ch. i+8, lst = .ch. i+16, lst; $ move day.
35 .ch. i+15, lst = .ch. i+13, lst; $ move year.
36 .ch. i+3, lst = .ch. dpos+i, names;
37 .ch. i+11, lst = .ch. mpos+i, names;
38 end do;
39 .ch. 15, lst = 1r ; .ch. 18, lst = 1r ;
40 .ch. 22, lst = 1r: ; .ch. 25, lst = 1r: ;
41 end subr lstime;
42 ..defenv_lstime
1 .=member lctime
2 .-defenv_lctime.
3 subr lctime(lca, lcalen); $ get string time as array of chars.
4 size lca(cs); dims lca(2); $ array of characters.
5 size lcalen(ps); $ number of characters to receive.
6 size lststr(.sds. lstimelen); $ time-date string.
7 size i(ps); $ loop index.
8 call lstime(lststr); $ get string time.
9 do i = 1 to lcalen;
10 if (i>lcalen) quit do;
11 lca(i) = .ch. i, lststr;
12 end do;
13 do i = lstimelen+1 to lcalen; lca(i) = 1r ; end do;
14 return;
15 end subr lctime;
16 ..defenv_lctime
1 .=member dumpaq
2 subr dumpaq(text, array, low, high);
3
4 $ this procedure dumps 'array' from index 'low' to 'high',
5 $ four elements per line. the first line is blank, the next is
6 $ 'dump of array ' !! text, and the remaining contain the array
7 $ elements. each array element is preceded by its index in
8 $ decimal. the element is dumped in machine form.
9 size text(ws+1); $ parameter, array name
10 size array(ws); $ parameter, array to dump.
11 size low(ps); $ parameter, starting index of array.
12 size high(ps); $ parameter, ending index of array.
13 size l(ps); $ current line number.
14 size index(ps); $ current index being dumped.
15 size nlines(ps); $ number of lines needed.
16 +* dumpentpl = $ number of entries per line.
17 ((pflen-1)/(bwordlen+8)) **
18 dims array(1); $ dummy dimension.
19
20 endl $ blank line
21 textl(' dump of array ') textl(text) endl
22
23 nlines = (high-low+dumpentpl)/dumpentpl; $ set number of line
24
25 do l = 1 to nlines; $ loop for printing lines.
26 index = l + low - 1; $ initialize index.
27
28 while index <= high; $ place dumpentpl items in a line.
29 charl(1r ); $ skip one space.
30 intl(index); $ output index in decimal.
31 textl('. ');
32 bwordl(array(index)); $ dump array element.
33 index = index + nlines; $ set index for next element.
34 end while;
35
36 endl; $ print a line
37 end do;
38
39 return;
40 macdrop(dumpentpl)
41 end subr dumpaq; $ dumpa
1 .=member termio
dsc 61 subr opnterm(filename); $ open terminal file
3 $ this procedure opens the terminal file used by the
4 $ compiler, via -lcp-, to isolate error messages.
dsc 62 size filename(sds(filenamelen)); $ file name
6 size iocc(ws); $ io completion code.
7 size lenopn(ps); $ line size obtained.
8
9 if (pftermopen) return; $ do nothing if already open.
dsi 70 call eretsio(termfilenumber, iocc, yes); $ set to return error.
10 call opensio(termfilenumber, iocc, access_print,
dsc 63 filename, pflen, lenopn, 0, 0);
dsi 71 pftermopen = (iocc = 0); $ show term file open if ok.
dsi 72 call eretsio(termfilenumber, iocc, no); $ set to quit on error.
13 end subr opnterm;
14 subr clsterm; $ close term file if open.
15 access lcpns;
16 size iorc(ps); $ io return code.
17 if (pftermopen) call clossio(termfilenumber, iorc);
18 pftermopen = no;
19 end subr clsterm;
1 .=member linepak
2 .-defenv_linepak.
3 subr linepak(pa, ua, lchars);
4 $ linepak takes the -nchars- characters in array ua which are
5 $ unpacked (one char word) and packs theminto array -pa-
6 $ the last wordof -pa- is filled with blanks, if appropriate.
7
8 size pa(ws); $ array into which we pack
9 size ua(cs); $ input array of input chars
10 size lchars(ps); $ num of chars to pack
11 size paword(ws); $ packed word temporary
12 size paptr(ps); $ pointer to pa
13 size papos(ps); $ last position in paword being build
14 size i(ps); $ do-loop temporary
15 dims pa(2), ua(2); $ dummy dims for parameters
16
17 paptr = 1;
18 papos = (ws+1); $ current position in pa
19 paword = blankword;
20 pa(1) = paword;
21 do i = 1 to lchars; $ pack charactrs in turn
22 papos = papos-cs;
23 .f. papos, cs, paword = ua(i);
24 if ( papos > 1) cont do;
25 $ finished current word
26 pa(paptr) = paword;
27 paword = blankword;
28 paptr = paptr+1;
29 papos = (ws+1);
30 end do;
31 $ if not packing integral no of words, store last word
32 if (papos ^= ws+1) pa(paptr) = paword;
33 end subr linepak;
34 ..defenv_linepak
1 .=member gobyerm
2 subr gotoem(index); $ prints diagnostic for bad goby index
3
4 $ this procedure is called from 7ngoto$er to print out diagnostic
5 $ information after bad goby argument detected.
6
7 size index(ws); $ bad index value
8
9 endl textl(' execution terminated - bad go to index ')
10 intlp(mradix, 1) textl('b''') bwordl(index) charl(1r') endl
11 call ltlfin(1, 1002); $ bad go to index.
12 end subr gotoem;
1 .=member incio
2 subr opninc(inputname, inimemname, includecode, updarg);
3 /*
4 open input file with included text processing.
5 inputname is name of input file; if null, use standard
6 input file. if inimemname is not null, it is name of
7 member to be included before reading input file.
8 if includecode is not null, it gives the initial pattern
9 which defines an include directive.
10 updarg is nonzero if input lines from standard input file
11 contain 8 characters of upd sequence information at the
12 start of a line which is to be removed.
13 */
14
15 $ inputname and inimemname are null to access default
16 $ input and library files, respectively.
17 size inputname(.sds. filenamelen); $ name of input file.
18 size inimemname(.sds. filenamelen); $ name of initial member.
19 size includecode(.sds. filenamelen); $ code for include.
20 size updarg(ps); $ upd sequence option.
21
22 size iname(.sds. filenamelen);
23 size i(ps), l(ps); $ loop indexes.
24
25 nameset inclio; $ globals for include processing.
26 $ inclev is the inclusion level. inclev is one when reading
27 $ the standard input file.
28 size inclev(ps); $ depth of inclusion.
dsc 64 data inclev = 1;
29
30 $ filenow is sio file value for the current file.
31 $ inpfile is the sio file value for the input file.
32 $ incfile is the sio file value for the include library.
33 $ incfile is initially zero, indicating that the include
34 $ library is not yet open. in this way opening the include
35 $ library and allocation of buffers can be deferred until
36 $ first include request seen.
37 size incfilenow(ps); $ current file.
38 size incfile(ps); size inpfile(ps);
dsc 65 data incfile = 0; $ indicate file not open.
dsc 66 data inpfile = 1; $ standard input file.
39
40 $ lastpos(i) is the number of lines read at inclusion level i.
41 $ lastpos is used to reposition within library when includes
42 $ are nested.
43 size lastpos(.ps.); dims lastpos(inclevmax);
44
45 $ curpos is number of lines read since inclusion library
46 $ opened or rewound.
dsc 67 size curpos(ws); data curpos = 0;
48
49 size updseq(ps); $ nonzero if upd sequence field.
50 $ the string idcode contains the codes for the include and
51 $ member directives. idcodelen gives the lengths of the
52 $ directives.
53 size idcode(.sds. 21); $ codes for include and member
54 data idcode = ' .=include .=member ';
55 size idcodelen(ps); dims idcodelen(2); data idcodelen = 11, 10 ;
56
57 $ memname is set by isidir to the member name if a directive
58 $ seen. a length of zero indicates directive not present.
59 size memname(.sds. filenamelen);
60 data memname = '';
61 $ memnext is set to name of next member when a member line is
62 $ encountered during text inclusion.
63 size memnext(.sds. filenamelen); data memnext = '';
64 end nameset;
65
68 updseq =updarg;
69
70 $ copy code for include, at most 11 characters.
71 l = slen includecode;
72 if (l < 3) l = 0; $ require at least three chars.
73 if (l > 11) l = 11;
74 do i = 1 to l;
75 .ch. i, idcode = .ch. i, includecode;
76 end do;
77 if (l) idcodelen(1) = l;
dsk 57 .+mc call stpc(idcode); $ convert to primary case.
78
79 incfilenow = inpfile; $ begin with input file.
82 if slen inimemname then $ if initial include, start it.
83 memname = inimemname;
dsk 58 .+mc call stpc(memname); $ convert to primary case.
84 call posinc(0);
85 incfilenow = incfile;
86 end if;
87
88 end subr opninc;
89 subr clsinc; $ close input (inclusion) file.
90 access inclio;
91 size iorc(ps); $ io return code.
92 if (incfile > 0) call clossio(incfile, iorc);
93 end subr clsinc;
94 subr isidir(code,uara,ulo,uhi); $ look for include or member.
95 access inclio;
96 $ code is 1 for include, 2 for member.
97 $ build line.
98 size code(ps); $ type of directive sought.
99 size uara(ws), ulo(ps), uhi(ps); $ line is uara(lo) to uara(hi).
100 dims uara(2);
101 size uaralo(ws); $ uara(ulo)
102 size c(cs); $ character.
103 size line(.sds. (cpw*wpc)); $ sds form of line.
104 size linewds(ps); $ words in line.
105 size ld(ps); $ length of desired directive.
106 size i(ps); $ loop indexes.
107 size porg(ps); $ start of parameter.
108 size pend(ps); $ end of parameter.
109 size plen(ps); $ length of parameter.
110 size corg(ps); $ origin of directive code in idcode.
111 size linemax(ps);
ldsd 11 size anyc(ps),nayc(ps); $ string search functions
dsk 59 .+mc size ctpc(cs); $ converts to primary case
112
113 +* lorg = (.sds. (cpw*wpc) + 1) **
114
115 $ look at first two characters in turn. if they match,
116 $ convert line to string and compare rest of characters.
117 .len. memname = 0; $ clear memname.
118 corg = (code-1) * 11;
119 uaralo = uara(ulo);
120 c = .f. ws+1 - cs, cs, uaralo; $ first char.
121 if (c ^= .ch. corg+1,idcode) return;
122 c = .f. ws+1 - 2*cs, cs, uaralo; $ second char.
123 if (c ^= .ch. corg+2,idcode) return;
124 $ first two chars match, take the long route.
125 linewds = (uhi-ulo+1);
126 if (linewds > wpc) linewds = wpc;
127 linemax = linewds * cpw;
128 do i = 1 to linewds;
129 .f. lorg - i*ws, ws, line = uara(ulo+i-1);
130 end do;
131 sorg line = lorg;
132 slen line = cpw * linewds;
133 .ch. (cpw*linewds-1), line = 1r); $ in case all blanks.
134 .ch. (cpw*linewds), line = 1r ;
dsk 60 .+mc call stpc(line); $ convert to primary case.
135 ld = idcodelen(code); if (ld = 2) go to found;
136 do i = 1 to ld;
dsd 10 $ fail by returning if no match.
dsk 61 if (.f. lorg - i*cs, cs, line)
dsk 62 ^= (.ch.corg+i,idcode) then return; end if;
139 end do;
140 $ is desired card, get member name.
141 /found/
142 porg = 2;
ldsd 12 while nayc((.ch. porg, line) ,2); $ skip to end of directive.
144 porg = porg + 1;
145 end while;
ldsd 13 while anyc((.ch. porg, line), 2); $ skip to start of member name
147 porg = porg + 1;
148 if (porg > linemax) return; $ if no name present, quit.
149 end while;
150 pend = porg;
ldsd 14 while nayc((.ch. pend, line), 2);
152 if (pend > linemax) return; $ if no name present, quit.
153 pend = pend + 1;
154 end while;
155 pend = pend - 1;
156 $ remove enclosing quotes or parentheses.
157 porg = porg + ((.ch. porg, line) = 1r');
158 porg = porg + ((.ch. porg, line) = 1r();
159 pend = pend - ((.ch. pend, line) = 1r');
160 pend = pend - (.ch. pend, line = 1r));
161 if (porg > pend) return; $ if param is only quotes and parens,
162 porg = porg - 1;
163 plen = pend - porg;
164 $ copy parameter name into member name, truncating long name.
165 if (plen > memnamelenmax) plen = memnamelenmax;
166 memname = .s. porg+1, plen, line;
167 return;
168 +* lorg = **
169 end subr isidir;
170 subr getinc(uara, ulo, uhi, udone); $ read with include processin
171 access inclio;
172 size uara(ws); dims uara(2); $ array to read.
173 size ulo(ps), uhi(ps); $ read uara(lo) to uara(hi).
174 size udone(1); $ set when end of input.
175 size endseen(ws); $ end of data indicator.
176 size i(ps);
177 size iwd(ws); $ dummy for read during skip.
178
179 $ read until line emerges or input exhausted.
180 while 1;
181 call getwsio(incfilenow,endseen,uara, ulo, (uhi-ulo+1)*cpw);
182 $ see if need to move upd sequence information.
183 if endseen=no & updseq=1 & incfilenow=inpfile then
184 call updinc(uara, ulo, (uhi-ulo+1));
185 end if;
186 if inclev > 1 then $ if including, member is end.
187 if endseen = no then
188 call isidir(2, uara, ulo, uhi);
189 endseen = (slen memname) > 0;
190 $ save name if including at first level.
191 if endseen & inclev=2 then
192 memnext = memname;
193 end if;
194 curpos = curpos + 1;
195 else .len. memnext = 0; $ if no next member.
196 end if;
197 end if inclev;
198 if endseen then $ if end, terminate if including, else done
199 if inclev = 1 then
200 udone = yes;
201 return;
202 else
203 call posinc(1); $ terminate include.
204 cont while;
205 end if inclev;
206 end if endseen;
207
208 $ line read, look for include.
209 call isidir(1, uara, ulo, uhi);
210 if slen memname then $ if include, save place, start includ
211 call posinc(0);
212 cont while;
213 else
214 quit while;
215 end if;
216 end while;
217
218 $ line available, return it.
219
220 udone = no;
221 end subr getinc;
222 subr posinc(ending); $ position inclusion file.
223 access inclio;
224 $ begin inclusion. increment inclusion level, locate desired
225 $ member. if member not found, issue warning and restore.
226 $ ending is zero to begin include, one to terminate include.
227 size ending(ps); $ nonzero to terminate.
228 size done(ws); $ end of data indicator.
229 size i(ps); $ loop index.
230
231 $ incline is the current line image.
232 size incline(ws); dims incline(wpc); $ line read in.
233 size iwd(ws); $ dummy for read during skip.
234 $ memwant is the desired member name when include begins.
235 size memwant(.sds. filenamelen);
236 size iorc(ps); $ io return code.
237 size startsearch(ws); $ starting position for search.
238 size eofok(ps); $ flag for search.
239
240 if (ending) go to restoreit;
241 memwant = memname; $ save desired member name.
242 if incfile = 0 then $ if include file not opened, open it.
243 call opensio(incfilenumber, iorc, access_get,
244 inclibname, cpw*wpc, i, 0, 0);
dsl 8 if iorc then $ if unable to open.
dsla 2 call remarkl(inclibname);
dsl 9 textl('error - unable to open inclusion file ')
dsl 10 textl(inclibname) endl
dsl 11 call ltlfin(1,1010);
dsl 12 end if;
245 incfile = incfilenumber;
246 end if;
247
248 lastpos(inclev) = curpos; $ save position within library.
249 inclev = inclev + 1;
250 incfilenow = incfile;
251 if inclev > inclevmax then $ if depth too great, abort.
252 textl('maximum include depth exceeded.') endl
253 call ltlfin(1, 1003); $ inclusion depth too great.
254 end if;
255
256 $ if prior include terminated by encountering member line for
257 $ member now desired, can just continue reading.
258 if (memwant .seq. memnext) return;
259 .len. memnext = 0; $ else reset memnext.
260 eofok = yes; $ ok to search past eof.
261 startsearch = curpos; $ starting point for end-around search.
262
263 while 1;
264 call getwsio(incfile, done, incline, 1, wpc*cpw);
265 if done then
dsd 14 if (eofok=no) quit while;
267 eofok = no; $ indicate part 1.
268 call rewisio(incfile, iorc, 0);
269 curpos = 0; $ indicate at start of file.
270 cont while;
271 end if;
272 curpos = curpos + 1;
dsd 15 if (eofok=no & curpos>startsearch) quit while;
274 call isidir(2, incline, 1, wpc); $ look for member line.
dsd 16 if (memwant .seq. memname) return;
276 end while;
dsd 17 $ member not present, print warning and restore.
280 textl(' ***error*** member ') textl(memwant)
281 textl(' not found, include ignored.') endl
282 /restoreit/
283 inclev = inclev - 1;
284 if inclev > 1 then $ if still including, restore pl
285 if lastpos(inclev)<= 0) ! (crfnum > 9) then $ if bad num. param.
14 textl('crfnam - bad file number ') intl(crfnum) endl
15 go to crfabt;
16 end if;
17 crfname = crfparm;
18 do l = slen crfparm to 1 by -1;
19 c = .ch. l, crfname;
20 do i = 1 to 10;
21 if .ch. i, '0123456789' = c then
22 .ch. l, crfname = charofdig(crfnum);
23 return;
24 end if;
25 end do;
26 end do;
27 $ error numeric to substitute not found.
28 textl('crfnam - missing numeric character in file name ')
29 textl(crfname) endl
30 /crfabt/
31 call ltlfin(1, 1004); $ bad reference file name.
32 end subr crfnam;
1 .=member reados
2 subr reados(key, code ,ifpres, ifval, inval, isval);$ read options
3 /*
4 obtain the user-supplied option string.
5 parameters are as follops:
6 key - desired action
7 1 - integer valued parameter
8 2 - octal valued parameter
9 3 - string valued parameter
10 4 - set inval to number of parameters and return
11 -i - set ifpres if i-th parameter available; if so, set
12 code to parameter, isval to value.
13 code - string giving parameter code
14 ifpres - switch indicating if parameter present
15 ifval - switch indicating if value supplied.
16 inval - numeric value given (key = 1,2)
17 isval - string value given (key=3)
18
19 the parameter string is obtained by the procedure -readsos-
20 which returns the parameter string as an array of characters.
21 the parameter string may not contain internal instances of , or );
22 blanks are ignored.
23 */
24
25 size key(ws); $ option desired
26 size code(sds(ospmax)); $ parameter code
27 size ifpres(1); $ set on if parameter supplied
28 size ifval(1); $ set if value supplied
29 size inval(ps); $ supplied numeric value
30 size isval(sds(ospmax)); $ supplied string value
31 size cc(ps); dims cc(oscmax); $ character array holding string
32 size cclen(ps); data cclen = oscmax-1; $ length of supplied str.
33 size nparms(ps); data nparms=0; $ number of supplied parameters
34 size ip(ps); $ parameter index
35 size i(ps), l(ps); $ loop indices, lengths
36 size c(ps); $ current character
37 size firstcall(1); data firstcall=1; $ to trap first call
38 size porg(ps); $ index of start of parameter, 0 if no proaram
39 size vorg(ps); $ index of start of value, 0 if no value
40 size plen(ps); $ number of characters in parameter
41 size vlen(ps); $ number of characters in value portion
42 size inc(ps); $ 1 when inside parameter, 0 when in value part
43 size ccp(ps); $ position in cc
44 size base(ps); $ arithmetic base for numeric conversion
dsb 45 size d(ws); $ digit value during numeric conversion.
plf 20 .+plf1 size passcom(1); $ on to pass commas to argument
45
46 if firstcall then $ if first time, get param string
47 firstcall = 0;
48 call readsos(cc, cclen); $ cclen set to length of string
49 $ on entry gives maximum allowed.
dsf 51
50 cclen = cclen+1; cc(cclen) = 1r, ;
51 /* terminal , simplifies scan */
plf 21 .+plf0.
52 do i = 1 to cclen; nparms = nparms + (cc(i)=1r,); end do;
plf 22 ..plf0
plf 23 .+plf1.
plf 24 $ take comma as separator, unless between [ (or <) and ] (or>).
plf 25 passcom = no;
plf 26 do i = 1 to cclen;
plf 27 c = cc(i);
dsn 18 if (c=1r[ ! c=1r< ! c=1r() & passcom=no then
dsn 19 passcom = yes;
dsn 20 elseif (c=1r] ! c=1r> ! c=1r)) & passcom=yes then
dsn 21 passcom = no;
plf 30 elseif (c=1r,) & passcom = no then nparms = nparms+1;
plf 31 end if;
plf 32 end do;
plf 33 ..plf1
53 end if;
54
55 if key=4 then $ if want number of parameters available
56 inval = nparms; return; end if;
57
dsc 68 if key=5 then $ if want full parameter string.
dsc 69 l = cclen-1; $ determine number of chars to copy.
dsc 70 if (l > inval) l = inval; $ if actual string too long.
dsc 71 .len. isval = l; $ set length of result.
dsc 72 sorg isval = 1 + (.sds. l);
dsc 73 do i = 1 to l; $ copy into isval.
dsc 74 .ch. i, isval = cc(i);
dsc 75 end do;
dsc 76 return;
dsc 77 end if;
dsc 78
58 ifpres = 0; ifval = 0; inval = 0; ccp = 0;
59
plf 34 .+plf1 passcom=no;
60 do ip = 1 to nparms;
61 porg = ccp; vorg = 0; plen = 0; vlen = 0;
62 inc = 1; $ 1 when inside parameter, 0 when inside val
63 while 1; $ scan parameter
64 ccp = ccp + 1;
plf 35 .+plf0.
65 if (cc(ccp)=1r,) quit while; $ end seen
plf 36 ..plf0
plf 37 .+plf1.
plf 38 $ take comma as separator, unless between [ (or <) and ] (or>).
plf 39 c = cc(ccp);
dsn 22 if (c=1r[ ! c=1r< ! c=1r() & passcom=no then
dsn 23 passcom = yes;
dsn 24 elseif (c=1r] ! c=1r> ! c=1r)) & passcom=yes then
dsn 25 passcom=no;
plf 42 elseif (c=1r,)&(passcom=no) then quit while;
plf 43 end if;
plf 44 ..plf1
66 if (cc(ccp) = 1r= ) then $ switch to value part
67 vorg = ccp; inc = 0; cont while; end if;
68 plen = plen + inc; vlen = vlen + (1-inc);
69 end while;
70
71 if key = -ip then $ if want this parameter
72 ifpres = 1; ifval = (vlen ^=0);
73 l = slen code; if (l>plen) l=plen;
74 do i = 1 to l;
75 .ch. i, code = cc(porg+i); end do;
76 slen code = l;
77 l = slen isval; if (l>vlen) l=vlen;
78 do i = 1 to l;
79 .ch. i, isval = cc(vorg+i); end do;
80 slen isval = l;
81 return;
82 end if;
83
84 if key>0 then $ if looking for param, this may be it
85 if slen code ^= plen then cont do; end if;
86 do i = 1 to plen;
87 if (.ch. i, code ^= cc(porg+i)) cont do ip;
88 end do;
89 $ parameter found, process value
90 ifpres = 1;
91 ifval = (vlen ^= 0);
92 go to l(key) in 1 to 3;
93 /l(1)/ base = 10; go to conv;
94 /l(2)/ base = 8;
95 /conv/ $ convert numeric value
96 do i = 1 to vlen;
dsb 46 d = digofchar(cc(vorg+i)); $ get value if digit.
dsb 47 if (d<0 ! d>9) cont do; $ ignore if not digit.
dsb 48 inval = inval*base + d;
98 end do;
99 return;
100 /l(3)/
101 l = vlen;
102 if (l>slen isval) l = slen isval;
103 do i = 1 to l;
104 .ch. i, isval = cc(vorg + i); end do;
105 slen isval = l;
106 return;
107 end if;
108
109 end do ip;
110 /* if reach here, parameter not found */
111 end subr reados;
1 .=member ltlxtr1
dsv 81 .+s10.
dsv 82 subr ltlxt1; $ dummy ltlxt1 for completion by mccann.
dsv 83 end subr ltlxt1;
dsv 84 ..s10
dsv 85 .+s11.
dsv 86 subr ltlxt1(cursp, initsp); $ produce trace back chain.
dsv 87 $ this procedure is invoked by -ltlxtr- when a listing of
dsv 88 $ the current trace back chain is desired.
dsv 89 size cursp(ws); $ stack pointer at time of call.
dsv 90 size initsp(ws); $ stack pointer at program init.
dsv 91
dsv 92 size 7nmget$li(ws); $ memory read routine.
dsv 93 size scanptr(ps); $ current scanning position in stack.
dsv 94 size endscan(ps); $ highest address in stack.
dsv 95 size tempadr(ps); $ temporary.
dsv 96 size i(ps); $ temporary.
dsv 97 size calladr(ps); $ address of -call-.
dsv 98 size ascii(cs); $ array to hold routine names.
dsv 99 dims ascii(9); $ number of chars in routine name.
dsv 100
dsv 101 scanptr = .f. 2, ps, cursp; $ get word value of stack pointer.
dsv 102 endscan = .f. 2, ps, initsp; $ get initial word initial stack ptr
dsv 103 endl; endl; $ leave two blank lines.
dsv 104 textl('trace back chain') endl endl $ print heading.
dsv 105
dsv 106 $ now scan the programs stack looking for the address of calls.
dsv 107 until scanptr = endscan; $ until scan completed.
dsv 108 tempadr = 7nmget$li(scanptr); $ get contents of stack.
dsv 109 tempadr = .f. 2, ps, tempadr; $ get word address value.
dsv 110 if 7nmget$li(tempadr-2) = 3b'4767' then $ could be -call-.
dsv 111 calladr = tempadr - 2; $ get address of call statement.
dsv 112 $ now get address of called routine.
dsv 113 tempadr = tempadr - 3 + .f. 2, ps, (7nmget$li(tempadr-1));
dsv 114 if 7nmget$li(tempadr+3) = 3b'4567' then $ is call.
dsv 115 call 6nrad$li(tempadr, ascii); $ convert rad50 -> as
dsv 116 do i = 1 to 9; $ write out routine name.
dsv 117 if (ascii(i) = 1r ) quit do; $ if end of name -
dsv 118 charl(ascii(i)) $ write out this part of name.
dsv 119 end do i;
dsv 120
dsv 121 textl(' called from location ')
dsv 122 octlp(calladr, 6) endl $ end line.
dsv 123 end if;
dsv 124 end if;
dsv 125
dsv 126 scanptr = scanptr + 1; $ back up stack.
dsv 127 end until;
dsv 128
dsv 129 end subr ltlxt1;
dsv 130 ..s11
2 .+s66.
3 subr ltlxtr1(locfrom); $ print part of trace back package
4 $ this procedure prints subroutine trace back chain as diagnostic ai
5 $ is it called from ltlxtr, which sets up argument locfrom as
6 $ location of most recent call.
7 $ implementation is necessarily system-dependent.
8
9 $ this cdc version assumes ftn calling conventions have been used,
10 $ and traces back at most 20 levels.
11
12 size locfrom(ws); $ location of most recent call
13 size memget(ws); $ returns contents in indicated memory wd.
14 size loc(ws); $ current location
15 size levels(ws); $ number of procedures traced back
16 size lineno(ws); $ line number withing procedure
17 size name(ws); $ entry word
18 size memname(ws); $ memget(name)
19 size ientry(ws); $ header word for procedure
20 size mentry(ws); $ memget(ientry)
21 size lname(ws); $ display code name of procedure
22 size memloc(ws); $ value of current loc
23
24 loc = locfrom; levels = 0;
25 endl textl(' trace back chain') endl
26 /next/
27 memloc = memget(loc); $ word with call
28 if .f. 49, 12, memloc ^= 3b'0100' then
29 $ quit if not subroutine call (return jump)
30 return; end if;
31 levels = levels + 1; if (levels >20) return;
32 $ avoid tracing too much, or infinite loop if core clobberec
33 lineno = .f. 19, 12, memloc; $ line number of call
34 name = .f. 1, 18, memloc; $ addr of header word for procedure
35 memname = memget(name); $ header word for procedure
36 ientry = .f. 1, 18, memname; $ true entry word
dsv 131 if (ientry=0) ientry = name+1; $ if cdc quirk.
38 mentry = memget(ientry);
39 lname = memname; .f. 1, 18, lname = 3r ; $ display code name
40
41 textl(' called by ') wordl(lname) textl(' at line ')
42 intl(lineno) textl(', location ') addrl(loc) endl
43
44 if .f. 49, 12, mentry ^= 3b'0400' then
45 $ quit if no further calls to process
46 return; end if;
47 loc = .f. 31, 18, mentry-1; $ address of previuus call
48 go to next;
49
50 end subr ltlxtr1;
51 ..s66
1 .=member ltlregl
2 subr ltlregl(regs); $ list machine register contents
3
4 $ this system-dependent procedure lists contents of machine register
5 $ contents, and is used for diagnostic purposes.
6 $ called from ltlregs, which sets up -regs- in system-dependent way.
7
8 .+s10.
9 size regs(ws); dims regs(16); $ general registers.
10 size i(ps); $ loop index.
11
12 endl textl('register contents') endl
13 do i = 1 to 16;
14 if i > 10 then textl(' r') intlp(i-1,2)
15 else textl(' r') intlp(i-1,1) end if;
16 textl(' ')
17 bwordl(regs(i))
18 if (mod(i, 4) = 0) endl $ four registers per line.
19 end do;
20 ..s10
21 .+s11.
22 size regs(ws); $ define register array.
23 dims regs(8);
24 size i(ps); $ temporary.
25
26 endl
27 textl('contents of registers') endl $ title output.
28 do i = 1 to 6; $ loop until registers are done.
29 textl(' r') intlp(i-1, 1) textl(' ') $ identify register.
30 bwordl(regs(i)) $ print contents of register.
31 if (mod(i, 4)=0) endl $ 4 registers per line
32 end do;
33
34 textl(' sp ') bwordl(regs(6)) endl
35 ..s11
vax 23 .+s32.
vax 24 size regs(ws); dims regs(16); $ general registers.
vax 25 size i(ps); $ loop index.
vax 26
vax 27 endl textl('contents of general purpose registers.') endl
vax 28 do i = 1 to 16;
vax 29 if i > 10 then textl(' r') intlp(i-1,2)
vax 30 else textl(' r') intlp(i-1,1) end if;
vax 31 textl(' ')
vax 32 bwordl(regs(i))
vax 33 if (mod(i, 4) = 0) endl $ four registers per line.
vax 34 end do;
vax 35 ..s32
36 .+s37.
37 size regs(ws); dims regs(16); $ general registers.
38 size i(ps); $ loop index.
39
40 endl textl('contents of general purpose registers.') endl
41 do i = 1 to 16;
42 if i > 10 then textl(' r') intlp(i-1,2)
43 else textl(' r') intlp(i-1,1) end if;
44 textl(' ')
45 bwordl(regs(i))
46 if (mod(i, 4) = 0) endl $ four registers per line.
47 end do;
48 ..s37
utsa 62 .+s47.
utsa 63 size regs(ws); dims regs(16); $ general registers.
utsa 64 size i(ps); $ loop index.
utsa 65
utsa 66 endl textl('contents of general purpose registers.') endl
utsa 67 do i = 1 to 16;
utsa 68 if i > 10 then textl(' r') intlp(i-1,2)
utsa 69 else textl(' r') intlp(i-1,1) end if;
utsa 70 textl(' ')
utsa 71 bwordl(regs(i))
utsa 72 if (mod(i, 4) = 0) endl $ four registers per line.
utsa 73 end do;
utsa 74 ..s47
49 .+s66. $ cdc 6000 series...
50 $ -regs- contains registers in order a0-a7, b0-b7, x0-x7.
51 size regs(ws); dims regs(24);
dsv 132 .+s10.
dsv 133 size regs(ws); dims regs(16); $ general registers.
dsv 134 size i(ps); $ loop index.
dsv 135
dsv 136 endl textl('contents of general purpose registers.') endl
dsv 137 do i = 1 to 16;
dsv 138 if i > 10 then textl(' r') intlp(i-1,2)
dsv 139 else textl(' r') intlp(i-1,1) end if;
dsv 140 textl(' ')
dsv 141 bwordl(regs(i))
dsv 142 if (mod(i, 4) = 0) endl $ four registers per line.
dsv 143 end do;
dsv 144 ..s10
52 size i(ps); $ do loop index
53
54 endl textl(' contents of machine registers ') endl
55 do i = 1 to 8;
56 textl(' a') intlp(i-1,1) skipl(2)
57 addrl(regs(i))
58 textl(' b') intlp(i-1,1) skipl(2)
59 addrl(regs(i+8))
60 textl(' x') intlp(i-1,1) skipl(2)
61 bwordl(regs(i+16))
62 endl
63 end do;
64 ..s66
65
66 end subr ltlregl;
1 .=member readsos
2 .-defenv_readsos.
3 subr readsos(cc, cclen); $ obtain option string from system
4
5 /* this system-dependent procedure obtains the option string.
6 the string is entered as an array of characters in -cc-.
7 on entry, cclen gives maximum characters that may be set;
8 on exit, cclen is the number of characters in the string.
9 */
10
11 size cc(ws); dims cc(2); $ array of option characters
12 size p(ws); $ length of option string
13 size cclen(ws); $ max. length of option string on entry,
14 $ true length on exit.
15
16 p = 0; $ assume no option string supplied.
17
18 .+s66.
19 /* for cdc 6000 systems, we require that the user supply the
20 string enclosed in parentheses after the standard execution
21 header, as in 'little(in,out) (optionstring)'.
22 the system places the string in absolute locations 70-77b,
23 marking the end of string with a 00 byte. our job here
24 is to skip past the prefix, which is terminated by . or ),
25 then to locate the ( marking the start of the list, and
26 finally accumulate options until ) seen.
27 we use a simple automaton to record our status.
28
29 memget is a library procedure which reads absolute core.
30
31 */
32 size i(ps), j(ps); $ loop indices
33 size memget(ws); $ system function to read core
34 size iwd(ws); $ last value returned by memget
35 size c(ws); $ current character
36 size state(ws); $ current state
37
38 /* states are encoded as follows :
39 1 - looking for . or ) at end of prefix
40 2 - looking for ( at start of list
41 3 - looking for ) ending list */
42
43 state = 1; $ begin looking for end of prefix
44 p = 0; $ no characters yet in cc
45
46 do i = 1 to 8;
47 iwd = memget(3b'67'+i); $ next word from low core
48 do j = ws-cs+1 to 1 by -cs; $ get characters
49 c = .f. j, cs, iwd;
50 if (c=0) quit do i; $ if end.
51 if state=1 then
52 if (c=1r. ! c=1r)) state=2;
53 elseif state=2 then
54 if (c=1r() state = 3;
55 else $ if state=3.
56 if (c=1r)) quit do i;
57 if p < cclen then $ if room for character.
58 p = p + 1; cc(p) = c;
59 end if;
60 end if;
61 end do j;
62
63 end do i;
64
65 ..s66
66
67 cclen = p;
68
69 end subr readsos;
70 ..defenv_readsos
1 .=member ltlfin
2 subr ltlfin(abnormal, completioncode);
3 $ terminate execution, abnormally if -abnormal- not zero.
4 $ completion code is passed on to host terminator.
5 size abnormal(ws); $ nonzero if abnormal termination.
6 size completioncode(ws); $ completion code.
7 $ sflev and sfcod are completion values passed to sysfin.
8 $ sflev is the largest (most severe) value encountered during
9 $ execution of ltlfin, and sfcod is code passed first time that
10 $ level encountered.
11 size sflev(ws), sfcod(ws);
12 data sflev=0;
13 data sfcod=0;
14 size i(ps); $ index, current line limit.
15
16 .+s10 size ncalls(ps); data ncalls = 0; $ number of -ltlfin- calls.
17 .+s11 size ncalls(ps); data ncalls = 0; $ number of -ltlfin- calls.
18 .+s32 size ncalls(ps); data ncalls = 0; $ number of -ltlfin- calls.
19 .+s66 size ncalls(ps); data ncalls = 0; $ number of -ltlfin- calls.
20 .+s37.
21 $ on s37, put termination variables in a nameset.
22 +* exitns = 7nexit$ns **
23 nameset exitns; $ start the nameset.
24 size ncalls(ps); data ncalls = 0; $ number of -ltlfin- calls.
25 size pgmckflg(1); data pgmckflg = no; $ recursion preventor.
26 size sioerflg(1); data sioerflg = no; $ ditto
27 end nameset;
28 ..s37
29 .+s47.
30 $ on s47, put termination variables in a nameset.
31 +* exitns = 7nexit$ns **
32 nameset exitns; $ start the nameset.
33 size ncalls(ps); data ncalls = 0; $ number of -ltlfin- calls.
34 size pgmckflg(1); data pgmckflg = no; $ recursion preventor.
35 size sioerflg(1); data sioerflg = no; $ ditto
36 end nameset;
37 ..s47
38
39 ncalls = ncalls + 1;
40
41 .+erexit if (ncalls<4) call 7nerxi$si;
42
43 if ncalls = 1 then $ if first call, try to terminate.
44 sflev = abnormal;
45 sfcod = completioncode;
46 if abnormal then
47 call contlpr(21, 0); $ set page limit to zero.
48
49 call contlpr(18, i); $ get current line limit.
50 if i then $ if line limit set, extend by 2000 lines.
51 call contlpr(19, i+2000);
52 end if;
53
54 .+s32 if abnormal=1 then $ traceback only if little error.
55 call ltlxtr; $ list trace back chain.
56 .+s32 end if;
57
58 $ increment ncalls so can close files.
59 ncalls = ncalls + 1;
60 call usratp; $ call user abnormal termination procedure.
61 else $ if normal, increment ncalls so can close.
62 ncalls = ncalls + 1;
63
64 .+extime. $ following text computes and writes elapsed time.
65
66 size timeoff(letimesz); $ end of job time.
67
68 if etim then $ if want elapsed time.
69 call letime(timeoff); timeoff = timeoff - timeon;
70 .+s11 timeoff = (timeon*1000)/60;
71 size msg(sds(38)); $ sds for execution time message
72 data msg = ' 0.000 cpu seconds execution time.';
73 size t10(letimesz); $ temporary for time output.
74 size pos(ps); $ position in output message
75
76 pos = 10;
77 while timeoff;
78 t10 = timeoff/10;
79 .ch. pos, msg = charofdig( timeoff - 10*t10);
80 pos = pos-1;
81 if (pos=7) pos = 6; $ skip across decimal point
82 timeoff = t10;
83 end while;
84 .+s66 call remarkl(msg); $ put etim in dayfile
85 .-s66.
86 $ put elapsed time on listing file.
87 call textlr(msg); call endlr; $ write to listing.
88 ..s66
89 end if etim;
90 ..extime
91 end if abnormal;
92
93 else
94 $ if not first call, reset level if
95 $ level of greater severity than any yet seen.
96 if abnormal > sflev then
97 sflev = abnormal;
98 sfcod = completioncode;
99 end if;
100 end if ncalls;
101
102 if ncalls=2 then $ if can try to close files.
103 call ltllio(1); $ terminate little io.
104 ncalls = ncalls + 1;
105 end if;
106
107 if ncalls = 3 then
108 call ltlsio(1); $ terminate sio.
109 end if;
110
111 while 1; $ sysfin must not return.
112 call sysfin(sflev, sfcod);
113 end while;
114 end subr ltlfin;
115 subr usratp;
116 $ null version of user abnormal termination procedure called if
117 $abnormal termination.
118 end subr usratp;
1 .=member s37xtr1
2 .+s37.
3 $ macros for s37 error routines.
4 +* badaddr = 7nbadr$li ** $ function to check for bad address.
5
6 +* addrp(n) = (.f. 1, 24, (n)) ** $ address value.
7
8
9 subr ltlxtr1(saveloc, parm); $ handle trace-back chain.
10 $ this routine processes trace-back chains. -saveloc- is set by
11 $ an assembler routine to point to the address of the last save
12 $ area. -parm- is 1 to just scan the trace-back chain and save
13 $ it in storage and 0 to print the trace-back chain. if -parm-
14 $ is zero and no trace-back chain has been saved, the current
15 $ trace-back chain is listed.
16 size saveloc(ps); $ location of highest save area.
17 size parm(1); $ set to 1 to print chain.
18 size backptrs(ps); data backptrs = 0; $ number of back pointers
19 size addrs(ws); dims addrs(15); $ calling addresses.
20 size rnames(.sds. 9); dims rnames(9); $ routine names.
21 size i(ps); $ loop variable.
22 size curaddr(ps); $ current save area address.
23 size entry(ps); $ possible routine entry address.
24 size namelen(ps); $ get name length.
25 size memget(ws); $ function to get a word from memory.
26 size badaddr(1); $ function to validity check an address.
27
28 +* byte(n) = $ fetch byte -n- from memory.
29 (.f. 25 - (.f. 1, 2, (n))*8, 8, memget((n)/cpw)) **
30
31 $ check for a trace-back chain already set and go print it if so
32 if (backptrs) go to print; $ go print chain.
33
34 /store/ $ here to store trace-back chain.
35 $ now store chain in local storage. first get initial save area
36 $ pointer.
37 curaddr = saveloc/cpw; $ set to word address.
38 do backptrs = 1 to 15; $ now process each save area.
39 if curaddr = 0 then $ this is the end of the chain.
40 addrs(backptrs) = 0; $ flag it as such.
41 quit do; $ done with this loop.
42
43 elseif badaddr(curaddr) then $ check for bad save-area addre
44 addrs(backptrs) = -1; $ flag as bad address.
45 quit do; $ done with loop.
46
47 else $ save area is valid - get calling address.
48 addrs(backptrs) = addrp(memget(curaddr+3)); $ get r14.
49 end if;
50
51 $ now see if can determine name of routine.
52 entry = addrp(memget(curaddr+4)); $ get contents of r15.
53 rnames(backptrs) = ''; $ set initially to null name.
54 until yes; $ quit if -entry- is not routine entry point.
55 if (badaddr(entry/cpw)) quit until; $ if invalid, not en
56 if (byte(entry) ^= 4b'47') quit until; $ not branch.
57 if (byte(entry+1) ^= 4b'f0') quit until;
58 if (byte(entry+2) ^= 4b'f0') quit until;
59 namelen = byte(entry+4); $ get name length.
60 if (namelen > 30) quit until; $ not valid if this long.
61 if (namelen > 9) namelen = 9; $ set to max. we will prin
62 rnames(backptrs) = '' .pad. 9; $ set to all blanks.
63 .len. rnames(backptrs) = namelen; $ set length.
64 do i = 1 to namelen; $ move in each character.
65 .ch. i, rnames(backptrs) = byte(entry+4+i);
66 end do;
67 end until;
68
69 curaddr = addrp(memget(curaddr+1))/cpw; $ next save area.
70 end do;
71
72 $ now, if -parm- is one, we are done and should return.
73 if (parm) return; $ done if just saving trace-back chain.
74
75 /print/ $ here to print trace-back chain.
76 $ now print the trace-back information stored from above or from
77 $ an earlier call.
78 endl textl(' trace-back chain:') endl endl
79
80 do i = 1 to backptrs; $ scan all back pointers.
81 if addrs(i) <= 0 then $ this is end of chain.
82 if addrs(i) < 0 then $ this is an error.
83 textl(' **** invalid trace-back chain ****') endl
84 end if;
85
86 quit do; $ done printing chain.
87 end if;
88
89 if .len. rnames(i) then $ print routine name.
90 textl('routine ''') textl(rnames(i)) textl(''' ')
91 end if;
92
93 $ now print calling address.
94 textl('called from ') addrl(addrs(i))
95 if (badaddr(addrs(i)/cpw)) textl(' (address invalid)')
96 endl
97 end do;
98
99 endl
100 backptrs = 0; $ show nothing saved to be printed.
101
102 $ now, if this was call to set trace-back chain, we must have ha
103 $ had one in the buffers already and have just printed it so
104 $ we must go back and set the current chain. note that this
105 $ will very often cause the set chain to be incorrect but it
106 $ is more important to get the initial chain correct since
107 $ it is the first error that the user is probably the most
108 $ interested in
109 if (parm = 1) go to store; $ go store trace-back chain.
110
111 end subr ltlxtr1;
1 .=member s37errs
2 subr ltlintr(psw, gpr);
3 access exitns; $ access termination nameset.
4 $ this routine is entered when osint detects a program
5 $ check.
6 size psw(2*ws); $ program status word at interrupt
7 size gpr(ws); dims gpr(16); $ machine registers at interrupt
8 size inttyp(ps); $ program check type
9 size intaddr(ps); $ interrupt address
10 size badaddr(1); $ checks for bad address.
11
12 size pgmmsg(sds(20)); $ program check messages
13 +* numchecks = 19 ** $ number of program check types
14 dims pgmmsg(numchecks);
15 data pgmmsg = 'operation',
16 'priv. operation',
17 'execute',
18 'protection',
19 'addressing',
20 'specification',
21 'data',
22 'fixed overflow',
23 'fixed divide',
24 'decimal overflow',
25 'decimal divide',
26 'exponent overflow',
27 'exponent underflow',
28 'significance',
29 'floating divide',
30 'segment translation',
31 'page translation',
32 'trans. specification',
33 'special operation';
34
35
36 if pgmckflg then $ this is recursive
37 call ltlfin(1, 4000); $ exit quickly.
38 else
39 pgmckflg = yes; $ show in program check routine
40 call ltlxtrs; $ set trace-back chain.
41 inttyp = .f. 33, 16, psw; $ set interrupt type
42 intaddr = .f. 1, 24, psw; $ set interrupt address
43 endl endl textl(' program check type')
44 intlp(inttyp, 3) $ write header message
45 if inttyp <= numchecks then $ value is valid
46 textl(' (') textl(pgmmsg(inttyp)) textl(' exception)')
47 end if;
48
49 textl(' occurred at ') addrl(intaddr)
50 if badaddr(intaddr/cpw) then $ write additional message
51 textl(' (psw address invalid)')
52 end if;
53
54 endl
55 call ltlregl(gpr); $ now list registers at time of error
56 psw = 0; $ show prgram check processed
57 pgmckflg = no; $ show out of routine.
58 call ltlfin(1, 2000+inttyp); $ terminate program.
59 end if;
60
61 end subr ltlintr;
62 subr ltlovtm; $ entered when time runs out
63 call ltlfin(1, 3220); $ abort program.
64
65 end subr ltlovtm;
66 subr ltlsioer(n, fn, iddname); $ print -sio- error message.
67 access exitns; $ access termination nameset.
68 $ this routine is called by -sio- to print error messages.
69 size n(ws); $ error number.
70 size fn(ps); $ file number.
71 size iddname(.sds. 18); $ ddname.
72 size ddname(.sds. 18); $ copy of -iddname-.
73 size i(ps); $ temporary.
74
75 size erntab(ps); dims erntab(40); $ error number table.
76
77 data erntab =
78
79 1, 2, 3, 3, 4, 4, 5, 5, 6, 6,
80 7, 8, 4, 5, 4, 4, 3, 3, 9, 10,
81 11, 12, 9, 9, 9, 9, 9, 9, 9, 11,
82 13, 0, 8, 14, 12, 12, 14, 15, 15, 9;
83
84 if sioerflg then $ this is recursive.
85 call ltlfin(1, 4001); $ get out.
86 end if;
87
88 sioerflg = yes; $ now set flag to indicate possible recursion.
89 call ltlxtrs; $ set trace-back chain.
90
91 endl textl(' error') intl(n) textl(' on file')
92 intl(fn) textl('. ') $ print header text.
93
94 if n = 32 then $ illegal file number.
95 textl('illegal file number')
96 go to ret;
97
98 elseif n > 40 ! n < 1 then $ bad error number.
99 textl('invalid error number')
100 go to ret;
101
102 else
103 ddname = iddname; $ copy input ddname parameter.
104 do i = 18 to 1 by -1; $ scan down ddname.
105 if (.ch. i, ddname = 1r ) .len. ddname = i-1; $ shorten
106 end do;
107
108 if .len. ddname then $ name is known.
109 textl('(ddname=''') textl(ddname) textl('''.) ')
110 else $ ddname is not known.
dsi 73 textl('(ddname=unknown.)')
112 end if;
113
114 go to e(erntab(n)) in 1 to 15; $ select code.
115 end if;
116
117 +* er(n, msg) = /e(n)/ textl(msg) go to ret; **
118
119 er(1, 'invalid file name')
120 er(2, 'missing dd card')
121 er(3, 'physical i/o error')
122 er(4, 'i/o sequence error')
123 er(5, 'file cannot be opened')
124 er(6, 'pds or tape already opened')
125 er(7, 'insufficient memory')
126 er(8, 'cannot close file')
127 er(9, 'unexpected error')
128 er(10, 'cannot rewind file')
129 er(11, 'file not connected')
130 er(12, 'bad record length on i/o operation')
131 er(13, 'formatted/unformatted conflict')
132 er(14, 'bad access code specified')
133 er(15, 'bad unformatted block length')
134
135 /ret/
136 textl('.') endl endl endl
137
138 sioerflg = no; $ show error processing done.
139
140 call ltlfin(1, 2100+n); $ terminate program.
141
142 end subr ltlsioer;
143 ..s37
1 .=member s47xtr1
2 .+s47.
3
4 $ the first version of these procedures obtained by copying s37
5 $ code. much of the traceback should be the same for s47, though
6 $ need to review interface with c, i.e., caller of little main
7 $ program.
8 $ s47errs contains ltlintr which for s37 is called by procedure
9 $ sysintr in little env (cms env assemble). some conversion to
10 $ error codes and conventions used by uts is needed; for example,
11 $ uts certainly doesn't have 'missing dd card' error, etc.
12 $ macros for s47 error routines.
13 +* badaddr = 7nbadr$li ** $ function to check for bad address.
14
15 +* addrp(n) = (.f. 1, 24, (n)) ** $ address value.
16
17
18 subr ltlxtr1(saveloc, parm); $ handle trace-back chain.
19 $ this routine processes trace-back chains. -saveloc- is set by
20 $ an assembler routine to point to the address of the last save
21 $ area. -parm- is 1 to just scan the trace-back chain and save
22 $ it in storage and 0 to print the trace-back chain. if -parm-
23 $ is zero and no trace-back chain has been saved, the current
24 $ trace-back chain is listed.
25 size saveloc(ps); $ location of highest save area.
26 size parm(1); $ set to 1 to print chain.
27 size backptrs(ps); data backptrs = 0; $ number of back pointers
28 size addrs(ws); dims addrs(15); $ calling addresses.
29 size rnames(.sds. 9); dims rnames(9); $ routine names.
30 size i(ps); $ loop variable.
31 size curaddr(ps); $ current save area address.
32 size entry(ps); $ possible routine entry address.
33 size namelen(ps); $ get name length.
34 size memget(ws); $ function to get a word from memory.
35 size badaddr(1); $ function to validity check an address.
36
37 +* byte(n) = $ fetch byte -n- from memory.
38 (.f. 25 - (.f. 1, 2, (n))*8, 8, memget((n)/cpw)) **
39
40 $ check for a trace-back chain already set and go print it if so
41 if (backptrs) go to print; $ go print chain.
42
43 /store/ $ here to store trace-back chain.
44 $ now store chain in local storage. first get initial save area
45 $ pointer.
46 curaddr = saveloc/cpw; $ set to word address.
47 do backptrs = 1 to 15; $ now process each save area.
48 if curaddr = 0 then $ this is the end of the chain.
49 addrs(backptrs) = 0; $ flag it as such.
50 quit do; $ done with this loop.
51
52 elseif badaddr(curaddr) then $ check for bad save-area addre
53 addrs(backptrs) = -1; $ flag as bad address.
54 quit do; $ done with loop.
55
56 else $ save area is valid - get calling address.
57 addrs(backptrs) = addrp(memget(curaddr+3)); $ get r14.
58 end if;
59
60 $ now see if can determine name of routine.
61 entry = addrp(memget(curaddr+4)); $ get contents of r15.
62 rnames(backptrs) = ''; $ set initially to null name.
63 until yes; $ quit if -entry- is not routine entry point.
64 if (badaddr(entry/cpw)) quit until; $ if invalid, not en
65 if (byte(entry) ^= 4b'47') quit until; $ not branch.
66 if (byte(entry+1) ^= 4b'f0') quit until;
67 if (byte(entry+2) ^= 4b'f0') quit until;
68 namelen = byte(entry+4); $ get name length.
69 if (namelen > 30) quit until; $ not valid if this long.
70 if (namelen > 9) namelen = 9; $ set to max. we will prin
71 rnames(backptrs) = '' .pad. 9; $ set to all blanks.
72 .len. rnames(backptrs) = namelen; $ set length.
73 do i = 1 to namelen; $ move in each character.
74 .ch. i, rnames(backptrs) = byte(entry+4+i);
75 end do;
76 end until;
77
78 curaddr = addrp(memget(curaddr+1))/cpw; $ next save area.
79 end do;
80
81 $ now, if -parm- is one, we are done and should return.
82 if (parm) return; $ done if just saving trace-back chain.
83
84 /print/ $ here to print trace-back chain.
85 $ now print the trace-back information stored from above or from
86 $ an earlier call.
87 endl textl(' trace-back chain:') endl endl
88
89 do i = 1 to backptrs; $ scan all back pointers.
90 if addrs(i) <= 0 then $ this is end of chain.
91 if addrs(i) < 0 then $ this is an error.
92 textl(' **** invalid trace-back chain ****') endl
93 end if;
94
95 quit do; $ done printing chain.
96 end if;
97
98 if .len. rnames(i) then $ print routine name.
99 textl('routine ''') textl(rnames(i)) textl(''' ')
100 end if;
101
102 $ now print calling address.
103 textl('called from ') addrl(addrs(i))
104 if (badaddr(addrs(i)/cpw)) textl(' (address invalid)')
105 endl
106 end do;
107
108 endl
109 backptrs = 0; $ show nothing saved to be printed.
110
111 $ now, if this was call to set trace-back chain, we must have ha
112 $ had one in the buffers already and have just printed it so
113 $ we must go back and set the current chain. note that this
114 $ will very often cause the set chain to be incorrect but it
115 $ is more important to get the initial chain correct since
116 $ it is the first error that the user is probably the most
117 $ interested in
118 if (parm = 1) go to store; $ go store trace-back chain.
119
120 end subr ltlxtr1;
1 .=member s47errs
2 subr ltlintr(psw, gpr);
3 access exitns; $ access termination nameset.
4 $ this routine is entered when osint detects a program
5 $ check.
6 size psw(2*ws); $ program status word at interrupt
7 size gpr(ws); dims gpr(16); $ machine registers at interrupt
8 size inttyp(ps); $ program check type
9 size intaddr(ps); $ interrupt address
10 size badaddr(1); $ checks for bad address.
11
12 size pgmmsg(sds(20)); $ program check messages
13 +* numchecks = 19 ** $ number of program check types
14 dims pgmmsg(numchecks);
15 data pgmmsg = 'operation',
16 'priv. operation',
17 'execute',
18 'protection',
19 'addressing',
20 'specification',
21 'data',
22 'fixed overflow',
23 'fixed divide',
24 'decimal overflow',
25 'decimal divide',
26 'exponent overflow',
27 'exponent underflow',
28 'significance',
29 'floating divide',
30 'segment translation',
31 'page translation',
32 'trans. specification',
33 'special operation';
34
35
36 if pgmckflg then $ this is recursive
37 call ltlfin(1, 4000); $ exit quickly.
38 else
39 pgmckflg = yes; $ show in program check routine
40 call ltlxtrs; $ set trace-back chain.
41 inttyp = .f. 33, 16, psw; $ set interrupt type
42 intaddr = .f. 1, 24, psw; $ set interrupt address
43 endl endl textl(' program check type')
44 intlp(inttyp, 3) $ write header message
45 if inttyp <= numchecks then $ value is valid
46 textl(' (') textl(pgmmsg(inttyp)) textl(' exception)')
47 end if;
48
49 textl(' occurred at ') addrl(intaddr)
50 if badaddr(intaddr/cpw) then $ write additional message
51 textl(' (psw address invalid)')
52 end if;
53
54 endl
55 call ltlregl(gpr); $ now list registers at time of error
56 psw = 0; $ show prgram check processed
57 pgmckflg = no; $ show out of routine.
58 call ltlfin(1, 2000+inttyp); $ terminate program.
59 end if;
60
61 end subr ltlintr;
62 subr ltlovtm; $ entered when time runs out
63 call ltlfin(1, 3220); $ abort program.
64
65 end subr ltlovtm;
66 subr ltlsioer(n, fn, iddname); $ print -sio- error message.
67 access exitns; $ access termination nameset.
68 $ this routine is called by -sio- to print error messages.
69 size n(ws); $ error number.
70 size fn(ps); $ file number.
71 size iddname(.sds. 18); $ ddname.
72 size ddname(.sds. 18); $ copy of -iddname-.
73 size i(ps); $ temporary.
74
75 size erntab(ps); dims erntab(40); $ error number table.
76
77 data erntab =
78
79 1, 2, 3, 3, 4, 4, 5, 5, 6, 6,
80 7, 8, 4, 5, 4, 4, 3, 3, 9, 10,
81 11, 12, 9, 9, 9, 9, 9, 9, 9, 11,
82 13, 0, 8, 14, 12, 12, 14, 15, 15, 9;
83
84 if sioerflg then $ this is recursive.
85 call ltlfin(1, 4001); $ get out.
86 end if;
87
88 sioerflg = yes; $ now set flag to indicate possible recursion.
89 call ltlxtrs; $ set trace-back chain.
90
91 endl textl(' error') intl(n) textl(' on file')
92 intl(fn) textl('. ') $ print header text.
93
94 if n = 32 then $ illegal file number.
95 textl('illegal file number')
96 go to ret;
97
98 elseif n > 40 ! n < 1 then $ bad error number.
99 textl('invalid error number')
100 go to ret;
101
102 else
103 ddname = iddname; $ copy input ddname parameter.
104 do i = 18 to 1 by -1; $ scan down ddname.
105 if (.ch. i, ddname = 1r ) .len. ddname = i-1; $ shorten
106 end do;
107
108 if .len. ddname then $ name is known.
109 textl('(ddname=''') textl(ddname) textl('''.) ')
110 else $ ddname is not known.
111 textl('(ddname=unknown.)')
112 end if;
113
114 go to e(erntab(n)) in 1 to 15; $ select code.
115 end if;
116
117 +* er(n, msg) = /e(n)/ textl(msg) go to ret; **
118
119 er(1, 'invalid file name')
120 er(2, 'missing dd card')
121 er(3, 'physical i/o error')
122 er(4, 'i/o sequence error')
123 er(5, 'file cannot be opened')
124 er(6, 'pds or tape already opened')
125 er(7, 'insufficient memory')
126 er(8, 'cannot close file')
127 er(9, 'unexpected error')
128 er(10, 'cannot rewind file')
129 er(11, 'file not connected')
130 er(12, 'bad record length on i/o operation')
131 er(13, 'formatted/unformatted conflict')
132 er(14, 'bad access code specified')
133 er(15, 'bad unformatted block length')
134
135 /ret/
136 textl('.') endl endl endl
137
138 sioerflg = no; $ show error processing done.
139
140 call ltlfin(1, 2100+n); $ terminate program.
141
142 end subr ltlsioer;
143 ..s47
1 .=member failml
2 subr 7nfal2$ml(enum,len, msg); $ failure in math library.
3 size enum(ps); $ error number.
4 size len(ps); $ number of words in message.
5 size msg(ws); dims msg(2); $ message text.
6 size i(ps); $ loop index.
7 endl textl('error number ')
8 intl(enum) textl(' in mathematical library: ')
9 do i = 1 to len; wordl(msg(i)); end do;
10 endl
11 call ltlfin(1, 1100+enum); $ math library error.
12 end subr;
1 .=member begmon
2 $ macro section for run time monitor aids procedures
3 +* subtabdim = 30 ** $ procedure stack limit
4 +* namelen = 15 ** $ length of significant part of name
5 +* subtabsiz = sds(namelen) ** $ length of subroutine stack
6 +* dbcursubn = dbsubtab(dbsubtabp) ** $ access top of stack
7 +* dbcurfsw = dbfswtab(dbsubtabp) ** $ access switch
8
9 $ to avoid conflicts with user procedures, the names of monitor procedu
10 $ begin with a four character code followed by '$mp'.
11
12 +* prst = 7nprst$mp ** $ print stores
13 +* prs3 = 7nprs3$mp ** $ print stores (3 parameters)
14 +* prs4 = 7nprs4$mp ** $ print stores (4 parameters)
15 +* prs5 = 7nprs5$mp ** $ print stores (5 parameters)
16 +* pren = 7npren$mp ** $ print entry
17 +* prex = 7nprex$mp ** $ print exit
18 +* prar = 7nprar$mp ** $ print argument
19 +* prfl = 7nprfl$mp ** $ print flow trace
20 +* trfl = 7ntrfl$mp ** $ trace flow
21 +* cinx = 7ncinx$mp ** $ check index on store
22 +* prhd = 7nprhd$mp ** $ print assert header
23 +* prvr = 7nprvr$mp ** $ print assert variable
24 +* asfl = 7nasfl$mp ** $ simple assertion failure
25 +* subn = 7nsubn$mp ** $ establish subprocedure name and type
26 +* subx = 7nsubx$mp ** $ show exit from procedure
27 +* setx = 7nsetx$mp ** $ set monitor parameters
28 +* cntu = 7ncntu$mp ** $ countup overflow
29 +* llex = 7nllex$mp ** $ monitor line limit exceeded
30 +* lhdr = 7nlhdr$mp ** $ print line header
31 +* varo = 7nvaro$mp ** $ output a variable
32
33 $ the names of namesets used by monitor are also protected.
34
35 +* bugns = 7ndbgn$mp ** $ monitor nameset
36 +* flown = 7nflwn$mp ** $ flow globals
37 +* storen = 7nstrn$mp ** $ store trace globals
38 +* entryn = 7nentn$mp ** $ entry trace globals
39 +* asertn = 7nastn$mp ** $ assert globals
40
41 $ macro -countup- increments ptr and checks for array overflow
42 +* countup(ptr, lim, msg) =
43 ptr = ptr + 1;
44 if (ptr > lim) then
45 call cntu(msg, lim); $ call error procedure
46 return;
47 end if; **
48
49 $ macro -endld- calls endl and increments line count to check for
50 $ line limit overflow.
51 +* endld = endl
52 dblinect = dblinect + 1;
53 if dblinect > dblinelim & dblinelim > 0 then
54 call llex; $ call error procedure
55 return;
56 end if;
57 **
58
59 +* newlin = $ this macro begins a new line
60 if pfcol > 2 then endld end if; $ start new line if needed
61 **
62
63 +* monitorhead(line, type) = $ print header - line is line no.
64 $ type is 1 for 'entry', 2 for 'exit', 3 for 'store', and 4 for 'error'
65 call lhdr(line, type); $ print header
66 **
67
68 +* monitorvarout(name, flag, index, nwds, val) =
69 $ this macro is used to print a value. -name- is the name of the
70 $ variable being printed, -nwds- is the number of words in the
71 $ variable, -val- is the value, -flag- is non-zero if the variable
72 $ is indexed, in which case -index- is the index.
73 call varo(name, flag, index, nwds, val); $ output variable
74 **
75
76 $ dimensions of arrays
77 +* flowtabdim = 200 ** $ table for flow trace counters
78 +* flroutsdim = 40 ** $ table for flow trace - ptrs to flowtab
79 +* labtabdim = 40 ** $ table for flow trace - label table
80
81 $ fields of flow table
82 $ fid is the id of the code block. fftyp is a subfield of
83 $ giving gross type. ffblock is unique identification number.
84 $ fdone is flag for when entry done. flino is line number.
85 $ flabnam is label name pointer. fcount is executions counter.
86
87 .+s10.
88 +* fid = .f. 01, 18, **
89 +* fftyp = .f. 01, 03, **
90 +* ffblock = .f. 04, 15, **
91 +* flabnam = .f. 19, 18, **
92 +* fdone = .f. 37, 01, **
93 +* flino = .f. 38, 17, **
94 +* fcount = .f. 55, 18, **
95 ..s10
96 .+s11.
97 +* fid = .f. 01, 16, **
98 +* fftyp = .f. 01, 03, **
99 +* ffblock = .f. 04, 13, **
100 +* flabnam = .f. 17, 16, **
101 +* fdone = .f. 33, 01, **
102 +* flino = .f. 34, 15, **
103 +* fcount = .f. 49, 16, **
104 ..s11
vax 36 .+s32.
vax 37 +* fid = .f. 01, 16, **
vax 38 +* fftyp = .f. 01, 03, **
vax 39 +* ffblock = .f. 04, 13, **
vax 40 +* flabnam = .f. 17, 16, **
vax 41 +* fdone = .f. 33, 1, **
vax 42 +* flino = .f. 34, 15, **
vax 43 +* fcount = .f. 49, 16, **
vax 44 ..s32
114 .+s37.
115 +* fid = .f. 01, 16, **
116 +* fftyp = .f. 01, 03, **
117 +* ffblock = .f. 04, 13, **
118 +* flabnam = .f. 17, 16, **
119 +* fdone = .f. 33, 1, **
120 +* flino = .f. 34, 15, **
121 +* fcount = .f. 49, 16, **
122 ..s37
utsa 98 .+s47.
utsa 99 +* fid = .f. 01, 16, **
utsa 100 +* fftyp = .f. 01, 03, **
utsa 101 +* ffblock = .f. 04, 13, **
utsa 102 +* flabnam = .f. 17, 16, **
utsa 103 +* fdone = .f. 33, 1, **
utsa 104 +* flino = .f. 34, 15, **
utsa 105 +* fcount = .f. 49, 16, **
utsa 106 ..s47
dsw 15 .+s40.
dsw 16 +* fid = .f. 01, 16, **
dsw 17 +* fftyp = .f. 01, 03, **
dsw 18 +* ffblock = .f. 04, 13, **
dsw 19 +* flabnam = .f. 17, 16, **
dsw 20 +* fdone = .f. 33, 01, **
dsw 21 +* flino = .f. 34, 15, **
dsw 22 +* fcount = .f. 49, 16, **
dsw 23 ..s40
123 .+s66.
124 +* fid = .f. 01, 13, **
125 +* fftyp = .f. 01, 03, **
126 +* ffblock = .f. 04, 10, **
127 +* fdone = .f. 14, 01, **
128 +* flino = .f. 17, 16, **
129 +* flabnam = .f. 33, 07, **
130 +* fcount = .f. 40, 17, **
131 ..s66
132
133 $ fields for flowrouts
134 +* fbeg = .f. 1, 8, ** $ ptr to flowtab - beginning of procedure
135 +* lbeg = .f. 9, 8, ** $ ptr to labtab - beginning of procedure
136
137 $ sizes of monitor tables
138
139 +* labtabsiz = sds(namelen) ** $ length of label table
140 +* flroutssiz = ws ** $ can fit in word for all machines
141 +* flowtabsiz = $ size of flow table
142 .+s10 2*ws
143 .+s11 4*ws
vax 45 .+s32 2*ws
145 .+s37 2*ws
utsa 107 .+s47 2*ws
dsw 24 .+s40 4*ws
146 .+s66 ws
147 **
148
149 +* dbgwordsz = $ size of 'word' passed as descriptor
150 .+s10 ws
151 .+s11 2*ws
vax 46 .+s32 ws
153 .+s37 ws
utsa 108 .+s47 ws
dsw 25 .+s40 2*ws
154 .+s66 ws
155 **
156
1 .=member subn
2 subr subn(name, fsw);
3 $ this procedure sets the global values for subroutine name
4 $ and switch at the start of a procedure.
dsx 13 nameset bugns;
dsx 14 $ globals for monitor package
dsx 15 size dbbytefg(1); data dbbytefg = no; $ set to print bit in all
dsx 16 size dbsubtab(subtabsiz); dims dbsubtab(subtabdim); $ procedure
dsx 17 size dbfswtab(ps); dims dbfswtab(subtabdim); $ switch value tab
dsx 18 size dbsubtabp(ps); data dbsubtabp = 0; $ pointer to -dbsubtab-
dsx 19 size dbnewsubfg(1); $ 'new subroutine' flag
dsx 20 end nameset bugns;
dsx 21 access lcpns;
6 size name(subtabsiz); $ procedure name
7 size fsw(ps); $ funct/subr/prog switch.
dsx 22 size i(ps); $ name length.
8
dsx 23 i = namelen;
dsx 24 if (slen name <= namelen) i = slen name;
dsz 8 $ accept null string as argument, and treat this as request
dsz 9 $ to reset dbsubtabp, as special service to setl system.
dsz 10 if i = 0 then $ if reset request.
dsz 11 dbsubtabp = 0;
dsz 12 return;
dsz 13 end if;
dsz 14 countup(dbsubtabp, subtabdim, 'dsubtab');
dsx 25 dbcursubn = .s. 1, i, name; $ extract part
15 dbcurfsw = fsw; $ set fnct/subr flag
16 dbnewsubfg = yes; $ set flag for flow trace
17 end subr subn;
1 .=member subx
2 subr subx;
3 access lcpns,bugns;;
4 $ this procedure pops the subroutine stack
5
6 if (dbsubtabp = 0) return; $ error
7 dbsubtabp = dbsubtabp-1; $ pop stack
8 end subr subx;
1 .=member lhdr
2 subr lhdr(line, type); $ print monitor header
dsx 26 access bugns, lcpns;
12 size line(ps); $ line number
13 size type(ps); $ type: 1=entry, 2=exit, 3=store, 4=error
14 size dbfswtxt(.sds. 5); dims dbfswtxt(3); $ name of proc type.
15 data dbfswtxt = 'subr ', 'fnct ', 'prog ';
16
17 newlin; $ start new line
18 dblinenum = dblinenum+1; $ count line
19 if dblinenum = 10 then $ must skip a line
20 dblinenum = 0; $ reset
21 endld $ leave blank line
22 end if;
23 tabl(dbsubtabp*4-2) textl('--> ') $ indent
24 if type = 1 then
25 textl('entry ')
26 elseif type = 2 then
27 textl('exit ')
28 elseif type = 3 then
29 textl('store ')
30 else
31 textl('error ')
32 end if;
33 textl('at line ') intl(line) textl(' in ')
34 textl(dbfswtxt(dbcurfsw+1))
35 textl(dbcursubn)
36 if (type > 2) textl(': ')
37
38 end subr lhdr;
1 .=member trfl
2 subr trfl(word, label);
3 $ procedure which counts number of times labeled blocks of code
4 $ are executed.
5 access lcpns,bugns;
6 size word(dbgwordsz); $ parameter 'word'
7 +* flowid = .f. 1, 13, ** $ block id
8 +* flowtyp = .f. 1, 3, ** $ block type
9 +* while_type = 1 ** $ type of 'while' statement
10 +* until_type = 2 ** $ type of 'until' statement
11 +* do_type = 3 ** $ type of 'do' statement
12 +* iftru_type = 4 ** $ 'if' - true
13 +* iffls_type = 5 ** $ 'if' - false
14 +* label_type = 6 ** $ label
15 +* flowblock = .f. 4, 10, ** $ block no.
16 +* flowlino = .f. 17, 16, ** $ line no.
17 size label(ws+1); $ label
18 size fent(flowtabsiz); $ flowtab entry
19 size i(ps); $ do loop var
20 size flowtabb(ps); $ bottom ptr to start of procedure
21
22 nameset flown; $ nameset for flow trace
23 size flowfg(1); data flowfg = 1; $ flow flag
24 size flowtab(flowtabsiz); dims flowtab(flowtabdim); $ table for
25 size flrouts(flroutssiz); dims flrouts(flroutsdim); $ procedures
26 size flowlab(labtabsiz); dims flowlab(labtabdim); $ label nam
27 size flowtabp(ps); data flowtabp = 0; $ ptr to flowtab
28 size flroutsp(ps); data flroutsp = 0; $ ptr to flrouts
29 size flowlabp(ps); data flowlabp = 0; $ ptr to flowlab
30 end nameset flown;
31
32 if (dbstoplist) return; $ excede line limit
33 if (flowfg = no) return; $ dynamic flag not on
34 if (flroutsp = 0) go to newrout;
35 if (dbnewsubfg) go to newrout;
36 $ in same procedure. search for entry in flowtab. if none exist,
37 $ start new entry.
38 flowtabb = fbeg flrouts(flroutsp); $ beginning of procedure
39 do i = flowtabb to flowtabp;
40 if (flowid word ^= fid flowtab(i)) cont do ;
41 $ found block
42 fcount flowtab(i) = fcount flowtab(i) + 1;
43 return;
44 end do;
45 $ block not found - add new entry to flowtab
46 go to addlab;
47
48 /newrout/ $ entered new procedure
49 dbnewsubfg = no;
50 countup(flroutsp, flroutsdim, 'flrouts');
51 fbeg flrouts(flroutsp) = flowtabp + 1; $ beg of rout in flowtab
52 lbeg flrouts(flroutsp) = flowlabp + 1; $ beg of rout in flowlab
53 /addlab/ $ add new entry to flowtab and flowlab if applicable
54 countup(flowtabp, flowtabdim, 'flowtab');
55 fent = 0; $ clear entry
56 fid fent = flowid word;
57 flino fent = flowlino word;
58 if flowtyp word = label_type then
59 countup(flowlabp, labtabdim, 'flowlab')
60 flabnam fent = flowlabp; $ ptr to label name
61 if slen label <= namelen then
62 flowlab(flowlabp) = label; $ just copy
63 else
64 flowlab(flowlabp) = .s. 1, namelen, label; $ else extract
65 end if;
66 end if;
67 fcount fent = 1;
68 flowtab(flowtabp ) = fent;
69 end subr trfl;
1 .=member prfl
2 subr prfl;
3 $ procedure to print flow statistic at exit from procedure
4 access lcpns,bugns;
5 size fent(flowtabsiz); $ entry in flowtab
6 size i(ps); $ do loop variables
7 size j(ps);
8 access flown;
9
10 if (dbstoplist) return; $ excede line limit
11 if (flroutsp = 0) return;
12 if (dbnewsubfg) return; $ nothing traced
13 if (flowfg = no) return;
14 newlin; endld textl('*** flow trace for ')
15 if dbcurfsw then textl('fnct ') else textl('subr ') end if;
16 textl(dbcursubn) textl(' ***') endld
17 textl('codeblock line executions') endld $ header
18 do i = fbeg flrouts(flroutsp) to flowtabp;
19 fent = flowtab(i);
20 go to l(fftyp fent) in while_type to label_type;
21 /l(while_type)/ textl('while') go to rest;
22 /l(until_type)/ textl('until') go to rest;
23 /l(do_type)/ textl('do') go to rest;
24 /l(label_type)/ charl(1r/) textl(flowlab(flabnam fent)) charl(1r/)
25 /rest/ tabl(namelen+3) intl(flino fent) skipl(12)
26 intl(fcount fent) endld
27 cont do i; $ go to next item
28 /l(iftru_type)/ $ number of times a condition is true
29 textl('if') tabl(namelen+3) intl(flino fent) skipl(5)
30 textl('true: ') intl(fcount fent)
31 do j = i + 1 to flowtabp; $ search for a matching false if
32 if (ffblock flowtab(j) ^= ffblock fent) cont do j;
33 $ found a match
34 textl(' false: ') intl(fcount flowtab(j))
35 fdone flowtab(j) = 1; $ flag entry as done
36 quit do j;
37 end do j;
38 endld
39 cont do i;
40 /l(iffls_type)/ $ number of times a condition was false
41 if (fdone fent) cont do i;
42 textl('if') tabl(namelen+3) intl(flino fent) skipl(5)
43 textl('false: ') intl(fcount fent) endld
44 end do i;
45 textl('*********************************') endld endld
46 $ update tables by popping top procedure from stacks
47 flowtabp = fbeg flrouts(flroutsp) - 1;
48 flowlabp = lbeg flrouts(flroutsp) - 1;
49 flroutsp = flroutsp - 1;
50 end subr prfl;
1 .=member prst
2 subr prst(varn, word, val, par1, par2, par3);
3 access lcpns,bugns;
4 size varn(ws+1); $ variable name
5 size word(dbgwordsz); $ parameter 'word'
6 +* vsize = .f. 01, 08, ** $ no. of words in var
7 +* vopcod = .f. 09, 03, ** $ store type
8 +* simp_type = 1 ** $ simple assignment
9 +* f_type = 2 ** $ .f. assignment
10 +* e_type = 3 ** $ .e. assignment
11 +* s_type = 4 ** $ .s. assignment
12 +* ch_type = 5 ** $ .ch. assignment
13 +* len_type = 6 ** $ .len. assignment
14 +* vindx = .f. 12, 01, ** $ flag for indexed assignment
15 +* vlino = .f. 17, 16, ** $ line no.
16 size val(ws+1); $ value to be listed
17 size par1(ps), par2(ps), par3(ps); $ these are parameters
18 $ for index, first bit, and length. if any of these if not
19 $ applicable it is skipped. i.e., in most cases at least one
20 $ of these variables is undefined.
21
22 size fbit(ps); $ first bit position
23 size flen(ps); $ field length
24 size nwd(ps); $ number of words of target
25 size vcod(ps); $ type of store
26 size fexts(sds(6)); dims fexts(len_type);
27 size i(ps); $ do loop var
28 data $ define values for store types
29 fexts(simp_type) = ' ': fexts(f_type) = '.f.':
30 fexts(e_type) = '.e.': fexts(s_type) = '.s.':
31 fexts(ch_type) = '.ch.': fexts(len_type) = '.len. ';
32
33 nameset storen; $ nameset for store trace
34 size storfg(1); data storfg = 1; $ store flag
35 end nameset storen;
36
37 if (dbstoplist) return; $ line limit exceded
38 if (storfg = no) return;
39 $ print trace
40 monitorhead(vlino word, 3); $ print header info
41 vcod = vopcod word;
42 nwd = vsize word;
43 textl(fexts(vcod)) $ print type of store
44 go to l(vcod) in simp_type to len_type; $ select type
45
46 /l(simp_type)/ /l(len_type)/ $ simple store or .len.
47 monitorvarout(varn, vindx word, par1, nwd, val); endld $ print va
48 return;
49
50 /l(f_type)/ /l(e_type)/ $ .f. or .e.
51 if vindx word then $ var. is indexed
52 fbit = par2; flen = par3; $ set values
53 else
54 fbit = par1; flen = par2; $ set values for non-indexed
55 end if;
56 intl(fbit) charl(1r,) intl(flen) textl(', ') $ write positions
57 monitorvarout(varn, vindx word, par1,
58 (flen+ws-1)/ws, (.e. 1, flen, val)); endld $ output value
59 return;
60
61 /l(s_type)/ $ .s. assignment
62 if vindx word then $ indexed
63 fbit = par2; flen = par3; $ get positions
64 else
65 fbit = par1; flen = par2; $ get positions if not indexed
66 end if;
67 intl(fbit) charl(1r,) intl(flen) textl(', ')
68 monitorvarout(varn, vindx word, par1, vsize word, val); endld
69 return;
70
71 /l(ch_type)/ $ .ch. type
72 if vindx word then fbit = par2; else fbit = par1; end if;
73 intl(fbit) textl(', ') textl(varn) $ start line
74 if vindx word then charl(1r() intl(par1) charl(1r)) end if;
75 textl(' = 1r') charl(val)
76 if dbbytefg then $ byte value wanted
77 textl(' = ') intlp(mradix, 1) textl('b''') bwordl(val)
78 charl(1r')
79 end if;
80 endld
81 end subr prst;
82 subr prs3(varn, word, val); $ print stores (3 parms)
83 size varn(ws+1), word(dbgwordsz), val(ws+1);
84 call prst(varn, word, val, 0, 0, 0);
85 end subr prs3;
86 subr prs4(varn, word, val, p1); $ print stores (4 parms)
87 size varn(ws+1), word(dbgwordsz), val(ws+1), p1(ps);
88 call prst(varn, word, val, p1, 0, 0);
89 end subr prs4;
90 subr prs5(varn, word, val, p1, p2); $ print stores (5 parms)
91 size varn(ws+1), word(dbgwordsz), val(ws+1), p1(ps), p2(ps);
92 call prst(varn, word, val, p1, p2, 0);
93 end subr prs5;
1 .=member pren
2 subr pren;
3 $ prints trace of entry to procedures if entry flag is on.
4
5 access lcpns,bugns;
6 nameset entryn;
7 size entrfg(1); data entrfg = 1; $ entry flag
8 end nameset entryn;
9
10 if (dbstoplist) return; $ excede line limit
11 if (entrfg = no) return;
12 monitorhead(1, 1); endld
13 end subr pren;
1 .=member prex
2 subr prex(lineno, nwds, val);
3 $ prints trace of exit from functions
4 access lcpns,bugns;
5 size lineno(ps); $ line no.
6 size nwds(ps); $ no. of words of return value (if present)
7 size val(ws+1); $ return value
8 access entryn;
9
10 if (dbstoplist) return; $ excede line limit
11 if (entrfg = no) return; $ runtime flag check
12 monitorhead(lineno, 2);
13 if dbcurfsw = 1 then $ this is a function.
14 textl(' with ') monitorvarout(dbcursubn, no, 0, nwds, val);
15 end if;
16 endld
17 end subr prex;
1 .=member prar
2 subr prar(varn, nwds, val);
3 access lcpns,bugns;
4 size varn(ws+1); $ variable name
5 size nwds(ps); $ no. of words in value
6 size val(ws+1); $ value of variable
7 size i(ps); $ do loop index
8 access entryn;
9
10 if (dbstoplist) return; $ excede line limit
11 if (entrfg = 0) return;
12 monitorhead(1, 1); $ say at line 1
13 textl(' with ') monitorvarout(varn, no, 0, nwds, val); endld
14 end subr prar;
1 .=member cinx
2 subr cinx(varn, val, dim, lineno);
3 $ this procedure checks the range of an indexed store to make sure
4 $ that no word outside the array boundary is being clobbered.
5 $ if the check fails, the program aborts.
6 access lcpns,bugns;;
7 size varn(ws+1); $ variable name
8 size val(ws); $ subscript value
9 size dim(ps); $ array dimension
10 size lineno(ps); $ line no.
11
12 if (val <= dim) & (val > 0) return;
13 $ print error message and abort
14 monitorhead(lineno, 4);
15 textl('*** index out of range. array = ') textl(varn)
16 tintl(' value of index', val) textl(' ***') endld
17 call ltlfin(1, 1005); $ $ array index out of range..
18 end subr cinx;
1 .=member prhd
2 subr prhd(lineno);
3 $ prints header of assertion list. streamlines output
4 access lcpns,bugns;
5 size lineno(ps); $ line no.
6 nameset asertn;
7 size assertno(ps); $ line no. of last assert failure
8 end nameset;
9
10 if (dbstoplist) return; $ excede line limit
11 assertno = lineno; $ set line no.
dsi 74 monitorhead(lineno, 4); textl('*** assertion failed ***') endld
13 end subr prhd;
1 .=member prvr
2 subr prvr(varn, nwds, val);
3 $ prints values of variables in assertion statement
4 access lcpns,bugns;
5 size varn(ws+1); $ variable name
6 size nwds(ps); $ number of words
7 size val(ws+1); $ value of variable
8 access asertn;
9
10 if (dbstoplist) return; $ excede line limit
11 monitorhead(assertno, 4); monitorvarout(varn, no, 0, nwds, val);
12 endld
13 end subr prvr;
1 .=member asfl
2 subr asfl;
3 $ print simple message for assertion faliure
4
5 endl textl('******** assertion failed ********') endl
6 call ltlfin(1, 1006); $ assertion failure.
7 end subr asfl;
1 .=member setx
2 subr setx(parm, change);
3 $ this procedure sets dynamic parameters
4
5 $ fields of -parm- and -change-
dsw 26 +* slct = .f. 1, ws-4, ** $ line limit
dsw 27 +* spbit = .f. ws-3, 1, ** $ 'print byte'
dsw 28 +* sflow = .f. ws-2, 1, ** $ 'set flow'
dsx 27 +* sstor = .f. ws-1, 1, ** $ 'set store'
dsw 30 +* sentr = .f. ws, 1, ** $ 'set entry'
11 access lcpns,bugns;
dsw 31 size parm(ws), change(ws); $ parameters
13 +* mod(val, fld) = if (fld change) val = fld parm **
14 access flown, storen, entryn; $ access namesets
15
16 mod(dblinelim, slct); mod(dbbytefg, spbit);
17 mod(flowfg, sflow); mod(storfg, sstor);
18 mod(entrfg, sentr);
19 macdrop(mod)
20
21 end subr setx;
1 .=member cntu
2 subr cntu(msg, lim); $ print countup overflow message
3 access lcpns,bugns;;
4 size msg(ws+1); $ message
5 size lim(ps); $ array limit
6
7 textl('***** monitor array ') textl(msg)
8 textl(' overflowed: limit is') intl(lim)
9 textl('. some monitor data lost *****') endld
10 end subr cntu;
1 .=member llex
2 subr llex; $ print monitor line limit exceeded
3 access lcpns,bugns;;
4
5 textl('***** monitor line limit of ') intl(dblinelim)
6 textl(' exceeded. further monitor output suppressed *****') endl
7 dbstoplist = yes; $ set flag to stop further output
8 end subr llex;
1 .=member varo
2 subr varo(name, flag, index, nwds, val); $ output variable - debu
3 access lcpns,bugns;;
4 size name(ws+1); $ variable name
5 size flag(1); $ set if variable is indexed
6 size index(ps); $ index if it is
7 size nwds(ps); $ number of words in vaariable
8 size val(ws+1); $ value of variable
9 size i(ps); $ define do loop variable
10 size flg(1); $ set if byte val must be printed
11
12 if (dbstoplist) return;
13 textl(name) $ output variable name
14 if flag then $ var. is indexed
15 charl(1r() intl(index) charl(1r)) $ print subscript
16 end if;
17 flg = yes; $ show should print bit value
18 if nwds = 1 then $ see if should print as integer
19 if .fb. .f.1, ws, val <= 16 !
20 .fb. (-(.f. 1, ws, val)) <= 11 then
21 $ value will fit in five digits printed by -intl-
22 textl(' = ') intl(val)
23 flg = no; $ need not print
24 end if;
25 end if;
26 if sorg val > cs & nwds*ws >= (sorg val)-1 then $ maybe sds
27 if ((sorg val)-1)/cs*cs = (sorg val)-1 &
28 sds(slen val) <= sorg val then $ if it is, it is well
29 if pfcol > pflen-(slen val)-5 then $ too long
30 endld tabl(10) $ start new line
31 end if;
32 textl(' = ''') textl(val) charl(1r')
33 flg = no;
34 end if;
35 end if;
36 if flg ! dbbytefg then $ print bit value
37 textl(' = ') intlp(mradix, 1) textl('b''')
38 do i = nwds to 2 by -1; $ print each word except last
39 if pfcol > pflen-bwordlen-5 then $ line too long
40 endld tabl(10)
41 end if;
42 bwordl(wordi(i, val)) charl(1r )
43 end do;
44 bwordl(wordi(1, val)) $ print last word
45 charl(1r')
46 end if;
47
48 end subr varo;
1 .=member endmon
1 .=member beglio
dsv 145 $ ifsa and ofsa are suggested optimizations that move
dsv 146 $ data directly from line buffer to user area where possible,
dsv 147 $ avoiding use of -gcb-.
dsv 148
dsv 149 .+s10.
dsv 150 .+set ifsa_env
dsv 151 .+set ofsa_env
dsv 152 .+set prfi $ set for debugging
dsv 153 ..s10
vaxa 11 .+s32.
vaxa 12 .+set ifsa_env
vaxa 13 .+set ofsa_env
dsb 49 .+set pcsa_env
vaxa 14 ..s32
vax 47 .+s37.
vax 48 .+set ifsa_env
vax 49 .+set ofsa_env
vax 50 ..s37
utsa 109 .+s47.
utsa 110 $ improved ifsa and ofsa not available (yet) for s47.
utsa 111 .-set ifsa_env
utsa 112 .-set ofsa_env
utsa 113 ..s47
2 .+s66.
3 .+set ofsa_env,ifsa_env
4 ..s66
dsf 74
utsb 33 .+s32u.
dsf 76 $ delete special env code for unix checkout.
dsf 77 .-set ifsa_env
dsf 78 .-set ofsa_env
dsf 79 .-set pcsa_env
utsb 34 ..s32u
dsf 81
utsa 114 .+s47.
utsa 115 $ delete special env code for unix checkout.
utsa 116 .-set ifsa_env
utsa 117 .-set ofsa_env
utsa 118 .-set pcsa_env
utsa 119 ..s47
utsa 120
5 $ fields of io status area.
6 $ title - characters of external name.
7 $ donotbit - 'should we ignore this io request.'
8 $ sfbit - 'has streaming been forced.'
9 $ ignorev - current 'ignore' value.
10 $ accessv - current 'access' value.
11 $ endseenv - used for 'mark' in 'filestat'.
12 $ errorv - associated with 'error' in 'filestat'.
13 $ binaryv - 'is this binary file'.
14 $ linesizev - 'linesize' value.
15 $ lbptr - current position in line buffer.
16 $ writing - 'are we writing to file' (0 if reading)
17 $ endack - 'must user acknowledge end of file.'
18 $ strorgv - address of lsw of string for access string.
19 $ lbmax - if lbptr decremented while forming line then
20 $ is largest value of lbptr, else is zero.
21 $ linenum - line number (number of sio ops)
22
23 +* donotbit(f) = .f. 01, 01, fatra(f) **
24 +* sfbit(f) = .f. 02, 01, fatra(f) **
25 +* ignorev(f) = .f. 04, 02, fatra(f) **
26 +* endack(f) = .f. 06, 01, fatra(f) **
27 +* accessv(f) = .f. 07, 03, fatra(f) **
28 +* endseenv(f) = .f. 10, 01, fatra(f) **
29 +* canput(f) = .f. 11, 01, fatra(f) **
30 +* canget(f) = .f. 12, 01, fatra(f) **
31 +* writing(f) = .f. 13, 01, fatra(f) **
32 +* errorv(f) = .f. 17, 05, fatra(f) **
33 +* binaryv(f) = .f. 22, 01, fatra(f) **
34 +* linesizev(f) = .f. 25, 08, fatra(f) **
35 .+s10.
36 +* lbptr(f) = .f. 37, 18, fatra(f) **
37 +* strorgv(f) = .f. 55, 18, fatra(f) **
38 +* lbmax(f) = .f. 73, 18, fatra(f) **
39 +* linenum(f) = .f. 91, 18, fatra(f) **
40 ..s10
41 .+s11.
42 +* strorgv(f) = .f. 33, 16, fatra(f) **
43 +* lbptr(f) = .f. 49, 08, fatra(f) **
44 +* lbmax(f) = .f. 57, 08, fatra(f) **
45 +* linenum(f) = .f. 65, 16, fatra(f) **
46 ..s11
vax 51 .+s32.
vax 52 +* strorgv(f) = .f. 33, 24, fatra(f) **
vax 53 +* lbptr(f) = .f. 57, 08, fatra(f) **
vax 54 +* lbmax(f) = .f. 65, 08, fatra(f) **
vax 55 $ for s32 redefine ignorev, accessv and errorv to
vax 56 $ improve code efficiency.
vax 57 +* ignorev(f) = .f. 73, 08, fatra(f) **
vax 58 +* accessv(f) = .f. 81, 08, fatra(f) **
vax 59 +* errorv(f) = .f. 89, 08, fatra(f) **
vax 60 +* linenum(f) = .f. 97, 24, fatra(f) **
vax 61 ..s32
53 .+s37.
54 +* strorgv(f) = .f. 33, 24, fatra(f) **
55 +* lbptr(f) = .f. 57, 08, fatra(f) **
56 +* lbmax(f) = .f. 65, 08, fatra(f) **
57 $ for s37 redefine ignorev, accessv and errorv to
58 $ improve code efficiency.
59 +* ignorev(f) = .f. 73, 08, fatra(f) **
60 +* accessv(f) = .f. 81, 08, fatra(f) **
61 +* errorv(f) = .f. 89, 08, fatra(f) **
62 +* linenum(f) = .f. 97, 24, fatra(f) **
63 ..s37
utsa 121 .+s47.
utsa 122 +* strorgv(f) = .f. 33, 24, fatra(f) **
utsa 123 +* lbptr(f) = .f. 57, 08, fatra(f) **
utsa 124 +* lbmax(f) = .f. 65, 08, fatra(f) **
utsa 125 $ for s47 redefine ignorev, accessv and errorv to
utsa 126 $ improve code efficiency.
utsa 127 +* ignorev(f) = .f. 73, 08, fatra(f) **
utsa 128 +* accessv(f) = .f. 81, 08, fatra(f) **
utsa 129 +* errorv(f) = .f. 89, 08, fatra(f) **
utsa 130 +* linenum(f) = .f. 97, 24, fatra(f) **
utsa 131 ..s47
dsw 32 .+s40.
dsw 33 +* strorgv(f) = .f. 33, 16, fatra(f) **
dsw 34 +* lbptr(f) = .f. 49, 08, fatra(f) **
dsw 35 +* lbmax(f) = .f. 57, 08, fatra(f) **
dsw 36 +* linenum(f) = .f. 65, 16, fatra(f) **
dsw 37 ..s40
64 .+s66.
65 +* strorgv(f) = .f. 33, 17, fatra(f) **
66 +* lbptr(f) = .f. 50, 08, fatra(f) **
67 +* lbmax(f) = .f. 61, 08, fatra(f) **
68 +* linenum(f) = .f. 69, 17, fatra(f) **
69 ..s66
70
71 +* fatrasz = $ size of fatra.
dst 74 .+s10 144
73 .+s11 80
vax 62 .+s32 128
75 .+s37 128
utsa 132 .+s47 128
dsw 38 .+s40 80
76 .+s66 120
77 **
78
79 +* titlev(f) = titlevara(f) **
80
81 $ line buffers for little io are allocated in iolba. iolbamax
82 $ gives upper bound on sum of line lengths of simultaneously
83 $ active formatted files.
84 +* iolbamax =
dsua 7 .+s10 1000
dsu 19 .+s11 400
dsf 82 .+s32 1000
dse 32 .+s37 500
utsa 133 .+s47 1000
dsw 39 .+s40 300
89 .+s66 80
90 **
91
92
93 +* iolb(c, f) = $ reference c-th char in line buffer of file -f-.
94 .f. 1 + cs*(cpw - c + cpw*((c-1)/cpw)), cs,
95 iolba(iolborg(f) + (c-1)/cpw) **
96
97
98 +* ifcanput(t) = .f. t, 1, 1b'110110' ** $ can we put to type f.
99 +* ifcanget(t) = .f. t, 1, 1b'011001' ** $ can we get from type f.
100 +* isbinary(t) = .f. t, 1, 1b'101000' ** $ if type t is binary
101 +* isoutput(t) = .f. t, 1, 1b'100110' ** $ if type t output.
102 +* isputorprint(t) = .f. t, 1, 1b'000110' **
103
104 /* all conversions take place in the global conversion
105 buffer, of length -gcblim- characters. the worst
106 case is conversion of a binary octal string of length
107 -szmax- which requires at least -szmax- characters.
108 most implementations will undoubtedly limit the length
109 of a single conversion. */
110 +* gcblim =
dsv 154 .+s10 200
112 .+s11 135
dse 33 .+s32 240
dse 34 .+s37 240
utsa 134 .+s47 240
dsw 40 .+s40 135
115 .+s66 240
116 **
117
118
119
120 $ to avoid conflicts with names of user procedures, the names of io
121 $ procedures begin with a four character code followed by a string
122 $ not usually found in names, but acceptable to the loader.
123 $ if possible, the trailer string should be '$io', as we expect
124 $ most loaders accept the character '$'.
125 $ if this string must be changed, consult use and definition of
126 $ -iorts- option in parser source.
127
dsw 41 .-s40. $ no trailer string for s40
129 +* cefr = 7ncefr$io ** $ convert exponent, fraction to real.
130 +* cref = 7ncref$io ** $ convert real for output.
131 +* deci = 7ndeci$io ** $ convert integer for output.
132 +* flsh = 7nflsh$io ** $ flush formatted output file
133 +* frew = 7nfrew$io ** $ rewind file (sys)
134 +* fwef = 7nfwef$io ** $ write eof (sys)
135 +* fwer = 7nfwer$io ** $ write record mark (sys)
136 +* gcfp = 7ngcfp$io ** $ control format processor
137 +* ifma = 7nifma$io ** $ -a- input format
138 +* ifmb = 7nifmb$io ** $ -b- input format
139 +* ifme = 7nifme$io ** $ -e- input format
140 +* ifmf = 7nifmf$io ** $ -f- input format
141 +* ifmi = 7nifmi$io ** $ -i- input format
142 +* ifmr = 7nifmr$io ** $ -r- input format
143 +* iget = 7niget$io ** $ get main procedure.
144 +* ilst = 7nilst$io ** $ get list mode.
145 +* ioer = 7nioer$io ** $ error processor
146 +* ions = 7nions$io ** $ io nameset.
147 +* ioqu = 7nioqu$io ** $ io query
148 +* iore = 7niore$io ** $ io request
149 +* iost = 7niost$io ** $ create and open std. get, put files
150 +* istr = 7nistr$io ** $ input streaming procedure
151 +* lpin = 7nlpin$io ** $ set initial position values.
152 +* makf = 7nmakf$io ** $ make system tables for file
153 +* pfin = 7npfin$io ** $ complete formatted put.
154 +* ogrp = 7nogrp$io ** $ put group constructor.
155 +* pdec = 7npdec$io ** $ put integer digits.
156 +* ofma = 7nofma$io ** $ -a- output format
157 +* ofmb = 7nofmb$io ** $ -b- output format
158 +* ofme = 7nofme$io ** $ -e- output format
159 +* ofmf = 7nofmf$io ** $ -f- output format
160 +* ofmi = 7nofmi$io ** $ -i- output format
161 +* ofmr = 7nofmr$io ** $ -r- output format
162 +* onma = 7nonma$io ** $ -n- array element name
163 +* onmv = 7nonmv$io ** $ -n- simple name list
164 +* ostr = 7nostr$io ** $ output streaming procedure
165 +* pcsa = 7npcsa$io ** $ process character for string access.
166 +* putf = 7nputf$io ** $ write print line through host io
167 +* pter = 7npter$io ** $ io error processor
168 +* prfi = 7nprfi$io ** $ print file (s66)
169 +* rdrb = 7nrdrb$io ** $ read binary slice (sys)
170 +* rlse = 7nrlse$io ** $ release file.
171 +* rwnd = 7nrwnd$io ** $ rewind file.
172 +* sigl = 7nsigl$io ** $ set ignore level.
173 +* uinp = 7nuinp$io ** $ unformatted input
174 +* unna = 7nunna$io ** $ io internal
175 +* uout = 7nuout$io ** $ unformatted output
176 +* vali = 7nvali$io ** $ validate io.
177 +* vnum = 7nvnum$io ** $ verify numeric constant.
178 +* wtrb = 7nwtrb$io ** $ write binary (sys)
dsw 42 ..s40
180
181 /* macros for standard io prologues and functions. */
182
183 $ fields of io paramter string.
184 +* iop_lm = .f. 01, 01, ** $ on if listing mode.
185 +* iop_fw = .f. 02, 08, ** $ field width.
186 +* iop_dw = .f. 10, 05, ** $ decimal (or byte) width.
187 +* iop_sz = .f. 17, 11, ** $ size of datum.
188 +* iop_gw = .f. 28, 04, ** $ group width.
189
190 +* iopsz = 32 ** $ size of io parameter string.
191
192 +* putg(c) = $ add character to gcb.
193 gcbptr = gcbptr+(gcbptr<1 ! fileid>maxfiles then $ if out of range.
237 ioerror(fileid, 2, 2);
238 end if;
239 **
240
241 +* chklioconn(f) = $ check that file f connected.
242 if accessv(f) = 0 then
243 ioerror(f, 2, 3);
244 end if;
245 **
246
1 .=member ltllio
2 subr ltllio(c); $ io executive.
3
4 size c(ps); $ action (1=start, 2=finis).
5 nameset ions; $ global conversion buffer.
6 $ printfileopen is set to one when standard print file opened.
7 size printfileopen(1); data printfileopen = no;
8 size titlevara(.sds. filenamelen); dims titlevara(maxfiles);
9 size ostr_rc(ws); $ return code from ostr.
10 size get_fc(ps); $ get format code.
11 size get_iop(iopsz); $ copy of get io parm string.
12 size ilst_rc(ws); $ get return code.
13 size istr_rc(ws); $ istr return code.
14 size get_not(ps); $ get 'global' do not bit.
15 size deci_arg(ws); $ binary integer input for conversion.
16 $ deci_lzero is nonzero if want at least deci_lzero digits
17 $ in integer conversion. leading zeros added if needed.
18 size deci_lzero(ps);
19
20 size deci_msd(ps); $ index in deciara of most significant dig.
21 $ deci_nsd is zero if all digits are to converted. if nonzero
22 $ then only first deci_nsd digits are converted.
23 size deci_nsd(ps);
24
25 $ deci_sign is zero if positive sign is not to be represented.
26 $ 1 - negative sign represented by minus.
27 $ 2 - positive sign represented by plus.
28 size deci_sign(ps);
29
30 size deci_unit(ps); $ index in deciara of 'units' digit.
31 size deciara(ws); dims deciara(deciaralen); $ integer conversio
32 size gcbptr(ps); $ on output, index of last char avail.
33 size get_mode(1); $ on if list mode input.
34 size get_bw(ps); $ byte width of l mode byte constant.
35 size get_char(cs); $ character for list mode input.
36 size get_fw(ps); $ number of characters istr is to get.
37 size get_expval(ws); $ value of exponent.
38 size gcb(ws);
39 dims gcb(gcblim);
40 size istr_file(ps); $ istr file.
41 size ostr_file(ps); $ osrt (and flsh) file.
42 size filenow(ps); $ current file.
43 size fatra(fatrasz); dims fatra(maxfiles);
44 size iolblistptr(ps);
45 size iolblist(ps); dims iolblist(maxfiles);
46 size iolborg(ps); dims iolborg(maxfiles);
47 size iolblen(ps); dims iolblen(maxfiles);
48 size iolbaptr(ps);
49 size iolba(ws); dims iolba(iolbamax);
50 end nameset ions;
51 size fi(ps);
dsi 75 size iorc(ws); $ io return code.
52
53
54 if c then $ if termination desired.
55 do fi = maxfiles to 3 by -1; $ inverse order.
56 if (accessv(fi)) call rlse(fi);
57 end do;
58 call rlse(1); call rlse(2); $ print file last.
59 return;
60 end if;
61
62 deci_lzero = 0; deci_nsd = 0; deci_sign = 0;
63 iolblistptr = 0; iolbaptr = 1;
64
65 do fi = 1 to maxfiles; $ initialize for each file.
66 fatra(fi) = 0; titlev(fi) = ''; $ set file status.
67 iolblen(fi) = 0; iolborg(fi) = 0;
68 end do;
69
dsi 76 call eretsio(2, iorc, 2); $ set verbose return if open fails.
70 call makf(2, 1b'1111', printfilename, access_print, pflen-1, 1);
dsf 83$ if cannot open standard output, terminate immediately.
dsf 84 if accessv(2)=0 then $ if could not open
dsf 85 call remarkl('cannot open standard output.');
dsf 86 $ call sysfin directly, as standard output not available.
dsj 13 call sysfin(1, 1007);
dsf 88 end if;
dsi 77 call eretsio(2, iorc, 0); $ set to quit if errors.
dsi 78
dsi 79 call eretsio(1, iorc, 1); $ set terse return if open fails.
71 call makf(1, 1b'1111', inputfilename, access_get, 0, 0);
dsi 80 call eretsio(1, iorc, 0); $ set to quit if errors.
72 end subr ltllio;
1 .=member makf
2 subr makf(farg, givarg, namearg, accarg, lnsarg, ignarg); $ make f
3 size farg(ps); $ file number.
4 $ givarg has bit -i- set if i-th attribute specified.
5 size givarg(ps);
6 size givens(ps); $ local copy of givarg.
7 size namearg(.sds.filenamelen); $ external name.
8 size accarg(ws); $ type of access.
9 size lnsarg(ws); $ line size.
10 size ignarg(ws); $ ignore level.
11 size lnsval(ps); $ copy of lnsarg.
12 size ignval(ps); $ copy of ignarg.
13 $ namearg, accarg, lnsarg and ignarg are -1 if not given in
14 $ file statement, in which case prior values are to be
15 $ inherited if possible.
16 size fileid(ps); $ file number.
17 size newname(.sds. filenamelen); $ new external name.
18 size i(ps); $ loop index.
19 size ret(ps); $ return code from oensio.
20 size ln(ps); $ name length.
21 size memptr(ps); $ returns address of argument.
22 size lnsret(ps); $ open returned linesize.
23 size accold(ps), accnew(ps); $ prior, new access codes.
24 access ions;
25
26 $ establish file correspondence.
27
28 fileid = farg;
29 chkliorange(fileid);
30 .+makfprfi call prfi(fileid,'entry to makf');
31
32 givens = givarg; $ find parameters actually specified.
33
34 .+ignoreinfilestatement.
35 if .f. 4, 1, givens then $ if ignore specified.
36 ignorev(fileid) = ignarg;
37 $ if ignore and access only specified, now pretend
38 $ that only access specified.
39 if (givens = 1b'1010') givens = 1b'0010';
40 if givens = 1b'1000' then $ if only ignore specified.
41 go to ret; end if;
42 end if;
43 ..ignoreinfilestatement
44
45 $ only can refer to file 2 once to open it (cf. ltllio).
46 if fileid=2 then
47 if (printfileopen) then ioerror(2, 2, 18); end if;
48 printfileopen = yes;
49 end if;
50
51 accnew = accarg; accold = accessv(fileid);
52
53 if givens = 1b'0010' then $ if access alone specified.
54 if accnew = access_release then $ if releasing.
55 call rlse(fileid); go to ret;
56 end if;
57 if ((accold=access_put ! accold=access_print) &
58 accnew=access_get)
59 ! (accold=access_write & accnew=access_read) then
60 $ here if changing from output to input.
61 call rwnd(fileid, accnew);
62 writing(fileid) = no;
63 errorv(fileid) = no;
64 canget(fileid) = yes; canput(fileid) = no;
65 accessv(fileid) = accnew;
66 go to ret;
67 else $ illegal case.
68 ioerror(fileid, 2, 4); go to ret;
69 end if;
70 end if;
71
72 $ here to terminate existing connection and prepare to set up
73 $ new one.
74
75 if accold then $ if existing connection.
76 call rlse(fileid);
77 end if;
78
79 .+ignoreinfilestatement.
80 $ if ignore not specified, pick default.
81 if .f. 4, 1, givens then
82 ignval = ignarg;
83 else $ pick default.
84 ignval = (accnew = access_print) ! (accnew = access_string);
85 end if;
86 .-ignoreinfilestatement.
87 ignval = (accnew = access_print) ! (accnew = access_string);
88 ..ignoreinfilestatement.
89
90 ignorev(fileid) = ignval;
91 accessv(fileid) = accnew;
92 canput(fileid) = ifcanput(accnew);
93 canget(fileid) = ifcanget(accnew);
94 binaryv(fileid)= isbinary(accnew);
95 lnsval = lnsarg * (.f. 3, 1,givens); $ set linesize if given.
96 if (lnsval^=0 & accnew=access_print) lnsval = lnsval+1;
97 iolblen(fileid) = 0;
99
100 if accnew = access_string then $ if string
101 strorgv(fileid) = memptr(namearg);
102 titlev(fileid) = '';
103 lnsret = lnsval;
104 go to allobuf;
105 end if;
106 newname = filenamelenblanks;
107 ln = slen namearg;
108 if (ln>filenamelen) ln = filenamelen;
109 do i = 1 to ln;
110 .ch. i, newname = .ch. i, namearg;
111 end do;
112 slen newname = ln;
113
dsb 50 titlev(fileid) = newname;
114 call opensio(fileid, ret, accnew, newname, lnsval, lnsret, 0, 0);
dsf 89 if ret then $ if cannot open, set access type to zero.
dsf 90 accessv(fileid) = 0;
dsf 91 go to ret;
dsf 92 end if;
dsnb 1 if accnew=access_get then $ if can get, set prompt
dsna 5 call promsio(fileid,ret,termprompt);
dsn 28 end if;
116 /allobuf/ $ here to allocate line buffer if need one.
117
118 linesizev(fileid) = lnsret;
dsy 8 call lpin(fileid); $ initialize line pointer.
119 if (lnsret) iolblen(fileid) = (lnsret-1)/cpw + 1;
120
121 if iolblen(fileid) then $ if need buffer
122 if iolblen(fileid) + iolbaptr <= iolbamax then
123 iolborg(fileid) = iolbaptr;
124 do i = 0 to iolblen(fileid)-1; $ clear buffer.
125 iolba(iolbaptr+i) = blankword;
126 end do;
127 iolbaptr = iolbaptr + iolblen(fileid);
128 iolblistptr = iolblistptr+1;
129 iolblist(iolblistptr) = fileid;
130 else
131 ioerror(fileid, 2, 7); $ if cannot allocate buffer.
132 end if;
133 end if;
134 /ret/
135 .+makfprfi call prfi(fileid,'exit from makf');
136 end subr makf;
1 .=member lpin
2 subr lpin(farg); $ initialize line pointer.
3 $ lpin contains code common to makf and rewi, which sets initial
4 $ line position for coded files and clears various fields.
5 access ions;
6 size farg(ps); $ file number.
7 size fileid(ps); $ working copy of file number.
8 size accnow(ps); $ file access.
9 size lbp(ps); $ new value of lbptr.
10
11 fileid = farg;
12 chkliorange(fileid);
13 chklioconn(fileid);
14
15 endseenv(fileid) = no;
16 endack(fileid) = no;
17 errorv(fileid) = 0;
18 $ initialize lbptr if get, put, print or string.
19 lbp = 0;
20 accnow = accessv(fileid);
21 if accnow = access_string then
22 lbp = 1;
23 elseif accnow = access_print then
24 lbp = 2; iolb(1, fileid) = 1r ;
25 elseif accnow = access_put then
26 lbp = 1;
27 elseif accnow = access_get then
28 lbp = 1 + linesizev(fileid);
29 end if;
30
31 lbmax(fileid) = 0; $ reset lbmax.
32 lbptr(fileid) = lbp;
33 linenum(fileid) = 0; $ reset line number.
34 end subr lpin;
1 .=member sigl
2 subr sigl(farg, iglev); $ set ignore level for file.
3 $ set ignore level for file. accept even if file not connected,
4 $ although value set will be lost when file opened.
5 size farg(ps); $ file number.
6 size iglev(ps); $ new ignore level.
7 size fileid(ps); $ local copy of farg.
8 access ions;
9
10 fileid = farg;
11 chkliorange(fileid);
12 ignorev(fileid) = iglev;
13 end subr sigl;
1 .=member rlse
2 subr rlse(farg); $ release file.
3 size farg(ps); $ file number.
4 access ions;
5 size fileid(ps); $ copy of file number.
6 size accnow(ps); $ type of file.
7 size j(ps), w(ps), fi(ps); $ loop indexes.
8 size oldorg(ps), neworg(ps); $ old, new line buffer origins.
9 size rc(ws); $ return code.
10
11 fileid = farg;
12 accnow = accessv(fileid);
13 if (accnow=0) return; $ if no file association.
14 if errorv(fileid)=0 & isoutput(accnow) then
dsg 8 if (accnow=access_put & lbptr(fileid)>1)
dsg 9 ! (accnow=access_print & lbptr(fileid)>2) then
17 ostr_file = fileid; call flsh;
18 end if;
19 end if;
20
21 $ if file has line buffer allocated, free it.
22 if iolborg(fileid) then
23 if iolblist(iolblistptr) = fileid then $ if last, just get s
24 iolbaptr = iolbaptr - iolblen(fileid);
25 else $ if not last, compact buffers above.
26 do j = 1 to iolblistptr;
27 if (iolblist(j)=fileid) quit do;
28 end do;
29 neworg = iolborg(fileid);
30 do fi = j+1 to iolblistptr;
31 oldorg = iolborg(iolblist(fi));
32 do w = 0 to iolblen(iolblist(fi))-1;
33 iolba(neworg+w) = iolba(oldorg+w);
34 end do w;
35 iolborg(iolblist(fi)) = neworg;
36 neworg = neworg + iolblen(iolblist(fi));
37 iolblist(fi-1) = iolblist(fi);
38 end do;
39 iolbaptr = neworg;
40 end if;
41 iolblistptr = iolblistptr - 1;
42 iolborg(fileid) = 0;
43 iolblen(fileid) = 0;
44 end if;
45
46 $ if actual file, close using sio.
47 $ if not print, or string file.
48 if accnow^=access_string then
49 call clossio(fileid, rc);
dsb 52 if rc then $ if cannot close file.
dsb 53 ioerror(fileid, 2, 21);
dsb 54 end if;
50 end if;
51 accessv(fileid) = 0; $ clear file association.
52 end subr rlse;
53 subr rwnd(farg, accnew); $ rewind file.
1 .=member rwnd
2 access ions;
3 size farg(ps); $ file number.
4 size accnew(ps); $ new access mode.
5 size fileid(ps); $ local copy of farg.
6 size ret(ws); $ return code.
7 size iot(ps); $ access of file.
8
9 fileid = farg;
10 chkliorange(fileid);
11 chklioconn(fileid);
12 iot = accessv(fileid);
13 if (iot=0) return; $ cannot rewind undefined file.
14 if errorv(fileid)=0 & isoutput(iot) then
15 if isputorprint(iot) &
16 lbptr(fileid)>1 then
17 ostr_file = fileid; call flsh;
18 end if;
19 end if;
20 if iot ^= access_string then $ if not string, can rewind.
21 $ the third argument for rewisio is nonzero if rewind is
22 $ to change access, or zero to keep current access and
23 $ rewisio is just to position file at start.
24 call rewisio(fileid, ret, accnew);
dsb 55 if ret then $ if cannot rewind file.
dsb 56 ioerror(fileid, 2, 22);
dsb 57 end if;
25 end if;
26 call lpin(fileid); $ set initial position values.
27 end subr rwnd;
1 .=member prfi
2 .+prfi.
3 $
4 $ purge this deck after debugging.
5 $
6 subr prfi(fileid,msg);
7 access ions;
8 size fileid(ps), msg(20*cs);
9 size i(ps);
10 endl; textl(msg); endl
11 tintl('file number',fileid) endl
12 textl('title=') textl(titlev(fileid)) endl
13 tintl('donotbit', donotbit(fileid)) endl
14 tintl('sfbit', sfbit(fileid)) endl
15 tintl('ignorev', ignorev(fileid)) endl
16 tintl('io access', accessv(fileid)) endl
17 tintl('end seen', endseenv(fileid)) endl
18 tintl('end acknowledge', endack(fileid)) endl
19 tintl('error', errorv(fileid)) endl
20 tintl('linesize', linesizev(fileid)) endl
21 tintl('lbptr', lbptr(fileid)) endl
22 tintl('canget',canget(fileid)) endl
23 tintl('canput',canput(fileid)) endl
24 tintl('writing', writing(fileid)) endl
25 tintl('line buff org',iolborg(fileid))
26 tintl('line buff len',iolblen(fileid)) endl
27 textl('end of file attribute list.') endl;
28 end subr prfi;
29 ..prfi
1 .=member vali
2 subr vali(farg, act); $ validation procedure.
3 access ions;
4 $ set =writing= value for file.
5 size farg(ps); $ file number.
6 size fileid(ps), what(ps);
7 size wb(1); $ on if want to write (output) to file.
8 $ verify that file fileid attributes consistent with desired
9 $ operation expressed in io parm string iop. if not, issue
10 $ error message and set donotbit. if ok, clear donotbit and
11 $ error fields, and set writing flag if writing to file.
12 size act(ps); $ type of validation.
13 $ .f. 1, 1, act on for read, .f. 2, 1, on for binary.
14
15 fileid = farg;
16 chkliorange(fileid);
17 chklioconn(fileid); $ verify connection.
18 filenow = fileid; $ set file for this op.
19 donotbit(fileid)= 0; $turn donotbit off
20 $ clear all error flags
21 errorv(fileid)= 0;
22 sfbit(fileid)= 0;
23
24 wb = .f. 1, 1, act; $ on if want to write to file.
25 if wb then $ if want to write.
26 if (canput(fileid) = no) go to valierr;
27 else
28 if (canget(fileid) = no) go to valierr;
29 end if;
30 writing(fileid) = wb;
31 if (binaryv(fileid) ^= .f. 2, 1, act) go to valierr;
32 return;
33 /valierr/ $ here if validation fails.
34 ioerror(fileid, 2, 8);
35 end subr vali;
1 .=member ioqu
2 fnct ioqu(farg, c); $ filestat function.
3 access ions;
4 $ return file attribute in response to filestat inquiry.
5 $ 1. cursor
6 $ 2. end
7 $ 3. err
8 $ 4. ignore
9 $ 5. access
10 $ 6. linesize
11 $ 7. stream
12 size ioqu (ws);
13 size farg(ps); $ file id as argument.
14 size fileid(ps), c(ps);
15
16 fileid = farg;
17 chkliorange(fileid);
18 $ require file connection unless query for access.
19 if c^=5 then
20 chklioconn(fileid);
21 end if;
22 go to l(c) in 1 to 7;
23 /l(1)/ $ return cursor position.
24 ioqu = lbptr(fileid)- (accessv(fileid) = access_print);
25 go to ret;
26 /l(2)/ $ return nonzero if at end of file.
27 endack(fileid) = 0; $ acknowledge end checked.
28 ioqu = endseenv(fileid); go to ret;
29 /l(3)/ $ return error state.
30 ioqu = errorv(fileid);
31 go to ret;
32 /l(4)/ $ return ignore level.
33 ioqu = ignorev(fileid); go to ret;
34 /l(5)/ $ return access.
35 ioqu = accessv(fileid); go to ret;
36 /l(6)/ $ return linesize.
37 ioqu = linesizev(fileid) - (accessv(fileid)=access_print);
38 go to ret;
39 /l(7)/ $ return nonzero if streaming forced.
40 ioqu = sfbit(fileid); go to ret;
41 /ret/ $ return.
42 end fnct ioqu;
1 .=member pcsa
dsb 58 .-pcsa_env.
2 subr pcsa(rc, putting, saddr, cpos, cval); $ process string access
3 /* process character for string access. saddr is the address of a
4 character string. if this string is not correctly formed, set rc
5 to one and return. cpos is an index in the string. if cpos is
6 not a valid index for the string, set rc to two and return.
7 if putting is nonzero, set the cpos-th character of the string to
8 be cval. if putting is zero, set cval to be the cpos-th character
9 of the string. */
10
11 size rc(ps); $ return code.
12 size putting(ps); $ nonzero to insert character.
13 size saddr(ps); $ address of string.
14 size cpos(ps); $ character index.
15 size cval(cs); $ character to get or put.
16 size strorg(ps); $ string origin.
17 size strlen(ps); $ current length of string.
18 size strwords(ps); $ words in string.
19 size fword(ps); $ word in string to process.
20 size fpos(ps); $ starting position of character.
21 size wd(ws); $ memory word.
22
23 size memget(ws); $ absolute memory reader.
24
25 $ sorg extraction complicated by possibility sorg and slen in
26 $ different words (code assumes if so, slen is full word).
27 wd = memget(saddr - (.sl./ws));
28 strorg = .e. (1+.sl.) - ws*(.sl./ws), .so., wd;
29 strlen = slen (memget(saddr));
30 if (strorg <= (.sl.+.so.)) go to giverr(1); $ if org too small.
31 strwords = strorg / ws;
32 if (strorg ^= (strwords*ws+1)) go to giverr(1);
33 if ((cpos<1) ! (cpos>strlen)) go to giverr(2);
34 fpos = strorg - cpos*cs;
35 if (fpos <= (.sl.+.so.)) go to giverr(2);
36 fword = fpos / ws;
37 fpos = fpos - fword*ws;
38 wd = memget(saddr-fword);
39 if putting then $ if inserting character.
40 .f. fpos, cs, wd = cval;
41 call memput(saddr-fword, wd); $ store new word.
42 else $ if extracting character.
43 cval = .f. fpos, cs, wd;
44 end if;
45 rc = 0;
46 return;
47 /giverr(1)/ $ here if string not well formed.
48 rc = 1; return;
49 /giverr(2)/ $ here if cpos not valid index.
50 rc = 2; return;
51 end subr pcsa;
dsb 59 ..pcsa_env
1 .=member ostr
2 subr ostr; $ output with streaming.
3 access ions;
4 size fw(ps); $ total external field width or nbr lines flus
5 size lbp(ps); $ entry value of lbptr for file.
6 $ 2 if physical output or system error
7 access ions;
8 size strfile(1); $ 1 if string file, 0 if external file
9 size saddr(ps); $ string address if string file.
10 size sarc(ps); $ pcsa return code.
11 size lpmax(ps); $ line buffer (or storage buffer) ptr maximum
12 size i(ps); $ loop index
13 size j(ps); $ loop index.
14 $ initialization, buffer flushing, and truncation action
15 ostr_rc = 0;
16 if gcbptr < 1 then
17 return; end if; $ useless to do anything more.
18 strfile = (accessv(ostr_file) = access_string);
19
20 lpmax = linesizev(ostr_file);
21 lbp = lbptr(ostr_file);
22
23 if strfile then $ string vs. external
24 saddr = strorgv(ostr_file);
25 end if;
26
27
28 do i = 1 to gcbptr;
29 if lbp > lpmax then $ first, write out the
30 $ line if it is full
31
32 lbptr(ostr_file) = lpmax+1; $ restore lbptr.
33 call flsh;
34 sfbit(ostr_file) = 1;
35 lbp = lbptr(ostr_file);
36 if (ostr_rc) go to error;
37 end if lbp;
38
39
40 if strfile then $ now, put -gcb(i)- into the line.
41 call pcsa(sarc, 1, saddr, lbp, gcb(i)); $ put character.
42 if sarc then
43 ioerror(ostr_file, 2, (13+sarc)); $ bad string.
44 end if;
45 else
46 iolb(lbp, ostr_file) = gcb(i);
47 end if;
48 lbp = lbp + 1;
49 end do;
50
51 lbptr(ostr_file) = lbp;
52 return;
53 /error/
54 lbptr(ostr_file) = lbp;
55 end subr ostr;
1 .=member flsh
2 subr flsh; $ flush formatted output buffer
3 access ions;
4 size strfile(1); $ 'is file of type string'
5 size lpmax(ps); $ line buffer pointer maximum
6 size qsa(ps); $ quoted string address (string file
7 size i(ps); $ counter
8 size printsw(ps); $ on for printer type files
9 size lborg(ps); $ origin position for line blanking.
10 size lbp(ps); $ copy of line buffer pointer.
11 size lbm(ps); $ copy of lbmax value.
12
13 ostr_rc = 0;
14 lpmax = linesizev(ostr_file);
15 strfile = (accessv(ostr_file) = access_string);
16 printsw = (accessv(ostr_file) = access_print);
17 lbp = lbptr(ostr_file);
18 lbm = lbmax(ostr_file);
19 if (lbm > lbp) lbp = lbm; $ set to last col if needed.
20
21 $ if string file, just reset; otherwise write line.
22 if strfile = no then $ if not string file.
23 if ostr_file = 2 then
24 call putf;
dse 35 else
26 call putwsio(ostr_file, ostr_rc, iolba,
27 iolborg(ostr_file), lbp-1);
28 linenum(ostr_file) = linenum(ostr_file)+1;
29 end if;
30 lborg = iolborg(ostr_file) - 1;
31 do i = 1 to iolblen(ostr_file);
32 iolba(lborg+i) = blankword;
33 end do;
34 end if strfile;
35 lbptr(ostr_file) = 1 + printsw;
36 lbmax(ostr_file) = 0; $ reset lbmax.
37 $ clear ostr buffer may be needed.
38 if (printsw) iolb(1, ostr_file) =1r ;
39 if (ostr_rc) go to error; $ for external fil
40 return;
41
42 /error/ $ physical or system error exit
43 ostr_rc = 3;
44 end subr flsh;
1 .=member putf
2 subr putf; $ put line to standard print file.
3 access ions;
4 access lcpns;
5
6 size lbp(ps); $ copy of line buffer pointer.
7 size lbm(ps); $ copy of lbmax value.
8
9 lbp = lbptr(2); lbm = lbmax(2) + 1;
10 if (lbm > lbp) lbp = lbm; $ set to last column if needed.
11 lbp = lbp - 1;
12 .+unpk_env.
13 $ pack line directly into lcp buffer.
14 call 7nunpk$li(pfl, 1, iolba, iolborg(2), lbp);
15 .-unpk_env.
16 size j(ps); $ loop counter
dsu 20 j = iolborg(2);
18 do pfcol = 1 to lbp;
19 pfl(pfcol) = .f. ws+1 - cs - cs*mod(pfcol-1,cpw), cs,
20 iolba(j+(pfcol-1)/cpw);
21 end do;
22 ..unpk_env
23
24 pfcol = lbp + 1;
25 call endlr; $ terminate line.
26 end subr putf;
1 .=member gcfp
2 subr_putfmt(gcfp); $ control format processor.
3 $ process control format.
4 size j(ps); $ loop index.
5 size n(ws); $ count, may be negative (x item).
6 size c(ps); $ type of control item.
7 size iot(ps); $ access of file.
8 size lbp(ps); $ entry value of lbptr.
9 size lbm(ps); $ entry value of max.
10 size writecase(1); $ on if writing to file.
11 size ret(ws); $ return code.
12
13 n = .f. 1, ws, datum;
14 c = iop;
15 lbp = lbptr(filenow);
16 lbm = lbmax(filenow);
17 writecase = writing(filenow);
18 iot = accessv(filenow);
19
20 go to l(c) in 1 to 4;
21 /l(1)/ $ column control format item
22
23 n = n + (iot = access_print);
24 if n <= 0 ! (n > linesizev(filenow)) then
25 go to parmerr;
26 else
27 if (lbp > lbm) lbmax(filenow) = lbp;
28 lbptr(filenow) = n;
29 endseenv(filenow) = 0;
30 end if;
31
32 return;
33
34 /l(2)/ $ skip (some number of lines) control format item
35 if (n = 0) return;
36
37 if iot = access_string then $ reset on skip or page.
38 lbptr(filenow) = 1; lbmax(filenow) = 0;
39 return;
40 end if;
41
42 if n < 0 ! n > 100 then
43 go to parmerr;
44 else
45 do i = 1 to n;
46 if writecase then
47 ostr_file = filenow;
48 call flsh;
49 if (ostr_rc) go to ostrerr;
50 else
51 $ force istr to read new line.
52 get_fw = 1; get_mode = 0;
53 istr_file = filenow;
54 lbptr(istr_file) = linesizev(istr_file)+1;
55 call istr;
56 ret = istr_rc;
57 if (istr_rc) go to istrerr;
58 end if;
59 end do;
60 if writecase = no then lbptr(filenow) = 1; end if;
61 end if;
62
63 return;
64 /l(3)/ $ page control format item
65
66 $ storage output -p- item becomes -j(1)- item.
67 if ((iot = access_string) & writecase) go to l(2);
68
69 if iot = access_print then
70 ostr_file = filenow;
71 call flsh;
72 if (ostr_rc) go to ostrerr;
73 iolb(1, filenow) = 1r1;
74 else
75 go to parmerr;
76 end if;
77
78 return;
79 /l(4)/ $ space control format item
80 if (n = 0) return;
81
82 if n < 0 then $ take back item
83 n = (lbp) + n;
84 $ permit retrieval of carriage control of print file.
85 if n < (1 - (iot=access_print)) then
86 go to parmerr;
87 else
88 if (lbp > lbm) lbmax(filenow) = lbp;
89 lbptr(filenow) = n + (iot=access_print);
90 end if;
91
92 else $ positive value in -x- item
93 if n > gcblim then
94 go to parmerr;
95 else
96 if writecase then
97 do i = 1 to n;
98 gcb(i) = 1r ;
99 end do;
100 gcbptr = n;
101 call pfin(iop, 0); $ write out gcb.
102 else
dsda 1 i = n + lbptr(filenow); $ desired position.
104 if i < linesizev(filenow) then
105 lbptr(filenow) = i; $ if stay in current line.
106 ret = 0;
107 else $ if x forces streaming, call istr.
108 get_fw = n; get_mode = 0;
109 istr_file = filenow; call istr;
110 if (istr_rc) go to istrerr;
111 end if;
112 end if;
113 end if;
114 end if;
115
116 return;
117
118 /istrerr/
119 /ostrerr/
120 $ here if transmission error or end seen.
121 return;
122 /parmerr/ $ here if bad parameter in control request.
123 ioerror(filenow, 2, 16);
124 return;
125 end subr gcfp;
1 .=member pfin
2 subr pfin(ioparg, c); $ complete formatted put.
3 access ions;
4 ostr_file = filenow;
5 size ioparg(iopsz); $ io parameter list.
6 $ c is termination type, as follows.
7 $ 0 - just call ostr (called from onma, onmv).
8 $ 1 - a, r formats. left align field.
9 $ 2 - b format. right align field.
10 $ 3 - e, f, i formats. groups already formed.
11 size c(ps);
12 size fw(ps); $ field width.
13 size gw(ps); $ group width.
14 size i(ps); $ loop index.
15 size nb(ps); $ number of blanks to insert.
16 size truncerr(ps); $ on if truncation error.
17
18 truncerr = no;
19 if (c=0) go to ostrdo;
20 if iop_lm ioparg then $ if list mode.
21 putg(1r ); $ terminate list field.
22 else $ if edit mode.
23 gw = iop_gw ioparg;
24 fw = iop_fw ioparg;
25 if fw >= gcblim then $ if fw too large, is truncation.
26 fw = gcblim;
27 truncerr = yes;
28 end if;
29 if ((gw>0)&(c>0)&(c<3)) call ogrp(gw, c); $ if groups.
30 if (fw > gcbptr) then
31 nb = (fw - gcbptr);
32 if c=1 then $ if left aligned, add trailing blanks.
33 do i = 1 to nb;
34 gcb(gcbptr+i) = 1r ;
35 end do;
36 else $ if right aligned, move and add leading blanks.
37 do i = gcbptr to 1 by -1; $ move data
38 gcb(i+nb) = gcb(i);
39 end do;
40 do i = 1 to nb;
41 gcb(i) = 1r ;
42 end do;
43 end if;
44 gcbptr = gcbptr + nb;
45 elseif fw < gcbptr then $ if possible truncation.
46 if (c=3) & (fw>0) then
47 truncerr = yes;
48 end if;
49 end if;
50 end if;
51
52 if (gcbptr >= gcblim) truncerr = yes;
53 /ostrdo/
54 if truncerr then $ if truncation, fill field with *.
55 do i = 1 to fw; gcb(i) = 1r*; end do;
56 gcbptr = fw;
57 end if;
58 call ostr;
59 if ostr_rc then $ if ostr transmission error.
dsb 60 ioerror(filenow, 2, 17);
61 end if;
62 if truncerr then $ if truncation error.
63 ioerror(filenow, 1, 1);
64 end if;
65 end subr pfin;
1 .=member ogrp
2 subr ogrp(gw, c); $ output group formation.
3 access ions;
4 $ form groups of gw characters each. c gives type of group:
5 $ c is one for groups formed from the left (a,r formats).
6 $ c is two for -b- format groups formed from the right.
7 size gw(ps); $ group width.
8 size c(ps); $ type of grouping desired.
9 size i(ps); $ loop index.
10 size inthis(ps); $ characters inserted in current group.
11 size nc(ps); $ number of data characters.
12 size ng(ps); $ number of groups to form.
13 size np(ps); $ position during grouping.
14 size gs(60); $ bit i on if group in numeric case.
15
16 if (gw<=0) return;
17 if c < 3 then
18 if (gcbptr<=gw) return;
19 ng = (gcbptr-1) / gw;
20 nc = gcbptr;
21 inthis = 0;
22 end if;
23 if c = 1 then $ if groups from left.
24 $ move data to right, then copy inserting group separating
25 $ blanks.
26 if ((gcbptr+ng) > gcblim) ng = gcblim - gcbptr;
27 do i = gcbptr to 1 by -1;
28 gcb(i+ng) = gcb(i);
29 end do;
30 gcbptr = gcbptr + ng;
31 np = 0;
32 do i = gcbptr-nc+1 to gcbptr;
33 np = np + 1;
34 gcb(np) = gcb(i);
35 inthis = inthis + 1;
36 if inthis=gw & (i1) then $ if group complete.
50 np = np - 1;
51 gcb(np) = 1r ;
52 inthis = 0;
53 end if inthis;
54 end do i;
55 elseif c = 3 then $ if numeric grouping, do in deciara.
56 gs = 0;
57 do i = deci_unit - gw to deci_msd by -gw;
58 .f. i, 1, gs = 1;
59 end do;
60 do i = deci_unit + gw to deci_lsd-1 by gw;
61 .f. i, 1, gs = 1;
62 end do;
63 ng = .nb. gs; $ number of groups.
64 if (ng = 0) return;
65 np = deci_msd - ng - 1;
66 do i = deci_msd to deci_lsd;
67 np = np + 1;
68 deciara(np) = deciara(i);
69 if .f. i, 1, gs then $ if end of group, add blank.
70 np = np + 1;
71 deciara(np) = 1r ;
72 end if;
73 if (i = deci_unit) deci_unit = np; $ adjust unit pos.
74 end do;
75 deci_msd = deci_msd - ng;
76 end if c;
77 end subr ogrp;
1 .=member deci
2 subr deci; $ convert integer to digit sequence.
3 access ions;
4 $ convert binary integer in deci_arg into sequence of numberic
5 $ character codes in deciara. deci_lsd gives index of least
6 $ significant digit, deci_msd gives index of most significant
7 $ digit. if deci_nsd is nonzero on entry, then only deck_nsd
8 $ digits are converted. deci_lzero is nonzero on entry to
9 $ indicate that leading zeros are to be added if necessary
10 $ to obtain deci_lzero digits.
11
12 $ the code will work correctly on two's complement machines,
13 $ which have a smallest negative integer whose absolute value is
14 $ one more than the absolute value of the largest postive
15 $ integer.
16
17 size n(ps); $ index.
18 size v(ws); $ value to convert.
19 size i(ps); $ loop indexes.
20 size d(ps); $ current digit.
21 size di(ps); $ index in ara to receive next digit.
22 size msdwant(ps); $ desired value of msd if deci_nsd given.
23
24 v = deci_arg;
25 .+itoc_env. $ if environment conversion procedure.
26 size itocara(ws); dims itocara((deciaralen/cpw)+1);
27 call itoc(v, itocara, di); $ convert.
28 deci_msd = (deci_lsd+1) - di;
29 call 7nunpk$li(deciara, deci_msd, itocara, 1, di);
30 .-itoc_env. $ if not done in environment.
31 di = deci_lsd + 1;
32 if v >= 0 then $ if nonnegative
33 until v = 0;
34 di = di - 1; $ move to next position.
35 deciara(di) = charofdig((v-(v/10)*10));
36 v = v/10;
37 end until;
38 else $ if negative.
39 until v = 0;
40 di = di - 1; $ move to next position.
41 deciara(di) = charofdig((10*(v/10)-v));
42 v = v/10;
43 end until;
44 end if;
45 deci_msd = di;
46 ..itoc_env
47 deci_msd = di; $ store position of msd.
48 deci_unit = 0; $ reset.
49 $ if exactly deci_nsd digits desired, see if more obtained.
50 $ if so, remove extra digits.
51 if deci_nsd then
52 msdwant = deci_lsd + 1 - deci_nsd; $ desired msd value.
53 if deci_msd < msdwant then $ if too many digits, drop exces
54 n = deci_msd + deci_nsd - 1;
55 do i = 0 to deci_nsd-1;
56 deciara(deci_lsd-i) = deciara(n-i);
57 end do;
58 elseif deci_msd > msdwant then $ if too few, add zeros.
59 n = deci_msd - msdwant;
60 do i = deci_msd to deci_lsd;
61 deciara(i-n) = deciara(i);
62 end do;
63 do i = 0 to n-1;
64 deciara(deci_lsd-i) = 1r0;
65 end do;
66 end if;
67 deci_msd = msdwant;
68 end if;
69 deci_nsd = 0; $ reset.
70
71 if deci_lzero then $ if want at least deci_lzero digits.
72 msdwant = deci_lsd + 1 - deci_lzero;
73 if msdwant < deci_msd then $ add leading zeros.
74 do i = msdwant to deci_msd-1;
75 deciara(i) = 1r0;
76 end do;
77 deci_msd = msdwant;
78 end if;
79 deci_lzero = 0;
80 end if;
81
82 end subr deci;
1 .=member pdec
2 subr pdec; $ copy deciara contents to gcb.
3 access ions;
4 size i(ps); $ loop index.
5 size c(cs); $ character for sign (if needed).
6
7 if deci_sign then $ if need sign character.
8 c = 1r+; if (deci_sign=1) c = 1r-;
9 putg(c);
10 deci_sign = 0; $ clear sign request.
11 end if;
12
13 do i = deci_msd to deci_lsd;
14 putg(deciara(i));
15 if i = deci_unit then putg(1r.); end if;
16 end do;
17 end subr pdec;
1 .=member ofma
2 subr_putfmt(ofma); $ -a- output format.
3 $ output character string.
4 size mode(ps); $ conversion type.
5 size sl(ps), so(ps); $ string length and origin.
6 size efw(ps); $ effective field width.
7 size c(cs); $ character in string
8 size fw(ps); $ field width.
9 size lm(1); $ on if list mode.
10
11 $ determine mode: 0=edit 1=list 2=list print.
12 lm = iop_lm iop; $ retrieve list mode.
13 fw = iop_fw iop; $ retrieve field width.
14 mode = (lm ) * (1 + (accessv(filenow) = access_print));
15 $ determine effective field width.
16 sl = .len. datum; so = sorg datum;
17 if (fw > gcblim) fw = gcblim;
18 if (fw = 0) fw = sl;
19 efw = sl; if (efw > fw) efw = fw;
20 .+ofsa_env. $ avoid use of gcb if no streaming occurs.
21 size lbp(ps); $ line buffer position.
22 size lsv(ps); $ linesize value.
23 size gw(ps); $ group width.
24
25 if mode=0 then $ can only zip through in edit mode.
26 lbp = lbptr(filenow); lsv = linesizev(filenow);
27 gw = iop_gw iop;
28 if accessv(filenow)^=access_string
29 & (lbp+fw <= lsv+1) & (gw=0) then
30 call 7nofsa$li(iolba, iolborg(filenow), lbp,
31 datum, efw, fw-efw);
32 lbptr(filenow) = lbp + fw;
33 return;
34 end if;
35 end if;
36 ..ofsa_env
37 $ verify sds structure.
38 gcbptr = 0;
39 if (mode = 1) then putg(1r'); end if;
40 do i = 1 to efw;
41 c = .f. so - i*cs, cs, datum;
42 if c = 1r' then $ if quote, see if should double.
43 if (mode = 1) then putg(1r'); end if;
44 end if;
45 putg(c);
46 end do;
47
48 if (mode = 1) then putg(1r'); end if;
49 call pfin(iop, 1);
50 end subr ofma;
1 .=member ofmb
2 subr_putfmt(ofmb); $ -b- output format.
3 size c(cs); $ character.
4 size efw(ps); $ effective field width.
5 size bw(ps); $ byte width.
6 size sz(ps); $ datum size.
7 size msb(ps); $ most significant bit to convert.
8 size j(ps); $ loop index.
9 size bv(4); $ byte from datum.
10 size lm(1); $ on if list mode.
11 size fw(ps); $ field width.
12 $ verify bw.
13 lm = iop_lm iop; $ retrieve list mode.
14 fw = iop_fw iop; $ retrieve field width.
15 bw = iop_dw iop;
16 if lm & (fw>0) then $ if list mode, fw is actually bw.
17 bw = fw;
18 fw = 0;
19 end if;
20 if (bw<1 ! bw>4) bw = mradix; $ for valid bw if not in range.
21 gcbptr = 0;
22 sz = iop_sz iop;
23 if lm then $ if list mode, put bfw and apostrophe.
24 putg(charofdig(bw)); putg(1rb); putg(1r');
25 end if;
26 if fw then $ if fw given, use fw to determine msd to convert.
27 msb = fw * bw;
28 else
29 msb = sz + 1;
30 end if;
31 if (msb > sz) msb = sz;
32
33 $ correct approximation to msb by examining data.
34 while (.f. msb, 1, datum) = 0;
35 if (msb=1) quit while;
36 msb = msb - 1;
37 end while;
38
39 do i = ((msb+bw-1)/bw -1)*bw to 0 by -bw;
40 $ can do full byte unless near end or would cross word boundary.
41 .+wsm3 if (i+bw <= sz) then
42 .-wsm3 if (i+bw<=sz) & ((i+bw-1)/ws = i/ws) then
43 bv = .f. i+1, bw, datum;
44 else $ if near end of datum, get bit by bit.
45 bv = 0; $ clear byte.
46 do j = 1 to bw;
47 .f. j, 1, bv = .f. i+j, 1, datum;
48 if ((i+j)=sz) quit do;
49 end do;
50 end if;
51 putg((.ch. bv+1, '0123456789abcdef'));
52 end do;
53
54 if (lm) then putg(1r'); end if;
55
56 call pfin(iop, 2);
57 end subr ofmb;
1 .=member ofme
2 .-fp. $ error exit if floating point not supported.
3 subr ofme(datum, ioparg); $ ofme fatal if fp not supported.
4 size datum(szmax), ioparg(iopsz);
5 call ltlfin(1, 1008); $ floating point not supported.
6 end subr ofme;
7 .+fp.
8 subr_putfmt(ofme); $ -e- output format.
9 size nsd(ps); $ number of significant digits.
10 size eint(ws); $ signed exponent value.
11 size fint(ws); $ signed fraction value.
12 size signed(1); $ on if negative value.
13 size fw(ps); $ field width.
14 size dw(ps); $ decimal (or byte) width.
15 size gw(ps); $ group width.
16 size lm(ps); $ list mode.
17
18 fw = iop_fw iop; $ retrieve field width.
19 dw = iop_dw iop; $ retrieve digit width.
20 gw = iop_gw iop; $ retrieve group width.
21 lm = iop_lm iop; $ get list mode.
22 if lm & (fw>1) then $ if list mode, fw is nsd.
23 dw = fw - 1;
24 fw = 0;
25 end if;
26 if (dw=0) dw = 5;
27 nsd = dw + 1;
28 gcbptr = 0;
29 call cref(datum, nsd, eint, fint);
30 signed = (fint<0);
31
32 if fint = 0 then $ if 0.0.
33 putg(1r0); putg(1r.);
34 else
35 deci_arg = fint; $ convert to decimal digits.
36 deci_nsd = nsd;
37 call deci;
38 deci_unit = deci_msd;
39 if gw then call ogrp(gw,3); end if;
40 deci_sign = signed; $ sign only if negative.
41 call pdec;
42 putg(1re);
43 deci_lzero = 2; $ at least two digits in exponent.
44 deci_arg = eint; call deci;
45 deci_sign = 2 - (eint<0); $ sign required for exponent.
46 call pdec;
47 end if;
48
49 call pfin(iop, 3);
50 end subr ofme;
51 ..fp
1 .=member ofmf
2 .-fp. $ error exit if floating point not supported.
3 subr ofmf(datum, ioparg); $ ofmf fatal if fp not supported.
4 size datum(szmax), ioparg(iopsz);
5 call ltlfin(1, 1008); $ floating point not supported.
6 end subr ofmf;
7 .+fp.
8 subr_putfmt(ofmf); $ -f- output conversion.
9 size n(ps); $ number of spaces to move.
10 size unitwant(ps); $ desired position of unit digit.
11 size e(ws); $ signed exponent.
12 size fint(ws); $ signed fraction value integer.
13 size nsd(ps); $ number of significant digits.
14 size signed(1); $ on if value negative.
15 size lm(1); $ on if list mode.
16 size fw(ps); $ field width.
17 size dw(ps); $ decimal (or byte) width.
18 size gw(ps); $ group width.
19
20 gcbptr = 0;
21 lm = iop_lm iop; $ get list mode.
22 if lm & (fw>0) then $ if list mode, fw is dw.
23 dw = fw;
24 fw = 0;
25 end if;
26 fw = iop_fw iop; $ retrieve field width.
27 dw = iop_dw iop; $ retrieve digit width.
28 gw = iop_gw iop; $ retrieve group width.
29 if (fw=0) fw = 8; $ 6 digits, sign and point.
30 if (fw<3) go to truncerr; $ at least one digit, sign and point.
31 nsd = 2;
32 call cref(datum, nsd, e, fint);
33 signed = (fint < 0);
34 if fint = 0 then $ 0.0 is special case.
35 e = 0; $ clear exponent, since result zero.
36 nsd = 1; go to zerocase;
37 end if;
38 if e >= 0 then $ if positive exponent, add leading dig count.
39 if (fw>0) & (e > (fw-dw-2)) then $ if overflow.
40 go to truncerr;
41 end if;
42 nsd = e + dw + 1;
43 else $ no leading digits, determine nsd.
44 e = 0 - e;
45 if (e > dw+1) then
46 e = 0; $ clear exponent, since result zero.
47 fint = 0; nsd = 1; go to zerocase; $ rounds to zero.
48 else nsd = (dw+1) - e; end if;
49 end if;
50 call cref(datum, nsd, e, fint);
51 /zerocase/
52 if (nsd = 0) nsd = 1;
53 deci_arg = fint; deci_nsd = nsd;
54 call deci;
55 deci_unit = deci_msd + e;
56
57 if deci_unit < deci_msd then $ if need leading zeros.
58 n = deci_msd - deci_unit;
59 do i = 1 to n; deciara(deci_msd-i) = 1r0; end do;
60 deci_msd = deci_msd - n;
61 end if;
62
63 unitwant = deci_lsd - dw; $ desired position of units digit.
64 if deci_unit > unitwant then $ move left, add trailing zeros.
65 n = deci_unit - unitwant;
66 do i = deci_msd to deci_lsd;
67 deciara(i-n) = deciara(i);
68 end do;
69 do i = 0 to n-1; deciara(deci_lsd-i) = 1r0; end do;
70 deci_msd = deci_msd - n;
71 elseif deci_unit < unitwant then $ move right, drop trailing di
72 n = unitwant - deci_unit;
73 do i = deci_lsd-n to deci_msd by -1;
74 deciara(i+n) = deciara(i);
75 end do;
76 deci_msd = deci_msd + n;
77 end if;
78
79 deci_unit = unitwant;
80
81 if gw then call ogrp(gw, 3); end if;
82 deci_sign = signed; $ give sign only if negative.
83 call pdec; $ add digits.
84
85 /ofmfdone/
86 call pfin(iop, 3);
87 return;
88
89 /truncerr/ $ here if truncation
90 gcbptr = fw + 1;
91 go to ofmfdone;
92 end subr ofmf;
93 ..fp
1 .=member ofmi
2 subr_putfmt(ofmi); $ -i- output format.
3 size v(ws); $ conversion value.
4 size signed(1); $ on if value negative.
5 size nsd(ps); $ number of significant digits in value.
6 size lm(1); $ on if list mode.
7 size fw(ps); $ field width.
8 size dw(ps); $ decimal (or byte) width.
9 size gw(ps); $ group width.
10 gcbptr = 0;
11 lm = iop_lm iop; $ get list mode.
12 fw = iop_fw iop; $ get field width.
13 dw = iop_dw iop; $ get digit width.
dst 75 gw = iop_gw iop;
15 v = .f. 1, ws, datum; $ is single word integer.
16 deci_arg = v;
17 deci_lzero = dw; $ if want leading zeros.
18 call deci; $ convert integer.
19 signed = (v<0);
20 nsd = deci_lsd - deci_msd + 1;
21
22 if gw then $ if groups desired.
23 deci_unit = deci_lsd;
24 call ogrp(gw, 3);
25 deci_unit = 0;
26 end if;
27
28 deci_sign = signed; $ sign only if negative.
29 call pdec;
30
31 call pfin(iop, 3);
32 return;
33 end subr ofmi;
1 .=member ofmr
2 subr_putfmt(ofmr); $ -r- output format.
3 size gi(ps); $ position in gcb
4 size di(ps); $ position in datum
5 size tw(ps); $ transmission width
6 size efw(ps); $ effective field width.
7 size sz(ps); $ datum size.
8 size lm(1); $ on if list mode.
9 size fw(ps); $ field width.
10 size dw(ps); $ decimal (or byte) width.
11
12
13 gcbptr = 0;
14 lm = iop_lm iop; $ get list mode.
15 fw = iop_fw iop; $ get field width.
16 sz = iop_sz iop;
17 dw = sz / cs;
18 efw = fw;
19 if (efw > dw) efw = dw;
20 if (efw = 0) efw = 1;
21 if lm then $ if list mode, generate prefix.
22 deci_arg = efw; $ convert to decimal.
23 call deci;
24 call pdec;
25 putg(1rr);
26 end if;
27 $ write member characters.
28 do i = (efw-1)*cs+1 to 1 by -cs;
29 putg((.f. i, cs, datum));
30 end do;
31
32 call pfin(iop, 1);
33 return;
34 end subr ofmr;
1 .=member onmv
2 subr onmv(datum); $ output variable name
3 /* output datum which is sds string generated by compiler
4 giving name of variable mentioned in -n- format. */
5 size datum(ws+1); $ sds naming variable
6 size sl(ws); $ length of name
7 size i(ps); $ do loop index for name copy to gcb
8 access ions;
9
10 if (donotbit(filenow)) return;
11 sl = slen datum;
12 gcbptr = 0;
13 putg(1r );
14 do i = 1 to sl;
15 putg((.ch. i, datum));
16 end do;
17 putg(1r=);
18 call pfin( 0, 0); $ put out gcb.
19 end subr onmv;
1 .=member onma
2 subr onma(datum, indexarg); $ print array name and inde
3 $ print name of array and value of index - 'datum(index) ='
4
5 size datum(szmax); $ contains name of array
6 size indexarg(ws); $ subscript value
7 size ret(ws); $ return value from -ostr-
8 size sl(ps); $ length of array name
9 size n(ps); $ do loop index
10 size i(ps); $ loop index.
11 access ions;
12
13 if (donotbit(filenow)) return;
14 gcbptr = 0;
15 putg(1r );
16 sl = slen datum;
17 do i = 1 to sl;
18 putg((.ch. i, datum));
19 end do;
20 putg(1r();
21 deci_arg = indexarg;
22 deci_lzero = 2;
23 call deci;
24 call pdec;
25
26 putg(1r)); putg(1r=);
27 call pfin(0, 0); $ put out gcb.
28 end subr onma;
1 .=member iget
2 subr iget(datum); $ get execu
3 access ions;
4 size datum(szmax); $ datum to convert.
5 size lm(1); $ list mode flag.
6 size fw(ps); $ field width.
7 size gw(ps); $ group width.
8 size sz(ps); $ datum size.
9 size dw(ps); $ decimal width.
10 size np(ps); $ position during group removal.
11 size i(ps); $ loop index.
12 size inthis(ps); $ number characters in current group.
13 size j(ps); $ loop index.
14 size dmax(ps); $ maximum acceptable digit for given bw.
15 size c(cs); $ current character.
16 size d(ws); $ value if character is digit.
17 size expgiven(ps); $ index of -e- in numeric constant.
18 size esign(ps); $ exponent sign (0=none, 1=+, 2=-).
19 size fsign(ps); $ fraction sign (0=none, 1=+, 2=-).
20 size fdigits(ps); $ position of decimal point.
21 access ions;
22 size eval(ws); $ absolute value of exponent.
dsi 81 .+mc size ctpc(cs); $ function to get primary case.
23
24 gcbptr = 0;
25 if (donotbit(filenow)) return;
26 ilst_rc = 0;
27 lm = iop_lm get_iop; $ get list mode.
28 fw = iop_fw get_iop; $ get field width.
29 gw = iop_gw get_iop; $ get group width.
30 sz = iop_sz get_iop; $ get datum size.
31 dw = iop_dw get_iop; $ get decimal width.
32 istr_file = filenow;
33
34 get_mode = lm; $ set input mode.
35 $ preset datum to zero.
36 do i = 1 to sz by ws;
37 .f. i, ws, datum = 0;
38 end do;
39 if lm then $ if list mode, call ilst to find field.
40 get_fw = 1;
41 call ilst;
42 if (ilst_rc) go to vererr;
43 else $ if edit mode, call istr to read in field.
44 get_fw = fw;
45 if (get_fc = get_fcb) get_bw = dw;
46 if (fw=0) go to vererr;
47 gcbptr = fw;
48 call istr;
49 end if;
50 if (istr_rc) go to istr_fail;
51 if gcbptr = gcblim then $ if truncation error
52 go to vererr;
53 end if;
54
55 if lm = 0 then $ if edit mode, process groups.
56 if gw then $ if groups, extract if -a- or -r- format.
57 if get_fc = get_fca ! get_fc = get_fcr then $ only a,r
58 inthis = 0;
59 np = 0;
60 do i = 1 to gcbptr;
61 inthis = inthis + 1;
62 if inthis <= gw then $ if datum.
63 np = np + 1;
64 gcb(np) = gcb(i);
65 else $ if end of group, skip char.
66 inthis = 0;
67 end if;
68 end do;
69 end if get_fc;
70 gcbptr = np;
71 end if gw;
72 end if;
73 $ verification required for b, e, f, i formats.
74 if get_fc = get_fcb then $ if b format,verify.
75 if (get_bw<1 ! get_bw>4) go to vererr;
76 dmax = .f. 1, get_bw, 15; $ maximum allowed digit.
77 np = 0;
78 do i = 1 to gcbptr;
79 c = gcb(i); $ get current character.
dsi 82 .+mc c = ctpc(c); $ convert to primary case.
80 if (c = 1r ) cont do; $ skip blanks.
81 d = digofchar(c); $ convert assuming decimal digit.
82 if get_bw < 4 then $ if constant takes only digits.
83 if (d<0 ! d > dmax) go to vererr;
84 else
85 if d<0 ! d>9 then $ see if hex char.
86 do j = 1 to 6;
87 if .ch. j, 'abcdef' = c then
88 quit do;
89 else
90 if (j=6) go to vererr;
91 end if;
92 end do;
93 d = j + 9;
94 end if;
95 end if;
96 np = np + 1;
97 gcb(np) = d;
98 end do;
99 gcbptr = np;
100 elseif get_fc = get_fce ! get_fc = get_fcf ! get_fc = get_fci
101 then call vnum(gcb, gcbptr, get_expval);
102 if (gcb(gcbptr+2)) go to vererr;
103 $ verify that if integer wanted, not floating point.
104 if get_fc = get_fci then $ if integer.
105 if (gcb(gcbptr+4) ! gcb(gcbptr+3)) go to vererr;
106 end if;
107 end if get_fc;
108 return;
109 /vererr/
110 gcbptr = 0; $ clear gcb, so no conversion done.
111 ioerror(filenow, 1, 1);
112 return;
113 /istr_fail/
114 donotbit(filenow) = 1;
115 return;
116 end subr iget;
1 .=member istr
2 subr istr; $ input with streaming.
3 access ions;
4 size i(ps); $ loop index.
5 access ions;
6 size strfile(1); $ 1 string file, zero if external file
7 size lbp(ps); $ working copy of lbptr(istr_file).
8 size lsv(ps); $ working copy of linesizev(istr_file).
9 size what(ps); $ return parameter from -getc-
10 size memget(ps); $ library function
11 size pfc(cs); $ place for character
12 size saddr(ps); $ string address if string file.
13 size sarc(ps); $ pcsa return code.
14 $ initialization and buffer flushing
15 istr_rc = 0;
16 lsv = linesizev(istr_file);
17 lbp = lbptr(istr_file);
18
19 strfile = (accessv(istr_file) = access_string);
20 if strfile then
21 saddr = strorgv(istr_file);
22 else
23 $ if prior end just seen, user must acknowledge it.
24 if endack(istr_file) then $ if outstanding request.
25 ioerror(istr_file, 2, 9); $ unacknowledged end.
26 end if;
27 end if;
28
29
30 if get_fw > gcblim then $ if field too large.
31 ioerror(istr_file, 2, 10); $ fw too large.
32 get_fw = gcblim; $ take acceptable value.
33 end if;
34
35 do i = 1 to get_fw;
36
37 if strfile then
38 if lbp <= slen(memget(saddr)) then
39 call pcsa(sarc, 0, saddr, lbp, pfc); $ get character.
40 if sarc then
41 ioerror(istr_file, 2, (10+sarc)); $ bad string.
42 end if;
43 lbp = 1 + lbp;
44 else
45 lbp = 1;
46 what = 1;
47 go to error;
48 end if lbp; $ end string case
49 else
50 if lbp > lsv then
51 sfbit(istr_file) = 1; $ a new line is needed
52 endseenv(istr_file) = no;
53 call getwsio(istr_file, what, iolba,iolborg(istr_file),
54 lsv);
55 linenum(istr_file) = linenum(istr_file)+1;
56 if (what) go to error;
57 lbp = 1;
58 end if;
59 pfc = iolb(lbp, istr_file);
60 lbp = 1 + lbp;
61 end if; $ character has been obtained
62
63 if get_mode then $ if list mode, return single char.
64 lbptr(istr_file) = lbp;
65 get_char = pfc;
66 return;
67 end if;
68
69
70 gcb(i) = pfc; $ put the character in pfc into
71
72 end do i;
73
74 /istrret/
75 lbptr(istr_file) = lbp;
76 return;
77 /error/
78 if what = 1 then $ if end seen.
79 endseenv(istr_file) = yes;
80 $ require user acknowledge end seen unless string file.
81 if strfile = no then
82 endack(istr_file) = yes;
83 donotbit(istr_file) = yes;
84 end if;
85 elseif what > 1 then $ if transmission error.
dsb 61 ioerror(istr_file, 2, 13);
87 end if;
88 go to istrret;
89 end subr istr;
1 .=member ilst
2 subr ilst; $ get -l- field.
3 access ions;
4 $ this procedure implements the 'free form' list mode input
5 $ as an interpreter for a special machine. the interpretive
6 $ method is used to reduce code size. the operations of the
7 $ machine are as follows:
8
9 $ act - perform action p.
10 $ add - add character, jmp to p.
11 $ cmp - compare current character with creg(p), skip on match.
12 $ dec - decrement numeric register, skip if result not zero.
13 $ err - abnormal termination.
14 $ fin - normal termination.
15 $ get - get next character.
16 $ int - collect integer, store value in numeric register.
17 $ jmp - jump to location p.
18 $ stc - store current character in character register p.
19 $ tnr - test numeric register, skip if not zero.
20 $ gnl - get next line (for skip during comments).
21
22 $ array lst is the machine memory. array creg contains
23 $ character code constants. the first entry in creg is used to
24 $ save the delimiting character of q and r constants. the
25 $ numeric register nreg contains the length prefix value for
26 $ b, q and r constants.
27
28 size creg(cs); dims creg(10); $ character registers.
29 data creg = 1r , 1r , 1r,, 1rr, 1r', 1rq, 1rb, 1r$, 1r/, 1r*;
30 size nreg(ws); $ numeric register.
31 size d(ws); $ value of decimal character.
32 size i(ps); $ loop index.
33 size holdchar(1); $ on to retain current character.
34 size lsp(ps); $ position in scan table.
35
36 size p(ps); $ parmeter value of ls op.
37 size cnow(cs); $ current character.
38 size ret(ws); $ return code.
39 size lst(16); dims lst(91); $ scan machine memory.
dsi 83 .+mc size ctpc(cs); $ function to get primary case.
40
41 $ the little macroprocessor is used to assemble the program.
42 $ the assembly is necessarily one-pass, so that labels used
43 $ in the program must be defined before use, as follows.
44 $ macros resolve labels in scan table.
45 +* l01 = 01 **
46 +* l02 = 05 **
47 +* l03 = 08 **
48 +* l04 = 15 **
49 +* l05 = 17 **
50 +* l06 = 24 **
51 +* l07 = 29 **
52 +* l08 = 37 **
53 +* l09 = 41 **
54 +* l10 = 45 **
55 +* l11 = 48 **
56 +* l12 = 52 **
57 +* l13 = 54 **
58 +* l14 = 56 **
59 +* l15 = 59 **
60 +* l16 = 61 **
61 +* l17 = 65 **
62 +* l18 = 66 **
63 +* l19 = 69 **
64 +* l20 = 72 **
65 +* l21 = 76 **
66 +* l22 = 81 **
67 +* l23 = 84 **
68 +* l24 = 88 **
69
70 $ macros for lscan opcodes.
71 +* ls_act = 01 ** +* ls_add = 02 **
72 +* ls_cmp = 03 ** +* ls_dec = 04 **
73 +* ls_err = 05 ** +* ls_fin = 06 **
74 +* ls_get = 07 ** +* ls_int = 08 **
75 +* ls_jmp = 09 ** +* ls_stc = 10 **
76 +* ls_tnr = 11 ** +* ls_gnl = 12 **
77
78 +* lsop(o,p) = o*256 + p , **
79 data lst = $ data for scan table.
80
81 $ begin by skip over sequence of blanks and commas.
82 lsop(ls_get, 0) $ l01 get
83 lsop(ls_cmp, 2) $ cmp 2 compare with blank
84 lsop(ls_jmp, l02) $ jmp l02 if not blank.
85 lsop(ls_jmp, l01) $ jmp l01 if blank.
86 lsop(ls_cmp, 3) $ l02 cmp 3 comma
87 lsop(ls_jmp, l20) $ jmp l20 if not comma.
88 lsop(ls_jmp, l01) $ jmp l01 if comma.
89
90 $ here to branch according to format type.
91 lsop(ls_act, 1) $ l03 act 1 branch on format type.
92 lsop(ls_jmp, l04) $ jmp l04 -a- format.
93 lsop(ls_jmp, l07) $ jmp l07 -b- format.
94 lsop(ls_add, l09) $ add l09 -e- format (numeric).
95 lsop(ls_add, l09) $ add l09 -f- format (numeric).
96 lsop(ls_add, l09) $ add l09 -i- format (numeric).
97 lsop(ls_jmp, l11) $ jmp l11 -r- format.
98
99 $ here for -a- format, see if quoted string or -q- constant.
100 lsop(ls_cmp, 5) $ l04 cmp 5 compare with quote.
101 lsop(ls_jmp, l06) $ jmp l06 if not quote.
102
103 $ here if quoted string, get text, watching for double apostrophe
104 lsop(ls_get, 0) $ l05 get
105 lsop(ls_cmp, 5) $ cmp 5 compare with quote.
106 lsop(ls_add, l05) $ add l05 if not quote, add.
107 lsop(ls_get, 0) $ get
108 lsop(ls_cmp, 5) $ cmp 5 compare with quote.
109 lsop(ls_jmp, l18) $ jmp l18 if not quote, done.
110 lsop(ls_add, l05) $ add l05 if (double) quote, add
111
112 $ here if -q- constant.
113 lsop(ls_int, 0) $ l06 int
114 lsop(ls_get, 0) $ get
115 lsop(ls_cmp, 6) $ cmp 6 compare with letter -q-
116 lsop(ls_err, 0) $ err if not -q-.
117 lsop(ls_jmp, l12) $ jmp l12 get delimited text.
118
119 $ here for -b- constant, get width, verify in range.
120 lsop(ls_int, 0) $ l07 int get byte width.
121 lsop(ls_act, 2) $ act 2 verify byte width.
122 lsop(ls_get, 0) $ get
123 lsop(ls_cmp, 7) $ cmp 7 compare with letter -b-
124 lsop(ls_err, 0) $ err if not -b-.
125 lsop(ls_get, 0) $ get
126 lsop(ls_cmp, 5) $ cmp 5 compare with quote.
127 lsop(ls_err, 0) $ err if not quote.
128 lsop(ls_get, 0) $ l08 get get until quote termina
129 lsop(ls_cmp, 5) $ cmp 5 compare with quote.
130 lsop(ls_add, l08) $ add l08 if not quote.
131 lsop(ls_jmp, l17) $ jmp l17 done if quote.
132
133 $ here for numeric, skip to blank or comma.
134 lsop(ls_get, 0) $ l09 get collect until blank or
135 lsop(ls_cmp, 2) $ cmp 2 compare with blank.
136 lsop(ls_jmp, l10) $ jmp l10 if not blank.
137 lsop(ls_fin, 0) $ fin if blank.
138 lsop(ls_cmp, 3) $ l10 cmp 3 comma.
139 lsop(ls_add, l09) $ add l09 if not comma.
140 lsop(ls_fin, 0) $ fin if comma.
141
142 $ here for -r- constant, get count, check for -r-.
143 lsop(ls_int, 0) $ l11 int
144 lsop(ls_get, 0) $ get
145 lsop(ls_cmp, 4) $ cmp 4 compare with letter -r-
146 lsop(ls_err, 0) $ err if not -r-.
147
148 $ here for body of -q- or -r- constant.
149 lsop(ls_tnr, 1) $ l12 tnr 1 see if count zero.
150 lsop(ls_jmp, l15) $ jmp l15 if count zero.
151
152 $ here if explicit count.
153 lsop(ls_get, 0) $ l13 get
154 lsop(ls_add, l14) $ add l14 add character.
155 lsop(ls_dec, 1) $ l14 dec 1 decrement count.
156 lsop(ls_jmp, l17) $ jmp l17 if count zero.
157 lsop(ls_jmp, l13) $ jmp l13 if chars remain.
158
159 $ here to get delimited text.
160 lsop(ls_get, 0) $ l15 get get delimiter.
161 lsop(ls_stc, 1) $ stc 1 save delimiter.
162 lsop(ls_get, 0) $ l16 get
163 lsop(ls_cmp, 1) $ cmp 1 compare with if delimit
164 lsop(ls_add, l16) $ add l16 if not delimiter.
165 lsop(ls_jmp, l17) $ jmp l17 if delimiter, done.
166
167 $ here to verify comma or blank follows constant.
168 lsop(ls_get, 0) $ l17 get
169 lsop(ls_cmp, 2) $ l18 cmp 2 compare with blank.
170 lsop(ls_jmp, l19) $ jmp l19 if not blank.
171 lsop(ls_fin, 0) $ fin
172 lsop(ls_cmp, 3) $ l19 cmp 3 compare with comma.
173 lsop(ls_err, 0) $ err
174 lsop(ls_fin, 0) $ fin if comma.
175
176 $ here to seek comment at start.
177 lsop(ls_cmp, 8) $ l20 cmp 8 compare with dollar.
178 lsop(ls_jmp, l21) $ jmp l21 if not dollar.
179 lsop(ls_gnl, 0) $ gnl get next line.
180 lsop(ls_jmp, l01) $ jmp l01 continue initial scan.
181 lsop(ls_cmp, 9) $ l21 cmp 9 compare with slash.
182 lsop(ls_jmp, l03) $ jmp l03 if not slash.
183 lsop(ls_get, 0) $ get get next character.
184 lsop(ls_cmp, 10) $ cmp 10 compare with star.
185 lsop(ls_err, 0) $ err if not * after /.
186 lsop(ls_get, 0) $ l22 get seek */ ending.
187 lsop(ls_cmp, 10) $ cmp 10 compare with star.
188 lsop(ls_jmp, l22) $ jmp l22 if not star.
189 lsop(ls_get, 0) $ l23 get seen *, seek /.
190 lsop(ls_cmp, 10) $ cmp 10 compare with star.
191 lsop(ls_jmp, l24) $ jmp l24 if not star.
192 lsop(ls_jmp, l23) $ jmp l23 seen *, seek /.
193 lsop(ls_cmp, 09) $ l24 cmp 9 compare with slash.
194 lsop(ls_jmp, l22) $ jmp l22 if not slash.
195 lsop(ls_jmp, l01) $ jmp l01 continue scan.
196 0;
197 macdrop(lsop)
198 macdrop(l01) macdrop(l02) macdrop(l03)
199 macdrop(l04) macdrop(l05) macdrop(l06)
200 macdrop(l07) macdrop(l08) macdrop(l09)
201 macdrop(l10) macdrop(l11) macdrop(l12)
202 macdrop(l13) macdrop(l14) macdrop(l15)
203 macdrop(l16) macdrop(l17) macdrop(l18)
204 macdrop(l19) macdrop(l20) macdrop(l21)
205 macdrop(l22) macdrop(l23) macdrop(l24)
206
207 holdchar = no; $ holdchar set by -int- action to retain char.
208 get_mode = yes; $ indicate that getting in l mode.
209 nreg = 0;
210 lsp = 1; $ start at first entry in scan table.
211 ilst_rc = 0; $ clear return code.
212
213 /next/
214 p = .f. 01, 08, lst(lsp); $ get parameter value.
215 go to l(.f. 09, 08, lst(lsp)) in 1 to 12; $ branch on opcode.
216
217 /l(ls_act)/ $ perform action -p-.
218 if p = 1 then $ jump according to format type.
219 lsp = lsp + get_fc; go to next;
220 elseif p = 2 then $ verify byte width.
221 get_bw = nreg;
222 if ((nreg<1) ! (nreg>4)) go to l(ls_err);
223 lsp = lsp + 1; go to next;
224 end if;
225
226 /l(ls_add)/ $ add cnow to gcb.
227 putg(cnow);
228 lsp = p; go to next;
229
230 /l(ls_cmp)/ $ compare cnow with creg(p), skip if match.
dsi 84 .+mc cnow = ctpc(cnow); $ convert to primary case.
231 lsp = lsp + 1 + (cnow = creg(p)); go to next;
232
233 /l(ls_dec)/ $ decrement nreg, skip if new value not zero.
234 if (nreg) nreg = nreg - 1;
235 lsp = lsp + 1 + (nreg ^= 0); go to next;
236
237 /l(ls_err)/ $ error, force abnormal termination.
238 ilst_rc = 1;
239 return;
240
241 /l(ls_fin)/ $ normal termination.
242 return;
243
244 /l(ls_get)/ $ get next character, end file gives error.
245 if holdchar then $ if holding char, return it.
246 holdchar = no;
247 else
248 call istr;
249 if (istr_rc) return;
250 cnow = get_char;
251 end if;
252 lsp = lsp + 1; go to next;
253
254 /l(ls_jmp)/ $ jump to position -p-.
255 lsp = p; go to next;
256
257 /l(ls_stc)/ $ store cnow in creg(p).
258 creg(p) = cnow;
259 lsp = lsp + 1; go to next;
260
261 /l(ls_tnr)/ $ test numeric register, skip if not zero.
262 lsp = lsp + 1 + (nreg ^= 0); go to next;
263
264 /l(ls_int)/ $ collect integer, error if not present.
265 nreg = 0;
266 d = digofchar(cnow);
267 if ((d < 0) ! (d > 9)) go to l(ls_err);
268 while 1;
269 nreg = nreg*10 + d;
270 istr_file = filenow; call istr;
271 if (istr_rc) return;
272 cnow = get_char;
273 d = digofchar(cnow);
274 if ((d < 0) ! (d > 9)) quit while;
275 end while;
276 holdchar = yes;
277 lsp = lsp + 1; go to next;
278
279 /l(ls_gnl)/ $ get new line (after $ comment header seen).
280 lbptr(istr_file) = linesizev(istr_file) + 1;
281 holdchar = no;
282 go to l(ls_get);
283
284 macdrop(ls_act) macdrop(ls_add) macdrop(ls_cmp)
285 macdrop(ls_dec) macdrop(ls_err) macdrop(ls_fin)
286 macdrop(ls_get) macdrop(ls_int) macdrop(ls_jmp)
287 macdrop(ls_stc) macdrop(ls_tnr) macdrop(ls_gnl)
288 end subr ilst;
1 .=member ifma
2 subr ifma(datum, ioparg); $ -a- input format.
3 size datum(szmax); $ datum.
4 size ioparg(iopsz); $ io parameter string.
5 size i(ps); $ loop index.
6 size n(ps); $ string capacity of datum.
7 size sz(ps); $ datum size.
8
9 access ions;
10
11 get_iop = ioparg;
12 get_fc = 1;
13 sz = iop_sz ioparg;
14
15 .+ifsa_env. $ bypass use of gcb if no streaming, edit mode.
16 if (donotbit(filenow)) return;
17 size lm(ps); $ on if list mode.
18 size gw(ps); $ group width.
19 size fw(ps); $ field width.
20 size efw(ps); $ effective field width.
21 size lbp(ps); $ line buffer pointer.
22 size lpb(ps); $ line position.
23 size lsv(ps); $ linesize value.
24
25 $ cannot special case string file, as data not in line buffer.
26 if (accessv(filenow) = access_string) go to notspecial;
27
28 lm = iop_lm get_iop; if (lm) go to notspecial;
29 gw = iop_gw get_iop; if (gw) go to notspecial;
30 fw = iop_fw get_iop;
31 if ((fw=0) ! ((.sds. fw) > sz)) go to notspecial;
32 lsv = linesizev(filenow);
33 lbp = lbptr(filenow);
34 if lbp+fw <= lsv+1 then
35 call 7nifsa$li(iolba, iolborg(filenow), lbp, datum, fw);
36 lbptr(filenow) = lbp + fw;
37 return;
38 end if;
39 /notspecial/
40 ..ifsa_env
41
42 sz = iop_sz get_iop;
43 call iget(datum);
44
45 if sz <= (.sl.+.so.) then $ if no room for str, get null.
46 n = 0;
47 else
48 n = (sz - (.sl.+.so.)) / cs;
49 end if;
50 if (n > gcbptr) n = gcbptr;
51 slen datum = n;
52 sorg datum = (.sds. n) + 1;
53 do i = 1 to n;
54 .ch. i, datum = gcb(i);
55 end do;
56 end subr ifma;
1 .=member ifmb
2 subr_getfmt(ifmb, 2); $ -b- output format.
3 size c(cs); $ character.
4 size efw(ps); $ effective field width.
5 size bw(ps); $ byte width.
6 size msb(ps); $ most significant bit to convert.
7 size j(ps); $ loop index.
8 size bv(4); $ byte from datum.
9 bw = get_bw;
10 msb = gcbptr * bw;
11 if (msb > sz) msb = sz;
12
13 do i = 1 to msb by bw;
14 bv = gcb(gcbptr - i/bw);
15 $ can do full byte unless near end or would cross word boundary.
16 .+wsm3 if (i+bw-1) <= sz then
17 .-wsm3 if ((i+bw-1)<=sz) & ((i+bw-2)/ws = (i-1)/ws) then
18 .f. i, bw, datum = bv;
19 else $ if near end of datum, get bit by bit.
20 do j = 0 to bw-1;
21 .f. i+j, 1, datum = .f. j+1, 1, bv ;
22 if ((i+j)=sz) quit do i;
23 end do;
24 end if;
25 end do;
26
27 end subr ifmb;
1 .=member ifme
2 .-fp.
3 subr ifme(datum, ioparg); $ ifme fatal if fp not supported.
4 size datum(szmax), ioparg(iopsz);
5 call ltlfin(1, 1008); $ floating point not supported.
6 end subr ifme;
7 .+fp.
8 subr_getfmt(ifme, 3); $ -e- and -f- input formats.
9 $ get floating point constant. iget verifies correct structure.
10 size dw(ps); $ decimal width.
11 real rv; $ real value.
12
13 dw = iop_dw ioparg; $ get decimal width.
14 $ if field given and no point or exponent in field, adjust expone
15 if gcb(gcbptr+3) > 0 then $ if point given, scale value if need
16 get_expval = get_expval - (gcb(gcbptr+3) -1);
17 elseif ((dw > 0) & (gcb(gcbptr+4)=0)) then $ if no point, and
18 get_expval = get_expval - dw;
19 end if;
20 call cefr(rv, gcb, gcbptr, get_expval);
dsx 29 if gcb(gcbptr+2) then $ if overflow or conversion error.
dsx 30 ioerror(filenow, 1, 1);
dsx 31 return;
dsx 32 end if;
21 .f. 1, ws, datum = rv;
22 end subr ifme;
23 ..fp
1 .=member ifmi
2 subr_getfmt(ifmi, 5); $ -i- input format.
3 size v(ws); $ value to convert.
4 size fnz(ps); $ index of first nonzero character.
5
6 $ use negative arithmetic to convert in case have two's
7 $ complement arithmetic.
8 v = 0;
9 do i = 1 to gcbptr; $ seek nonzero character.
10 if gcb(i) then $ if nonzero character.
11 fnz = i; go to haveval; end if;
12 end do;
13 go to retval; $ go to return zero value.
14 /haveval/
15 v = - gcb(fnz);
16 do i = fnz+1 to gcbptr; $ convert remaining digits.
17 if (v < maxnegint/10) go to oflow;
18 v = 10 * v;
19 if (((v-maxnegint)-gcb(i)) < 0) go to oflow;
20 v = v - gcb(i);
21 end do;
22 if (gcb(gcbptr+1) = 0) v = 0 - v; $ if positive result.
23 /retval/
24 .f. 1, ws, datum = v;
25 return;
26 /oflow/ $ if overflow during conversion.
27 ioerror(filenow, 1, 1); $ conversion error.
28 return;
29 end subr ifmi;
1 .=member ifmr
2 subr_getfmt(ifmr, 6); $ input -r- format
3 size n(ps); $ number of characters to convert.
4
5 n = sz / cs;
6 if (gcbptr < n) n = gcbptr;
7
8 do i = n-1 to 0 by -1;
9 .f. i*cs +1, cs, datum = gcb(gcbptr-i);
10 end do;
11 end subr ifmr;
1 .=member vnum
2 subr vnum(ara, araptr, expval);
3 $ verify structure of numeric constant.
4 $ on entry:
5 $ ara(1) to ara(araptr) contains character codes.
6 $ on exit:
7 $ ara(1) to ara(araptr) contain integers in range 0 to 9.
8 $ ara(araptr+1) is zero if value positive, one if negative.
9 $ ara(araptr+2) is zero if verification ok.
10 $ ara(araptr+2) is one if ara does not contain valid
11 $ constant.
12 $ ara(araptr+3) indicates presence of decimal point.
13 $ if ara(araptr+3) is zero, constant does not contain poin
14 $ otherwise, ara(araptr+3) is one more than the number of
15 $ digits which follow the decimal point.
16 $ of digits following the point.
17 $ ara(araptr+4) is zero if no exponent field, one if
18 $ exponent field.
19 $ if ara(araptr+4) is one, expval is a signed integer giving
20 $ the exponent value.
21
22 size ara(cs); dims ara(2); $ character list.
23 size araptr(ps); $ position in ara.
24 size np(ps); $ new value for araptr.
25 size expval(ws); $ exponent value.
26 size i(ps); $ loop index.
27 size c(cs); $ character code.
28 size d(ws); $ converted code.
29 size epos(ps); $ index of -e- in numeric constant.
30 size esign(ps); $ exponent sign (0=none, 1=+, 2=-).
31 size fsign(ps); $ fraction sign (0=none, 1=+, 2=-).
32 size pointpos(ps); $ position of decimal point.
dsi 85 .+mc size ctpc(cs); $ function to get primary case.
33 np =0;
34 epos = 0; esign = 0; fsign = 0; expval = 0;
35 pointpos = 0;
36 do i = 1 to araptr;
37 c = ara(i);
38 if (c = 1r ) cont do;
39 d = digofchar(c);
40 if d >= 0 & d <= 9 then $ if digit.
41 if epos then $ if in exponent, convert.
42 expval = expval*10 + d;
43 epos = epos + 1;
44 else $ if part of fraction, add to ara.
45 np = np + 1;
46 ara(np) = d;
47 end if;
48 elseif c = 1r. then
49 if (epos) go to vererr;
50 pointpos = np + 1;
dsi 86 .-mc elseif c = 1re then
dsi 87 .+mc elseif ctpc(c) = 1re then
52 if (epos) go to vererr; $ if duplicate -e-.
53 epos = 1;
54 elseif c = 1r+ ! c = 1r- then $ if sign.
55 if fsign=0 & np=0 then $ if first sign.
56 fsign = 1 + (c = 1r-);
57 elseif esign = 0 then $ if second sign.
58 if epos = 0 then $ if e not seen, pretend it wa
59 epos = 1;
60 esign = 1 + (c = 1r-);
61 else $ second sign, check that e came just before
62 if (epos>1) go to vererr;
63 esign = 1 + (c = 1r-);
64 end if;
66 end if fsign;
dsc 81 else go to vererr;
67 end if d;
68 end do i;
69 araptr = np;
70 if (np=0) go to vererr; $ if no digits in constant.
71 if pointpos
72 then ara(araptr+3) = np + 2 - pointpos;
73 else ara(araptr+3) = 0; end if;
74 ara(araptr+4)= (epos ^= 0);
75 if (esign=2) expval = 0 - expval;
76 ara(araptr+1) = (fsign = 2); $ restore sign code.
77 ara(araptr+2) = 0; $ indicate wellformed constant.
78 return;
79 /vererr/ $ illformed constant.
80 ara(araptr+2) = 1; $ indicate illformed constant.
81 end subr vnum;
1 .=member uinp
2 subr uinp(ara, nwords); $ unformatted input.
3 access ions;
4 size ara(ws); dims ara(2);
5 size nwords(ws); $ words to transmit
6 size ret(ws); $ return value from -rdrb- primitive -
7 $ e-o-f hit, -3 is e-o-i hit.
8 if (donotbit(filenow)) return; $ previous error, so do nothing.
9
10 if nwords < 0 then $ if bad slice spec.
11 ioerror(filenow, 2, 19);
12 elseif nwords = 0 then $ if null slice.
13 return;
14 end if;
15
16 $ if user has not acknowledged end encountered, give error.
17 if endack(filenow) then $ if outstanding request.
18 ioerror(filenow, 2, 9);
19 end if;
20
21 call rdrwsio(filenow, ret, ara, 1, nwords);
22
23 endseenv(filenow) = 0;
24 if (ret = 0) return; $ normal return
25 donotbit(filenow) = 1;
26
27 if ret > 1 then
dsb 62 ioerror(filenow, 2, 7); $ unformatted input transmission failu
29 elseif ret = 1 then $ end of file.
30 endseenv(filenow) = yes;
31 end if;
32
33 end subr uinp;
1 .=member uout
2 subr uout(ara, nwords); $ unformatted output.
3 access ions;
4 size ara(ws); dims ara(2); $ array to write.
5 size nwords(ws); $ words to transmit
6 size ret(ws); $ return value from -wtrb- primitive -
7 $ 0 is o.k., anything else is system failure.
8 if (donotbit(filenow)) return; $ previous error, so do nothing.
9 if nwords < 0 then $ if bad slice spec.
10 ioerror(filenow, 2, 19);
11 elseif nwords = 0 then $ if null slice.
12 return;
13 end if;
14 call wtrwsio(filenow, ret, ara, 1, nwords);
15 if ret then
dsb 63 ioerror(filenow, 2, 17);
17 end if;
18 end subr uout;
1 .=member ioer
2 subr ioer(farg, ernov); $ process io error.
3 access ions;
4 size farg(ps); $ file number.
5 size fileid(ps);
6 size lsv(ps); $ linesize value.
7 size lbp(ps); $ buffer pointer.
8 size lbo(ps); $ buffer origin.
9 size i(ps); $ loop index.
10 size ernov(ws); $ errorv setting + 16*error no.
11 size errno(ps); $ error number
12 size erlev(ps); $ error level.
13 $ erlev=1 for truncation/conversin, 2 for specification, and 3
14 $ if op.sys. reported transmission failure.
15 size ertab(.sds. 36); $ error message text table.
dsb 64 +* ioertot = 22 ** $ number of errors with messages.
17 +* ioert(n, t) = data ertab(n) = t; **
18 dims ertab(ioertot);
19 ioert(01, 'conversion or truncation error.')
20 ioert(02, 'invalid file number.')
21 ioert(03, 'file not connected.')
22 ioert(04, 'access alone given, not valid.')
23 ioert(05, 'linesize given, require title.')
24 ioert(06, 'require title specification.')
25 ioert(07, 'cannot allocate line buffer.')
26 ioert(08, 'file not connected for this access.')
27 ioert(09, 'attempt to read past end.')
28 ioert(10, 'field width too large.')
29 ioert(11, 'string access, get from nonstring.')
30 ioert(12, 'string access, get with bad index.')
31 ioert(13, 'input transmission failure.')
32 ioert(14, 'string access, put to nonstring.')
33 ioert(15, 'string access, put with bad index.')
34 ioert(16, 'bad control format specification.')
35 ioert(17, 'output transmission failure.')
36 ioert(18, 'cannot redefine standard print file.')
37 ioert(19, 'invalid array slice.')
dsb 65 ioert(20, 'cannot open file.')
dsb 66 ioert(21, 'cannot close file.')
dsb 67 ioert(22, 'cannot rewind file.')
38
39
40 $ must copy file argumennt in case is ostr_file.
41 fileid = farg;
42
43 if fileid<1 ! fileid>maxfiles then $ if invalid file.
44 endl textl('fatal error - invalid file number') intl(fileid)
45 endl
46 call ltlfin(1,0);
47 end if;
48
49 errno = ernov / 16;
50 erlev = ernov - 16*errno;
51
52 donotbit(fileid) = (errno^=1);
53 errorv(fileid) = erlev;
54 $ if conversion or truncation, accept only if ignore level>0.
55 $ return if error of this level acceptable.
56 if (ignorev(fileid) >= erlev) return;
57
58 if printfileopen = no then $ if cannot print message.
59 call remarkl('cannot open print file.');
60 call ltlfin(1, 1007); $ cannot open print file.
61 end if;
62
63 textl('i/o error - program fileid is ');
dsb 68 intl(fileid);
dsb 69 textl(', title is <') textl(titlev(fileid)) textl('>.')
65 endl textl(ertab(errno)) endl
66
67 $ if file has line buffer, print it and record number.
68 lbo = iolborg(fileid); $ see if origin.
69 if lbo then $ if origin, print line
70 textl('near line') intlp((linenum(fileid)),7)
71 textl(' in file') intl(fileid) endl
72 lsv = linesizev(fileid);
73 do i = 1 to iolblen(fileid);
74 wordl(iolba(lbo+i-1)); end do;
75 endl
76 lbp = lbptr(fileid);
77 if lbp>1 & lbp<=lsv then $ mark position of line pointer.
78 do i = 1 to lbp-1; charl(1r-); end do;
79 charl(1r$); $ mark line pointer position.
80 endl
81 end if;
82 end if;
83
84 $ debug printout trace if error detected
85 .+prfi call prfi(fileid,'io error detected');
86 endl
87 $ here if fatal error.
88 call ltlfin(1, 1300+errno); $ fatal io error.
89 end subr ioer;
1 .=member endlio
1 .=member blds
2 .-defenv_ss.
3 /*
4 string primitives
5
6 author - d. shields (nyu-cims) 02-aug-79
7
8 this code describes and provides an initial implementation of a
9 set of string search primitives based in part on those of snobol4
10 and using the implementation method of various spitbol implementations.
11 the basic idea is to build 'string sets' which are represented as
12 one-bit fields in a table indexed by character code. the operation
13 to determine if a character is in a set involves indexing the table
14 by the code and then anding with the appropriate mask.
15 the primitives should admit an implementation substantially more
16 efficient than the provided little implementation on most machines.
17
18 anyc(c, ss) match any character in string set ss
19 anys(s, sp, ss) match any character in string set ss
20 blds(s, ss) build string set from string s
21 brkc(s, sp, c) break to character
22 brks(s, sp, ss) break to character in string set ss
23 ctlc(s) convert character to lower case
24 ctuc(s) convert character to upper case
25 nayc(c, ss) match any character not in character set ss
26 nays(s, sp, ss) match any character not in character set ss
27 rbrc(s, sp, c) right break to character c
28 rbrs(s, sp, ss) right break to character in string set ss
29 rpld(s1, s2) define replacement string for rple
30 rple(s) execute replacement
31 rspc(s, sp, c) right span character
32 rsps(s, sp, ss) right span to character in string set ss
33 spnc(s, sp, c) span character
34 spns(s, sp, ss) span characters in string set ss
35 stlc(s) convert string to lower case
36 stuc(s) convert string to upper case
37
38 pre-assigned string sets
39 1 1b'000001' ss_blank blank
40 2 1b'000010' ss_separ separators (blank, tab, form feed)
41 4 1b'000100' ss_digit digits 0..9
42 8 1b'001000' ss_ucltr upper case letters a..z
43 16 1b'010000' ss_lcltr lower case letters a..z (if available)
44 32 1b'100000' ss_break break (underline) character '_'
45
46 ss_separ includes blank as well as any other characters which
47 by usual practice are considered equivalent to blank for separating
48 symbols. for ascii environments, the separators include horizontal
49 tab and form feed.
50
51 support up to 16 string sets
52
53
54 */
55
56 $ ss_sz is number of string sets supported. this need be no more
57 $ 16 for assembly language implementations, but is ws for the li
58 $ implementation.
59 +* ss_sz = ws ** $ number of string sets supported.
60
61 +* nchars = $ number of characters in character set.
62 $ assume cs=6 or cs=8 or cs=9
63 ((cs=8)*256 + (cs=6)*64 + (cs=9)*512)
64 **
65
66 $ codes for pre-defined string sets.
67
68 +* ss_blank = 1b'000001' **
69 +* ss_separ = 1b'000010' **
70 +* ss_digit = 1b'000100' **
71 +* ss_ucltr = 1b'001000' **
72 +* ss_lcltr = 1b'010000' **
73 +* ss_break = 1b'100000' **
74
75 subr blds(s, sma); $ build string set.
76 $ build string set for string s
77 $ which can be accessed by string mask sma.
78 nameset ssns; $ nameset for string search functions
79 size rpltab(cs); $ translate table
80 dims rpltab(nchars);
81 size sstab(ss_sz); $ string search table.
82 dims sstab(nchars);
dsc 82 .+s10. $ initialize sstab for s10 (9 bit ascii)
84 data sstab =
dsc 83 0(9), ss_separ /* tab */, 0(2), ss_separ /* form feed */,
dsc 84 0(19), ss_blank ! ss_separ, 0(15), ss_digit(10), 0(7),
dsc 85 ss_ucltr(26), 0(4), ss_break, 0, ss_lcltr(26), 0(5), 0(384);
87 ..s10
88 .+s11. $ initialize sstab for s11 (8 bit ascii)
89 data sstab =
90 0(9), ss_separ /* tab */, 0(2), ss_separ /* form feed */,
91 0(19), ss_blank ! ss_separ, 0(15), ss_digit(10), 0(7),
92 ss_ucltr(26), 0(4), ss_break, 0, ss_lcltr(26), 0(5), 0(128);
93 ..s11
94 .+s32. $ initialize sstab for s32 (8 bit ascii)
95 data sstab =
96 0(9), ss_separ /* tab */, 0(2), ss_separ /* form feed */,
97 0(19), ss_blank ! ss_separ, 0(15), ss_digit(10), 0(7),
98 ss_ucltr(26), 0(4), ss_break, 0, ss_lcltr(26), 0(5), 0(128);
99 ..s32
100 .+s37. $ initialize sstab for s37 (8 bit ebcdic)
101 data sstab =
dsbb 2 0(5), ss_separ /* tab */, 0(6), ss_separ /* form feed */,
103 0(51), ss_blank ! ss_separ, 0(44), ss_break, 0(18),
dsbb 3 0(1), ss_lcltr(9), 0(7), ss_lcltr(9), 0(8), ss_lcltr(8),
105 0(22), 0, ss_ucltr(9), 0(7), ss_ucltr(9), 0(8), ss_ucltr(8),
106 0(6), ss_digit(10), 0(6);
107 ..s37
utsa 135 .+s47. $ initialize sstab for s47 (8 bit ascii)
utsa 136 data sstab =
utsa 137 0(9), ss_separ /* tab */, 0(2), ss_separ /* form feed */,
utsa 138 0(19), ss_blank ! ss_separ, 0(15), ss_digit(10), 0(7),
utsa 139 ss_ucltr(26), 0(4), ss_break, 0, ss_lcltr(26), 0(5), 0(128);
utsa 140 ..s47
108 .+s66. $ initialize sstab for s66
109 data sstab =
110 0,
111 ss_ucltr(26), $ alphabetics
112 ss_digit(10), $ numerics
113 0(8),
114 ss_blank ! ss_separ, $ blank (the only separator)
115 0(7),
116 ss_break, $ break (underline)
117 0(10); $ remaining characters.
118 ..s66
119 end nameset;
120
121 size s(.sds. 72); $ string
122 size sma(ss_sz); $ string mask argument.
123 size sm(ss_sz); $ copy of argument.
124 size c(cs); $ character
125 size v(ps); $ temporary.
126 size i(ps); $ loop index.
127
128 $ initialize if sm is zero.
129 sm = sma; $ copy argument.
130
131 $ clear existing definition.
132
133 do i = 1 to nchars;
134 sstab(i) = sstab(i) & (.not.sm);
135 end do;
136
137 do i = 1 to (.len. s); $ enter set.
138 c = .ch. i, s;
139 sstab(1+c) = sstab(1+c) ! sm;
140 end do;
141 end subr blds;
1 .=member anyc
2 fnct anyc(c, sm); $ look for character in string set
3 $ return one if character c is in string set sm;
4 $ otherwise return zero.
5
6 access ssns; $ access ss globals.
7 size c(cs); $ character to check.
8 size anyc(ws); $ result.
9 size sm(ss_sz); $ string set mask
10
11 anyc = (sm & sstab(1+c)) ^= 0;
12 end fnct anyc;
1 .=member anys
2 fnct anys(s, sp, sm); $ look for character in string set
3 $ return one if sp-th character of string s is in string set sm;
4 $ otherwise return zero.
5
6 access ssns; $ access ss globals.
7 size s(.sds. 10); $ string to search.
8 size sp(ps); $ starting position.
9 size anys(ws); $ result.
10 size sm(ss_sz); $ string set mask
11
12 if (sp<1 ! (sp>(.len.s))) then anys = -1; return; end if;
13 anys = (sm & sstab(1+(.ch.sp,s))) ^= 0;
14 end fnct anys;
1 .=member brkc
2 fnct brkc(s, sp, ch); $ break character.
3 $ return length of longest string of s, starting at sp-th
4 $ character, which is followed by character ch.
5 $ the function must find an instance of the break character
6 $ if a nonnegative result is returned. the result is the number
7 $ of characters matched not including the break character.
8 size s(.sds. 10); $ string to search.
9 size sp(ps); $ starting position.
10 size sm(cs); $ break character.
11 size brkc(ws); $ result.
12 size i(ps); $ loop index.
13 size si(ps); $ string index.
14 size ch(cs); $ character argument..
15 size c(cs); $ character temporary.
16
17 brkc = -1;
18 if (sp<1 ! (sp>(.len.s))) return;
19 si = sp;
20 while si <= .len. s;
21 c = .ch. si, s;
22 if c=ch then $ if break character found.
23 brkc = si - sp;
24 quit while;
25 end if;
26 si = si + 1;
27 end while;
28 end fnct brkc;
1 .=member brks
2 fnct brks(s, sp, sm); $ break string set.
3 $ return length of longest string of s, starting at sp-th
4 $ character, which is followed by character in char set sm.
5 $ the function must find an instance of the break character
6 $ if a nonnegative result is returned. the result is the number
7 $ of characters matched not including the break character.
8 size s(.sds. 10); $ string to search.
9
10 access ssns; $ access ss globals.
11 size sp(ps); $ starting position.
12 size sm(ss_sz); $ string set mask
13 size brks(ws); $ result.
14 size i(ps); $ loop index.
15 size si(ps); $ string index.
16 size c(cs); $ character temporary.
17
18 brks = -1;
19 if (sp<1 ! (sp>(.len.s))) return;
20 si = sp;
21 while si <= .len. s;
22 c = .ch. si, s;
23 if sstab(1+(c)) & sm then $ if break character found.
24 brks = si - sp;
25 quit while;
26 end if;
27 si = si + 1;
28 end while;
29 end fnct brks;
1 .=member ctlc
2 fnct ctlc(c); $ convert character to lower case
3 access ssns;
4 size c(cs); $ string to translate
5 size ctlc(cs); $ translated character.
6
7 $ just copy argument if not upper case letter.
8 ctlc = c;
9 if ((sstab(1+ctlc) & ss_ucltr) = 0) return;
10 $ here to convert known upper case to lower case.
dsc 86 .+s10 ctlc = ctlc + 32;
11 .+s11 ctlc = ctlc + 32;
12 .+s32 ctlc = ctlc + 32;
13 .+s37 ctlc = ctlc - 64;
utsa 141 .+s47 ctlc = ctlc + 32;
14 end fnct ctlc;
1 .=member ctuc
2 fnct ctuc(c); $ convert character to upper case
3 access ssns;
4 size c(cs); $ string to translate
5 size ctuc(cs); $ translated character.
6
7 $ just copy argument if not lower case letter.
8 ctuc = c;
9 if ((sstab(1+ctuc) & ss_lcltr) = 0) return;
10 $ here to convert known lower case to upper case.
dsc 87 .+s10 ctuc = ctuc - 32;
11 .+s11 ctuc = ctuc - 32;
12 .+s32 ctuc = ctuc - 32;
13 .+s37 ctuc = ctuc + 64;
utsa 142 .+s47 ctuc = ctuc - 32;
14 end fnct ctuc;
1 .=member nayc
2 fnct nayc(c, sm); $ look for character not in string set
3 $ return one if character c is not in string set sm;
4 $ otherwise return zero.
5
6 access ssns; $ access ss globals.
7 size c(cs); $ character to check.
8 size nayc(ws); $ result.
9 size sm(ss_sz); $ string set mask
10
11 nayc = (sm & sstab(1+c)) = 0;
12 end fnct nayc;
1 .=member nays
2 fnct nays(s, sp, sm); $ look for character not in string set
3 $ return one if sp-th character of string s is not in string set sm;
4 $ otherwise return zero.
5
6 access ssns; $ access ss globals.
7 size s(.sds. 10); $ string to search.
8 size sp(ps); $ starting position.
9 size nays(ws); $ result.
10 size sm(ss_sz); $ string set mask
11
12 nays = -1;
13 if (sp<1 ! (sp>(.len.s))) return;
14 nays = (sm & sstab(1+(.ch.sp,s))) = 0;
15 end fnct nays;
1 .=member rbrc
2 fnct rbrc(s, sp, ch); $ right break character
3 $ return length of longest string of s, starting at sp-th
4 $ character, which is preceded by character ch.
5 $ the function must find an instance of the break character
6 $ if a nonnegative result is returned. the result is the number
7 $ of characters matched not including the break character.
8 size s(.sds. 72); $ string to search.
9 size sp(ps); $ starting position.
10 size ch(cs); $ character argument..
11 size rbrc(ws); $ result.
12 size i(ps); $ loop index.
13 size si(ps); $ string index.
14 size c(cs); $ character temporary.
15
16 rbrc = -1;
17 if (sp<1 ! (sp>(.len. s))) return;
18 si = sp;
19 while si >= 1;
20 c = .ch. si, s;
21 if c=ch then $ if break character found.
22 rbrc = sp - si;
23 quit while;
24 end if;
25 si = si - 1;
26 end while;
27 end fnct rbrc;
1 .=member rbrs
2 fnct rbrs(s, sp, sm); $ right break string set.
3 $ return length of longest string of s, starting at sp-th
4 $ character, which is preceded by character in char set sm.
5 $ search from right to left.
6 $ the function must find an instance of the break character
7 $ if a nonnegative result is returned. the result is the number
8 $ of characters matched not including the break character.
9
10 access ssns; $ access ss globals.
11 size s(.sds. 72); $ string to search.
12 size sp(ps); $ starting position.
13 size sm(ss_sz); $ string set mask
14 size rbrs(ws); $ result.
15 size i(ps); $ loop index.
16 size si(ps); $ string index.
17 size c(cs); $ character temporary.
18
19 rbrs = -1;
20 if (sp<1 ! (sp>(.len. s))) return;
21 si = sp;
22 while si >= 1;
23 c = .ch. si, s;
24 if sstab(1+(c)) & sm then $ if break character found.
25 rbrs = sp - si;
26 quit while;
27 end if;
28 si = si - 1;
29 end while;
30 end fnct rbrs;
1 .=member rpld
2 fnct rpld(s1, s2); $ define replacement string
3 $ define replacement string for subsequent use by rple.
4 $ strings s1 and s2 must have the same nonzero length, else
5 $ rpld returns failure. otherwise, the i-th character or
6 $ s1 is to be translated to the i-th character of s2.
7 size s1(.sds. 72); $ source string.
8 size s2(.sds. 72); $ target string.
9 size rpld(ws); $ function value.
10 size i(ps); $ loop index.
11 size l(ps); $ string length.
12 access ssns;
13 l = .len. s1;
14 rpld = -1;
15 if (l ^= .len. s2) return; $ if lengths differ.
16 do i = 1 to nchars; $ default is identity transformation.
17 rpltab(i-1) = i;
18 end do;
19 if (l=0) return; $ if lengths zero.
20 do i = 1 to l;
21 rpltab(1+(.ch. i, s1)) = .ch. i, s2;
22 end do;
23 rpld = 0;
24 end fnct rpld;
1 .=member rple
2 subr rple(s); $ translate string
3 $ translate string s according to translation table last
4 $ established by rpld.
vaxa 15 access ssns; $ access ss globals.
5 size s(.sds. 72);
6 size i(ps); $ loop index.
7 do i = 1 to .len. s;
8 .ch. i, s = rpltab(1+(.ch. i, s));
9 end do;
10 end subr rple;
1 .=member rspc
2 fnct rspc(s, sp, ch); $ right span character
3 $ return length of longest string of s, starting at sp-th
4 $ character, which consists of character ch.
5 $ search from right to left.
6 $ the search must find at least one instance of the character
7 $ if a nonnegative result is returned.
8 size s(.sds. 10); $ string to search
9 size sp(ps); $ starting index
10 size ch(cs); $ span character.
11 size rspc(ws); $ result.
12 size i(ps); $ loop index.
13 size si(ps); $ string index.
14 size c(cs); $ character temporary.
15
16 if (sp<1 ! sp>(.len. s)) then rspc = -1; return; end if;
17 si = sp;
18 while si >= 1;
19 c = .ch. si, s;
20 if (c^=ch) quit while; $ if end of span.
21 si = si - 1;
22 end while;
23 rspc = sp - si; $ return length.
24 if (rspc=0) rspc = -1; $ fail if no characters matched.
25 end fnct rspc;
1 .=member rsps
2 fnct rsps(s, sp, sm); $ right span string set
3 $ return length of longest string of s, starting at sp-th
4 $ character, which consists of characters in string mask sm.
5 $ search from right to left.
6 $ the search must find at least one instance of a character
7 $ in the specified string set if a nonnegative result is returned.
8
9 access ssns; $ access ss globals.
10 size s(.sds. 10); $ string to search
11 size sp(ps); $ starting index
12 size sm(16); $ string set.
13 size rsps(ws); $ result.
14 size i(ps); $ loop index.
15 size si(ps); $ string index.
16 size c(cs); $ character temporary.
17
18 if (sp<1 ! sp>(.len. s)) then rsps = -1; return; end if;
19 si = sp;
20 while si >= 1;
21 c = .ch. si, s;
22 if ((sstab(1+(c))&sm)=0) quit while; $ if end of span.
23 si = si - 1;
24 end while;
25 rsps = sp - si; $ return length.
26 if (rsps=0) rsps = -1; $ fail if no characters matched.
27 end fnct rsps;
1 .=member spnc
2 fnct spnc(s, sp, ch); $ span character
3 $ return length of longest string of s, starting at sp-th
4 $ character, which consists of character ch.
5 $ the search must find at least one instance of the character
6 $ if a nonnegative result is returned.
7 size s(.sds. 10); $ string to search
8 size sp(ps); $ starting index
9 size ch(cs); $ span character.
10 size spnc(ws); $ result.
11 size i(ps); $ loop index.
12 size si(ps); $ string index.
13 size c(cs); $ character temporary.
14
15 if (sp<1 ! sp>(.len. s)) then spnc = -1; return; end if;
16 si = sp;
17 while si <= .len. s;
18 c = .ch. si, s;
19 if (c^=ch) quit while; $ if end of span.
20 si = si + 1;
21 end while;
22 spnc = si - sp; $ return length.
23 if (spnc=0) spnc = -1; $ fail if no characters matched.
24 end fnct spnc;
1 .=member spns
2 fnct spns(s, sp, sm); $ span string set
3 $ return length of longest string of s, starting at sp-th
4 $ character, which consists of character in string set sm.
5 $ the search must find at least one instance of a character
6 $ in the specified string set if a nonnegative result is returned.
7
8 access ssns; $ access ss globals.
9 size s(.sds. 10); $ string to search
10 size sp(ps); $ starting index
11 size sm(16); $ string set.
12 size spns(ws); $ result.
13 size i(ps); $ loop index.
14 size si(ps); $ string index.
15 size c(cs); $ character temporary.
16
17 if (sp<1 ! sp>(.len. s)) then spns = -1; return; end if;
18 si = sp;
19 while si <= .len. s;
20 c = .ch. si, s;
21 if ((sstab(1+(c))&sm)=0) quit while; $ if end of span.
22 si = si + 1;
23 end while;
24 spns = si - sp; $ return length.
25 if (spns=0) spns = -1; $ fail if no characters matched.
26 end fnct spns;
1 .=member stlc
2 subr stlc(s); $ convert string to lower case.
3 size s(.sds. 72); $ string to convert
4 size ctlc(cs); $ convert character to lower case.
5 size i(ps); $ loop index.
6
7 do i = 1 to .len. s;
8 .ch. i, s = ctlc((.ch. i, s));
9 end do;
10 end subr stlc;
1 .=member stuc
2 subr stuc(s); $ convert string to upper case.
3 size s(.sds. 72); $ string to convert
4 size ctuc(cs); $ convert character to upper case.
5 size i(ps); $ loop index.
6
7 do i = 1 to .len. s;
8 .ch. i, s = ctuc((.ch. i, s));
9 end do;
10 end subr stuc;
11 ..defenv_ss
1 .=member endltl
1 .=member io16
dsx 33 .+s40.
3 subr ltlini( dummy ) ;
4 $ initialize the little system
5
6 size dummy( ws ) ;
7 call ltlsio ; $ intialize lower level
8 call ltllio( 0 ) ;
9 return ;
10 end subr ltlini;
11
12
13
14 subr ltlfin( a , b ) ;
15 size a(ws), b(ws);
16
17 call ltllio(1) ; $ terminate i/o, flush buffers
18
19 end subr ltlfin;
20
21
22
23 subr putf;
24 $ honeywell procedure to output file 2
25
26 access ions ;
27
28 call putwsio( 2 , ostr_rc , iolba , iolborg(2) , lbptr(2)-1 ) ;
29
30 end subr putf ;
31
32
33
34 subr ioer(fileid, ernov); $ error processor 1
35 access ions;
36 /* process io error -errno-. error is fatal unless -ignorev-
37 of fileid is 2. */
38 size fileid(ps);
39 size ernov(ws); $ errorv setting + 16*error no.
40 size errno(ps); $ error number
41
42 errno = ernov / 16;
43
44 donotbit(fileid) = (errno^=10);
45 errorv(fileid) = ernov - 16*errno;
46 if (errno = 10) return; $ no message if conv, trunc.
47
48 size m(.sds. 24);
49 data m = 'i/o error on file ' ;
50 .ch. 11 , m = errno/10 + 1r0 ;
51 .ch. 12 , m = mod(errno , 10) + 1r0 ;
52 .ch. 22 , m = fileid/10 + 1r0 ;
53 .ch. 23 , m = mod(fileid , 10) + 1r0 ;
54 call crlf ; call twch( m ) ; call crlf ;
55 $ error printed
56
57 end subr ioer;
dsw 44 ..s40
1 .=member begmul
2 $ we now define the multi-word support procedures.
3 $
4 $ protected names of multiword procedures.
5 +* addmw = 7niadd$mw **
6 +* andmw = 7nband$mw **
7 +* beqmw = 7nbequ$mw **
dsx 34 +* bnemw = 7nbneq$mw **
8 +* bgemw = 7nbgeq$mw **
blea 1 +* bltmw = 7nbles$mw **
9 +* casmw = 7ncasi$mw **
10 +* catmw = 7nccat$mw **
11 +* ceqmw = 7ncequ$mw **
12 +* cexmw = 7ncext$mw **
13 +* cinmw = 7ncind$mw **
14 +* divmw = 7nidiv$mw **
15 +* easmw = 7neasi$mw **
16 +* eexmw = 7neext$mw **
17 +* ermwns = 7nermw$ns ** $ nameset for multiword errors.
18 +* errmw = 7neror$mw **
19 +* ersmw = 7neros$mw **
20 +* fbtmw = 7nbfir$mw **
21 +* iormw = 7nbior$mw **
22 +* mulmw = 7nimul$mw **
23 +* notmw = 7nbnot$mw **
24 +* nbtmw = 7nbnum$mw **
25 +* submw = 7nisub$mw **
26 +* vcsmw = 7nvstr$mw **
27 +* xormw = 7nbxor$mw **
28 +* emagn = .f.1,(ws-2),** $ extract magnitude of arith item
29 +* erest = .f.(ws-1),2, ** $ extract rest of arithmetic item
30 +* ehichunk = $ extracts high order chunk of word
31 .f. ws/2, ws/2-1, **
32
33 +* elochunk = $ extract low order chunk of word
34 $ (used by multiword procedures)
35 .f. 1, ws/2-1, **
36
37 +* ehibint = $ extracts high order bits of integer
38 .f. ws/2, ws/2, **
39
1 .=member errmw
2 subr errmw(n); $ error procedure for multi-word procedures
3 $ process error detected by multiword procedures.
4 nameset ermwns;
5 size xopern(ws); $ error number.
6 size xopsorg(ws); $ sorg value if trouble with string.
7 size xopslen(ws); $ slen value if trouble with string.
8 end nameset;
9 size n(ws);
10 .+mwcc.
11 size k(ps);
12 ..mwcc
13 $
14 $ this procedure is called when multi-word procedures detect error.
15 $ negative argument indicates error in compiler, which generated
16 $ bad call; postiive argument values indicate error in user-
17 $ supplied values.
18 .+mwcc.
19 if n < 0 then
20 k = - n;
21 endl
22 textl(' system error - compiler generated bad call')
23 textl(' to multi-word procedure.')
24 go to errproc;
25 end if;
26 ..mwcc
27 endl textl('error in multi-word calculation') endl
28 textl('in construct ')
29 +* pmr(txt) = textl(txt); go to errproc; **
30 go to u(n) in 1 to 31;
31
32
33 /u( 1)/textl('=.e.p,n,x: p<=0 ! p>(size x)'); go to ernproc;
34 /u( 2)/textl('=.e.p,n,x: n<=0 ! n>(size x)'); go to ernproc;
35 /u( 3)/textl('=.e.p,n,x: p and n define field not in x.');
36 go to ernproc;
37 /u( 4)/pmr('x+y: x illformed.');
38 /u( 5)/pmr('x+y: y illformed.');
39 /u( 6)/pmr('x+y: overflow.');
40 /u( 7)/pmr('x-y: x illformed.');
41 /u( 8)/pmr('x-y: y illformed.');
42 /u( 9)/pmr('x-y: underflow');
43 /u(10)/pmr('x*y: x illformed.');
44 /u(11)/pmr('x*y: y illformed.');
45 /u(12)/pmr('x/y: x illformed.');
46 /u(13)/pmr('x/y: y illformed.');
47 /u(14)/pmr('x/y: y = 0');
48 $ 15 is standard error for illformed character string.
49 /u(15)/textl('argument not in form of string.'); go to ersproc;
50 /u(16)/textl('x.cc.y: y not in sds format.'); go to ersproc;
51 /u(17)/textl('x.in.y: x not in sds format.'); go to ersproc;
52 /u(18)/textl('x.in.y: y not in sds format.'); go to ersproc;
53 /u(19)/textl('=.s.p,n,s: p<=0 '); go to ernproc;
54 /u(20)/textl('=.s.p,n,s: n<0 '); go to ernproc;
55 /u(21)/pmr('=.s.p,n,s: p and n define substring not in s.');
56 /u(22)/textl('=.s.p,n,s: s is not in sds format.'); go to ersproc;
57 /u(23)/textl('.s.p,n,t=s: p<=0 '); go to ernproc;
58 /u(24)/textl('.s.p,n,t=s: n<0 '); go to ernproc;
59 /u(25)/textl('.s.p,n,t=s: s is not in sds format.'); go to ersproc;
60 /u(26)/textl('.s.p,n,t=s: t is not in sds format.'); go to ersproc;
61 /u(27)/pmr('.s.p,n,t=s: (p+n-1)>(slen t) (invalid position)');
62 /u(28)/textl('.e.p,n,t=s: p<=0 ! p>(size t)'); go to ernproc;
63 /u(29)/textl('.e.p,n,t=s: n<=0 ! n>(size t)'); go to ernproc;
64 /u(30)/textl('.e.p,n,t=s: (p+n-1)>(size t) (invalid position)');
65 /u(31)/textl('argument to .seq. or .sne. not char. string.')
66 go to ersproc;
67 go to ernproc;
68 /ernproc/ $ print troublesome value
69 textl(' unacceptable value =') intl(xopern);
70 go to errproc;
71 /ersproc/ $ indicate string parameters
72 textl(' unacceptable string ') endl
73 tintl('origin',xopsorg); tintl(' current length',xopslen);
74 size cap(ws); $ capacity (maximmum slen allowed by sorg)
75 cap = (xopsorg - ldcs - 1) / cs;
76 tintl(' capacity',cap) endl
77 if (cap*cs+ldcs+1)^= xopsorg then
78 textl(' string not aligned on character boundary.'); endl
79 end if;
80 if cap<= 0) ! (wy <= 0))
15 then call errmw(-1); $ bad argument to land
16 end if;
17 ..mwcc
18 $ set minof and maxof
19
20 if wx < wy then minof = wx; maxof = wy;
21 else minof = wy; maxof = wx; end if;
22
23 $ compute low order portion of result
24
25 do i = 1 to minof;
26 wordi(i, at) = (wordi(i, ax)) & (wordi(i, ay));
27 end do;
28 $
29 $ zero out high order portion of result
30 $
31 do i = 1+minof to maxof;
32 wordi(i, at) = 0;
33 end do;
34 $
35 return;
36 end subr andmw;
37 ..defenv_andmw
38
1 .=member iormw
2 .-defenv_iormw.
3 subr iormw(ax, wxarg, ay, wyarg, at); $ x ! y
4 access ermwns;
5 access ermwns;
6 size ax(szmax), ay(szmax), at(szmax); $ t = x + y.
7 size wxarg(ps), wyarg(ps); $ words in x, y.
8 size wx(ps), wy(ps); $ words in x, y (working copy).
9 size i(ps); $ loop index.
10 size minof(ps); $ min of wx, wy.
11
12 wx = wxarg; wy = wyarg;
13 .+mwcc. $ check for compiler error
14 if ((wx <= 0) ! (wy <= 0))
15 then call errmw(-2); $ bad argument to iormw
16 end if;
17 ..mwcc
18 $ set high order words of result to those of longer argument.
19 if wx < wy then
20 minof = wx;
21 do i = 1+minof to wy; wordi(i, at) = wordi(i, ay); end do;
22 else
23 minof = wy;
24 do i = 1+minof to wx; wordi(i, at) = wordi(i, ax); end do;
25 end if;
26
27 do i = 1 to minof;
28 wordi(i, at) = (wordi(i,ax)) ! (wordi(i, ay));
29 end do;
30 end subr iormw;
31 ..defenv_iormw
32
1 .=member xormw
2 .-defenv_xormw.
3 subr xormw(ax, wxarg, ay, wyarg, at); $ x .exor. y
4 access ermwns;
5 size ax(szmax), ay(szmax), at(szmax); $ t = x .exor. y.
6 size wxarg(ps), wyarg(ps); $ words in x, y.
7 size wx(ps), wy(ps); $ words in x, y (working copy).
8 size i(ps); $ loop index.
9 size minof(ps); $ min of wx, wy.
10
11 wx = wxarg; wy = wyarg;
12 .+mwcc. $ check for compiler error
13 if ((wx <= 0) ! (wy <= 0))
14 then call errmw(-3); $ bad argument to exor
15 end if;
16 ..mwcc
17 $ set high order words of result to those of longer argument.
18 if wx < wy then
19 minof = wx;
20 do i = 1+minof to wy; wordi(i, at) = wordi(i, ay); end do;
21 else
22 minof = wy;
23 do i = 1+minof to wx; wordi(i, at) = wordi(i, ax); end do;
24 end if;
25
26 do i = 1 to minof;
27 wordi(i, at) = (wordi(i,ax)) .exor. (wordi(i, ay));
28 end do;
29 end subr xormw;
30 ..defenv_xormw
31
1 .=member notmw
2 .-defenv_notmw.
3 subr notmw(ax, bxarg, at); $ ^ x
4 access ermwns;
5 size ax(szmax); $ argument.
6 size bxarg(ps), bx(ps); $ number of bits in x, and local copy.
7 size at(szmax); $ result.
8 size i(ps); $ loop index.
9 size wx(ps); $ words in argument.
10
11 bx = bxarg;
12 wx = (bx -1 ) / ws + 1;
13 .+mwcc. $ check for compiler error
14 if (wx <= 0)
15 then call errmw(-4); $ bad argument to notmw
16 end if;
17 ..mwcc
18 $ compute the result
19
20 do i = 1 to wx;
21 wordi(i, at) = .not. wordi(i, ax);
22 end do;
23
24 $ clear high order part of last word.
25 .f. bx+1, wx*ws-bx, at = 0;
26
27 end subr notmw;
28 ..defenv_notmw
1 .=member eexmw
2 subr eexmw(axarg, ayarg, az, bzarg, at, btarg); $ t = .e. x, y, z
3 access ermwns;
4 $
5 $
6 size axarg(ps), ax(ps); $ starting position, and copy.
7 size ayarg(ps), ay(ps); $ field length, and copy.
8 size bzarg(ps), bz(ps); $ size of input string.
9 size btarg(ps), bt(ps); $ size of temporary.
10 size az(szmax); $ input.
11 size at(szmax); $ output.
12 size lastbit(ps); $ number of last bit to be moved
13 size over(ps); $ number of bits left over in word
14 size wsmover(ps); $ wordsize minus over
15 size overp1(ps); $ over plus one
16 size wsmoverp1(ps); $ wsmover plus one
17 size nwtm(ps); $ number of words to move
18 size swtm(ps); $ starting word to move
19 size temp(ws); $ temporary
20 size i(ps); $ counter
21 size wint(ps); $ number of words in t
22 size nbnm(ps); $ number of bits not moved
23 ax = axarg; ay = ayarg; bz = bzarg; bt = btarg;
24 .+mwcc. $ check for compiler and user errors
25 if ((bz <= 0) ! (bt <= 0))
26 then call errmw(-6); $ bad argument to eexmw
27 end if;
28 ..mwcc
29 if ((ax <= 0) ! (ax > bz))
30 then xopern =ax; call errmw(1); $ bad lbe
31 end if;
32 if ((ay < 0) ! (ay > bz))
33 then xopern=ay; call errmw(2); $ bad eexmw user arg two
34 end if;
35 if ay then lastbit = ax + ay - 1;
36 else lastbit = ax; end if;
37 if (lastbit > bz)
38 then xopern=lastbit; call errmw(3); $ bad eexmw user arg
39 end if;
40 .+mwcc. if (ay > bt)
41 then call errmw(-6);
42 $ bad argument to eexmw
43 end if;
44 ..mwcc
45 $ move z (the data) into t (the result)
46 $
dsi 88 wint = (bt + (ws-1)) / ws;
48 nwtm = ay / ws;
49 swtm = (ax - 1) / ws;
50 wsmover = ax - (1 + swtm * ws);
51 if wsmover = 0 $ if field starts in bit 1 of a word
52 then $ the fast special case
53 do i = 1 to nwtm;
54 wordi(i, at) = wordi(i + swtm, az);
55 end do;
56 do i = nwtm + 1 to wint;
57 wordi(i, at) = 0;
58 end do;
59 over = ay - nwtm * ws;
60 if (over > 0) then
61 temp = .f. 1, over, (wordi(swtm + nwtm + 1, az));
62 wordi(nwtm + 1, at) = temp;
63 end if;
64 else $ the general case
65 over = ws - wsmover;
66 overp1 = over + 1;
67 wsmoverp1 = wsmover + 1;
68 do i = 1 to nwtm;
69 temp = .f. wsmoverp1, over, (wordi(swtm + i, az));
70 .f. overp1, wsmover, temp = wordi(swtm + i + 1, az);
71 wordi(i, at) = temp;
72 end do;
73 do i = 1+nwtm to wint;
74 wordi(i, at) = 0;
75 end do;
76 nbnm = ay - nwtm * ws;
77 if (nbnm ^= 0) then
78 if (nbnm < over) then
79 wordi(nwtm + 1, at) = .f. wsmoverp1, nbnm,
80 (wordi(swtm + nwtm + 1, az));
81 else
82 wordi(nwtm + 1, at) = .f. wsmoverp1, over,
83 (wordi(swtm + nwtm + 1, az));
84 nbnm = nbnm - over;
85 if (nbnm ^= 0) then
86 temp = 0;
87 .f. overp1, nbnm, temp = wordi(swtm + nwtm + 2, az);
88 wordi(nwtm + 1, at) = wordi(nwtm + 1, at) ! temp;
89 end if;
90 end if;
91 end if;
92 end if;
93 $
94 end subr eexmw;
1 .=member easmw
2 subr easmw(axarg, ayarg, az, bzarg, at, btarg); $ .e. x,y,t = z
3 access ermwns;
4 $
5 $
6 size axarg(ps), ax(ps); $ starting position, and copy.
7 size ayarg(ps), ay(ps); $ field length, and copy.
8 size bzarg(ps), bz(ps); $ size of input string.
9 size btarg(ps), bt(ps); $ size of temporary.
10 size az(szmax); $ input.
11 size at(szmax); $ output.
12 size lastbit(ps); $ number of last bit to be moved
13 size sworg(ps); $ source word bit origin in z
14 size nba(ps); $ number of bits available in source wo
15 size tworg(ps); $ target word bit origin in t
16 size twd(ws); $ target word (will be replaced in t)
17 size fbtbr(ps); $ first bit to be replaced in twd
18 size lbtbr(ps); $ last bit to be replaced in twd
19 size nbtbr(ps); $ number of bits to be replaced in twd
20 size swd(ws); $ source word (from z, or perhaps zero)
21 size width(ps); $ number of zero pad bits in source wor
22 size nbufsw(ps); $ number of bits used from source word
23
24 ax = axarg; ay = ayarg;
25 bz = bzarg; bt = btarg;
26 .+mwcc. $ check for compiler error
27 if ((bz <= 0) ! (bt <= 0))
28 then call errmw(-17); $ bad argument to easmw
29 end if;
30 ..mwcc
31 if ((ax <= 0) ! (ax > bt)) then
32 xopern=ax; call errmw(28); $ bad easmw user arg one
33 end if;
34 if ((ay < 0) ! (ay > bt)) then
35 xopern=ay; call errmw(29); $ bad easmw user arg two
36 end if;
37 if (ay = 0) return;
38 lastbit = ax + ay - 1;
39 if (lastbit > bt) then
40 xopern=lastbit; call errmw(30);
41 $ bad combination of arguments
42 end if; $ arguments to easmw
43
44 $ move z (the data) into t (the target field)
45
46 sworg = 1; $ initialize delimiters
47 nba = 0;
48 tworg = ((ax - 1) / ws) * ws + 1;
49 $
50 while (tworg <= lastbit);
51 twd = .f. tworg, ws, at;
52 if (tworg < ax)
53 then fbtbr = 1 + ax - tworg;
54 else fbtbr = 1;
55 end if;
56 if (lastbit < (tworg + ws))
57 then lbtbr = lastbit + 1 - tworg;
58 else lbtbr = ws;
59 end if;
60 nbtbr = lbtbr + 1 - fbtbr;
61 while (nbtbr);
62 if (nba = 0) then $ fetch ws source bits
63 if (sworg) then $ from z (or some zero
64 swd = .f. sworg, ws, az; $ bits if z has already
65 sworg = sworg + ws; $ been exhausted)
66 if (sworg > bz) then
67 width = sworg - (1 + bz);
68 if (width) then
69 .f. ws + 1 - width, width, swd = 0;
70 end if;
71 sworg = 0;
72 end if;
73 else swd = 0;
74 end if;
75 nba = ws;
76 end if; $ end bit fetch from z
77 if (nba < nbtbr)
78 then nbufsw = nba;
79 else nbufsw = nbtbr;
80 end if;
81 .f. fbtbr, nbufsw, twd = .f. ws + 1 - nba, nbufsw, swd;
82 nba = nba - nbufsw;
83 nbtbr = nbtbr - nbufsw;
84 fbtbr = fbtbr + nbufsw;
85 end while;
86 .f. tworg, ws, at = twd; $ replace twd in t
87 tworg = tworg + ws;
88 end while;
89
90 end subr easmw;
91
1 .=member fbtmw
2 .-defenv_fbtmw.
3 fnct fbtmw(ax, wxarg); $ .fb. x
4 size ax(szmax); $ argument.
5 size wxarg(ps), wx(ps); $ words in argument, and copy.
6 size fbtmw(ps); $ function value.
7 size i(ps); $ index.
8
9 wx = wxarg;
10 .+mwcc. $ check for compiler error
11 if (wx <= 0)
12 then call errmw(-7); $ bad argument to fbtmw
13 end if;
14 ..mwcc
15 fbtmw = 0;
16 do i = wx to 1 by -1;
17 if wordi(i,ax) then fbtmw = i; quit do; end if;
18 end do;
19 if fbtmw then
20 fbtmw = ws * (fbtmw - 1) + .fb. (wordi(fbtmw, ax));
21 end if;
22
23 end fnct fbtmw;
24 ..defenv_fbtmw
25
1 .=member nbtmw
2 .-defenv_nbtmw.
3 fnct nbtmw(ax, wxarg); $ .nb. x
4
5
6 size nbtmw(ps); $ function value.
7 size ax(szmax); $ argument.
8 size wxarg(ps), wx(ps); $ words in argument, and copy.
9 size i(ps); $ index.
10
11 wx = wxarg;
12 .+mwcc. $ check for compiler error
13 if (wx <= 0)
14 then call errmw(-8); $ bad argument to nbtmw
15 end if;
16 ..mwcc
17 nbtmw = 0;
18 do i = 1 to wx;
19 nbtmw = nbtmw + .nb. (wordi(i, ax));
20 end do;
21 end fnct nbtmw;
22 ..defenv_nbtmw
23
1 .=member beqmw
2 fnct beqmw(ax, wxarg, ay, wyarg); $ x = y
3
4
5 size ax(szmax), ay(szmax); $ arguments.
6 size wxarg(ps), wyarg(ps); $ words in arguments.
7 size wx(ps), wy(ps); $ words in arguments, working copy.
8 size beqmw(1); $ function value.
9 size minof(ps); $ min of wx, wy.
10 size i(ps); $ loop index.
11
12 wx = wxarg; wy = wyarg;
13 .+mwcc. $ check for compiler error
14 if ((wx <= 0) ! (wy <= 0)) then
15 call errmw(-9); $ bad argument to beqmw
16 end if;
17 ..mwcc
18 beqmw = 1;
19 if (wx < wy)
20 then minof = wx;
21 else minof = wy;
22 end if;
23
24 $ one or two of the following three loops will be executed
25
26 do i = 1 to minof;
27 if (wordi(i, ax) .ex. wordi(i, ay)) then
28 beqmw = 0;
29 return;
30 end if;
31 end do;
32 do i = 1 + minof to wx;
33 if (wordi(i, ax)) then
34 beqmw = 0;
35 return;
36 end if;
37 end do;
38 do i = 1 + minof to wy;
39 if (wordi(i, ay)) then
40 beqmw = 0;
41 return;
42 end if;
43 end do;
44
45 end fnct beqmw;
1 .=member bnemw
2 fnct bnemw(ax, wxarg, ay, wyarg); $ x .ne. y
3
4
5 size ax(szmax), ay(szmax); $ arguments.
6 size wxarg(ps), wyarg(ps); $ words in arguments.
7 size wx(ps), wy(ps); $ words in arguments, working copy.
8 size bnemw(1); $ function value.
9 size minof(ps); $ min of wx, wy.
10 size i(ps); $ loop index.
11
12 wx = wxarg; wy = wyarg;
13 .+mwcc. $ check for compiler error
14 if ((wx <= 0) ! (wy <= 0)) then
15 call errmw(-9); $ bad argument to bnemw
16 end if;
17 ..mwcc
18 bnemw = 0;
19 if (wx < wy)
20 then minof = wx;
21 else minof = wy;
22 end if;
23
24 $ one or two of the following three loops will be executed
25
26 do i = 1 to minof;
27 if (wordi(i, ax) .ex. wordi(i, ay)) then
28 bnemw = 1;
29 return;
30 end if;
31 end do;
32 do i = 1 + minof to wx;
33 if (wordi(i, ax)) then
34 bnemw = 1;
35 return;
36 end if;
37 end do;
38 do i = 1 + minof to wy;
39 if (wordi(i, ay)) then
40 bnemw = 1;
41 return;
42 end if;
43 end do;
44
45 end fnct bnemw;
1 .=member bgemw
2 fnct bgemw(ax, wxarg, ay, wyarg); $ x >= y
3 size ax(szmax), ay(szmax); $ arguments.
4 size wxarg(ps), wyarg(ps); $ words in arguments.
5 size wx(ps), wy(ps); $ words in arguments, working copy.
6 size bgemw(1); $ function value.
7 size minof(ps); $ min of wx, wy.
8 size i(ps); $ loop index.
9 size tempx(ws), tempy(ws); $ temporaries.
10
11 wx = wxarg; wy = wyarg;
12 .+mwcc. $ check for compiler error
13 if ((wx <= 0) ! (wy <= 0)) then
14 call errmw(-11); $ bad argument to bgemw
15 end if;
16 ..mwcc
17 if (wx < wy)
18 then minof = wx;
19 else minof = wy;
20 end if;
21
22 $ one or two of the following three loops will be executed
23
24 do i = 1 + minof to wx;
25 if (wordi(i, ax)) then
26 bgemw = 1;
27 return;
28 end if;
29 end do;
30 do i = 1 + minof to wy;
31 if (wordi(i, ay)) then
32 bgemw = 0;
33 return;
34 end if;
35 end do;
36 bgemw = 1;
37 do i = minof to 1 by -1;
38 tempx = wordi(i, ax);
39 tempy = wordi(i, ay);
40 if tempx ^= tempy then
41 bgemw = (tempx >= tempy);
42 return;
43 end if;
44 end do;
45 $ here if items agree, return true.
46
47 end fnct bgemw;
1 .=member bltmw
2 fnct bltmw(ax, wxarg, ay, wyarg); $ x < y
3 size ax(szmax), ay(szmax); $ arguments.
4 size wxarg(ps), wyarg(ps); $ words in arguments.
5 size wx(ps), wy(ps); $ words in arguments, working copy.
6 size bltmw(1); $ function value.
7 size minof(ps); $ min of wx, wy.
8 size i(ps); $ loop index.
9 size tempx(ws), tempy(ws); $ temporaries.
10
11 wx = wxarg; wy = wyarg;
12 .+mwcc. $ check for compiler error
13 if ((wx <= 0) ! (wy <= 0)) then
14 call errmw(-11); $ bad argument to bltmw
15 end if;
16 ..mwcc
17 if (wx < wy)
18 then minof = wx;
19 else minof = wy;
20 end if;
21
22 $ one or two of the following three loops will be executed
23
24 do i = 1 + minof to wx;
25 if (wordi(i, ax)) then
26 bltmw = 0;
27 return;
28 end if;
29 end do;
30 do i = 1 + minof to wy;
31 if (wordi(i, ay)) then
32 bltmw = 1;
33 return;