.TITLE CLIPRS -- PARSING TABLES/ROUTINES FOR "CLI" TASK .IDENT /010983/ .ENABL GBL .NLIST BEX .ENABL LC ; ;+ ;***** ; ; CLIPRS - Defines the table driven parser MACROS and action ; routines required to parse the CLI task command lines. ; ; CLI task command syntax: ; ; CLI /keyword=cliname ; ; Keywords: ; ELIM=cliname or ELIM=* ; INIT=cliname[/subkeyword(s)] ; Subkeywords: CPR="string" ; DPR="string" ; LGO ; NULL ; PROMPT ; TASK=taskname ; SHOW ; SET[=TTnn:[cliname]] ; ;***** ; ; Update 1/9/83 -- PRS; original edit ; Update 4/10/84 -- PRS; add /NULL and /PROMPT switches to ; control handling of TTDRV and task exit prompting ; ;***** ;- ; .MCALL DIR$,QIOW$ CR=15 ; MISC ASCII CONSTANTS LF=12 BL=40 LT=74 GT=76 UA=136 .page ; ; *** TABLE DRIVEN PARSER DIRECTIVES ; .MCALL STATE$,TRAN$,ISTAT$ $RONLY=1 ; DEFINE TPARS .PSECT'S AS READ-ONLY ISTAT$ CLISTB,CLIKTB ; INIT THE PARSER ; STATE$ START ; INITIAL ENTRY POINT TRAN$ '/,SWITCH ; STUFF STARTS AT 1ST "/" TRAN$ $EOS,$EXIT ; HANDLE NULL LINES TRAN$ $ANY,START ; LOOP TILL SEE "/" OR $EOS ; STATE$ SWITCH ; PARSE KEYWORD TRAN$ "INIT",INISW,,CI.INI,$CIFLG TRAN$ "ELIM",ELISW,,CI.ELI,$CIFLG TRAN$ "SHOW",$EXIT,,CI.SHW,$CIFLG TRAN$ "SET",SETSW,,CI.SET,$CIFLG ; STATE$ ELISW ; PARSE /ELIM OPTIONS TRAN$ '= STATE$ TRAN$ '*,$EXIT ; "*" OPTION LEAVES "$CINAM" = 0 TRAN$ $RAD50,$EXIT,CLINAM ; ELSE, DEFINE "$CINAM" ; STATE$ SETSW ; PARSE /SET OPTIONS TRAN$ $EOS,$EXIT ; *** NEW, ALLOW "/SET" TRAN$ '= STATE$ TRAN$ $EOS,$EXIT ; *** NEW, ALLOW "/SET=" TRAN$ '*,$EXIT ; OR "/SET=*" TRAN$ $ALPHA,,SETDV1 ; DEFINE 1ST CHAR OF DEVICE NAME STATE$ TRAN$ $ALPHA,,SETDV2 ; DEFINE 2ND CHAR OF DEVICE NAME STATE$ TRAN$ $NUMBR,DEV,SETUNT ; DEFINE OPTIONAL UNIT # TRAN$ $LAMDA STATE$ DEV TRAN$ ':,,SETDFU ; REQUIRED TERMINATOR STATE$ TRAN$ $EOS,$EXIT ; ALL DONE ?? TRAN$ $RAD50,$EXIT,CLINAM ; NO, PICKUP CLI NAME AND EXIT ; STATE$ INISW ; PARSE /INIT OPTIONS TRAN$ '= STATE$ TRAN$ $RAD50,,CLINAM ; PICKUP CLI NAME ; STATE$ INISUB ; PARSE /INIT SUBKEYWORDS TRAN$ $EOS,$EXIT TRAN$ '/ ; CHECK FOR /INIT SUBKEYS STATE$ TRAN$ "CPR",CPRSW TRAN$ "DPR",DPRSW TRAN$ "LGO",INISUB,,CL.ILO,$CIFL2 TRAN$ "NULL",INISUB,,CL.INL,$CIFL2 TRAN$ "PROMPT",INISUB,,CL.IEX,$CIFL2 TRAN$ "TASK",TSKSW ; STATE$ CPRSW ; PARSE /CPR SWITCH TRAN$ '=,STRING,CPRSTR ; STATE$ DPRSW ; PARSE /DPR SWITCH TRAN$ '=,STRING,DPRSTR ; STATE$ STRING ; PARSE QUOTED STRING TRAN$ $ANY,,SETQ1 ; SETUP BY SAVING 1ST CHARACTER ; STATE$ STR1 ; PARSE OUT MACRO TYPE ".ASCII" SYNTAX TRAN$ LT,OCT ; HANDLE "<#>" SYNTAX TRAN$ $ANY,STR2,TESTQ1 ; ELSE, CHECK FOR END OF QUOTED STRING TRAN$ $LAMDA ; NEED DUMMY TRAN$ STATE$ ; AND NEW STATE TO TRAN$ $ANY,INISUB ; ABSORB TRAILING QUOTE CHAR ; STATE$ STR2 ; PARSING "/.../" SYNTAX TRAN$ !QSTRG2,,SETST ; 1ST CHAR DEFINES DELIMITING CHAR STATE$ ; AFTER !QSTRG2, NEED DUMMY TRAN$ TRAN$ $ANY,STR1 ; TO ABSORB TRAILING CHAR ; STATE$ OCT ; HANDLES OCTAL LITERAL IN "<>" TRAN$ $NUMBR,,SETN STATE$ TRAN$ GT,STR1 ; STATE$ QSTRG2 ; SUBEXPRESSION TO GET STRING DELIMITED TRAN$ $ANY,QSTRG2,TESTQ2 ; BY NESTED SET OF PAIRED DELIMITERS TRAN$ $LAMDA,$EXIT ; STATE$ TSKSW ; PARSE TASK NAME TRAN$ '= STATE$ TRAN$ $RAD50,INISUB,TSKNAM ; STATE$ ; END-OF-TABLE .PAGE ; ; *** LOCAL DATA/DIRECTIVES ; .PSECT $PDATA,RO,D,LCL,CON,REL EM1: ; ERROR MESSAGE DEFN .ASCII /CLI -- Syntax error:/ L.EM1=.-EM1 .EVEN .PSECT $IDATA,RW,D,LCL,CON,REL QSTRST: .WORD 0 ; POINTS TO START OF BUFFER FOR /CPR, /DPR QSTRPT: .WORD 0 ; UPDATED POINTER FOR BUILDING /CPR, /DPR QCHAR1: .BYTE 0 ; CHARACTER DELIMITING ENTIRE /CPR, /DPR STRING QCHAR2: .BYTE 0 ; CHARACTER DELIMITING ASCII STRINGS WITHIN ; /CPR, /DPR SWITCH ERRQIO: ; ERROR REPORT QIO QIOW$ IO.WVB,TI$LUN,TI$EFN,,,,<,,40> .PAGE .PSECT $PCODE,RO,I,LCL,CON,REL ; .CIPRS:: ; GLOBAL ENTRY POINT FOR CLI TASK PARSER CLR $CIFLG ; CLEAR FLAGS WORD CLR $CIFL2 CLR $CINAM ; CLEAR CLI'S NAME CLR $CINAM+2 CLR $CITSK ; CLEAR TASK'S NAME CLR $CITSK+2 CLR $CIDEV ; CLEAR TERMINAL DEVICE NAME MOV #-1,$CIUNT ; SETUP SPECIAL UNIT # MOV #1000,R1 ; IGNORE BLANKS-2CHAR ABBR. ALLOWED MOV #CLIKTB,R2 ; KEYWORD TABLE ADDRESS MOV #$CIMCR,R4 ; PICKUP START OF MCR BUFFER SPACE MOV (R4)+,R3 ; DEFINE # WORDS & START OF BUFFER PROPER MOV #START,R5 ; START ADDRESS OF 1ST TPARS STATE CALL .TPARS ; CALL THE PARSER BCS 30$ ; BRANCH ON SYNTAX ERROR TST $CITSK ; TASK NAME SUPPLIED ?? BNE 50$ ; YES, RETURN WITH CARRY CLEAR MOV $CINAM,$CITSK ; ELSE, FORCE DEFAULT FOR /INIT OPTION MOV $CINAM+2,$CITSK+2 BR 50$ ; AND RETURN WITH CARRY CLEAR 30$: MOV #EM1,ERRQIO+Q.IOPL ; DEFINE START ADDR MOV #L.EM1,ERRQIO+Q.IOPL+2 ; AND LENGTH OF ERROR MESSAGE DIR$ #ERRQIO ; SEND IT TO TI: MOV #$CIMCR,R0 ; PICKUP COMMAND LINE DEFN MOV (R0)+,R1 ; FETCH LENGTH OF LINE MOV R0,R2 ; COPY START ADDRESS OF LINE MOV R0,ERRQIO+Q.IOPL ; DEFINE START ADDR MOV R1,ERRQIO+Q.IOPL+2 ; AND LENGTH FOR QIO DIR$ #ERRQIO ; ECHO OFFENDING COMMAND LINE SUB R3,R1 ; COMPUTE # CHARS CORRECTLY PARSED 40$: MOVB #BL,(R0)+ ; BLANK OUT ALL VALID FIELDS SOB R1,40$ MOVB #UA,(R0)+ ; POINT TO OFFENDING FIELD SUB R2,R0 ; REDEFINE LENGTH OF STRING MOV R0,ERRQIO+Q.IOPL+2 ; AND PUT IT IN QIO DIR$ #ERRQIO ; SEND IT TO TI: SEC ; SHOW PROBLEMS IN CARRY BIT 50$: RETURN ; RETURN WITH CARRY = SUCCESS/FAILURE .PAGE ; ; *** LOCAL ACTION ROUTINES CALLED BY TPARS ; .ENABL LSB CLINAM: ; ACCESSORY ROUTINE TO DEFINE CLI NAME MOV #$CINAM,-(SP) ; PUSH ADDRESS OF NAME TO DEFINE BIT #CI.INI,$CIFLG ; IS THIS THE /INIT OPTION ?? BEQ 20$ ; BRANCH IF NO MOV #$CICPR,R0 ; GET PLACE TO DEFINE CTRL-C PROMPT MOV #3,(R0) ; SETUP LEADIN/TRAILER LENGTH MOV .PSTCN,R2 ; PICKUP LENGTH OF CLI NAME STRING ADD R2,(R0)+ ; ADD IT TO LEADIN/TRAILER COUNT MOV #LF*400!CR,(R0)+ ; LEADIN = CR/LF MOV .PSTPT,R1 ; GET START ADDRESS OF CLI NAME 8$: MOVB (R1)+,(R0)+ ; COPY ASCII NAME SOB R2,8$ MOVB #GT,(R0)+ ; TRAILER = ">" CLRB (R0) ; MAKE IT ASCIZ MOV #$CIDPR,R0 ; FILL IN DEFAULT PROMPT MOV #3,(R0)+ ; HAS JUST LEADIN/TRAILER MOV #LF*400!CR,(R0)+ ; LEADIN = CR/LF MOV #GT,(R0) ; TRAILER = >/NULL BR 20$ ; PICKUP WITH CONVERSION ROUTINES TSKNAM: ; ACCESSORY ROUTINE TO DEFINE CLI'S TASK NAME MOV #$CITSK,-(SP) ; PUSH ADDRESS OF NAME TO DEFINE 20$: MOV .PSTPT,R0 ; PICKUP ADDRESS OF CLI NAME STRING MOV #1,R1 ; ALLOW "." IN NAME CALL $CAT5 ; CONVERT 3 CHARS TO RAD50 MOV R1,@(SP) ; DEFINE 1ST HALF OF NAME BCC 10$ ; BRANCH IF MORE TO DO TST (SP)+ ; ALIGN STACK RETURN ; RETURN TO TPARS 10$: MOV #1,R1 ; ALLOW "." IN NAME CALL $CAT5 ; CONVERT 3 CHARS TO RAD50 MOV (SP)+,R0 ; RECOVER ADDRESS OF NAME MOV R1,2(R0) ; DEFINE 2ND HALF OF NAME RETURN ; RETURN TO TPARS .DSABL LSB ; SETDV1: ; ACCESSORY ROUTINES TO DEFINE TERMINAL DEVICE MOVB .PCHAR,$CIDEV ; SAVE 1ST CHARACTER OF DEVICE RETURN SETDV2: MOVB .PCHAR,$CIDEV+1 ; SAVE 2ND CHARACTER OF DEVICE RETURN SETUNT: MOV .PNUMB,$CIUNT ; DEFINE DEVICE UNIT # RETURN SETDFU: TST $CIUNT ; DEVICE UNIT # DEFINED YET ?? BGE 4$ ; BRANCH IF YES, LEAVE IT CLR $CIUNT ; ELSE, DEFAULT IT TO 0 4$: RETURN ; .ENABL LSB CPRSTR: ; SETUP ROUTINES FOR CTRL-C PROMPTS MOV #$CICPR+2,R0 ; DEFINE PLACE TO BUILD STRING BR 4$ DPRSTR: MOV #$CIDPR+2,R0 ; DEFINE PLACE TO BUILD STRING 4$: MOV R0,QSTRST ; DEFINE START OF STRING POINTER MOV R0,QSTRPT ; AND POINTER TO USE BUILDING STRING RETURN .DSABL LSB ; SETQ1: MOVB .PCHAR,QCHAR1 ; DEFINE CHARACTER ENDING /CPR, /DPR INCB .PFLAG ; DISABLE SPACE SUPPRESSION RETURN ; SETN: MOV QSTRPT,R0 ; PICKUP CURRENT POINTER MOVB .PNUMB,(R0)+ ; SAVE OCTAL EQUIVALENT MOV R0,QSTRPT ; UPDATE CURRENT POINTER RETURN ; SETST: MOV QSTRPT,R0 ; PICKUP CURRENT POINTER MOV .PSTPT,R1 ; AND POINTER TO START OF ASCII STRING MOV .PSTCN,R2 ; GET CHARACTER COUNT 4$: MOVB (R1)+,(R0)+ ; COPY STRING SOB R2,4$ MOV R0,QSTRPT ; UPDATE POINTER RETURN ; TESTQ1: CMPB .PCHAR,QCHAR1 ; FOUND END OF ENTIRE /CPR, /DPR SWITCH BEQ 4$ ; BRANCH IF YES MOVB .PCHAR,QCHAR2 ; ELSE, ITS START OF ASCII STRING RETURN 4$: MOV QSTRPT,R0 ; PICKUP CURRENT POINTER CLRB (R0) ; MAKE IT ASCIZ MOV QSTRST,R1 ; PICKUP START POINTER SUB R1,R0 ; DETERMINE BYTE COUNT MOV R0,-(R1) ; AND SAVE IT AT HEAD OF STRING ADD #2,(SP) ; REJECT TRAN$ TO NEXT STATE RETURN ; TESTQ2: CMPB .PCHAR,QCHAR2 ; CHECK FOR END OF ASCII STRING BNE 4$ ; BRANCH IF NOT FOUND ADD #2,(SP) ; ELSE, REJECT TRAN$ TO NEXT STATE 4$: RETURN ; RESET: DECB .PFLAG ; RESTORE SPACE SUPPRESSION RETURN .END