.TITLE PARSE .SBTTL HANDLE PARAMETER PARSING FOR CCL V8.0/9.0 .IDENT /23MAR83/ .ENABL GBL .ENABL LC .NLIST BEX ; ;+ ;***** ; ; PARSE.MAC - CONTAINS 5 MAJOR SUBROUTINES TO HANDLE THE PARSING ; OF A MCR/CLI COMMAND LINE. MOST VARIABLES ARE GLOBALLY DEFINED ; IN "CCL.MAC". ; ; EXTERNAL ENTRY POINTS: ; ; DEFDEL - DEFINES THE COMMAND PARAMETER DELIMITERS. CALLED TO SET ; DEFAULT DELIMITERS EACH TIME A NEW FILE/TABLE OPENED, AND ; WHEN A "CHANGE PARAMETER DELIMITERS" LINE IS ENCOUNTERED ; IN A CCL FILE/TABLE. ; SAVDEL - SAVES THE CURRENT DELIMITER/KEYWORD DEFINITION ; PRIOR TO MAKING A TEMPORARY CHANGE IN PARSING SENSE. ; RSTDEL - RESTORES THE PARSING AND DELIMITER/KEYWORD CONTEXT ; IN EFFECT PRIOR TO LAST CALL TO "DEFDEL", E.G. SAVED BY ; "SAVDEL" ; DEFKEY - DEFINES KEYWORD START ADDRESS AND LENGTH ACCORDING TO ; CURRENT DEFINITION OF KEYWORD DELIMITERS ; DEFPRM - DEFINES PARAMETER START ADDRESSES AND LENGTHS ACCORDING ; TO CURRENT DEFINITION OF PARAMETER DELIMITERS. ALSO PROMPTS ; FOR REQUIRED BUT UNDEFINED INFORMATION. ; ; ; UPDATES: ; PRS01 March, 1983 -- Make CCL V8 vs. V9 parsing more ; compatible. V9 will now define %B% ; and %C%. ;***** ;- ; ; LOCAL SYMBOLS/DATA ; .MCALL QIOW$S ; SPA = 40 ;ASCII SPACE LANGLE = 74 ;ASCII "<" EQUAL = 75 ;ASCII "=" UNDSCR = 137 ;ASCII "_" SWTCH = 57 ;ASCII "/" COMMA = 54 ;ASCII "," CR = 15 QNMRK = 77 ;ASCII "?" STAR = 52 ;ASCII "*" ; .PSECT $IDATA,RW,D,CON,LCL,REL ; ; IOSTS: .BLKW 2 ; Status block for prompting (QIO IO.RPR) SAVPTR: .BLKW 1 ; Address of previous delimiter/keyword context ;PRS01 DEL1: .BLKW 1 ; Pointer to 1st delimiter string DEL2: .BLKW 1 ; Pointer to 2nd delimiter string DEL3: .BLKW 1 ; Pointer to 3rd delimiter string DEL4: .BLKW 1 ; Pointer to 4th delimiter string NPRM: .BLKW 1 ; Counter for # of parameters found .PSECT $PDATA,RO,D,LCL,CON,REL ; ; DEFINE DEFAULT PARSING DELIMITER STRINGS 1-4 ; S1LST: S3LST: .BYTE SPA,0 ;KEYWORD FIELD AND MAJOR COMMAND FIELD ; SEPARATORS, E.G. SPLIT %B% AND %C% IN V8 ; CONTEXT OR %1%-%9% IN V9 CONTEXT S2LST: .BYTE SWTCH,SPA,0 ;KEYWORD FIELD SUBEXPRESSION E.G. %0% ; DELIMITERS + ALL VALID KEYWORD DELIMITERS ; .IF EQ DEFPRS ;SET DEFAULTS FOR OLD V8.0 PARAMETER PARSING S4LST: .BYTE SPA,EQUAL,LANGLE,UNDSCR,COMMA,0 ;VALID %1%-%9% DELIMITERS ; .IFF ;SET DEFAULTS FOR NEW V9.0 PARAMETER PARSING S4LST: .BYTE COMMA,SPA,0 ;ALPHABETIC SUBEXPRESSION DELIMITERS, E.G. ; %1a% DELIMETERS. ; .ENDC ;DEFPRS MSG1: .ASCIZ %CCL -- Required prompt missing prior to :% MSG2: .ASCIZ %CCL -- Bad "change delimiters line" format :% .EVEN PAIRS: ;DEFINE SETS OF MATCHING CHARACTERS THAT WILL SUSPEND ; SCANNING FOR A DELIMITER UNTIL CLOSING (MATCHING) ; CHARACTER IS ENCOUNTERED. .BYTE '[,'] ;SKIP SCAN WHEN IN UIC FIELD .BYTE '",'" ; AND IN QUOTED STRING .BYTE 0,0 ;DOUBLE NULL TERMINATES LIST ; .PSECT $CODE1,RO,I,LCL,CON,REL ; ;+ ;***** ; ; DEFDEL - REDEFINES VALID DELIMITERS SEPARATING COMMAND PARAMETERS. ; A COMMAND IS CONSIDERED AS HAVING TWO MAJOR FIELDS; 1) KEYWORD ; FIELD INCLUDES THE KEYWORD AND ALL KEYWORD QUALIFIERS, E.G. ; "BRU/REW", AND 2) COMMAND FIELD WHICH INCLUDES EVERYTHING NOT ; IN THE KEYWORD FIELD. NOTE: A SPECIAL PARAMETER "%A%" MAY ; INCLUDE PART OF THE KEYWORD FIELD IF A KEYWORD QUALIFIER WAS ; FOUND IN THE KEYWORD FIELD. ; ; DEFINE COMMAND DELIMITERS LINE IN CCL FILE/TABLE FORMAT: ; ; XX ; WHERE: ; XX - SELECTS PARSING STYLE (V8/OLD OR V9/NEW). THE ; CALLER FLUSHES OUT "XX" AND BEHAVES ACCORDINGLY, ; "DEFDEL" WILL BE PASSED A POINTER TO THE 1ST "<" ; IN THE LINE. XX MAY BE EITHER "~" WHICH SELECTS ; V8 PARSING, OR "^" WHICH SELECTS V9 PARSING. ; A SINGLE CHARACTER MAKES THE CHANGE TEMPORARY ; WHILE 2 IDENTICAL CHARACTERS (^^ OR ~~) MAKE THE ; CHANGE PERMANENT. ; ; **** FOR THE NEW (V9.0) PARSING SYNTAX... ; ; STRING1 = ASCII STRING OF VALID DELIMITERS SEPARATING THE KEYWORD ; FIELD FROM THE REST OF THE COMMAND LINE. IT TERMINATES THE ; KEYWORD IF NO QUALIFIER IS PRESENT, OR TERMINATES THE QUALIFIER ; IF A KEYWORD QUALIFIER (E.G. "/SWITCH") IS PRESENT. ; DEFAULT = SPACE ; ; STRING2 = ASCII STRING OF VALID DELIMITERS SEPARATING THE ; KEYWORD FIELD INTO THE KEYWORD AND ANY QUALIFIERS OR THE REST ; OF THE COMMAND LINE. MUST (!!!) CONTAIN ALL STRING1 DELIMITERS ; PLUS THE KEYWORD QUALIFIER DELIMITER. DEFAULT = "/" OR SPACE ; ; STRING3 = ASCII STRING OF VALID DELIMITERS SEPARATING THE ; MAIN COMMAND INTO PARAMETERS WHICH WILL BE LABELED AS ; %1% - %9% IN ORDER OF THEIR APPEARANCE ON THE COMMAND LINE. ; NOTE: ALL RESPONSES TO PROMPT LINES WILL ALSO BE SCANNED AND ; SUBDIVIDED USING THESE DELIMITERS. DEFAULT = SPACE ; ; STRING4 = ASCII STRING OF VALID DELIMITERS WITHIN A MAIN COMMAND ; PARAMETER SEPARATING SUBPARAMETERS WHICH WILL BE LABELLED AS ; %Na% - %Nz% (N=1-9). MUST (!!!) CONTAIN ALL STRING3 DELIMITERS ; PLUS THE SUBEXPRESSION DELIMITERS. DEFAULT = "," OR SPACE. ; ; **** FOR THE OLD (V8.0 COMPATIBLE) PARSING SYNTAX... ; ; STRING1 = ASCII STRING OF VALID DELIMITERS SEPARATING THE KEYWORD ; FIELD FROM THE REST OF THE COMMAND LINE. IT TERMINATES THE ; KEYWORD IF NO QUALIFIER IS PRESENT, OR TERMINATES THE QUALIFIER ; IF A KEYWORD QUALIFIER (E.G. "/SWITCH") IS PRESENT. ; DEFAULT = SPACE ; ; STRING2 = ASCII STRING OF VALID DELIMITERS SEPARATING THE ; KEYWORD FIELD INTO THE KEYWORD AND ANY QUALIFIERS OR THE REST ; OF THE COMMAND LINE. MUST (!!!) CONTAIN ALL STRING1 DELIMITERS ; PLUS THE KEYWORD QUALIFIER DELIMITER. DEFAULT = "/" OR SPACE ; ; STRING3 = ASCII STRING OF VALID DELIMITERS SEPARATING THE ; MAIN COMMAND INTO THE MAIN PARAMETERS %B% AND %C%. ; DEFAULT = SPACE ; ; STRING4 = ASCII STRING OF VALID DELIMITERS SEPARATING PARAMETERS ; WHICH WILL BE LABELLED AS %1%-%9%. MUST (!!!) CONTAIN ALL STRING3 ; DELIMITERS PLUS ANY OTHER PARAMETER DELIMITERS NEEDED. ; DEFAULT = "," "=" "_" "<" OR SPACE. ; ; ; ; NOTE: "<" AND ">" CHARACTERS MUST ENCLOSE ALL STRINGS. "><" ; COMBINATION USED FOR SEPARATING THE 4 FIELDS, IF NEED BOTH ; "<" AND ">" DEFINED AS LITERALS MAKE SURE THEY APPEAR WITHIN ; THE "<..>" FIELD AS "<>". ALL DELIMITERS IN THE LINE ARE ; PLACED IN "P" ARRAY WORKSPACE !!! ; ;***** ; ; REGISTERS ON CALL: ; R0 - POINTS TO START OF NEW DELIMITER RECORD. IF 0, SETS UP ; THE DEFAULT (SET AT ASSEMBLY TIME) DELIMITER STRINGS. ; R1 - # BYTES IN RECORD ; ; REGISTERS ON RETURN: ; R0,R1,R2,R3 - DESTROYED !!! ; ;***** ;- ; DEFDEL:: ;(RE)DEFINE COMMAND DELIMITERS MOV #DEL1,R3 ;GET ADDRESS OF 4 WORD POINTER BLOCK TST R0 ;VALID RECORD POINTER ? BNE 2$ ;BRANCH IF YES, SETUP NEW DELIMITERS ;PRS01 ; MOVB #DEFPRS,PRSFLG ;SET PARSING STYLE TO ITS DEFAULT VALUE ;PRS01 CLR SAVPTR ;SHOW NO PREVIOUS CONTEXT SAVED ;PRS01 MOV #S1LST,(R3)+ ;SET ADDRESSES OF DEFAULT DELIMITER ;PRS01 MOV #S2LST,(R3)+ ; STRINGS ;PRS01 MOV #S3LST,(R3)+ ;PRS01 MOV #S4LST,(R3)+ ;PRS01 MOV #P,NEXTP ;SET STARTING POINT IN WORK SPACE ;PRS01 BR 29$ ;PRS01 ; 2$: MOV NEXTP,R2 ;PUT DELIMITERS INTO TEMPORARY WORKSPACE;PRS01 CMPB (R0),#'< ;VALID 1ST STRING LEAD CHARACTER ? ;PRS01 BNE 30$ ;BRANCH IF NO, TRAP ERROR ;PRS01 5$: DEC R1 ;ADJUST COUNT FOR "<" BLE 30$ ;BRANCH IF NOTHING LEFT ;PRS01 INC R0 ;ADJUST POINTER MOV R2,(R3)+ ;SET POINTER TO DELIMITER LIST 10$: MOVB (R0)+,(R2) ;COPY CHARACTER FROM RECORD CMPB (R2)+,#'> ;WAS IT END-OF-FIELD? BEQ 20$ ;BRANCH IF YES, MAY BE EOF SOB R1,10$ ;LOOP TO END-OF-FIELD OR END-OF-STRING ;PRS01 BR 30$ ;SHOULDN'T END UP HERE, TRAP ERROR ;PRS01 20$: DEC R1 ;ADJUST COUNT BLE 25$ ;BRANCH IF DONE ;PRS01 CMPB (R0),#'< ;START OF NEW FIELD NEXT ? BNE 10$ ;BRANCH IF NO, TAKE ">" AS LITERAL 25$: ;REF LABEL, MORE SYNTAX CHECKING ;PRS01 CLRB -1(R2) ;REPLACE ">" WITH NULL CMP R3,#DEL4 ;FILLED IN 4 DELIMITER STRINGS ? BLOS 5$ ;BRANCH IF NO, KEEP GOING ;PRS01 MOV R2,NEXTP ;DEFINE NEXT FREE SPOT IN "P" ;PRS01 29$: ;PRS01 RETURN ; RETURN TO CALLER ; ;*** ERROR TRAP ;PRS01 ; 30$: ; Bad line format... ;PRS01 MOV #MSG2,R0 ; Get address of error message ;PRS01 JMP LINERR ; Display error message and bad line ;PRS01 .PAGE ; ;+ ;***** ; ; SAVDEL - SAVES CURRENT PARSING CONTEXT BY PUSHING PERTINENT DATA ; INTO "P" WORKSPACE AND DEFINING "SAVPTR" TO POINT TO START OF ; SAVED DATA. ; ;***** ;- SAVDEL:: MOV R0,-(SP) ;SAVE R0 AND R1 MOV R1,-(SP) ; MOV NEXTP,R0 ;GET PLACE FOR SAVING CONTEXT INC R0 ;MAKE SURE ITS WORD ALIGNED BIC #1,R0 MOV #SAVPTR,R1 ;GET START OF BLOCK TO SAVE MOV R0,(R1)+ ;DEFINE START ADDRESS FOR RESTORE ROUTINE MOVB PRSFLG,(R0)+ ;SAVE CURRENT PARSING STYLE MOVB KEYL,(R0)+ ;SAVE LENGTH OF KEYWORD...CAN'T > 80., ; START ADDRESS WILL NOT CHANGE !!! MOV (R1)+,(R0)+ ;SAVE 4 DELIMITER POINTERS MOV (R1)+,(R0)+ MOV (R1)+,(R0)+ MOV (R1)+,(R0)+ MOV R0,NEXTP ;DEFINE NEW START OF WORKSPACE MOV (SP)+,R1 ;RESTORE R0 AND R1 MOV (SP)+,R0 RETURN ;RETURN TO CALLER ; ;+ ;***** ; ; RSTDEL - RESTORES PREVIOUS PARSING CONTEXT. ; ;***** ;- RSTDEL:: MOV R0,-(SP) ;SAVE R0 AND R1 MOV R1,-(SP) MOV #SAVPTR,R0 ;GET ADDRESS OF DATA BLOCK TO REDFINE MOV (R0),R1 ;GET START OF SAVED DATA IN "P" BEQ 10$ ;BRANCH IF 0, NOTHING TO RESTORE MOV R1,NEXTP ;RESET START OF WORKSPACE, NOTE: THIS WIPES ; OUT EVERYTHING IN "P" ADDED SINCE "SAVDEL" MOVB (R1)+,PRSFLG ;RESTORE PARSING STYLE MOVB (R1)+,KEYL ;RESTORE KEYWORD LENGTH CLR (R0)+ ;CLEAR OUT POINTER MOV (R1)+,(R0)+ ;RESTORE 4 DELIMITER POINTERS MOV (R1)+,(R0)+ MOV (R1)+,(R0)+ MOV (R1)+,(R0)+ 10$: MOV (SP)+,R1 ;RESTORE REGISTERS MOV (SP)+,R0 RETURN ;RETURN TO CALLER ; .PAGE ; ;+ ;***** ; ; DEFKEY - DEFINES KEYWORD ACCORDING TO CURRENT DELIMITERS @DEL1,DEL2. ; KEYWORD FIELD (KEYWORD+QUALIFIERS)ENDS AT 1ST DELIMITER IN LIST ; @DEL1. KEYWORD ENDS AT 1ST DELIMITER IN LIST @ DEL2. KEYWORD ; QUALIFIER (PARAMETER %0%) STARTS AT 1ST DELIMITER IN LIST @DEL2 ; AND ENDS WITH 1ST DELIMITER IN LIST @DEL1. BY DEFINITION, ; PARAMETER %A% WILL INCLUDE EVERYTHING IN COMMAND EXCEPT KEYWORD. ; ; REGISTERS ON RETURN: ; R0,R1,R2,R3 - DESTROYED !!! ; ; NOTE: IN CURRENT REVISION, AN EXTERNAL CALL TO DEFKEY WILL NOT ;PRS01 ; NORMALLY BE MADE...CHAINED TO BY "DEFDEL" ;PRS01 ;***** ;- DEFKEY:: ;DEFINE COMMAND KEYWORD MOV MCRB,R0 ;GET COMMAND START ADDRESS MOV MCRL,R1 ; AND LENGTH MOV #KEYL,R2 ;GET ADDRESS OF 2 WORD BLOCK TO DEFINE MOV DEL2,R3 ;GET ADDRESS OF VALID DELIMITERS CALL SCAN ;FIND KEYWORD MOV R0,PNTRA+2 ;CURRENT POINTER AND # CHARACTERS MOV R1,PNTRA ; LEFT IN COMMAND DEFINE %A% RETURN ;RETURN TO CALLER .PAGE ; ;+ ;***** ; ; DEFPRM - DEFINES CCL PARAMETERS IN COMMAND LINE. PARAMETERS ; ARE DEFINED AND REFERENCED BY A 2 WORD DEFINITION BLOCK ; CONSISTING OF: ; 1) LENGTH IN BYTES ; 2) START ADDRESS OF STRING ; ; **** NEW (V9.0) PARSING/PARAMETER DEFINITION.... ; ; THE STANDARD CCL PARAMETERS %1% - %9% WILL BE SCANNED FOR ; SUBEXPRESSIONS WITHIN THEIR STRING. THE PARAMETERS %1%- %9% ; ARE SEPARATED BY THE LOGICAL OR OF DELIMITERS IN LIST @DEL3. ; THE SUBEXPRESSIONS WITHIN %1% - %9% ARE SEPARATED BY THE ; LOGICAL OR OF DELIMITERS IN LIST @ DEL4. NOTE: ALL DELIMITERS ; IN LIST @DEL3 MUST ALSO BE IN LIST @DEL4. ; ; THIS NEW PARSING REQUIRED THE PARAMETER DEFINITION BLOCKS TO ; BE 4 WORDS LONG FOR EACH MAJOR PARAMETER (%1%-%9%): ; 1) LENGTH IN BYTES OF MAJOR PARAMETER ; 2) START ADDRESS OF STRING ; 3) # OF 2 WORD SUBEXPRESSION BLOCKS DEFINED ; 4) START ADDRESS OF 2 WORD SUBEXPRESSION DEFN. BLOCKS ; ; THE SUBEXPRESSION DEFINITION BLOCKS ARE ALLOCATED IN A CONTIGUOUS ; SECTION OF THE "P" ARRAY WORK SPACE, AND DEFINE THE LENGTH ; AND START ADDRESS OF THE SUBEXPRESSION. SUBEXPRESSIONS ARE ; REFERENCED BY A LOWER CASE CHARACTER FOLLOWING THE NUMERIC CHARACTER ; OF THE MAJOR PARAMETER BEING REFERENCED, E.G. %4c% WILL ; BE INTERPRETTED AS THE 3RD SUBEXPRESSION OF THE 4TH MAJOR ; COMMAND FIELD. ; ; AS AN EXAMPLE, USING SPACES FOR THE MAJOR DELIMITERS AND ; COMMAS AS THE SUBEXPRESSION DELIMITERS, THE COMMAND: ; CCL/QUALIFIER FILE1,FILE2 FILE3 FILE4/Q ; WILL RESULT IN: ; KEYWORD = CCL ; %0% = /QUALIFIER ; %A% = /QUALIFIER FILE1,FILE2 FILE3 FILE4/Q ; %1% = FILE1,FILE2 ; %1a% = FILE1 ; %1b% = FILE2 ; %2% = FILE3 ; %2a% = %2% ; %3% = FILE4/Q ; %3a% = %3% ; ; IN CONTRAST, CCL V8.0 PARSING WOULD SPLIT THE ABOVE COMMAND ; INTO: ; KEYWORD = CCL ; %0% = /QUALIFIER ; %A% = /QUALIFIER FILE1,FILE2 FILE3 FILE4/Q ; %B% = FILE1,FILE2 ; %C% = FILE3 FILE4/Q ; %1% = FILE1 ; %2% = FILE2 ; %3% = FILE3 ; %4% = FILE4/Q ; ; IF THE FIELD "FILE1,FILE2" MEANT THESE 2 PARAMETERS WERE ; MORE CLOSELY TIED TOGETHER THAN TO "FILE3" OR "FILE4", CCL V8.0 ; WOULD NOT PRESERVE THIS RELATIONSHIP. FURTHER, IF "FILE2" ; WERE OPTIONAL, AND SHOULD BE DEFAULTED TO A NON-NULL STRING, CCL V8.0 ; COULD NOT HANDLE THE REGENERATION OF THE COMMAND LINE SINCE ; %2% WOULD BECOME "FILE3" IF ",FILE2" WERE LEFT OUT. ; THIS PROBLEM WAS THE MAJOR IMPETUS FOR REDEFINING THE PARAMETER ; PARSING IN CCL V9.0. ;***** ; ; PRS01 -- TO MAKE V9.0 PARSING MORE COMPATIBLE WITH V8.0 DEFINITIONS, ; %B% AND %C% WILL BE DEFINED. %B% IS EQUIVALENT TO %1%; ; WHILE %C% IS EQUIVALENT TO %2%-%9%. ALSO, ALL PARSING ; WILL BE DONE IN V9.0 SENSE, THEN CONVERTED TO V8.0 SENSE ; IF SO DIRECTED BY THE BYTE FLAG "PRSFLG" (0=USE V8 SENSE). ; ; V8 PARSING ASSIGNS %1%- %9% TO EACH SUBFIELD PARSED USING ; THE V9 RULES. THESE SUBFIELDS WERE ALLOCATED FROM THE FREE ; WORK SPACE @"P", AND WILL OVERWRITE THE V9 DEFINITIONS OF %1%- ; %9% PRIOR TO CHECKING FOR UNDEFINED PARAMETERS. ; ; SPECIAL NOTE: V9 PARSING RESCANS ALL INPUT FROM PROMPT LINES, ; V8 PARSING DOES NOT !!! ; ;***** ; ; REGISTERS ON RETURN: ; R0-R5 DESTROYED !!! ; ;***** ;- DEFPRM:: ; Define command parameters CLR NPRM ; Show no parameters yet MOV PNTRA+2,R0 ; Fetch %A% start address MOV PNTRA,R1 ; and length BEQ DONE ; Branch if nothing there ; ; *** Flush out any qualifiers after keyword => parameter 0 ; MOV #PNTR0,R2 ; Fetch address of %0% defn block MOV DEL1,R3 ; Fetch address of %0% delimiters CALL SCAN ; Find %0% DEC R1 ; Step over delimiter BLE DONE ; Branch if nothing left INC R0 ; else, update pointer ; ; *** Flush out major command sections => parameters %1% - %9% ; *** by scanning for all subexpression delimiters currently in effect. ; MOV #PNTR1,R5 ; Major command sections are %1% - %9% ; START: MOV NEXTP,R2 ; Fetch place to build subexp. defn. blocks INC R2 ; Force it to word boundary BIC #1,R2 MOV R2,NEXTP ; Save it for later ;PRS01 MOV DEL4,R3 ; Fetch address of subexp. delimiters 20$: MOV R0,2(R5) ; Define major section's start address CLR 4(R5) ; Show no subexpressions yet MOV R2,6(R5) ; Define address of subexp. defn blocks 23$: CALL SCAN ; Find delimiter ADD #4,R2 ; Step to next 2 word block to fill in INC 4(R5) ; Show 1 more subexp. defined DEC R1 ; Adjust # bytes left BLE 30$ ; Branch if nothing left MOV DEL3,R4 ; Check for major delimiter 27$: CMPB (R4),(R0) ; Hit major field delimiter too ? BEQ 30$ ; Branch if yes, finish up TSTB (R4)+ ; End-of-list ? BNE 27$ ; Loop til done INC R0 ; Step pointer over delimiter BR 23$ ; and continue scanning ; ; *** Hit a major field delimiter ; 30$: ; Finish defining the 4 word defn. block MOV R0,(R5)+ ; Save current pointer SUB (R5),-(R5) ; and compute length of major field INC R0 ; Step pointer over delimiter ;PRS01 ; ;PRS01 ;+++++ ;PRS01 ; THIS SECTION MAINTAINS COMPATIBILITY WITH V8.0, SUPPORT MAY ;PRS01 ; BE DROPPED IN THE FUTURE... ;PRS01 ; Under V9, define %B% and %C% in same sense as V8 parsing ;PRS01 ; ;PRS01 TST NPRM ; Defined anything yet ? ;PRS01 BNE 35$ ; Branch if yes ;PRS01 MOV (R5),PNTRB ; Define %B%... ;PRS01 MOV 2(R5),PNTRB+2 ;PRS01 MOV R1,PNTRC ; ...and %C% is everything left ;PRS01 MOV R0,PNTRC+2 ;PRS01 35$: ; Reference label ;PRS01 ; ;PRS01 ;----- ;PRS01 ; INC NPRM ; Show 1 more parameter defined ADD #8.,R5 ; Step to next parameter block CMP R5,#PNTR9 ; Defined last parameter ? BHI 40$ ; Branch if yes, ignore rest TST R1 ; Check if anything left BGT 20$ ; Branch if yes, define next parameter ; ; *** All parameter blocks have been defined... ; 40$: TSTB PRSFLG ; Check parsing flag ;PRS01 BNE 48$ ; Branch if under V9 parsing, all done ;PRS01 ; ; *** Under V8 parsing rules, all V9 subfields are V8 parameters %1%-%9% ; MOV NEXTP,R0 ; Fetch start of subfield defn blocks ;PRS01 MOV #PNTR1,R1 ; and %n% defn blocks ;PRS01 SUB R0,R2 ; Determine # subfields defined... ;PRS01 ASR R2 ; 2 words long ;PRS01 BLE 49$ ; Branch if nothing there ;PRS01 CMP R2,#9. ; Check if have more than 9 fields ;PRS01 BLE 45$ ; Branch if yes, okay ;PRS01 MOV #9.,R2 ; Else, set limit to 9 ;PRS01 45$: MOV (R0)+,(R1)+ ; Copy field definition to %n% ;PRS01 MOV (R0)+,(R1)+ ;PRS01 ADD #4,R1 ; Adjust offset, %n% blocks are 4 words ;PRS01 SOB R2,45$ ; Loop til done ;PRS01 BR 49$ ; Don't need stuff in "P" anymore ;PRS01 ; 48$: MOV R2,NEXTP ; Save new start of free space 49$: ; Reference label ;PRS01 ; ; *** Now, prompt for all required parameters not defined ; *** NOTE: V9.0 parsing scans all responses for multiple parameters. ; *** Also, minimum # parameters must be ; Issue prompt CMPB IOSTS,#IS.SUC ; Check QIO error status BNE 40$ ; Branch on error CMP IOSTS,#IS.CR ; Check for return BNE 40$ ; Branch if not termination MOV IOSTS+2,R1 ; Fetch byte count for parameter just read in ADD R1,NEXTP ; Define next available spot in P array MOV R1,(R5) ; For V8, define parameter's length ;PRS01 MOV R0,2(R5) ; and start address ;PRS01 ; NOTE: V9 parsing will redefine these ;PRS01 TSTB PRSFLG ; Check if using V9 parsing ;PRS01 BNE 35$ ; Branch if yes ;PRS01 INC NPRM ; Show 1 more defined BR DONE ; Check if done ; ;PRS01 ;+++++ ;PRS01 ; THIS SECTION MAINTAINS COMPATIBILITY WITH V8.0, SUPPORT MAY ;PRS01 ; BE DROPPED IN THE FUTURE... ;PRS01 ; Under V9, all responses will be reparsed to identify additional ;PRS01 ; parameters that may have been included in the response. ;PRS01 ; Prompting for %A%-%C% has been retained for compatibility ;PRS01 ; with V8, %B% is roughly = to %1%, %C% = %2%, therefore ;PRS01 ; convert prompts for %A% and %B% as request for %1%, prompts ;PRS01 ; for %C% as request for %2%. Then, go back and reparse ;PRS01 ; the response for any other parameters. V9 only behaves ;PRS01 ; if prompts for parameters appear in order !!!! ;PRS01 ; ;PRS01 35$: CMP R5,#PNTRC ; Defined %C% ? ;PRS01 BHI 39$ ; If HI, must be %1%-%9%...normal ;PRS01 BLO 38$ ; If LO, must be %A%-%B%...change to %1%;PRS01 MOV #PNTR2,R5 ; %C% => %2% ;PRS01 MOV #1,NPRM ; Force %1% to have been defined... ;PRS01 BR 39$ ; preventing parser from redefining %C%;PRS01 38$: MOV #PNTR1,R5 ; %A%-%B% => %1% ;PRS01 39$: ; Under V9 rules... ;PRS01 JMP START ; ...scan response for parameters ;PRS01 ; ;PRS01 ;----- ;PRS01 ; ; ; Something went wrong on read after prompt, set severe exit ; status and leave. ; 40$: JMP ERROR ; .PAGE .SBTTL LOCAL SUBROUTINES ; ;+ ;***** ; ; SCAN LOOKS FOR MATCHING DELIMITER IN MASTER STRING AND FILLS IN A ; 2 WORD INFORMATION BLOCK (LENGTH, START ADDRESS) ; ; REGISTERS REQ. WHEN CALLED: ; R0 - POINTS TO STRING TO SCAN FOR DELIMITER ; R1 - LENGTH OF STRING...END-OF-STRING ALWAYS CONSIDERED A VALID ; DELIMITER ; R2 - POINTS TO 2 WORD INFO BLOCK TO FILL IN WITH LENGTH OF STRING ; AND START ADDRESS OF STRING PRECEEDING DELIMITER ; R3 - POINTS TO ASCIZ LIST OF VALID CHARACTER DELIMITERS ; ; REGISTERS ON RETURN: ; R0 - POINTS TO DELIMITER OR PAST END-OF-STRING ; R1 - SET TO # CHARACTERS LEFT IN STRING ; R2 - UNALTERED, INFO BLOCK @ R2 DEFINED ; R3 - UNALTERED ;***** ;- SCAN: ;ENTRY POINT MOV R0,2(R2) ;SAVE START ADDRESS INTO INFO BLOCK MOV R2,-(SP) ;SAVE POINTER TO INFO BLOCK MOV R3,-(SP) ;SAVE ADDRESS OF LIST OF DELIMITERS TST R1 ;CHECK FOR # CHARS IN STRING BLE 26$ ;BRANCH ON NONSENSE CALL 2$: MOVB (R0)+,R2 ;GRAB CHARACTER FROM STRING ; ; LOOK FOR VALID DELIMITER IN STRING (END-OF-STRING IS ALWAYS VALID DELIMITER) ; 5$: CMPB R2,(R3) ;VALID DELIMITER ? BEQ 25$ ;BRANCH IF YES, ALL DONE TSTB (R3)+ ;HIT END OF DELIMITERS LIST ? BNE 5$ ;BRANCH IF NO, CONTINUE ; ; LOOK FOR ANY SPECIAL FIELDS ENCLOSED BY CHARACTER PAIR, E.G. "[..]" ; MOV #PAIRS,R3 ;FETCH LIST OF MATCHED CHARACTER PAIRS 10$: CMPB R2,(R3)+ ;IN SPECIAL STRING ? BEQ 15$ ;BRANCH IF YES, SUSPEND DELIMITER SCAN TSTB (R3)+ ;HIT END OF MATCHED PAIRS LIST ? BNE 10$ ;BRANCH IF NO, CONTINUE BR 20$ ;BRANCH TO TRY AGAIN ; ; INSIDE SPECIAL FIELD, SUSPEND DELIMITER SCAN UNTIL SEE CLOSING CHARACTER ; 15$: DEC R1 ;SHOW 1 LESS CHARACTER TO SCAN BLE 26$ ;BRANCH IF AT END-OF-STRING CMPB (R0)+,(R3) ;HIT 2ND CHARACTER IN PAIR ? BNE 15$ ;BRANCH IF NO, KEEP LOOKING ; 20$: DEC R1 ;SHOW 1 LESS CHARACTER TO SCAN BLE 26$ ;BRANCH IF AT END-OF-STRING MOV (SP),R3 ;RECOVER START OF DELIMITERS LIST BR 2$ ; AND CHECK AGAIN ; ; HIT VALID DELIMITER OR END-OF-LINE, RETURN UPDATED R0 POINTER, R1 COUNT ; AND FILL IN 2 WORD BLOCK = # CHARACTERS PRECEEDING DELIMITER, START ADDRS. ; 25$: ;MATCHED DELIMITER DEC R0 ; STEP POINTER BACK TO DELIMITER 26$: ;HIT END-OF-STRING MOV (SP)+,R3 ;RESTORE REGISTERS MOV (SP)+,R2 MOV R0,(R2)+ ;COMPUTE LENGTH OF STRING PRECEEDING DELIMITER SUB (R2),-(R2) ; RETURN ; AND RETURN TO CALLER ; .END