.TITLE GREPAR -- PARSE GREP COMMAND LINE .IDENT -010100- .ENABL LC .SBTTL Title page ;+ ; Abstract: Grepar ; ; This subroutine parses the command line for the GREP task. ; ; Calling sequence: ; ; Not strictly applicable. ; ; Written: 12-Apr-80, -1.0.0-, Bruce C. Wright ; Modified: 15-Jul-1981, -1.1.0-, Bruce C. Wright ; Fixed bug which didn't raise output file name ; to upper case in some cases. ; Verified: 15-Jul-1981, -1.1.0-, Bruce C. Wright ;- .SBTTL State tables and command string definition. .MCALL ISTAT$,STATE$,TRAN$ ; .GLOBL STATBL,KEYTBL,BEGSTA ; ; ::= ; ::= = ! ; ::= ; ::= : ! ; ::= ; ::= ; ::= [,] ! ; ::= ! ; ::= ; ::= ! ; ::= . ! ; ::= ; ! ;* ! ; ::= ! ; ::= 0 ! 1 ! 2 ! 3 ! 4 ! 5 ! 6 ! 7 ; ::= A - Z, a - z ; $RONLY = 1 ; Define P-sections as read-only. LA = '< ; < for literals. RA = '> ; > for literals. ISTAT$ STATBL,KEYTBL ; STATE$ BEGSTA TRAN$ $LAMDA,,INISWS ; Initialise switches. STATE$ TRAN$ !PAROUT,PRESWS,CHKOUT,SW.OUT,SWORD TRAN$ $LAMDA STATE$ PRESWS TRAN$ !RSWS,PRESWS TRAN$ $BLANK,PRESWS TRAN$ $LAMDA STATE$ INPSTA TRAN$ !FILE,,SETINP STATE$ SWSSTA TRAN$ !RSWS,SWSSTA TRAN$ $BLANK STATE$ TRAN$ '',STRSTA TRAN$ !SRCSTR,ENDSTA,SETSTR STATE$ STRSTA TRAN$ !SRCSTR,,SETSTR STATE$ ENDSTA TRAN$ $EOS,$EXIT ; ; Subexpression for reading the search string ; STATE$ SRCSTR TRAN$ $ANY,SRCSTR TRAN$ $EOS,$EXIT ; ; Subexpression for reading the output file ; STATE$ PAROUT TRAN$ !FILE,,SETOUT STATE$ TRAN$ '=,$EXIT ; ; Subexpression for reading a file specification. ; STATE$ FILE TRAN$ $LAMDA,,INIPAR STATE$ TRAN$ !DEVICE,UICSTA,GETDEV TRAN$ $LAMDA STATE$ UICSTA TRAN$ !UIC,NAMSTA,GETUIC TRAN$ $LAMDA STATE$ NAMSTA TRAN$ !FILENA,$EXIT,GETFIL TRAN$ $LAMDA,$EXIT ; ; Subexpression for reading a device name ; STATE$ DEVICE TRAN$ $ANY,,CHKALF STATE$ TRAN$ $ANY,,CHKALF STATE$ TRAN$ $DIGIT,DEV1,CHKDIG TRAN$ $LAMDA STATE$ DEV1 TRAN$ ':,$EXIT ; ; Subexpression for reading a UIC specification ; STATE$ UIC TRAN$ '[ STATE$ TRAN$ $NUMBR,,CHKUIC STATE$ TRAN$ <',> STATE$ TRAN$ $NUMBR,,CHKUIC STATE$ TRAN$ '],$EXIT ; ; Subexpression for reading in a filename. ; STATE$ FILENA TRAN$ !SRCARG STATE$ FILDOT TRAN$ '. STATE$ TRAN$ !SRCARG STATE$ FILSEM TRAN$ <';>,FILVER TRAN$ $LAMDA,$EXIT STATE$ FILVER TRAN$ '*,$EXIT,,1,WLDFLG TRAN$ $NUMBR,$EXIT ; ; Subexpression for reading a search argument. This will ; be used only for file names, for which certain characters ; (e. g., ".", ";", "/", and " ") have no meaning, and are ; treated as delimeters of the search argument. The normal ; search argument is taken as simply the remainder of the ; command line and has no such restrictions. ; STATE$ SRCARG TRAN$ $ANY,SRCARG,CHKALF TRAN$ '*,SRCARG,,1,WLDFLG TRAN$ '?,SRCARG,,1,WLDFLG TRAN$ LA,SRCARG,,1,WLDFLG TRAN$ '-,SRCARG,,1,WLDFLG TRAN$ RA,SRCARG,,1,WLDFLG TRAN$ $LAMDA,$EXIT ; ; Subexpression for reading a string. The normal $STRNG ; operator cannot be used because that will not accept ; lower case letters. ; STATE$ STRNG TRAN$ $ANY,,CHKALF STATE$ STR1 TRAN$ $ANY,STR1,CHKALF TRAN$ $LAMDA,$EXIT ; ; Subexpression for reading the switches. ; STATE$ RSWS TRAN$ $BLANK,RSWS1 TRAN$ $LAMDA STATE$ RSWS1 TRAN$ '/ STATE$ ; TRAN$ "COUNT",$EXIT,,SW.CNT,SWORD ; TRAN$ "EXCEPT",$EXIT,,SW.EXC,SWORD ; TRAN$ "UPPER",$EXIT,,SW.UPC,SWORD ; TRAN$ "FILES",$EXIT,,SW.FIL,SWORD ; TRAN$ "OUTPUT",SWIOUT,,SW.OUT,SWORD ; TRAN$ "count",$EXIT,,SW.CNT,SWORD ; TRAN$ "except",$EXIT,,SW.EXC,SWORD ; TRAN$ "upper",$EXIT,,SW.UPC,SWORD ; TRAN$ "files",$EXIT,,SW.FIL,SWORD ; TRAN$ "output",SWIOUT,,SW.OUT,SWORD TRAN$ !STRNG,$EXIT,MATCNT,SW.CNT,SWORD TRAN$ !STRNG,$EXIT,MATEXC,SW.EXC,SWORD TRAN$ !STRNG,$EXIT,MATUPC,SW.UPC,SWORD TRAN$ !STRNG,$EXIT,MATFIL,SW.FIL,SWORD TRAN$ !STRNG,SWIOUT,MATOUT,SW.OUT,SWORD ; ; Parse DCL-like output switch (/OUTPUT:filename) ; STATE$ SWIOUT TRAN$ ':,SWIOU1 TRAN$ '= STATE$ SWIOU1 TRAN$ !OUTNAM,$EXIT,CHKOUT STATE$ OUTNAM TRAN$ !FILE,$EXIT,SETOUT ; ; Dummy STATE$ macro to compile the previous ones. ; STATE$ .SBTTL Action subroutines to check subexpressions. .PSECT ACTION,RO,I ; ; These are the action subroutines for the command string ; parser. ; ; Routine 1: Check a digit to ensure that it is an octal ; digit. ; CHKDIG: CMPB .PCHAR,#'0 ; Is it < '0? BLO 10$ ; J if so. CMPB .PCHAR,#'7 ; Is it > '7? BLOS 20$ ; J if not. 10$: ADD #2,(SP) ; Reject the transition - not octal. 20$: RETURN ; And return to the caller. ; ; Routine 2: Check a UIC group or owner code to ensure that ; it is within range. ; CHKUIC: TST .PNUMH ; Reject if > 32767 or < -32768. BNE 10$ ; J if no good. CMP .PNUMB,#377 ; Is it > 377? BLOS 20$ ; J if not. 10$: ADD #2,(SP) ; Reject the transition - not legal. 20$: RETURN ; And return to the caller. ; ; Routine 3: Check that the output file does not have any ; wild cards in it. ; CHKOUT: TST WLDFLG ; Wild cards present? BEQ 10$ ; J if not. ADD #2,(SP) ; Reject the transition if so. RETURN ; And return to the caller. 10$: CALL UPCASE ; Uppercase the current argument. RETURN ; and return to the caller. ; ; Routine 4: Check that the character matched is alphanumeric. ; The $ALPHA operator cannot be used because it ; does not recognise the lower case letters as ; alphabetic. ; CHKALF: CMPB .PCHAR,#'0 ; Is it < '0? BLO 10$ ; J if so - not a number or letter. CMPB .PCHAR,#'9 ; Is it <= '9? BLOS 20$ ; J if so - is a number. CMPB .PCHAR,#'A ; Is it < 'A? BLO 10$ ; J if so - not a letter. CMPB .PCHAR,#'Z ; Is it <= 'Z? BLOS 20$ ; J if so - is a letter. CMPB .PCHAR,#'A+40 ; Is it < 'a? BLO 10$ ; J if so - not a letter. CMPB .PCHAR,#'Z+40 ; Is it <= 'z? BLOS 20$ ; J if so - is a letter. 10$: ADD #2,(SP) ; Not a letter - reject transition. 20$: RETURN ; And return to the caller. ; ; Routine 5: Check that the matched string is equal to "COUNT" ; This is necessary because keyword matching is ; not properly sensitive to case in TPARS. ; MATCNT: MOV #CNTSTR,R0 ; Point to the count string. BR MATKEY ; And join common code. ; ; Routine 6: Check that the matched sting is equal to "UPPER". ; This is necessary because keyword matching is ; not properly sensitive to case in TPARS. ; MATUPC: MOV #UPCSTR,R0 ; Point to the upper string. BR MATKEY ; And join common code. ; ; Routine 7: Check that the matched string is equal to "EXCEPT". ; This is necessary because keyword matching is ; not properly sensitive to case in TPARS. ; MATEXC: MOV #EXCSTR,R0 ; Point to the except string. BR MATKEY ; And join common code. ; ; Routine 8: Check that the matched string is equal to "FILES". ; This is necessary because keyword matching is ; not properly sensitive to case in TPARS. ; MATFIL: MOV #FILSTR,R0 ; Point to the files string. BR MATKEY ; And join common code. ; ; Routine 8a: Compare the keyword matched in TPARS with "OUTPUT". ; MATOUT: MOV #OUTSTR,R0 ; Point to /OUTPUT: string BR MATKEY ; And join common code. ; ; Routine 9: Compare the keyword matched in TPARS with that ; pointed to by (R0). The matching must be made ; without regard to case. ; MATKEY: MOV R3,-(SP) ; Save R3 MOV .PSTPT,R1 ; Get pointer to matched string. MOV .PSTCN,R2 ; Get count of matched string. BEQ 30$ ; J if nothing there. 10$: MOVB (R1)+,R3 ; Pick up character. BIC #177400,R3 ; Fixup R3 CMPB R3,#'A+40 ; > 'a? BLO 20$ ; J if not. CMPB R3,#'Z+40 ; < 'z? BHI 20$ ; J if not. BIC #40,R3 ; Fixup R3 20$: CMPB R3,(R0)+ ; Match? BNE 30$ ; J if not. SOB R2,10$ ; And loop. BR 40$ ; Success - end the lookup. 30$: ADD #2,2(SP) ; Reject the transition. 40$: MOV (SP)+,R3 ; Recover R3 RETURN .SBTTL Action routines for returning values. ; ; These action routines return values to the main line of GREP. ; ; Routine 0: Initialise switches. ; INISWS: CLR SWORD ; Clear switch word. RETURN ; And return to the caller. ; ; Routine 1: Initialise the parser. ; INIPAR: CLR DEVCNT ; Clear count of device string. CLR DEVPTR ; Clear pointer of device strng. CLR UICCNT ; Clear count of UIC string. CLR UICPTR ; Clear pointer of UIC string. CLR FILCNT ; Clear count of file string. CLR FILPTR ; Clear pointer of file string. CLR WLDFLG ; Clear wild cards flag. RETURN ; And return to the caller. ; ; Routine 2: Set search string ; SETSTR: MOV #STRBUF,R0 ; Point to the string to be set. MOV .PSTPT,R1 ; Point to the string to be moved. MOV .PSTCN,R2 ; Get the length of the string. BEQ 20$ ; J if null string. 10$: MOVB (R1)+,(R0)+ ; Move in the search string. SOB R2,10$ ; And loop. 20$: CLRB (R0)+ ; Terminate the string with a MOV .PSTCN,STRSIZ ; Set the character count anyway. RETURN ; And return to the caller. ; ; Routine 3: Set up strings for device name. ; GETDEV: MOV .PSTCN,DEVCNT ; Set count of characters. MOV .PSTPT,DEVPTR ; Set pointer to characters. RETURN ; And return. ; ; Routine 4: Set up strings for UIC. ; GETUIC: MOV .PSTCN,UICCNT ; Set count of characters. MOV .PSTPT,UICPTR ; Set pointer to UIC RETURN ; And return. ; ; Routine 5: Set up strings for file name. ; GETFIL: MOV .PSTCN,FILCNT ; Set count of characters. MOV .PSTPT,FILPTR ; Set pointer to file name. RETURN ; And return. ; ; Routine 6: Return output file name. ; SETOUT: MOV DEVCNT,OUTFIL ; Move the device length ... MOV DEVPTR,OUTFIL+2 ; Move the device pointer ... MOV UICCNT,OUTFIL+4 ; Move the UIC length ... MOV UICPTR,OUTFIL+6 ; Move the UIC pointer ... MOV FILCNT,OUTFIL+10 ; Move the file length ... MOV FILPTR,OUTFIL+12 ; Move the file pointer ... RETURN ; And return to the caller. ; ; Routine 7: Return input file name. ; SETINP: MOV DEVCNT,INPFIL ; Move the device length ... MOV DEVPTR,INPFIL+2 ; Move the device pointer ... MOV UICCNT,INPFIL+4 ; Move the UIC length ... MOV UICPTR,INPFIL+6 ; Move the UIC pointer ... MOV FILCNT,INPFIL+10 ; Move the file length ... MOV FILPTR,INPFIL+12 ; Move the file pointer ... TST WLDFLG ; Wild cards specified? BEQ 10$ ; J if not. BIS #SW.WLD,SWORD ; Indicate so to the main line if so. 10$: CALL UPCASE ; Raise the argument to upper case. RETURN ; And return to the caller. ; ; Routine 8: Raise the current subexpression to upper case. ; UPCASE: MOV .PSTPT,R0 ; Point to the current string MOV .PSTCN,R1 ; Get the count of the string. BEQ 20$ ; J if nothing there. 10$: CMPB (R0)+,#'A+40 ; Is it < 'a? BLO 15$ ; J if so - not lower case. CMPB -1(R0),#'Z+40 ; Is it > 'z? BHI 15$ ; J if so - not lower case. BICB #40,-1(R0) ; Convert to upper case. 15$: SOB R1,10$ ; And loop over the string. 20$: RETURN ; And return to the caller. .SBTTL Read/write area for action routines. .PSECT IDATA,RW,D ; ; This area holds local variables for the GREP parser. ; DEVCNT: .WORD 0 ; Device name count. DEVPTR: .WORD 0 ; Device name string. UICCNT: .WORD 0 ; UIC string count UICPTR: .WORD 0 ; UIC string pointer FILCNT: .WORD 0 ; File name string count FILPTR: .WORD 0 ; File name pointer. ; WLDFLG: .WORD 0 ; Wild cards present in filename. ; .PSECT PDATA,RO,D ; ; Pure data section. ; FILSTR: .ASCIZ "FILES" UPCSTR: .ASCIZ "UPPER" CNTSTR: .ASCIZ "COUNT" EXCSTR: .ASCIZ "EXCEPT" OUTSTR: .ASCIZ "OUTPUT" .EVEN .END