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
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
;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.
;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
;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.
TAB←←11 ;ASCII characters
;FL bits (right half)
QUO←←1 ;Currently inside quotes
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,JOBFF↑ ;Save top of core ptr
TLNN A,-1 ;Zero in left half?
HRLI A,440700 ;Yes, make 7-bit byte ptr
INIT DSK,17 ;Dump mode
JRST NOINIT ;INIT failed
GETPPN A, ;Always look on login area
JRST NOLOOK ;LOOKUP failed, maybe file isn't there
MOVEM A,FILADR ;Address where we'll read the file into
MOVN B,B ;Word count of file
ADDB B,JOBFF ;New core size
CAMG B,JOBREL↑ ;Skip if we need more core
JRST GOTCOR ;Got enough already
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
MOVEI A,[ASCIZ/Input error reading OPTION.TXT./]
;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
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
JRST SEARCH ;Go and do it again
MOVEI A,[ASCIZ/Probable infinite loop expanding abbreviations./]
;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
IOPOP DSK,0 ;And I/O channel
JRST IOPDLO ;This IOPOP can't fail
IOPDLO: MOVEI A,[ASCIZ\IOPUSH/POP failed reading OPTION.TXT.\]
NOINIT: MOVEI A,[ASCIZ/INIT failed reading OPTION.TXT./]
NOLOOK: HRRZ A,ABRFIL+1 ;Get error code
JUMPE A,NOMORE ;File doesn't exist, fine
MOVEI A,[ASCIZ/LOOKUP failed reading OPTION.TXT./]
NOCORE: MOVEI A,[ASCIZ/Can't get core to read OPTION.TXT./]
FBEGIN: MOVE A,FILLNG
IMULI A,5 ;Compute char count
HRLI A,440700 ;Point to first char
;Check for @ in input string. If found, adjust INPTR and ATPTR.
ATSIGN: MOVE B,INPTR
SETZM ATPTR ;No @ found yet
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
;Get next non-null character from input file into A. Skips on success.
GETCHR: SOSG CCOUNT
POPJ P, ;End of file
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>
CAIN A,LF ;End line at <lf>
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
;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
MOVEI C,0 ;Stick a null in to end the string
;(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
;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
CAIE A,(C) ;Skip if the same
POPJ P, ;Fail if different
CAIE A,":" ;Same, check if done
JRST ABBCH1 ;Not done, keep testing
;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!
JRST TOKEN ;Skip whitespace
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
CAIE A,SPACE ;Whitespace ends token also
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,(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
CAIL A,"a" ;Map lower case to upper
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
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
CAME B,INPTR ;This is where it ends
NOATSN: MOVE B,EXPPTR ;Now copy expansion text
NOATS1: ILDB A,B