; ; ; MATCHK ; ; MATCHK- DATABASE FILE SEARCH ROUTINE ; ; ROUTINE NAME: MATCHK ; ; PURPOSE: MATCHK searches database structures exactly the ; same way that FNDKEY does accept a more complex ; "string pattern recognition" is done to find the ; key that matches. Not only can the pattern con- ; tain wildcards in the form of backslashes (\), but ; the following constructs are also recognized: ; * The asterisk matches any sub-string, including the ; null substring. ; -c (Where c represents any character) Matches any ; character that is not equal to c. ; [set] (Where set represents any set of characters) ; Matches any one of the characters in the set. ; -[set] Matches any character not in the set. example: ; -[aeiouy] will match any consonant. ; ; CALLABLE: From FORTRAN only: ; CALL MATCHK(ROOT,PATT[,KEY][,VAL][,ERR]) ; or ; ERR=MATCHK(ROOT,PATT[,KEY][,VAL]) ; ; PARAMETERS: ; ROOT Database root block and I/O buffers. ; PATT The pattern to search for. This pattern MUST be ; terminated with a NUL byte or your program will ; blow up. ; KEY A buffer to store the actual string matched to. ; VAL A buffer to contain the data section of the key ; found ; ERR The error return parameter, where the possible er- ; rors are: ; ERR= +n means successful return. ; ERR= 0 means no keys matched your pattern. ; ERR= -1 means no more keys match your pattern. ; ERR= -100 means you sent me a bad root block. ; ; ROUTINES USED: B$ACTIVATE B$GETKEY B$GETNEXT $MATCH ; ; EXAMPLE: ; CALL MATCHK(ROOT,'*MUTAGENISIS*',KEY,ERR) ; IF (MATCHK(ROOT,PATTRN,KEY) .LE. 0) GOTO 999 ; ; AUTHOR: Mike Higgins ; ; SOURCE LANGUAGE: MACRO11 with SUPERMAC ; ; OBJECT MODULE NAME: MATCHK ; ; LIBRARY: [60,100]DATABASE ; ; MAINTENANCE: See Mike Higgins ; ; ;PARAMETER ASSIGNMENTS ROOTV=2 PATT=4 KEY=6 VAL=10 ERR=12 .MCALL SUPER SUPER ;REGESTER ASSIGNMENTS ROOT=R4 BUF=R3 LEVEL=R2 TEM=R1 TEM2=R0 PROCEDURE MATCHK LET ROOT := ROOTV(R5) ;GET POINTER TO ROOT BLOCK IF DB.BLT(ROOT) NE #"RT ;IS THIS REALLY A ROOT BLOCK? FORET #ER.NRB,ERR ;NO! IT'S NOT!!! RETURN ;RETURN AN ERROR END LET LEVEL := RT.PCL(ROOT) ;GET THE STACK POINTER IF #FL.ACT OFF.IN LV.FLG(LEVEL) ;IS THIS LEVEL ACTIVE YET? SCALL B$ACTIVATE ;WELL THEN, ACTIVATE IT! ON.ERROR FORET #0,ERR ;OOPS, THIS LEVEL HAS NO DATA RETURN END ELSE LET BUF := LV.PCE(LEVEL) + LV.LEN(LEVEL) ;GET PONTER TO CURRENT ELEMENT END REPEAT: IF BUF GT RT.LLA(ROOT) ;AM I PAST THE LAST KEY IN BUFFER? SCALL B$GETNEXT ;YES, GET NEXT BLOCK ON.ERROR ;NO MORE BLOCKS, TO AN EFFECTIVE RESET LET LV.FLG(LEVEL) := . OFF.BY #FL.ACT IF #FL.FKY SET.IN LV.FLG(LEVEL) ;DID I FIND ANY AT THIS LEVEL? FORET #ER.NMK,ERR ;YES, RETURN NO MORE KEYS ;AND CLEAR THE KEY FOUND BIT LET LV.FLG(LEVEL) := . OFF.BY #FL.FKY RETURN ELSE FORET #0,ERR ;NO, RETURN NO KEYS FOUND RETURN END END END IF (BUF) EQ #0 ;IS THIS KEY A DELETED ONE? LET BUF := BUF + LV.LEN(LEVEL) ;YES, SKIP TO NEXT KEY GOTO REPEAT END LET LV.PCE(LEVEL) := BUF ;POINT STRUCTURE AT THIS NEW KEY LET TEM2 := LV.SCN(LEVEL) ;GET LENGTH OF SCAN SECTION IF RESULT IS GT ;IS THERE ANYTHING TO SCAN??? LET TEM2 := . + BUF ;GET ADDRESS OF END OF KEY LET -(SP) :B= (TEM2) ;PUSH THE NEXT BYTE ON SYS STACK LET (TEM2) :B= #0 ;ZERO IT FOR $MATCH ;SET UP THE REGESTERS FOR CALLING ;THE STRING PATTERN RECOGNITION ROUTINE LET R0 := PATT(R5) ;POINT R0 AT PATTERN LET R1 := BUF ;POINT R1 AT KEY SCALL $MATCH ;CALL MATCH ON.ERROR ;RATS! THEY DIN'T MATCH, NOW I HAVE LET TEM := BUF + LV.SCN(LEVEL) ;TO CLEAN UP AFTER MYSELF LET (TEM) :B= (SP)+ ;RECOVER THE BYTE YOU ZEROED LET BUF := BUF + LV.LEN(LEVEL) ;INCRIMENT TO THE NEXT KEY GOTO REPEAT END LET TEM := BUF + LV.SCN(LEVEL) ;I HAVE TO CLEAN UP EVEN WHEN THE LET (TEM) :B= (SP)+ ;MATCH WAS A SUCCESS END SCALL B$GETKEY ;RETURN THE KEY AND VAL PARAMETERS ;SET THE FOUND A KEY FLAG LET LV.FLG(LEVEL) := . SET.BY #FL.FKY ENDPROCEDURE MATCHK .END