.TITLE LOOKUP .IDENT /V3.1/ .enabl lc ; Not a cheap teletype ; ; This is derived from a (deceased) FORTRAN program so please excuse the ; odd names of variables and PSECTs. ; ; This subroutine is entered with a file open on LUN 1. ; This file must be in the specified form for a CCL command set. ; ; ADDENDUM FOR V2.0A ; ; ; Major revision of LOOKUP -- 3/81, by P. Sorenson ; Extensive modification has been made to the FORTRAN common PSECT .$$$$. ; with all parameters now being variable length strings identified ; by a corresponding pointer (e.g. Parameter 0 pointed to ; by PNTR0). Additionally, order of variables has been rearranged ; for no particularly good reason; 2 new parameters have been added, "B", ; which points to the first major section of the command specifiers up to ; a major delimiter (currently only space), and 'C' which points to ; the remainder of the command specifiers (from B on, without delimiter). ; Finally, added an internal "file" to implement a more flexible and ; easily altered set of internal functions then allowed by DCL; ; use of this "file" is keyed to all program elements by setting the ; LUN to 0. ; ; ADDENDUM FOR V3.0 ; ; Two new file/table line types have been added to allow the user to ; redefine the parameter delimiters used in parsing the command line. ; These new lines are signified by starting with a "^" or "~". Consult ; CCL.DOC and PARSE.MAC for more information on the format and ; use of this special line type. ; ; MODIFIED: ; ; PRS01 5/5/81 CHANGE HANDLING OF KEYWORD FROM 8 BYTE ; LONG STRING TO VARIBLE LENGTH STRING ; POINTED TO BY 'KEYB'. SUPPORT '0' FOR MAX. ; STRING LENGTH TO DISABLE MAX. KEYWORD STRING ; LENGTH CHECK. ; ; JGD09 Oct 23,1981 Modify so CCL can be a full CLI. ; ; PRS07 Jan 7, 1983 Modify so user can alter command punctuation. ; All variables from .PSECT .$$$$. are now ; global, so don't need .PSECT definition here. ; ; PRS08 March, 1983 Alter the "change parameter delimiters" line ; to allow switching between V8 and V9 parameter ; definitions; and allow a change to be ; temporary, e.g. hold only for 1 keyword line. ; ; PRS09 October, 1983 Add support for "matchall" command from ; file/table using "$0000*" keyword line ; .MCALL GET$ SPA = 40 ; Blank CR = 15 ; LF = 12 ; ESC = 33 ; TILDE = 176 ; <~> ;PRS08 UPARW = 136 ; <^> ;PRS08 .PSECT $CODE1,RO,I,CON,LCL,REL ;PRS07 ; ; Entry to get next record for processing. ; Note the effect of null records and of records with junk in the first ; 5 columns is undefined, but unlikely to be nasty in the extreme. ; worst case is CCL could spin on incomplete data set of CCL spec. ; LOOKUP:: ; External entry point CALL $SAVAL ; Free up all registers CLR -(SP) ; Clear local flag on stack ;PRS08 CLR R0 ; Setup for special 1st call to DEFDEL ;PRS07 2$: ;PRS08 CALL DEFDEL ; Define parameter delimiters ;PRS07 3$: ;PRS08 CALL DEFKEY ; Define keyword in current context ;PRS08 5$: ;PRS08 CALL GETLIN ; Fetch line from correct file BCS 30$ ; Branch if read failed ;PRS08 ; ; The result of a failure to find the keyword which is presented ; in the buffer pointed to by KEYB of length KEYL bytes is to return ; carry bit set ;PRS07 ; ; The first character of the line is checked for a "$" symbol ; if it's not, must check for a change delimiters line starting ;PRS08 ; with either "^" or "~". The change in delimiters is temporary ;PRS08 ; if only one "^" or "~" is in line; change is permanent if see ;PRS08 ; 2 consecutive "^" or "~" characters ;PRS08 ; MOV FDB+F.URBD+2,R0 ; Pointer to input line MOV FDB+F.NRBD,R1 ; Fetch # bytes read ;PRS07 BEQ 5$ ; Skip null lines ;PRS08 CMPB (R0),#'$ ; Line start with "$"? ;PRS08 BEQ 10$ ; Yes, look for keyword match ;PRS07 CLR R2 ; Anticipate V8 delimiters line ;PRS08 CMPB (R0),#TILDE ; Was it a "change V8 delimiters" line ;PRS08 BEQ 6$ ; Branch if yes, reset delimiters ;PRS08 INC R2 ; Anticipate V9 delimiters line ;PRS08 CMPB (R0),#UPARW ; Was it a "change V9 delimiters" line ;PRS08 BNE 5$ ; Branch if no, ignore line ;PRS08 6$: TST (SP) ; Temporary change still in effect ? ;PRS08 BEQ 7$ ; Branch if no, okay ;PRS08 CALL RSTDEL ; Else, undo last change ;PRS08 CLR (SP) ; and clear flag ;PRS08 7$: ;PRS08 DEC R1 ; Adjust byte count ;PRS08 BLE 8$ ; Branch if temp change in parsing style;PRS08 CMPB (R0)+,(R0) ; Double key in line ? ;PRS08 BNE 8$ ; Branch if no, temporary change ;PRS08 INC R0 ; Advance pointer past 2nd key ;PRS08 DEC R1 ; and adjust byte count ;PRS08 BR 9$ ; Finish up ;PRS08 8$: ;PRS08 CALL SAVDEL ; Temporary change, save current context;PRS08 INC (SP) ; Signal temporary change ;PRS08 9$: ;PRS08 MOVB R2,PRSFLG ; Change parsing style ;PRS08 TST R1 ; New delimiters in line ? ;PRS08 BGT 2$ ; Branch if new delimiters given too ;PRS08 BR 3$ ; Else, reevaluate keyword ;PRS08 ; ; The 4 number fields of a "$" record are now obtained with no ; checking and an enormous degree of hopefulness. ; They are in turn: ; length minimum match ; length max ; parameter count minimum ; parameter count required if no params specified ; 10$: ;PRS07 INC R0 ; Step over '$' ;PRS08 SUB #5,R1 ; Adjust byte count for $nnnn ;PRS07 BLE 20$ ; Branch if no keyword text, ignore it ;PRS08 MOV #60,R2 ; Setup for ASCII to binary conversions MOVB (R0)+,R4 ; Get minimum match length for name SUB R2,R4 ; Make integer BLE 19$ ; Branch if "0" = matchall keyword ;PRS09 MOVB (R0)+,R5 ; Set up to handle max. length ;PRS01 SUB R2,R5 ; Convert to integer ;PRS01 BGT 13$ ; Branch if valid # ;PRS07 MOV #80.,R5 ; Else, set R5>>>0 to skip max. length check ;PRS01 13$: ;PRS07 MOVB (R0)+,R3 ; Get minimum parameters to process SUB R2,R3 MOVB R3,PMIN ;PRS07 MOVB (R0)+,R3 ; Get minimum pameters that must be non-NULL SUB R2,R3 MOVB R3,PMAX ; And last of the numbers. :PRS07 ; ; At this point, R0 points to start of master string to match with ; keyword. Set R1 to master string length; R2 to start of keyword; ; and R3 to length of keyword. ; ; First matching criteria is that have at least minimum # characters ; necessary (in R4) in the keyword. ; MOV KEYL,R3 ; Fetch keyword length CMP R4,R3 ; Check keyword length against min # to match BGT 20$ ; Branch if not at least LMIN characters;PRS08 CMP R5,R3 ; Check keyword length against max. ;PRS01 BLT 20$ ; Branch if more than max. characters ;PRS08 ; in keyword ;PRS08 MOV KEYB,R2 ; Fetch start address of keyword ;PRS01 15$: CMPB (R0)+,(R2)+ ; Do characters match? BNE 20$ ; Branch if no, get new master string ;PRS08 DEC R1 ; Set R1 to # characters left in master string BLE 19$ ; Branch if 0, all done DEC R3 ; Set R3 to # characters left in keyword BGT 15$ ; Branch if still more keyword to match up 19$: ; To get here must have matched, ;PRS07 CLC ; return success ;PRS07 BR 30$ ; ...to caller ;PRS08 ; ; To get here, encountered a keyword line but failed to match. ;PRS08 ; Now, check to see if there was a temporary redefinition of ;PRS08 ; command delimiters; if so, reset to previous delimiters ;PRS08 20$: ;PRS08 TST (SP) ; Temporary change in delimiters ? ;PRS08 BEQ 5$ ; Branch if no, get next keyword line ;PRS08 CALL RSTDEL ; Else, reset previous context ;PRS08 CLR (SP) ; Reset temporary flag ;PRS08 BR 5$ ; and get next keyword line ;PRS08 ; ;PRS08 ; Common exit, carry bit => status ;PRS08 30$: ;PRS08 INC (SP)+ ; Align stack, preserve C-bit ;PRS08 RETURN .END