.TITLE CSI - COMMAND SYNTAX INTERPRETER .IDENT /12APR8/ ;MK ; .ENTRY CSI - COMMAND SYNTAX INTERPRETER ; ;+ ; C S I S U B R O U T I N E S ; PROGRAM NAMES - CSI, CSISW, CSIVAL, CSIGO ; ; ; PURPOSE: CSI WILL EXAMINE A STRING OF CHARACTERS IN RSX ; COMMAND LINE FORMAT AND RETURN INDICES POINTING ; TO THE MAJOR COMPONENTS OF THE STRING. SWITCHES ; AND SWITCH VALUES MAY ALSO BE DETECTED AND DECODED. ; THE CSI PACKAGE CONTAINS MULTIPLE ENTRY POINTS. ; EACH WILL BE DISCUSSED SEPARATELY. ; ; INTERFACE: CALLING SEQUENCE: (FORTRAN-CALLABLE SUBROUTINE) ; CALL CSI ; CALL CSISW ; CALL CSIVAL ; CALL CSIGO ; ; LANGUAGE: MACRO-11 ; ; RESTRICTIONS: CSI MUST BE CALLED TO INITIALIZE THE PACKAGE WHETHER ; ANY OF THE RETURNS ARE UTILIZED OR NOT. NO DATA IS ; RETURNED UNTIL CSIGO IS CALLED. ; ; ;- ; REVISIONS: ; APR-75 RK WRITTEN ; 10-JUL-75 RK MADE 3RD PARAM OF CSISW DEFAULTABLE, ; AND UPGRADED DOCUMENTATION. ; 14-JUL-75 RK FIXED SCREW-UP IN DEFAULTING 3RD PARAM. ; 16-DEC-75 RK UPGRADED TO USE V6 FEATURES. ; 10-MAR-76 RK CORRECTED SETTING OF "EQUAL" PARAMETER, ; AND USED READ-ONLY AREAS. ; 29-MAR-76 MK COMMENTED OUT F4P PSECTS. FIXED SETTING OF ; FLAGS AND TESTING FOR ARGUMENTS PRESENT. ; 02-SEP-76 SS DEFINE SPECIAL MACROS LOCALLY. ; MAKE RSX-11M COMPATIBLE ; 20-JAN-77 NS REMOVE SPECIAL MACRO DEFINITIONS. ; PREFIX FILE HANDLES IT. ; 04-MAY-77 LV UPDATED TO CONFORM TO STANDARDS ; 12-APR-78 MK ADD LINE COMPRESSION BEFORE CALLING CSI1 ; TO PREVENT SYNTAX ERRORS WHEN SCANNING ; RT SIDE OF EQUAL SIGN ; .SBTTL MACROS-- ; ; .MCALL CSI$ .MCALL PUSH,POP,CALL .MCALL DIR$,EXIT$S,WTSE$S,QIO$ ; ; .MACRO WRITE,BUFFER,LENGTH,?L MOV BUFFER,QIO+Q.IOPL MOV LENGTH,QIO+Q.IOPL+2 DIR$ #QIO BCS L WTSE$S #EF L: .ENDM WRITE ; ; THE GETARG MACRO MOVES AN ARGUMENT ADDRESS FROM A1 TO A2. ; IF THE ADDRESS IS -1 (NULL ARG) IT BRANCHES TO B. ; .MACRO GETARG A1,A2,B MOV A1,A2 CMP A2,#-1 BEQ B .ENDM GETARG ; ; .MACRO .DATAB N,CHAR .REPT N .BYTE CHAR .ENDR .ENDM .DATAB ; .MACRO .DATAW N,DATA .REPT N .WORD DATA .ENDR .ENDM .DATAW ; .SBTTL SYMBOL DEFINITIONS-- ; ; CSI$ ;DEFINE CSI SYMBOLIC OFFSETS NSW=20. ;MAXIMUM NUMBER OF SWITCHES NVAL=30. ;MAXIMUM NUMBER OF VALUES SWLEN=4 ;LENGTH OF SWITCH ENTRY VALEN=2 ;LENGTH OF VALUE ENTRY TRUE=177777 ;VALUE OF FORTRAN .TRUE. FALSE=0 ;VALUE OF FORTRAN .FALSE. LUN=5 ;DEFAULT LOGICAL UNIT FOR ERROR MESSAGE EF=24 ;EVENT FLAG FOR ERROR MESSAGE .SBTTL STORAGE ALLOCATION AND INITIALIZATION-- ; ; ; .PSECT $IDATA,D CSIBLK: .BLKB C.SIZE .EVEN SWBLK: .DATAW <+1>,0 SWEND=.-4 VALBLK: .DATAW <+1>,0 VALEND=.-4 DEFLTS: .BLKW NSW DEFEND=.-2 DESCRP: .BLKW 3 SWPNT: SWBLK VALPNT: VALBLK DEFPNT: DEFLTS QIO: QIO$ IO.WVB,LUN,EF,,,,<0,0,40,0,0,0> ; ; .NLIST BIN ; ; ; .PSECT $PDATA,D,RO SYNMSG: .ASCII /SYNTAX ERROR:/ SYNLEN=.-SYNMSG SWMSG: .ASCII /INVALID OR IMPROPERLY SPECIFIED SWITCH OR VALUE/ SWMLEN=.-SWMSG ; .PSECT $IDATA MSG3: .ASCII /CSISW -- SWITCH "/ SW3: .DATAB 2,40 .ASCII /" ALREADY DEFINED/ LEN3=.-MSG3 MSG4: .ASCII /CSI/ ENT4: .DATAB 3,40 .ASCII /-- OUT OF / TYPE4: .DATAB 7,40 .ASCII /ROOM FOR SWITCH "/ SW4: .DATAB 2,40 .ASCII /"/ LEN4=.-MSG4 MSG5: .ASCII /CSIVAL -- NO ENTRY FOR SWITCH "/ SW5: .DATAB 2,40 .ASCII /"/ LEN5=.-MSG5 .EVEN ; .PSECT $PDATA SWITCH: .ASCII /SWITCH/ VALUE: .ASCII /VALUE / ; ; .LIST BIN ; ; .EVEN ; .PSECT $IDATA WILD: 0 MORE: 0 EQUAL: 0 .SBTTL ENTRY POINT: CSI ; .ENTRY CSI ;+ ; C S I ; ; PURPOSE: THIS ENTRY POINT INITIALIZES THE PACKAGE AND ; SAVES ADDRESSES FOR RETURN OF DESIRED DATA WHEN ; LINE IS PROCESSED. ; ; INTERFACE: CALLING SEQUENCE: (FORTRAN-CALLABLE SUBROUTINE) ; CALL CSI[DEVIND] [,UICIND] [,FILIND] [,MORE] ; 1 [,WILD] [,EQUAL] [,LUN] ) ; ; INPUT: ; DEVIND = 2 INTEGER WORD ARRAY: WILL RECEIVE ; INDEXES OF DEVICE STRING. STRING WILL ; NOT INCLUDE THE COLON. ; ; UICIND = 2 INTEGER WORD ARRAY: WILL RECEIVE ; INDEXES OF UIC STRING. BRACKETS ARE ; PART OF THE STRING. ; ; FILIND = 2 INTEGER WORD ARRAY: WILL RECIEVE ; INDEXES OF FILE DESCRIPTION STRING, ; INCLUDING NAME, TYPE, AND VERSION, ; AND ALL DELIMITERS ("." AND/OR ";"). ; ; MORE = 1 WORD LOGICAL: SET TO .TRUE. IF THE ; CURRENT STRING IS TERMINATED WITH A COMMA. ; NOTE: 'MORE' MUST BE PRESENT IN ORDER TO ; SCAN MORE THAN ONE STRING ON EITHER SIDE ; OF THE COMMAND LINE. IF PRESENT, 'MORE' ; MUST BE FALSE ANY TIME CSIGO IS CALLED ; WITH A NEW COMMAND LINE. CALLING CSI ; SETS 'MORE' FALSE. ; ; WILD = 1 WORD LOGICAL: SET TO .TRUE. IF THE UIC ; OR FILE DESCRIPTOR CONTAINS WILDCARD(S). ; ; EQUAL = 1 WORD LOGICAL: SET TO .TRUE. IF AN '=' ; APPEARS IN LINE, SIGNIFYING BOTH INPUT ; AND OUTPUT STRINGS. ; ; LUN = 1 WORD INTEGER: SPECIFIES LUN TO USE WHEN ; OUTPUTTING ERROR MESSAGES. DEFAULTS TO ; 5 (TI:). ; ; METHOD: THE FIRST 3 ARGUMENTS RECEIVE INDICES OF THEIR ; RESPECTIVE DATA, RELATIVE TO THE BEGINNING OF ; THE LINE. THE FIRST CHARACTER IS #1, NOT #0. ; ; EXAMPLE: THE LINE "DK1:CSI.MAC" IS BEING ; PROCESSED. DEVIND(1)=1, DEVIND(2)=3; ; UICIND(1) AND UICIND(2)=0; FILIND(1)=5, ; FILIND(2)=11. ; ; ALL ARGUMENTS ARE OPTIONAL, BUT THIS ROUTINE ; MUST BE CALLED REGARDLESS OF WHETHER ; THERE ARE ARGUMENTS IN THE CALL OR NOT. ; ; LANGUAGE: MACRO-11 ; ;- ; PROGRAM FLOW-- ; ; DEFAULT ALL ADDRESS POINTERS ; ; .PSECT $CODE1,RO CSI:: PUSH R0 ;SAVE REGISTER MOV #-1,R0 ;NULL ARGUMENT INDICATOR MOV R0,DESCRP ;DEVICE DESCRIPTOR ADDR MOV R0,DESCRP+2 ;UIC DESCRIPTOR ADDR MOV R0,DESCRP+4 ;FILE NAME DESCRIPTOR ADDR MOV R0,MORE ;MORE FLAG MOV R0,WILD ;WILDCARD FLAG MOV R0,EQUAL ;EQUAL SIGN FLAG MOVB #LUN,QIO+Q.IOLU ;DEFAULT LUN NUMBER ; ; SAVE AND/OR DEFAULT ARGUMENTS ; TSTB @R5 ;WERE ANY ARGUMENTS SENT? BLE INIT ;NO, INITIALIZE MOV 2(R5),DESCRP ;SAVE DEVICE DESCRIPTOR ADDR (IF ANY) CMPB @R5,#2 ;WERE TWO ARGUMENTS SENT? BLT INIT ;NO MOV 4(R5),DESCRP+2 ;SAVE UIC DESCRIPTOR ADDR (IF ANY) CMPB @R5,#3 ;WERE THREE ARGUMENTS SENT? BLT INIT ;NO MOV 6(R5),DESCRP+4 ;SAVE FILE NAME DESCRIPTOR ADDR (IF ANY) CMPB @R5,#4 ;WERE FOUR ARGUMENTS SENT? BLT INIT ;NO GETARG 10(R5),R0,10$ ;GET MORE FLAG (IF ANY) MOV R0,MORE ;SAVE MORE FLAG ADDR CLR (R0) ;SET MORE FLAG FALSE 10$: CMPB @R5,#5 ;WERE FIVE ARGUMENTS SENT? BLT INIT ;NO MOV 12(R5),WILD ;SAVE WILDCARD FLAG ADDR (IF ANY) CMPB @R5,#6 ;WERE SIX ARGUMENTS SENT? BLT INIT ;NO MOV 14(R5),EQUAL ;SAVE EQUAL FLAG ADDR (IF ANY) CMPB @R5,#7 ;WERE SEVEN ARGUMENTS SENT? BLT INIT ;NO MOVB @16(R5),QIO+Q.IOLU ;SET NEW LUN NUMBER ; ; INITIALIZE TABLES AND POINTERS ; INIT: MOV #SWBLK,SWPNT ;SET SWITCH ENTRY POINTER MOV #VALBLK,VALPNT ;SET VALUE ENTRY POINTER MOV #DEFLTS,DEFPNT ;SET DEFAULT ENTRY POINTER MOV SWPNT,R0 ;SWITCH ENTRY TABLE STARTING ADDR 10$: CLR (R0)+ ;CLEAR ENTRY WORD CMP R0,#SWEND+2 ;ARE WE PAST END OF TABLE? BLOS 10$ ;NO, KEEP GOING MOV VALPNT,R0 ;VALUE ENTRY TABLE STARTING ADDR 20$: CLR (R0)+ ;CLEAR ENTRY WORD CMP R0,#VALEND+2 ;ARE WE PAST END OF VALUE TABLE? BLOS 20$ ;NO, KEEP GOING MOV DEFPNT,R0 ;DEFAULT ENTRY TABLE STARTING ADDR 30$: CLR (R0)+ ;CLEAR ENTRY WORD CMP R0,#DEFEND ;ARE WE PAST END OF DEFAULT TABLE? BLOS 30$ ;NO, KEEP GOING POP R0 ;RESTORE REGISTER RETURN ;INITIALIZATION COMPLETE .SBTTL ENTRY POINT: CSISW ; .ENTRY CSISW ;+ ; C S I S W ; ; PURPOSE: THIS ENTRY IS USED TO ENABLE THE DETECTION OF ; SWITCHES IN THE STRING. NOTE AGAIN THAT NO DATA IS ; RETURNED FROM THIS ROUTINE, IT ONLY SAVES ADDRESSES ; AND VALUES FOR USE IN THE STRING PROCESSING CALL. ; YOU MAY DEFINE UP TO "NSW" SWITCHES. (SEE ; "SYMBOL DEFINITIONS--"). ; ; INTERFACE: CALLING SEQUENCE: (FORTRAN-CALLABLE SUBROUTINE) ; CALL CSISW (NAME,STATE [,DEFAULT]) ; ; INPUT: NAME = ASCII STRING: THE 1ST 2 CHARACTERS ; OF WHICH DEFINE THE SWITCH NAME. ; ; STATE = 1 WORD LOGICAL: SET TO .TRUE. IF ; SWITCH APPEARS AS (/SW), AND SET TO ; .FALSE. IF THE SWITCH APPEARS AS (/-SW). ; IF THE SWITCH IS NOT SPECIFIED AT ALL, ; THIS VARIABLE IS UNCHANGED (SEE NEXT ; PARAMETER). ; ; DEFAULT = 1 WORD CONSTANT: THE STATE IS SET TO ; THIS VALUE BEFORE A STRING IS PROCESSED. ; THE STATE WILL HAVE THIS VALLUE AFTER ; PROCESSING ONLY IF THE SWITCH WAS NOT ; SPECIFIED IN THE STRING, OR PROCESSING ; SET IT TO THE SAME VALUE. IF NOT ; .FALSE. WILL BE USED. ; ; LANGUAGE: MACRO-11 ; ; ;- ; PROGRAM FLOW-- ; ; PUT DATA FROM CALL INTO SWITCH TABLE ; CSISW:: PUSH ;SAVE REGISTERS MOV SWPNT,R0 ;ADDR OF NEXT ENTRY SUB #2,R0 ;ADDR OF LAST WORD OF LAST ENTRY CALL LOCATE ;,$CODE1 ;FIND THIS ENTRY POP R5 ;RESTORE ARGUMENT POINTER TST R0 ;IS SWITCH ALREADY IN TABLE? BEQ 2$ ;NO MOV 2(R5),R0 ;ADDR OF SWITCH NAME MOVB (R0),SW3 ;PUT SWITCH NAME IN MESSAGE MOVB 1(R0),SW3+1 WRITE #MSG3,#LEN3 ;WRITE MESSAGE EXIT$S 2$: CMP SWPNT,#SWEND-SWLEN+1 ;DO WE HAVE ROOM FOR ANOTHER ENTRY? BLOS 4$ ;YES MOVB #'S,ENT4 ;SET ENTRY POINT NAME INTO MSG MOVB #'W,ENT4+1 MOVB #40,ENT4+2 MOV #6,R0 ;MOVE 6 CHARS MOV #SWITCH,R1 ;ADDR OF "SWITCH" MOV #TYPE4,R2 ;ADDR IN MSG 3$: MOVB (R1)+,(R2)+ SOB R0,3$ MOV 2(R5),R0 ;ADDR OF SWITCH NAME MOVB (R0),SW4 ;PUT SWITCH NAME INTO MSG MOVB 1(R0),SW4+1 WRITE #MSG4,#LEN4 ;WRITE MESSAGE EXIT$S 4$: MOV SWPNT,R0 ;ADDR OF NEXT AVAILABLE SWITCH ENTRY MOV 2(R5),R1 ;ADDR OF SWITCH NAME MOVB (R1)+,(R0)+ ;MOVE 1ST BYTE OF NAME TO ENTRY MOVB (R1),(R0)+ ; " 2ND " " " " " MOV #TRUE,(R0)+ ;MASK TO TURN ON OR OFF MOV 4(R5),(R0)+ ;SWITCH STATUS WORD ADDR MOV #1,(R0)+ ;ENABLE NEGATION OF SWITCH MOV R0,SWPNT ;SAVE NEXT ENTRY ADDR MOV #FALSE,@DEFPNT ;DEFAULT TO .FALSE. CMPB @R5,#3 ;DID WE GET 3 ARGS? BLT 10$ ;NO CMP 6(R5),#-1 ;WAS A DEFAULT VALUE SPECIFIED? BEQ 10$ ;NO MOV @6(R5),@DEFPNT ;SAVE DEFAULT VALUE 10$: ADD #2,DEFPNT ;POINT TO NEXT ENTRY POP ;RESTORE REGISTER RETURN ;ALL DONE .SBTTL ENTRY POINT: CSIVAL ; .ENTRY CSIVAL ;+ ; C S I V A L ; ; PURPOSE: THIS ENTRY POINT ENABLES THE DECODING OF VALUES ; ACCOMPANYING A SWITCH SPECIFICATION. THIS CALL MUST ; FOLLOW A CALL TO CSISW FOR THE SWITCH IT REFERENCES, ; AND MUST PRECEDE ANY REFERENCES TO ANOTHER SWITCH. ; IN OTHER WORDS, FOR A GIVEN SWITCH, THE CALL TO ; CSISW AND CALL(S) TO CSIVAL ARE GROUPED TOGETHER. ; ; AS IN THE PRECEDING CALLS, NO DATA IS RETURNED ; UNTIL THE STRING IS PROCESSED. VALUES ARE APPENDED TO ; THE SWITCH IN THE STRING, SEPARATED BY COLONS. AS MANY ; VALUES AS DESIRED MAY BE USED, AS LONG AS THE TOTAL ; NUMBER OF VALUES ON ALL SWITCHES DOES NOT EXCEED ; "NVAL" (SEE SYMBOL DEFINITIONS). VALUES MAY BE ; NUMERIC OR CHARACTER, AND KEEP IN MIND THAT THE ; DEFAULT BASE FOR NUMERIC VALUES IS DECIMAL. A DECIMAL ; FOLLOWING THE NUMBER FORCES BASE TEN, WHILE A NUMBER ; SIGN '#' PRECEDING A NUMBER FORCES OCTAL CONVERSION. ; AN EXPLICIT NEGATIVE NUMBER MUST BE EXPRESSED '-#NN', ; '-#NN', NOT '#-NN'. ; ; FOR ASCII VALUES, THE GIVEN VALUE IS NULL EXTENDED ; OR TRUNCATED TO MATCH THE VALUE OF LENGTH. ; ; ALL VALUES NOT PRESENT IN THE STRING ARE DEFAULTED ; TO ZERO (FOR NUMERIC VALUES) OR NULLS (FOR ASCII VALUES). ; ; INTERFACE: CALLING SEQUENCE: (FORTRAN-CALLABLE SUBROUTINE) ; CALL CSIVAL (NAME,BUFFER [,LENGTH] [,OCTAL]) ; ; INPUT: NAME = ASCII STRING: 1ST 2 CHARACTERS OF ; WHICH MUST MATCH A SWITCH NAME ALREADY ; DEFINED. ; BUFFER = 1 WORD INTEGER OR BYTE ARRAY: FOR ; NUMERIC VALUES, MUST BE A 1 WORD LOCATION. ; FOR ASCII VALUES, MUST BE AN ARRAY WITH ; AT LEAST "LENGTH" BYTES. (SEE NEXT) ; LENGTH = IF NOT PRESENT, DECLARES VALUE TYPE ; AS NUMERIC. IF PRESENT, MUST BE A 1 WORD ; INTEGER CONSTANT DEFINING THE ; LENGTH OF BUFFER. ; OCTAL = IF PRESENT AND NON-ZERO, SETS DEFAULT ; CONVERSION RADIX FOR THIS VALUE TO OCTAL. ; DEFAULT RADIX IS DECIMAL OTHERWISE. ; ; LANGUAGE: MACRO-11 ; ; ;- ; PROGRAM FLOW-- ; ; LOCATE SWITCH ENTRY FOR THIS SWITCH ; CSIVAL::PUSH ;SAVE REGISTERS MOV SWPNT,R0 ;ADDR OF NEXT ENTRY SUB #2,R0 ;ADDR OF LAST WORD OF LAST ENTRY CALL LOCATE ;,$CODE1 ;R0 IS INDEX OF ENTRY POP R5 ;RESTORE ARGUMENT POINTER MOV R0,R1 ;WAS ENTRY FOUND? BGT 10$ ;YES MOV 2(R5),R0 ;ADDR OF SWITCH NAME MOVB (R0),SW5 ;PUT SWITCH NAME INTO MESSAGE MOVB 1(R0),SW5+1 WRITE #MSG5,#LEN5 ;WRITE MESSAGE EXIT$S 10$: DEC R1 ;ADDR=<#SWBLK+<*#SWLEN*2>> MUL #SWLEN*2,R1 ADD #SWBLK,R1 MOV R1,R0 ;PUT ENTRY ADDR IN R0 ; ; SEE IF ANY VALUES ALREADY IN FOR THIS SWITCH ; BIT #177776,6(R0) ;IS THERE A VALUE TABLE ADDR? BEQ 20$ ;NO, PUT IT IN MOV VALPNT,R1 ;ADDR OF NEXT FREE ENTRY BR 30$ ;PUT IN THE DATA 20$: CMP #VALBLK,VALPNT ;HAVE WE PUT IN ANY VALUES YET? BEQ 25$ ;NO, THIS IS THE FIRST ADD #2,VALPNT ;END PREVIOUS ENTRY WITH A ZERO ENTRY 25$: CMP VALPNT,#VALEND-VALEN+1 ;DO WE HAVE ROOM FOR ANOTHER? BLOS 27$ ;YES MOVB #'V,ENT4 ;PUT ENTRY ID INTO MSG MOVB #'A,ENT4+1 MOVB #'L,ENT4+2 MOV #6,R0 ;MOVE 6 CHARS MOV #VALUE,R1 ;ADDR OF "VALUE" MOV #TYPE4,R2 ;ADDR OF MSG LOC 26$: MOVB (R1)+,(R2)+ SOB R0,26$ MOV 2(R5),R0 ;ADDR OF SWITCH NAME MOVB (R0),SW4 ;PUT SWITCH NAME INTO MSG MOVB 1(R0),SW4+1 WRITE #MSG4,#LEN4 ;WRITE MESSAGE EXIT$S 27$: MOV VALPNT,6(R0) ;ADDR OF VALUE ENTRY INTO SWITCH ENTRY BIS #1,6(R0) ;RENABLE NEGATION OF SWITCH MOV VALPNT,R1 ;ADDR OF VALUE TABLE ENTRY ALSO IN R1 ; ; PUT DATA FROM CALL INTO VALUE ENTRY AND UPDATE POINTER ; 30$: MOV 4(R5),2(R1) ;PUT IN VALUE LOCATION ADDR MOV #3,@R1 ;DEFAULT TO NUMERIC (DECIMAL) TYPE CMPB @R5,#3 ;DO WE HAVE THREE ARGUMENTS? BLT 36$ ;NO CMP 6(R5),#-1 ;WAS LENGTH SPECIFIED? BEQ 35$ ;NO MOV @6(R5),R0 ;PUT STRING LENGTH IN REGISTER MOVB R0,1(R1) ;PUT LENGTH BYTE IN ENTRY MOVB #1,@R1 ;SET TYPE TO ASCII BR 36$ 35$: CMPB @R5,#4 ;DO WE HAVE 4 ARGS? BLT 36$ ;NO CMP 10(R5),#-1 ;WAS OCTAL SPECIFIED? BEQ 36$ ;NO TST @10(R5) ;IS IT NON-ZERO? BEQ 36$ ;NO MOVB #2,@R1 ;SET NUMERIC (OCTAL) TYPE 36$: ADD #VALEN*2,VALPNT ;POINT TO NEXT FREE ENTRY 40$: POP ;RESTORE REGISTERS RETURN .SBTTL ENTRY POINT: CSIGO ; .ENTRY CSIGO ;+ ; C S I G O ; ; PURPOSE: THIS ROUTINE SCANS THE GIVEN STRING, SETS THE ; REQUESTED INDEXES, AND PROCESSES SWITCHES AND SWITCH ; VALUES. THIS ROUTINE CAN BE CALLED WHENEVER YOU HAVE ; A NEW STRING, WITHOUT CALLING ALL THE OTHER ENTRIES. ; ; INTERFACE: CALLING SEQUENCE: (FORTRAN-CALLABLE SUBROUTINE) ; CALL CSIGO (LINE,LENGTH [,TYPE] [,ERROR]) ; ; INPUT: LINE = BYTE ARRAY: CHARACTER STRING TO PROCESS. ; LENGTH = 1 WORD INTEGER: NUMBER OF BYTES IN LINE. ; TYPE = BYTE CONSTANT: 'I' TO PROCESS DATA TO ; THE RIGHT OF AN EQUAL SIGN, OR 'O' ; TO PROCESS DATA TO THE LEFT OR IN THE ; ABSENCE OF AN EQUAL SIGN. IF NOT SPECIFIED, ; 'O' IS ASSUMED. ; ; OUTPUT: ERROR = 1 WORD LOGICAL: SET TO .TRUE. ; IF AN ERROR IS DETECTED WHILE PROCESSING ; STRING. A MESSAGE IS AUTOMATICALLY ; WRITTEN TO THE LOGICAL UNIT SPECIFIED ; BY TO ARGUMENT 'LUN' IN THE CALL TO ; CSI. LOGICAL UNIT 5 IS USED IF THIS ; ARGUMENT WAS NOT PRESENT WHEN CSI ; WAS CALLED. ; ; LANGUAGE: MACRO-11 ;- ; PROGRAM DETAIL-- ; ; DEFAULT SWITCHES, IF ANY ; CSIGO:: PUSH ;SAVE REGISTERS MOV #DEFLTS,R0 ;ADDR OF DEFAULT ENTRY TABLE MOV #SWBLK,R1 ;ADDR OF SWITCH TABLE 10$: CMP R0,DEFPNT ;ARE WE AT END-OF-DATA? BHIS 20$ ;YES MOV (R0)+,@4(R1) ;DEFAULT SWITCH STATUS ADD #SWLEN*2,R1 ;POINT TO NEXT SWITCH ENTRY BR 10$ ; ; DEFAULT SWITCH VALUES, IF ANY ; 20$: MOV #VALBLK,R0 ;ADDR OF VALUE ENTRY TABLE 30$: CMP R0,VALPNT ;ARE WE AT END OF DATA? BHIS SETUP ;YES 40$: TST @R0 ;NULL ENTRY? BNE 45$ ;NO ADD #2,R0 ;SKIP ZERO PAD WORD BR 30$ ;LOOK AT NEXT WORD 45$: CMPB (R0),#1 ;IS IT AN ASCII TYPE VALUE? BEQ 50$ ;YES CLR @2(R0) ;CLEAR NUMERIC VALUE WORD BR 61$ 50$: MOVB 1(R0),R1 ;LENGTH OF STRING MOV 2(R0),R2 ;ADDR OF STRING 60$: CLRB (R2)+ ;SET NULL CHARACTER DEC R1 ;CONTINUE TILL ALL OF STRING IS NULL BGT 60$ 61$: ADD #VALEN*2,R0 ;POINT TO NEXT VALUE ENTRY BR 30$ ; ; SET UP CALLS TO CSI PROCESSORS ; SETUP: CMP MORE,#-1 ;IS USER WATCHING MORE? BEQ 10$ ;NO TSTB @MORE ;WAS MORE FLAG SET BY LAST CALL? BNE SEM ;YES, GO DIRECTLY TO SEMANTIC ANALYZER ; ; SET UP LINE DESCRIPTOR AND COMPRESS LINE ; 10$: MOV #CSIBLK,R0 ;GET ADDR OF CSI CONTROL BLOCK MOV 2(R5),R1 ;GET LINE ADDR MOV R1,C.CMLD+2(R0) ;SET ADDR IN LINE DESCRIPTOR MOV @4(R5),R2 ;GET LINE LENGTH BPL 20$ CLR R2 ;ZERO IT IF LESS THAN ZERO 20$: MOV R2,C.CMLD(R0) ;SET LENGTH IN LINE DESCRIPTOR BEQ 60$ ;SKIP THE COMPRESS IF IT'S ZERO MOV R1,R0 ;PUT LINE ADDR IN R0 30$: CMPB (R0),#' ;CHECK FOR BLANK BEQ 40$ ;YES CMPB (R0),#' ;CHECK FOR TAB BEQ 40$ ;YES MOVB (R0),(R1)+ ;MOVE A NON-BLANK 40$: INC R0 ;POINT TO NEXT CHAR SOB R2,30$ ;LOOP UNTIL DONE 50$: CMP R1,R0 ;DONE ENTIRE LINE? BEQ 60$ ;YES MOVB #' ,(R1)+ ;BLANK TRAILING LINE POSITION BR 50$ ;TRY ANOTHER ; ; CALL SYNTAX ANALYZER AND CHECK FOR ERRORS ; 60$: MOV #CSIBLK,R0 ;GET ADDR OF CSI CONTROL BLOCK PUSH R5 ;SAVE ARGUMENT POINTER CALL .CSI1 ;CALL SYNTAX ANALYZER POP R5 ;RESTORE ARGUMENT POINTER BCC EKWAL ;IF C-BIT CLEAR, CARRY ON WRITE #SYNMSG,#SYNLEN ;WRITE MESSAGE WRITE CSIBLK+C.FILD+2,CSIBLK+C.FILD ;ECHO LINE ERR: CMPB @R5,#4 ;WERE FOUR ARGUMENTS SENT? BLT 10$ ;NO CMP #-1,10(R5) ;WAS ERROR FLAG RETURN SPECIFIED? BEQ 10$ ;NO MOV #TRUE,@10(R5) ;SET ERROR FLAG 10$: JMP OUT ; ; RETURN "EQUAL" INDICATION IF REQUESTED ; EKWAL: GETARG EQUAL,R1,SEM ;GET 'EQUAL' ADDR CLR (R1) ;SET IT FALSE BITB C.STAT(R0),#CS.EQU ;WAS EQUAL SIGN PRESENT? BEQ SEM ;NO DEC (R1) ;SET IT TRUE ; ; CALL SEMANTIC ANALYZER AND CHECK FOR ERRORS ; SEM: MOV #CSIBLK,R0 ;ADDR OF CONTROL BLOCK MOVB #CS.OUT,C.TYPR(R0) ;DEFAULT TO OUTPUT REQUEST CMPB @R5,#3 ;WERE 3 ARGS SENT? BLT 10$ ;NO CMP #-1,6(R5) ;WAS TYPE SPECIFIED? BEQ 10$ ;NO CMPB @6(R5),#'I ;IS AN INPUT LINE REQUESTED? BNE 10$ ;NO MOVB #CS.INP,C.TYPR(R0) ;SET TO INPUT REQUEST 10$: CLR C.SWAD(R0) ;DEFAULT TO NO SWITCHES CMP #SWBLK,SWPNT ;DO WE HAVE ANY SWITCHES? BEQ 20$ ;NO MOV #SWBLK,C.SWAD(R0) ;SET SWITCH TABLE ADDR 20$: PUSH R5 ;SAVE ARGUMENT POINTER CALL .CSI2 ;CALL ANALYZER POP R5 ;RESTORE ARGUMENT POINTER BCC AFTER ;RETURN DATA IF NO ERRORS MOV #SWMSG,QIO+Q.IOPL ;MSG ADDR MOV #SWMLEN,QIO+Q.IOPL+2 ;MSG LENGTH DIR$ #QIO ;WRITE MESSAGE BR ERR ; ; RETURN INDICES OF REQUESTED STRING DATA AND FLAGS ; AFTER: GETARG DESCRP,R1,UIC ;GET DEVICE DESCRIP ADDR CLR (R1) ;DEFAULT DESCRIPTOR VALUES CLR 2(R1) BITB C.STAT(R0),#CS.DVF ;DID WE GET A DEVICE? BEQ UIC ;NO MOV C.DEVD+2(R0),R2 ;ADDR OF DEVICE STRING SUB 2(R5),R2 ;CALCULATE OFFSET FROM LINE INC R2 ;ADJUST FOR FORTRAN ARRAY INDEXING MOV R2,(R1)+ ;RETURN BEGINNING INDEX ADD C.DEVD(R0),R2 ;COMPUTE END INDEX DEC R2 MOV R2,(R1) ;RETURN END INDEX UIC: GETARG DESCRP+2,R1,FILNAM ;GET UIC DESCRIP ADDR CLR (R1) ;CLEAR DESCRIPTOR VALUES CLR 2(R1) BITB C.STAT(R0),#CS.DIF ;DID WE GET A UIC? BEQ FILNAM ;NO MOV C.DIRD+2(R0),R2 ;ADDR OF UIC STRING SUB 2(R5),R2 ;CALCULATE OFFSET FROM LINE INC R2 ;ADJUST FOR FORTRAN ARRAY INDEXING MOV R2,(R1)+ ;RETURN INDEX ADD C.DIRD(R0),R2 ;COMPUTE END INDEX DEC R2 MOV R2,(R1) ;RETURN END INDEX FILNAM: GETARG DESCRP+4,R1,MOR ;GET FILE NAME DESCRIP ADDR CLR (R1) ;DEFAULT DESCRIPTOR VALUES CLR 2(R1) BITB C.STAT(R0),#CS.NMF ;DID WE GET A FILE NAME? BEQ MOR ;NO MOV C.FILD+2(R0),R2 ;ADDR OF FILE NAME STRING SUB 2(R5),R2 ;CALCULATE OFFSET FROM LINE INC R2 ;ADJUST FOR FORTRAN ARRAY INDEXING MOV R2,(R1)+ ;RETURN BEGINNING INDEX ADD C.FILD(R0),R2 ;COMPUTE END INDEX DEC R2 MOV R2,(R1) ;RETURN END INDEX MOR: GETARG MORE,R1,WLD ;GET MORE FLAG ADDR CLR (R1) ;SET IT FALSE BITB C.STAT(R0),#CS.MOR ;IS MORE THERE? BEQ WLD ;NO DEC (R1) ;SET IF TRUE WLD: GETARG WILD,R1,OKOUT ;GET WILD CARD FLAG ADDR CLR (R1) ;SET IT FALSE BITB C.STAT(R0),#CS.WLD ;WAS A WILD CARD PRESENT? BEQ OKOUT ;NO DEC (R1) ;SET IT TRUE ; ; CLEAR ERROR RETURN IF NECESSARY AND RETURN ; OKOUT: CMPB @R5,#4 ;WERE FOUR ARGUMENTS SENT? BLT OUT ;NO CMP #-1,10(R5) ;WAS ERROR RETURN ADDR SPECIFIED? BEQ OUT ;NO CLR @10(R5) ;RETURN FALSE OUT: POP ;RESTORE REGISTERS RETURN .END