.TITLE FIXUP .IDENT /Y02.1/ .enabl lc ; More than a teletype ; ; This is derived from an original in FORTRAN (now deceased) so excuse ; the odd names for PSECTs, variables etc. ; ; This module fixes up the parameters in the final output line ; from the parameter specifications given in return to ; questions or on the initial command line. ; ; ADDENDUM: ; ; This version of FIXUP is for use with CCL V7.0B. Extensive ; revision of .PSECT .$$$$. (former FORTRAN common) and a new ; method for defining parameters have been implemented. FIXUP ; has been extended to include two new key characters in its ; repertoire, "\" and "?". An option for parameter substitution ; has been added to the standard CCL file action line, "\string". ; If this argument is included in a parameter substitution field ; and the parameter is null, the character string following the "\" ; will be inserted instead. For example, by defining a command: ; ; $4412DUMP ; ?1File ; ?2To ; *RUN $DMP/PRM="%2.DMP\TI:%%1=%" ; ; and giving it the MCR line: ; ; DUMP MYFILE.BIN ; ; CCL would not issue a prompt for the 2nd parameter since only 1 needed ; (minimum), and FIXUP would substitute TI: for the null 2nd parameter. ; The new command to spawn to MCR would end up being: ; ; RUN $DMP/PRM="TI:=MYFILE.BIN" ; ; An additional CCL file action line has also been included: ; ; %?<\string2>% ; where: ; = Parameter specifier (0-9,A-C) ; ? = Key character to evaluate status ; (null or not) of parameter pn. ; = Character string to be inserted ; into command line if the parameter ; is not null. ; <\string2> = Character string to be inserted ; into command line if the parameter ; is null. ; For example, given: ; ; $3300UIC ; *SET /UIC%1?=[%%1%%2,]% ; ; The first parameter substitution field (%1?=[%) tests if parameter ; 1 was entered. If it was, insert "=["; if not, insert nothing. ; The next paramater substitution field (%1%) either inserts parameter 1 ; or not, and the final field (%2,]%) inserts parameter 2 preceeded by ; "," and ended with ] (unless ] in parameter 2) provided a 2nd parameter ; was entered. Thus, the following 3 MCR lines would be interpretted as: ; ; UIC = SET /UIC ; UIC 100,2 = SET /UIC=[100,2] ; UIC 100 2 = SET /UIC=[100,2] ; ; ; Paul Sorenson -- 3/81 ; Dept. of Physiol. ; Mich. State Univ. ; E. Lansing, MI 48824 ; ; J. DOWNWARD 22-MAR-81 Fix problems introduced by above ; JGD04 enhancements. 1) Ensure that task ; started by CCL prompts on exit unless ; %$ form is used., 2) add %R to replace ; the old %B (ring bell on exit) since ; %B seems to have a better use now. ; ; 23-MAR-81 Added %D (debug). If encountered the ; JGD05 line will automatically be considered ; too long (even if it isn't) and will ; be printed out so one can see what ; the line sent to MCR will look like. ; ; JGD06 Added %Q, (quit). Exit CCL without ; sending command to MCR if the default ; substitution filed is null and a ; required input parameter is not present ; JGD07 Added %P, (print) print the action ; line to TI: rather than sending it ; to MCR. Like %D but not additional ; message is produced. %P should be ; at end of CCL command string. ; ; JGD08 Add a space as a prefix character. ; This is done for RSX11M V4.0. The ; new INS /CMD="XXX cmdlin" requires ; a space between XXX and 'cmdlin' but ; some RSX utilities will not accept ; a space following the XXX if 'cmdlin' ; is a null (ie EDI). Thus the one can ; now have a CCL template line: ; *INS/CMD="XXX%A %" ; ; JGD09 Modify so that CCL can be a CLI ; Oct 23,1981 just like DEC's DCL. ; ; Setup miscellaneous definitions ; SPA = 40 ; Blank CR = 15 ; LF = 12 ; ESC = 33 ; PCNT = 45 BSLASH = 134 QNMRK = 77 COMMA = 54 EQUAL = 75 DOLLAR = 44 TERM = 124 GROUP = 107 MEMBER = 115 UIC = 125 .PSECT .$$$$.,rw,d,ovr,gbl ; ; The common data area for the routines FIXUP,LOOKUP and the MAIN program. ; CMD: .blkb 80. ; Output command line CLIBF: .BLKW 3 ; For CLI support ;JGD09 MCRL: .word 0 ; Length of mcr line MCR: .blkb 80. ; MCR line KEYL: .word 0 ; Length of keyword KEYB: .WORD MCR ; Keyword start address ;PRS01 P: ; Buffer for parameters fetched after prompt .BLKB 256. ; Def parameter buffer, 256 should be enough NEXTP: .WORD P ; Points to next free spot in P ; ; Parameter pointers consist of: 1st word = byte count, 2nd word = address ; of parameter string. ; PNTR0: .WORD 0,0 ; Parameter 0 pointer; leading switches PNTR1: .WORD 0,0 ; Parameter 1 pointer PNTR2: .WORD 0,0 ; Parameter 2 pointer PNTR3: .WORD 0,0 ; Parameter 3 pointer PNTR4: .WORD 0,0 ; Parameter 4 pointer PNTR5: .WORD 0,0 ; Parameter 5 pointer PNTR6: .WORD 0,0 ; Parameter 6 pointer PNTR7: .WORD 0,0 ; Parameter 7 pointer PNTR8: .WORD 0,0 ; Parameter 8 pointer PNTR9: .WORD 0,0 ; Parameter 9 pointer PNTRA: .WORD 0,0 ; Parameter A pointer; MCR line minus keyword PNTRB: .WORD 0,0 ; Parameter B pointer; 1st major parameter set PNTRC: .WORD 0,0 ; Parameter C pointer; 2nd major parameter set PMIN: .WORD 0 ; Min # of parameters allowed PMAX: .WORD 0 ; Max # of parameters to prompt for EXSTAT: .WORD EX$SUC ; To keep commons aligned DUIC: .WORD 0 ; Default (or Current) UIC TERMIN: .BYTE 0 ; Terminal char 1 ie V of VT .BYTE 0 ; ............ 2 ie T of VT UNIT: .BYTE 0 ; Terminal unit # (ie 1 if VT1) .BLKB 9. ; Hold rest of space claimed by GLBUF .PSECT $VARS,RW,D,CON,LCL DEFUIC: .BLKB 9. ; Space to hold ASCII default uic DEFCH: .BYTE 0 ; This is the character at the start ; of a default extender field. .PSECT $CODE1,rw,i,con,lcl ; ; Entry here occurs for each occurance of the parameter flag ; character "%" in the template line and is pointed to by R2. ; The new command is being generated into CMD, with R0 pointing to ; next available slot in CMD and R1 set to # available bytes left in CMD ; (only allowed 79 for an MCR line). R3 is maintained as # bytes left to ; process in template line, while R4 and R5 are used as pointers to ; the parameters being accessed. ; FIXUP:: ; External entry point CLRB DEFCH ; For now, signal no default extender field INC R2 ; Skip template pntr over the "%" that caused DEC R3 ; call, readjust # bytes left to look at also BGT 5$ ; Branch if still stuff in template JMP EXIT ; Else, return to caller 5$: MOVB (R2),R4 ; Get parameter designator; character after % SUB #60,R4 ; Convert ASCII 0-9 to binary # BLT NOPARM ; Branch if < 0, no parameter # CMP R4,#10. ; Check if < 10 BLT 10$ ; Branch if yes SUB #21,R4 ; Check if A-C BLT NOPARM ; Branch if < A CMP R4,#3 ; Check if < D BGE NOPARM ; Branch if >/= D ADD #10.,R4 ; Offset A-C to 10-12 10$: INC R2 ; Have valid parameter designator, readjust DEC R3 ; template pointer, byte count and branch BLE ERROR ; if nothing left in template (must be at ; least a trailing % for valid template) ASL R4 ; Multiply R4 by ASL R4 ; 4 to get correct offset ADD #PNTR0,R4 ; to parameter from PNTR0 MOV (R4)+,R5 ; Move parameter length into R5 MOV (R4),R4 ; Recover parameter's start address CMPB (R2),#QNMRK ; Doing test parameter field? BNE 15$ ; Branch if no INC R2 ; Step over the '?', DEC R3 ; and adjust # bytes left to scan BLE ERROR ; Branch if nothing left in template -- error CALL SUBST ; Call SUBST to substitute correct field ; dependent on whether param is null or not BR 35$ ; Branch 15$: TST R5 ; Check parameter length BGT 20$ ; Branch if not null CALL SUBST ; Null parameter, check for substitution field BR 35$ ; Branch to move substitute field into command ; ; Now check for a prefix character %n,xxxxxxx% or %n=xxxxxx% ; Insert the prefix characeter now because we know the parameter is non null. ; 20$: CMPB (R2),#COMMA ; Check if next template character a "," BEQ 25$ ; Branch if yes CMPB (R2),#SPA ; Check if next template char a space ; JGD08 BEQ 25$ ; Branch if yes ; JGD08 CMPB (R2),#EQUAL ; Check if "=" BNE 30$ ; Branch if no 25$: MOVB (R2)+,(R0)+ ; Insert prefix into command DEC R1 ; Readjust # available bytes in command BLT ERROR ; Branch if getting too long DEC R3 ; Readjust # bytes left in template BLE ERROR ; Branch if nothing left ; ; Here we set the default starter character for an extender field ; into DEFCH. ; 30$: CMPB (R2),#PCNT ; Check for "%", end of current template field BEQ 35$ ; Branch if found CMPB (R2),#BSLASH ; Check for "\" BEQ 35$ ; Branch if found MOVB (R2),DEFCH ; Assume its legitimate extender field 35$: MOVB (R4),(R0)+ ; Move parameter to new command line DEC R1 ; Readjust # bytes available in new command BLT ERROR ; Branch if getting too long CMPB (R4)+,DEFCH ; Check for default extender character BNE 39$ ; Branch if not CLRB DEFCH ; Signal saw default extender character 39$: SOB R5,35$ ; Continue till move parameter over ; ; Insert default extender if not encountered in body of parameter ; 40$: TSTB DEFCH ; Check DEFCH status BEQ SKPFWD ; Branch if nothing there 42$: MOVB (R2)+,(R0)+ ; Substitute new stuff in DEC R1 ; Adjust # available bytes in command BLT ERROR ; Branch if getting too long 46$: DEC R3 ; Adjust # bytes left to scan in template BLE ERROR ; Branch if nothing left CMPB (R2),#PCNT ; Pointing to "%" ? 47$: BEQ ENDFLD ; Branch if yes, all done: and link to ENDFLD ; for preceeding code CMPB (R2),#BSLASH ; Pointing at substitution character ("\") ? BNE 42$ ; Branch if no, keep moving stuff over BR SKPFWD ; If yes, skip forward to "%" delimiter ERROR: BR ERREX ; ERROR links to ERREX, error exit ; ; Out of range for 1-9, A-C is it %% meaning insert "%" ; NOPARM: MOVB (R2)+,R4 ; Copy character that got us here DEC R3 ; Adjust # bytes left in template CMP R4,#PCNT ; Was it "%" BNE 20$ ; Branch if no MOVB R4,(R0)+ ; Move % into command line DEC R1 ; Adjust # bytes available in command BLT ERREX ; Branch if too long BR EXIT ; All done, including pointer positioning ; ; handle %$- don't wait for spawned task to exit ; 20$: CMP R4,#DOLLAR ; Check for $ BNE 25$ ; Branch if not ;JGD04 MOVB #15,(R0)+ ; Tack on a so it task will prompt ;JGD04 DEC R1 ; Adjust # bytes left in command ;JGD04 BLT ERREX ; Error exit, if too long ;JGD04 INC NOSTOP ; Set NOSTOP non-zero BR EXIT ; Done 25$: CMP R4,#'R ; Is it %R, ring bell on exit ;JGD04 BNE 27$ ; If NE, no ;JGD04 INC RING ; Set flag to ring bell on exit ;JGD04 BR EXIT ; Done ;JGD04 27$: CMP R4,#'Q ; Is it %Q, quit if req parm missing ;JGD06 BNE 28$ ; If NE, NO ;JGD06 INC QTFLAG ; Show flag is found ;JGD06 BR EXIT ; Done ;JGD06 28$: CMP R4,#'D ; Is it %D (for debug) ;JGD05 BNE 29$ ; If NE, no ;JGD05 INC DBGFLG ; Tell CCL this is a DEBUG display ;JGD05 BR EXIT ; Yes, pretend command too long ;JGD05 29$: CMP R4,#'P ; Is it %P (for print line) ;JGD07 BNE 30$ ; If NE, no ;JGD07 INC PRINT ; Show its a PRINT line ;JGD07 BR EXIT ; Done ;JGD07 ; ; handle %T; note that this does what CCL documentation says should ; happen, e.g. that %T encountered from TT6 should return T6 in ; new command line. The original version of FIXUP looked like it ; would return the full TT6. ; 30$: CMP R4,#TERM ; Check for "T" BNE 40$ ; Branch if not MOV #TERMIN,R4 ; Fetch start address of terminal SUB #2,R1 ; Anticipate room min room needed (Tn) BLT ERREX ; Branch if it won't fit MOVB (R4)+,(R0)+ ; Move 1st character over (T or V) INC R4 ; Skip 2nd; see note above MOVB (R4),R5 ; Fetch unit # ASR R5 ASR R5 ; fetch high order unit # ASR R5 BEQ 35$ ; Branch if high order unit = 0 ADD #60,R5 ; Else, make it ASCII MOVB R5,(R0)+ ; Move it to command DEC R1 ; Adjust # bytes available BLT ERREX ; Branch if can't hold last # 35$: MOVB (R4),R5 ; Fetch unit # again BIC #^C<7>,R5 ; Clear out high order # ADD #60,R5 ; Make it ASCII MOVB R5,(R0)+ ; Move it to command BR EXIT ; Done ; ; Only valid things left are %G, %M, and %U, anticipate this ; and convert default UIC to ASCII ; 40$: MOV R2,-(SP) ; Save registers used by .PPASC MOV R3,-(SP) MOV R4,-(SP) MOV #DEFUIC,R2 ; Set up start address MOV DUIC,R3 ; Fetch UIC to convert MOV #1,R4 ; Specify no leading 0 suppresion, include [,] CALL .PPASC ; Convert it to ASCII MOV (SP)+,R4 ; Recover registers MOV (SP)+,R3 MOV (SP)+,R2 ; ; Now find out what was required ; 50$: CMP R4,#GROUP ; Was it %G BNE 55$ ; Branch if no MOV #DEFUIC+1,R4 ; Set up start address of group # BR 65$ ; and branch 55$: CMP R4,#MEMBER ; Was it %M BNE 60$ ; Branch if no MOV #DEFUIC+5,R4 ; Fetch start address of member # BR 65$ ; and branch 60$: CMP R4,#UIC ; Was it %U BNE SKPFWD ; Branch if no, don't know what it was MOV #DEFUIC,R4 ; Fetch start address MOV #9.,R5 ; Define # bytes to move BR 66$ ; and branch 65$: MOV #3,R5 ; Define # bytes to move 66$: SUB R5,R1 ; Adjust # available bytes in command BLT ERREX ; Branch if won't fit 68$: MOVB (R4)+,(R0)+ ; Move it to command SOB R5,68$ ; Until done BR EXIT ; Done ; ; Skip forward in template field until hit trailing % ; SKPFWD: 1$: CMPB (R2),#PCNT ; Hit delimiter yet BEQ ENDFLD ; Branch if yes INC R2 ; Adjust template pointer, # bytes left SOB R3,1$ ; in template, and branch if still more to go ; ; Ran out of template or command space ; ERREX: SEC ; Set carry bit and exit BR EXIT ; ; End of template field, skip over trailing % ; ENDFLD: INC R2 DEC R3 ; Caller should determine if anything left ; in template line EXIT: RETURN .SBTTL Local subroutine section ; ; SUBST -- substitution routine: Call with R2 pointing to character ; following character in template causing the call, either "?" ; or # (0-9,A-C), and the length of the parameter referenced in R5. ; R0, R1 are used. If the parameter is null (R5=0), substitute ; the address of the character immediately following a "\" and the # of ; characters from there to "%" field delimiter in R4 and R5 respectively. ; If the parameter is not null, substitute the address of the character ; immediately following the ? or parameter number (currently not allowed; ; FIXUP won't call SUBST of non-null parameter without a '?') and the # ; characters from there to either "\" or "%" delimiters into R4 and R5 ; respectively. ; ; It is the caller's responsibility to actually move the string. ; ; On return: ; R0 = unaltered ; R1 = unaltered ; R2 = points to trailing % in template ; R3 = # bytes left in template to scan ; R4 = pointer to string to substitute ; R5 = # bytes in substitute string ; SUBST: MOV R0,-(SP) ; MOV R1,-(SP) ; Save registers going to need MOV R2,-(SP) ; CLR R0 ; CLR R1 ; Signal haven't seen either "%" or "\" 5$: CMPB (R2),#PCNT ; Check if at end of field BEQ 10$ ; Branch if yes CMPB (R2),#BSLASH ; Check if at backslash BNE 7$ ; Branch if no, look again MOV R2,R0 ; Set R0 to address of "\" 7$: INC R2 ; Step over character, DEC R3 ; and adjust # bytes left in template BLE 35$ ; Branch if ran out = error BR 5$ ; Else, keep going till hit "%" 10$: MOV R2,R1 ; Set R1 to point to end of field MOV (SP)+,R4 ; Pop start address of current template field TST R5 ; Was parameter referenced in caller null? BLE 20$ ; Branch if yes MOV R0,R5 ; Copy position of "\" BNE 15$ ; Branch if defined MOV R1,R5 ; Otherwise, use end of field 15$: SUB R4,R5 ; Subtract string start address to compute BR 30$ ; string length, and get out 20$: MOV R0,R4 ; Set string start address to address of "\" BNE 25$ ; Branch if defined CLR R5 ; If not defined, nothing to substitute BR 30$ ; Branch to get out 25$: INC R4 ; Step pointer to character following "\" MOV R1,R5 ; Set R5 to point to end of field SUB R4,R5 ; Subtract start address ; and get out TST R5 ; Test length of substitute string ;JGD06 BGT 30$ ; OK ;JGD06 INC QUIT ; Show a required field had a null ;JGD06 30$: MOV (SP)+,R1 ; Normal exit, restore registers MOV (SP)+,R0 ; from stack TST R5 ; Check length of substitute string BGT 40$ ; Branch if something to substitute MOV #ENDFLD,(SP) ; Otherwise, reset return point BR 40$ ; before leaving 35$: MOV (SP)+,R2 ; Error exit, restore registers MOV (SP)+,R1 MOV (SP)+,R0 MOV #ERREX,(SP) ; Alter return point before leaving 40$: RETURN .END