perm filename NETLIB.FAI[S,NET] blob
sn#794284 filedate 1985-05-25 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00004 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 This is a library of network subroutines, to be linked together with
C00003 00003 TITLE EXPABR FL A B C D P DSK TAB LF FF CR SPACE QUOTE QUO ABRFIL BUFSIZ OUTBFR OUTPTR LINBUF LINPTR ABBPTR EXPPTR INPTR ATPTR FILADR FILLNG FILPTR CCOUNT EXPABR GOTCOR SEARCH NXTLIN NOMORE RESTR IOPDLO NOINIT NOLOOK NOCORE FBEGIN ATSIGN ATSIG1 GETCHR CPOPJ1 CPOPJ GETLIN GETLI1 GETLI2 GETLI3 SPLIT ABBCHK ABBCH1 TOKEN TOKEN2 TOKEN3 DELIM0 DELIM COMPAR COMPA1 NEWSTR ATCOPY NOATSN NOATS1
C00019 00004 END
C00020 ENDMK
C⊗;
;This is a library of network subroutines, to be linked together with
;programs that need them. It extends basic support in the NETWRK package,
;but differs in that these are separately compiled, independent routines.
;Contents:
;
;EXPABR - expands abbreviations using ABBREV.TXT files.
TITLE EXPABR ;⊗ FL A B C D P DSK TAB LF FF CR SPACE QUOTE QUO ABRFIL BUFSIZ OUTBFR OUTPTR LINBUF LINPTR ABBPTR EXPPTR INPTR ATPTR FILADR FILLNG FILPTR CCOUNT EXPABR GOTCOR SEARCH NXTLIN NOMORE RESTR IOPDLO NOINIT NOLOOK NOCORE FBEGIN ATSIGN ATSIG1 GETCHR CPOPJ1 CPOPJ GETLIN GETLI1 GETLI2 GETLI3 SPLIT ABBCHK ABBCH1 TOKEN TOKEN2 TOKEN3 DELIM0 DELIM COMPAR COMPA1 NEWSTR ATCOPY NOATSN NOATS1
INTERN EXPABR
;EXPABR - Expand abbreviations using OPTION.TXT entries.
;
;Call: MOVE 1,[<byte ptr to string to be expanded, or
; addr of first word if 7-bit bytes>]
; PUSHJ 17,EXPABR
; <error return: addr of error text in 1>
; <normal return: byte ptr to expanded string in 1>
;
;All strings are assumed to be ASCIZ strings. Saves and restores all ACs.
FL←0
A←1
B←2
C←3
D←4
P←17
DSK←←0
TAB←←11 ;ASCII characters
LF←12
FF←14
CR←15
SPACE←40
QUOTE←42
;FL bits (right half)
QUO←←1 ;Currently inside quotes
ABRFIL: SIXBIT/ABBREV/
SIXBIT/TXT/
0
0 ;PPN to be filled in
BUFSIZ←←50 ;Size of various buffers
OUTBFR: BLOCK BUFSIZ ;Buffer to hold final output string
OUTPTR: POINT 7,OUTBFR
LINBUF: BLOCK BUFSIZ ;Buffer to hold input line
LINPTR: POINT 7,LINBUF
ABBPTR: 0 ;Pointer to abbreviation part of a line
EXPPTR: 0 ;Pointer to expansion part of a line
INPTR: 0 ;Pointer to current input string
ATPTR: 0 ;Pointer to original string, if it had an @
FILADR: 0 ;Address of start of file image
FILLNG: 0 ;Length of file, in words
FILPTR: 0 ;Pointer to current char in file
CCOUNT: 0 ;Count of remaining chars
PASSCT: 0 ;Number of passes over input file so far
EXPABR: IOPUSH DSK,0 ;Get a temporary I/O channel
JRST IOPDLO ;IOPUSH failed
PUSH P,FL
PUSH P,B
PUSH P,C
PUSH P,D
PUSH P,JOBFF↑ ;Save top of core ptr
SETZM PASSCT
TLNN A,-1 ;Zero in left half?
HRLI A,440700 ;Yes, make 7-bit byte ptr
MOVEM A,INPTR
INIT DSK,17 ;Dump mode
SIXBIT/DSK/
0
JRST NOINIT ;INIT failed
GETPPN A, ;Always look on login area
MOVEM A,ABRFIL+3
LOOKUP DSK,ABRFIL
JRST NOLOOK ;LOOKUP failed, maybe file isn't there
HRRZ A,JOBFF
MOVEM A,FILADR ;Address where we'll read the file into
MOVS B,ABRFIL+3
MOVN B,B ;Word count of file
MOVEM B,FILLNG
ADDB B,JOBFF ;New core size
CAMG B,JOBREL↑ ;Skip if we need more core
JRST GOTCOR ;Got enough already
CORE B,
JRST NOCORE
GOTCOR: HLL A,ABRFIL+3 ;-count in left half
SUBI A,1 ;Form IOWD
SETZ B, ;End IOWD list
IN DSK,A ;Read the whole file into core
JRST SEARCH
MOVEI A,[ASCIZ/Input error reading OPTION.TXT./]
JRST RESTR
;Start searching at beginning of abbreviation file.
SEARCH: PUSHJ P,FBEGIN ;Set up pointers to beginning of file
PUSHJ P,ATSIGN ;Check for @ in input string
NXTLIN: PUSHJ P,GETLIN ;Get a line from the abbreviation file
JRST NOMORE ;No more lines
PUSHJ P,SPLIT ;Split line into abbreviation and expansion
JRST NXTLIN ;Not an ABBREV line or error, ignore line
PUSHJ P,COMPAR ;Compare and skip if equal
JRST NXTLIN
PUSHJ P,NEWSTR ;Construct new string in OUTBFR
;Now we go back and repeat the process. You might think there is a problem
;since our input text is now in OUTBFR, and we'd be reading and writing it
;simultaneously after we find the next expansion. But this is only there
;is an @ sign in it, and in that case, the text before the @ sign isn't
;altered, so it is unchanged by the copying. (Lucky, aren't we!)
MOVE A,OUTPTR ;Our output text
MOVEM A,INPTR ;Is now the input
AOS A,PASSCT ;Prevent infinite loops
CAIGE A,=100
JRST SEARCH ;Go and do it again
MOVEI A,[ASCIZ/Probable infinite loop expanding abbreviations./]
JRST RESTR
;Here after abbreviation file exhausted without having done any substitution.
NOMORE: AOS -5(P) ;Set skip return
SKIPN A,ATPTR ;Point to original INPTR if it's here
MOVE A,INPTR ;Else it is still here
RESTR: POP P,JOBFF ;Restore what we saved
POP P,D
POP P,C
POP P,B
POP P,FL
IOPOP DSK,0 ;And I/O channel
JRST IOPDLO ;This IOPOP can't fail
POPJ P,
IOPDLO: MOVEI A,[ASCIZ\IOPUSH/POP failed reading OPTION.TXT.\]
POPJ P,
NOINIT: MOVEI A,[ASCIZ/INIT failed reading OPTION.TXT./]
JRST RESTR
NOLOOK: HRRZ A,ABRFIL+1 ;Get error code
JUMPE A,NOMORE ;File doesn't exist, fine
MOVEI A,[ASCIZ/LOOKUP failed reading OPTION.TXT./]
JRST RESTR
NOCORE: MOVEI A,[ASCIZ/Can't get core to read OPTION.TXT./]
JRST RESTR
FBEGIN: MOVE A,FILLNG
IMULI A,5 ;Compute char count
MOVEM A,CCOUNT
HRRZ A,FILADR
HRLI A,440700 ;Point to first char
MOVEM A,FILPTR
POPJ P,
;Check for @ in input string. If found, adjust INPTR and ATPTR.
ATSIGN: MOVE B,INPTR
SETZM ATPTR ;No @ found yet
TLZ FL,QUO
ATSIG1: ILDB A,B ;Get next char
JUMPE A,CPOPJ ;Return if done
CAIN A,QUOTE ;Skip unless it's a quote
TLC FL,QUO ;Quoting ↔ not quoting
TLNN FL,QUO ;If quoting,
CAIE A,"@" ;or not an atsign,
JRST ATSIG1 ;keep looking
EXCH B,INPTR ;Store pointer to new beginning
MOVEM B,ATPTR ;Remember old one
POPJ P,
;Get next non-null character from input file into A. Skips on success.
GETCHR: SOSG CCOUNT
POPJ P, ;End of file
ILDB A,FILPTR
JUMPE A,GETCHR ;Don't return nulls
CPOPJ1: AOS (P)
CPOPJ: POPJ P,
;Get a line from the input file. Skips on success, line in LINBUF.
GETLIN: MOVE B,LINPTR ;Place to store line
MOVEI C,BUFSIZ*5-1 ;Max count of chars to store
GETLI1: PUSHJ P,GETCHR ;Get next character
JRST GETLI2 ;No more
CAIE A,CR ;Ignore <cr>
CAIN A,FF ;Ignore <ff>
JRST GETLI1
CAIN A,LF ;End line at <lf>
JRST GETLI3
JUMPLE C,GETLI1 ;If buffer full, skip to end of line
IDPB A,B ;Save character
SOJA C,GETLI1 ;Decrement count and continue
;Here at end of file.
GETLI2: CAIN C,BUFSIZ*5-1 ;Did the luser omit the last <lf>?
POPJ P, ;No, normal end of file
;Here at end of an input line.
GETLI3: MOVEI A,0 ;End with a null
IDPB A,B
JRST CPOPJ1
;Split input line into abbreviation and expansion parts. Skips on success.
;ABBPTR is set to point to the abbreviation part of the line, EXPPTR to the
;expansion part. The line is altered by depositing null bytes at the end
;of each of these two parts in LINBUF.
SPLIT: MOVE B,LINPTR ;Point to beginning of line
PUSHJ P,ABBCHK ;Skip if it's an "ABBREV:" line
POPJ P, ;Return if it's something else
MOVEI D,"=" ;Delimiter for abbreviation
PUSHJ P,TOKEN ;Find the abbreviation
POPJ P, ;Pass back error return
ADD C,[70000,,0] ;Back up the byte ptr for future ILDBs
MOVEM C,ABBPTR
MOVEI C,0 ;Stick a null in to end the string
DPB C,B
;(Note: contents of A and D needed for call to DELIM.)
PUSHJ P,DELIM ;Skip up to the delimiter
POPJ P, ;Something else was there!
MOVEI D,0 ;Use no delimiter for expansion
PUSHJ P,TOKEN ;Find the expansion
POPJ P, ;Another chance for errors
ADD C,[70000,,0]
MOVEM C,EXPPTR
MOVEI C,0
DPB C,B
JRST CPOPJ1
;ABBCHK checks for the string "ABBREV:" at the beginning of the line,
;and skips if it is found, with B updated to scan for the first token.
ABBCHK: MOVE D,[POINT 7,[ASCII/ABBREV:/]]
ABBCH1: ILDB A,B ;Char from line
ILDB C,D ;Char from test string
CAIL A,"a" ;Upper-casify
CAILE A,"z"
JRST .+2
SUBI A,40
CAIE A,(C) ;Skip if the same
POPJ P, ;Fail if different
CAIE A,":" ;Same, check if done
JRST ABBCH1 ;Not done, keep testing
JRST CPOPJ1
;TOKEN takes an ILDB pointer to the potential first character of a token
;in B and a delimiter character in D (use 0 if no delimiter desired),
;and skip returns if it finds a legal token, with an LDB pointer to
;the actual first character in C, and an LDB pointer to the character
;following the token in B. The direct return is taken on errors.
TOKEN: ILDB A,B ;Start examining characters
JUMPE A,CPOPJ ;Oops, can't be done yet!
CAIE A,SPACE
CAIN A,TAB
JRST TOKEN ;Skip whitespace
CAIN A,";"
POPJ P, ;No token here, just a comment
MOVE C,B ;Remember this position
;Now we search for the end of the token.
TOKEN2: CAIN A,QUOTE ;Skip unless it's a quote
TLC FL,QUO ;Quoting ↔ not quoting
TLNE FL,QUO ;Quoting?
JRST TOKEN3 ;Yes, don't examine char
CAIE A,";" ;Comment always ends token
CAIN A,(D) ;So does delimiter if there is one
JRST CPOPJ1
CAIE A,SPACE ;Whitespace ends token also
CAIN A,TAB
JRST CPOPJ1
TOKEN3: ILDB A,B
JUMPN A,TOKEN2 ;Get next char, jump unless end of line
TLZN FL,QUO ;Still quoting at end of line?
AOS (P) ;No, we're at end of token
POPJ P, ;Error if we are
;Skip whitespace up to and including the delimiter, if not already there.
DELIM0: ILDB A,B
DELIM: CAIE A,SPACE ;Skip whitespace ...
CAIN A,TAB
JRST DELIM0
CAIN A,(D) ;This better be the delimiter
AOS (P) ;Yes, give skip return
POPJ P, ;Else fail
;Compare input string with line from file. Skip if they match.
COMPAR: MOVE B,INPTR ;Compare the input string
MOVE D,ABBPTR ;With the abbreviation
COMPA1: ILDB A,B ;Get a char from each
ILDB C,D
CAIL A,"a" ;Map lower case to upper
CAILE A,"z"
JRST .+2
SUBI A,40
CAIL C,"a"
CAILE C,"z"
JRST .+2
SUBI C,40
CAIE A,(C) ;Skip if the same
POPJ P, ;Different, fail
JUMPN A,COMPA1 ;Same, continue checking unless done
JRST CPOPJ1 ;Successful compare
;Construct the new string in OUTBFR, with the abbreviation replaced by
;the expansion.
NEWSTR: MOVE C,OUTPTR
SKIPN B,ATPTR ;Was there text before an @?
JRST NOATSN ;No
ATCOPY: ILDB A,B ;Yes, copy text up to @ sign
IDPB A,C
CAME B,INPTR ;This is where it ends
JRST ATCOPY
NOATSN: MOVE B,EXPPTR ;Now copy expansion text
NOATS1: ILDB A,B
IDPB A,C
JUMPN A,NOATS1
POPJ P,
PRGEND
END