.TITLE GREP -- GET REPRESENTATION .IDENT /1.4X/ ;+ ; Abstract: GREP ; ; This program will print out all files which have a specifec ; string contained in them, and print the lines in the files ; which contain the string. ; ; Operating procedures: ; ; GREP [ =] /SE:/CO:NNN ; ; May be any legal filename to which the output will ; be written. If not specified, OUTPUT will be written ; to the user's terminal. If OUTPUT is to other ; than a terminal (i.e., a file or LP:) the output will ; preceded by the command line. Multiple commands to ; the same output file (or LP:) will be delimited by a ; line of astericks. ; ; May be any legal RSX-11 filespec, and may have ; *-file names. If a * is used, the version defaults ; to * automatically. For example, X.MAC, TEST.*, *.PLI. ; ; May be any string with the following restrictions: ; If the string is unquoted: ; 1) Embedded blanks and tabs will be ignored. ; 2) The characters ',', '=', '[', ']', '/', ':' and ';' ; cannot be used in the string since they are ; treated as special characters by the command ; string interpreter. ; 3) Everything is passed if it is contained in " ". ; ; If the string is enclosed in leading and trailing ; quotes ("), everthing contained within the quotes is passed ; for matching. Note that this means that: ; A) Quotes can not be searched for if they are the first ; or first and last characters of the string. ; B) Upper case characters must be entered for the search ; string. ; ; ; Wildcards: ; ; & Any character '&' (ampersand) in the search will match exactly ; 1 character in the files regardless of what it is. ; - Any character '_' will match exactly 1 space character. ; \ Any character '\' (backslash) will match any of the above ; characters in (2) but no others ; ; /CO:nnn ; The switch /CO:NNN will list the match line and nnn (decimal) ; lines after it in the source. Lines whose first character is ; form feed will however terminate the /CO:NNN print scan. ; Default lists only the matching line. ; ; WRITTEN: 3-AUG-78, -0.0.0-, BRUCE C. WRIGHT ; MODIFIED: ; VERIFIED: ; ; +001 MAY 1979 RAY FRENCH CHANGED OUTPUT QIO'S TO RECORD I/O ; AND ADDED OUTPUT FILESPEC. MINOR ; MODIFICATIONS TO OUTPUT TO IMPROVE ; READABILITY. ; +002 MAY 1979 RAY FRENCH ADDED LINE NUMBERS TO OUTPUT. ; ; JGD1 MARCH 1980 J. DOWNWARD FIXED BUG CAUSED BY TRANSFERING ; FROM IAS TO 11M($CBDMB DOES NOT SAVE ; R2.) ; JGD2 MODIFIED TO SUPPORT BIG BUFFERING ; RSX11M STYLE RATHER THAN MULTI- ; BUFFERING. ; JGD3 FIXED BUG WITH OVERWRITING FILE ; HEADER ON WILDCARD SEARCHES. ; JGD4 IF NO DEVICE SPECIFIED IN , ; ; JGD5 J. DOWNWARD ATTACH TERMINAL SO OUTPUT CAN BE ^O'ed ; OUTPUT DEFAULTS TO SY: ; ; JGD6 March 81 J. DOWNWARD Use the "_" to match a space. ; ; GCE1 G. EVERHART ADDED MATCH CHARS & AND \ ; ADDED /CO:NNN SUPPORT FOR MULTILINE ; RETRIEVALS. ; GCE2 G. EVERHART ALLOW LOWER CASE CHARACTERS TO MATCH ; UPPER CASE SEARCH STRINGS. CONVERT ; BOTH TO UPPERCASE. ; ALLOW SPACE TO MATCH \ IN SEARCH STRING. ; JGD7 11-Feb-1983 J. Downward Attach os can ^O, also allow ^C, ^Y ; and ^Z to abort listing. Allow a ; quoted string to be passed so that ; all characters can be searched for ; (except quotes) ;- ; .MCALL QIOW$,EXIT$S .MCALL GCMLB$,GCML$,CSI$,CSI$1,CSI$2,CSI$SW,CSI$SV,CSI$ND .MCALL FINIT$,FSRSZ$,FDBDF$,FDOP$A,CLOSE$,OFID$R,GET$ .MCALL FDBF$R,FDRC$R .MCALL FHDOF$,FDOF$L,NBOFF$ .MCALL FDAT$A,NMBLK$,OPEN$W,PUT$ ;+001 .MCALL DIR$ ; JGD5 .MCALL ASTX$S ; JGD6 ; ; Multi-Block count (Big Buffering) ; JGD2 ; ; JGD2 MBCT = 2. ; JGD2 ; .MACRO ERRMSG MSG .NCHR $$$, JSR R0,$TYPE .WORD $$$ .ASCII "MSG" .EVEN .ENDM FHDOF$ DEF$L ; DEFNE FILE HEADER OFFSETS NBOFF$ DEF$L ; DEFINE NAME BLOCK OFFSETS LOCALLY ; ; COMMAND LINE MACROS AND DATA BLOCKS GCLBLK: GCMLB$ 1,GRE,HEADER,2 CSI$ .EVEN CSIBLK: .BLKB C.SIZE ; CSI BLOCK .EVEN SWTABL: CSI$SW SE,SW.SE,SWORD,SET,,SVTABL CSI$SW CO,SW.CO,AUXSW,,,SVTB2 SW.CO=2 ;CO:NNN CONTINUE LISTING FOR NNN LINES CSI$ND SVTABL: CSI$SV ASCII,STRBUF,STRLEN SVTB2: CSI$SV DECIMAL,COSIZ,2 ;2 BYTE DECIMAL NO CSI$ND AUXSW: .WORD 0 ;AUX SWITCH WORD (DON'T INTERFERE WITH SWORD) SWORD: .WORD 0 SW.SE = 000001 ;SE - SELECT STRING COCNT: COSIZ: .WORD 0 ;LENGTH FOR /CO:NNN SCANS ; HEADER: .BLKB 82. LINBUF: .BLKB 50. ; MUST USE DIFFERENT BUFFER BECAUSE ; JGD3 .BLKB 82. ; THE FILE STRING WILL GET OVERWRITTEN ; JGD3 STAT: .WORD 0 ; BUFFER FOR STATISTICS BLOCK .WORD 0 .WORD 0 WLDFLG: .WORD 0 ; FLAG FOR WILD CARDS QOTFLG: .BYTE 0 ; Set if first char is a quote ;JGD6 .EVEN DEV: .ASCII /SY:/ .EVEN ; I/O MACROS AND DATA BLOCKS FDOF$L FSRSZ$ MBCT+1 ; SET UP FOR BIG BUFFERING ; JGD2 FDB: FDBDF$ ; START OF FDB FDBF$A ,BUFLEN ; DEFINE THE BUFFER'S LENGTH FDOP$A 1,CSIBLK+C.DSDS BUFFER: .BLKB 1000*MBCT BUFLEN = .-BUFFER BUFEND: .WORD 0 LINFLG: .WORD 0 STRBUF: .BLKB 80. STRLEN = .-STRBUF ; FDB1: FDBDF$ ;+001 - FDB FOR OUTPUT FILE FDAT$A R.VAR,FD.CR,132. ;+001 FDOP$A 3 ;+001 ASTER: .BYTE 12 ;+001 - LINE OF ASTERICKS FOR OUTPUT .REPT 10 ;+001 .ASCII /**********/ ;+001 .ENDR ;+001 .EVEN COMMD: .WORD 0 ;+001 - POINTER FOR START OF COMMAND COUNT: .BLKW 1 ;+002 - LINE COUNTER CLDSPT: .WORD 3,DEFDEV ;+001 - DATASET DESCRIPTOR FOR 'TI:' .WORD 0,0,0,0 ;+001 DEFDEV: .ASCII /SY:/ ; OUTPUT BY DEFAULT TO SY: ; JGD .EVEN ; ; Read and decode the command line ; ; A rather sneaky quirk pops up in using CSI$1 and CSI$2. ; If the input command line omits the DEV: and the [UIC], ; nothing is placed in the CSI file descriptor block (pointed to by ; C.DEVD etc.). Now all is ok if one just wishes to decode the ; command line and then open the file. OPEN assumes that if the DEV ; and UIC are missing it should open the file using the current terminal ; UIC and the disk from which the task is initially installed. ; One never notices a problem if the utility is run using the RUN $ ; convention. However, if the utlity is installed off of say DK0: ; (ASN SY:=SY:/LOGIN) then a user whose system device is different ; (ASN DKN:=SY:/LOGIN) then it is mandatory to put in a DEV: in the file ; spec, because if it is omitted the utility can not find the file on ; the user's system device. ; ; The matter is further complicated if .PARSE and .FIND are to be ; used. They will not parse and find a file correctly if the command ; line assumes the device will default to SY:. The solution to this ; is to test the command line to see if a DEV: is specified. If not ; insert a SY: ; ; One nice feature of this quirk, and (using hindsight) a much used ; feature of the command string interpreters, is that once a DEV: or ; [UIC] is specified in a command line, all subsequent file specifiers ; can omit them. ; ; .ENABLE LC GREP: FINIT$ ; INITIALIZE FSR START: GCML$ #GCLBLK ; GET COMMAND LINE BCS 10$ ; ERROR? CLR CNTCTR ;GCE1 - NO LEFTOVER CONTINUES MOV #HEADER,R1 ;+001 - POINT TO COMMAND LINE MOV GCLBLK+G.CMLD,R2 ;+001 - SIZE IN R2 1$: CMPB #' ,(R1)+ ;+001 - SEARCH FOR A BLANK BEQ 2$ ;+001 SOB R2,1$ ;+001 MOV #HEADER,COMMD ;+001 - NO BLANKS, SO POINT TO START JMP CONTIN ;+001 2$: MOV R1,COMMD ;+001 - SAVE THE POINTER JMP CONTIN ; NO ERROR, SO SKIP AROUND 10$: CLR CNTCTR ;GCE1 - NO LEFTOVER CONTINUES CMPB #GE.IOR,GCLBLK+G.ERR ; I/O ERROR? BNE 20$ ; NO ERRMSG EXIT$S ; THIS IS FATAL 20$: CMPB #GE.OPR,GCLBLK+G.ERR ; OPEN ERROR? BNE 30$ ; NO ERRMSG JMP START ; RE-DO CMD LINE 30$: CMPB #GE.MDE,GCLBLK+G.ERR ; MAX @ DEPTH? BNE 40$ ; NO ERRMSG JMP START 40$: CMPB #GE.BIF,GCLBLK+G.ERR ; SYNTAX ERROR? BNE 50$ ; NO ERRMSG JMP START ; RE-START PGM 50$: CMPB #GE.EOF,GCLBLK+G.ERR ; END-OF-FILE? BEQ EXIT ; YES ERRMSG EXIT: CLOSE$ #FDB1 DIR$ #DTCH ; DETACH TERMINAL ; JGD5 EXIT$S ; NO INPUT SO EXIT SERR: ERRMSG JMP START ; CONTIN: DIR$ #ATCH ; ATTACH TI: ; JGD5 CLR WLDFLG ; ASSUME NO WILDCARDS TO START WITH CLR CNTCTR ;ASSUME NO CONTINUATION ACROSS FILES ; GCE1 TST ; IS ANYTHING TYPED BNE 1$ ; YES -- INTERPRET IT JMP START ; 1$: CLRB STRBUF ; NUL PAD THE STRING BUFFER. CSI$1 #CSIBLK,GCLBLK+G.CMLD+2,GCLBLK+G.CMLD ; CHECK SYNTAX BCS SERR ; ERROR IN SYNTAX FOUND TST ; JUST IN CASE A BUNCH OF SPACES FOLLOWED ; BY A ^Z WERE TYPED, CHECK TO BE SURE >0 ; PARSED CHARACTER IS IN THE CSIBLK BNE 2$ ; ONLY ONE CHARACTER EXIT JMP EXIT ;+001 2$: ;+001 ; DECODE THE COMMAND LINE AND OPEN OUTPUT FILE ; MOV #CSIBLK+C.STAT,R0 ; GET ADDRESS OF STATUS WORD BITB #CS.EQU,(R0) ; WAS AN EQUAL SIGN SEEN? BNE 3$ ;+001 - IF SO, JUST CONTINUE JMP 20$ ;+001 - OTHERWISE JUMP 3$: CSI$2 #CSIBLK,OUTPUT ;+001 - DECODE THE OUTPUT FILE BCS SERR ;+001 - CHECK FOR ERROR DIR$ #DTCH ; DETACH TI: ; JGD5 TST FDB1+F.FNB ;+001 - IS AN OUTPUT FILE OPEN? BEQ 10$ ;+001 - IF NOT, DON'T TRY TO CLOSE IT CLOSE$ #FDB1 ;+001 - CLOSE THE OLD ONE 10$: TST CSIBLK+C.DEVD ; WAS A DEVICE SPECIFIED ; JGD4 BNE 15$ ; IF >0 YES ; JGD4 MOV #3,CSIBLK+C.DEVD; NO, MOVE IN LENGTH ; JGD4 MOV #DEFDEV,CSIBLK+C.DEVD+2 ; SET ADDRESS OF DEFAULT DEVICE ; JGD4 15$: OPEN$W #FDB1,,#CSIBLK+C.DSDS ;+001 - OPEN THE OUTPUT FILE ; JGD4 CSI$2 #CSIBLK,INPUT,#SWTABL ;+001 - DECODE THE INPUT FILE BCC CONT ; JMP SERR ; 20$: MOV #"TI,DEFDEV ; DEFAULT OUT TO TI: ; JGD CSI$2 #CSIBLK,OUTPUT,#SWTABL ; DECODE THE FILE NAME BCC 30$ ; ANY ERRORS? JMP SERR ; IF SO, SYNTAX ERROR 30$: TST FDB1+F.FNB ;+001 - IS OUTPUT FILE OPEN? BNE CONT ;+001 - IF SO, DON'T TRY TO OPEN ONE CLR FDB1+F.DSPT ;+001 - MAKE SURE WE GET THE DEFAULT FILENAME OPEN$W #FDB1,,#CLDSPT ;+001 - OPEN THE DEFAULT OUTPUT FILE CONT: BITB #FD.TTY,FDB1+F.RCTL ;+001 - WRITING TO TTY ? BNE 10$ ;+001 - IF SO, SKIP ASTERICKS AND COMMAND DIR$ #DTCH ; DETACH TI: ; JGD5 TST FDB1+F.NRBD ;+001 - WAS FILE JUST OPENED ? BEQ 1$ ;+001 - THEN FORGET ASTERICKS PUT$ #FDB1,#ASTER,#81. ;+001 - WRITE LINE OF ASTERICKS 1$: PUT$ #FDB1,COMMD,GCLBLK+G.CMLD ;+001 - AND PRINT COMMAND 10$: ;+001 CLR CNTCTR ;GCE1 - ASSUME NO CONTINUATION ACROSS FILES ; ; NOW CHECK TO SEE IF WILD CARDS ARE SPECIFIED ; MOV #CSIBLK+C.STAT,R0 ; GET ADDRESS OF STATUS WORD BITB #CS.WLD,(R0) ; ANY WILD CARDS BEQ 5$ ; IF EQ, NO WILD CARDS INC WLDFLG ; SET WILDCARD FLAG ; ; DO WE NEED TO INSERT A SY:? ; 5$: BITB #CS.DVF,(R0) ; WAS DEV SPECIFIER FOUND IN CURRENT COMMAND BNE 15$ ; IF NE YES, SO DON'T FILL IN SY: ; NO, FIRST INIT THE DEV STRING IN THE CSIBLK ; TO BE 'SY0:' MOV #CSIBLK+C.DEVD,R0 ; GET ADDRES OF BYTE COUNT MOV #2,(R0) ; FIRST INSERT NEW BYTE COUNT MOV #CSIBLK+C.DEVD+2,R0 ; GET ADR OF PNTR TO DEV STRING IN CSIBLK MOV #DEV,(R0) ; INSERT NEW ADDRESS TO DEVICE STRING 15$: MOV #FDB,R0 ; FDB ADRESS IN R0 MOV #FDB+F.FNB,R1 ; FNB ADDRESS IN R1 MOV #CSIBLK+C.DSDS,R2 ; DATASET POINTER IN R2 CLR R3 CALL .PARSE ; PARSE THE FDB BCC 20$ ; ALL OK SO SKIP ERROR MESSAGE CALL FERR ; ERROR (FCS) FOUND JMP START ; AND RE-START. 20$: TST WLDFLG ; WILDCARD OPERATION? BEQ RETURN ; IF EQ NO BIS #NB.SVR, ; YES, SO SET THE FLAG BIT ; TO INSURE ANY VERSION WILL BE OPENED RETURN: CALL .FIND ; FIND THE FILE BCS OPNERR ; IF CARRY SET, ERROR TST WLDFLG ; IS THIS A WILD CARD GREP? BEQ OPEN ; IF EQ NO, SO GO DIRECTLY TO OPEN FILE CLR CNTCTR ;NO LEFTOVER CONTINUES ; CGE1 CMP , ; DO WE HAVE A NEW FILE? BEQ RETURN ; NO, TRY AGAIN RET1: MOV , ; SAVE INDEX POINTER MOV , ; SAVE STATUS BR OPEN ; TRY AND OPEN FILE OPNERR: CMPB #IE.NSF,FDB+F.ERR ; IS IT NO SUCH FILE? BEQ 5$ ; YES 3$: CALL FERR ; NO, IT MUST BE AN FCS ERROR JMP START ; AND RE-START. 5$: TST WLDFLG ; IS THIS A WILDCARD OPERATION BEQ 3$ ; NO, NSF IS NOT NORMAL ; YES, NSF IS NORMAL. CLR ; RESET INDEX POINTER JMP START ; AND BACK FOR MORE ; ;CONTINUE COUNTER CNTCTR: .WORD 0 ;NO LINES TO EMIT ;ILLEGAL CSI CHARACTER LIST ILLST: .ASCII ",=[]/ :;" ; NOTE SPACE IS ONE OF THE CHARS ILSIZ=.-ILLST .EVEN ; ; OPEN THE FILE AND LOOK AT IT. ; OPEN: CLR LINFLG ; CLEAR HEADER PRINT FLAG. FDRC$R #FDB,#FD.PLC FDBF$R #FDB,,#BUFLEN ; USE BIG BUFFERING OFID$R #FDB ; OPEN THE FILE BY ID BCC LOOKA ; FILE OPENED WITHOUT ERRORS CALL FERR ; PRINT FILE ERROR CMPB #IE.PRI,FDB+F.ERR ; DID WE PERHAPS HAVE A PRIVLEGE VIOLATION? ; IF SO IGNORE IT AND CONTINUE BECAUSE FILES ; MAY BE ENTERED FROM ANOTHER DIRECTORY BEQ NXT ; PRIVLEGE VIOLATION - DON'T TRY TO OPEN CMPB #IE.VER,FDB+F.ERR ; PARITY ERROR ON DEVICE? BEQ NXT ; YES -- DON'T TRY TO OPEN CMPB #IE.BBE,FDB+F.ERR ; BAD BLOCK ON DEVICE? BEQ NXT ; YES -- DON'T TRY TO OPEN CMPB #IE.FHE,FDB+F.ERR ; FATAL HARDWARE ERROR? BEQ NXT ; YES -- DON'T TRY TO OPEN CMPB #IE.BCC,FDB+F.ERR ; BLOCK OR CRC ERROR? BEQ NXT ; YES -- DON'T TRY TO OPEN CMPB #IE.LCK,FDB+F.ERR ; LOCKED FROM WRITE? BEQ NXT ; YES -- DON'T TRY TO OPEN CMPB #IE.WAC,FDB+F.ERR ; ACCESSED FOR WRITE? BEQ NXT ; YES -- DON'T TRY TO OPEN CMPB #IE.CKS,FDB+F.ERR ;HEADER CHECKSUM FAILURE? BEQ NXT ; YES -- DON'T TRY TO OPEN CMPB #IE.RER,FDB+F.ERR ; DEVICE READ ERROR? BEQ NXT ; YES -- DON'T TRY TO OPEN CMPB #IE.SNC,FDB+F.ERR ; FID, FILE NUMBER CHECK? BEQ NXT ; YES CMPB #IE.SQC,FDB+F.ERR ; FID, SEQUENCE CHECK? BEQ NXT ; YES CMPB #IE.CLO,FDB+F.ERR ; NOT PROPERLY CLOSED? BEQ NXT ; YES CMPB #IE.BHD,FDB+F.ERR ; BAD FILE HEADER? BEQ NXT ; YES CMPB #IE.EXP,FDB+F.ERR ; EXPIRATION DATE ? BEQ NXT ; YES JMP START ; SOMETHING WORSE - GIVE UP. NXT: JMP NEXT ;+001 LOOKA: CLR COUNT ;+002 - CLEAR LINE COUNTER CLR CNTCTR ;INITIALIZE MATCH COUNTER TO NO MATCH ; GCE1 LOOK: INC COUNT ;+002 - INCREMENT LINE COUNTER GET$ #FDB,#BUFFER,#BUFLEN,FILERR TST XITFLG ; Should we exit ; jgd6 BLE 5$ ; If LE, no ; JGD6 JMP 180$ ; If GT, yes ; JGD6 5$: MOV FDB+F.NRBD+2,R2 ; GET THE START OF THE BUFFER IN R2. MOV FDB+F.NRBD,R3 ; AND LENGTH OF BUFFER. ADD FDB+F.NRBD+2,R3 ; POINT TO LAST BYTE OF BUFFER. CMPB @R2,#14 ;FORMFEED IN START OF BUFFER? ; GCE1 BNE 10$ ;IF NOT NORMAL USE ; GCE1 CLR CNTCTR ;IF SO, END ANY CONTINUATION PRINTS ; GCE1 10$: MOV R2,-(SP) ; SAVE BUFFER POINTER. MOV #STRBUF,R4 ; GET STRING ADDR MOV #STRLEN,R5 ; AND LENGTH CMPB #'",(R4) ; Is first character a quote ; jgd6 BNE 20$ ; If No, skip ; jgd6 MOVB #1,QOTFLG ; Set 1st char is quote flag ; jgd6 INC R4 ; Point to next char ; JGD6 20$: TSTB (R4) ; AT END OF DATA? BEQ 110$ ; YES TSTB QOTFLG ; Is quote flag set ; jgd6 BEQ 25$ ; No don't check for quote ; jgd6 CMPB #'",(R4) ; Is it a quote ; JGD6 BNE 25$ ; No, just proceed ; JGD6 TSTB 1(R4) ; Is net char end of data? ; JGD6 BNE 25$ ; If NE, no, count the quote ; JGD6 JMP 110$ ; If last char is ", its end of data ; JGD6 25$: CMP R2,R3 ; OVER TOP OF BUFFER? BHIS 170$ ;SKIP TEST FOR CONT IF AT BUFF END ; GCE1 CMPB @R4,#'& ;MATCH CHAR FOR ANY CHARACTER? ; GCE1 BNE 40$ ;IF NO, LOOK MORE ; GCE1 30$: CMPB (R2)+,(R4)+ ;YES, BUMP POINTERS ; GCE1 BR 100$ ;AND SKIP REAL TEST ; GCE1 40$: CMPB @R4,#'_ ; Match a space ; JGD6 BNE 50$ ; If NE, no, check for a \ ; JGD6 MOVB #40,@R4 ; If EQ, replace with a space ; JGD6 50$: CMPB @R4,#'\ ;BACKSLASH MATCH FOR CSI ILLEGAL CHARS? ; GCE1 BNE 80$ ;IF NOT, DO NORMAL PROCESSING ; GCE1 MOV R0,-(SP) ; MOV R1,-(SP) ; MOV R4,-(SP) ;CHECK FOR ONE OF CSI REJECTED CHARS ; GCE1 MOVB @R2,R4 ;GET TEXT CHAR. ; GCE1 MOV #ILLST,R0 ;LIST OF REJECTS HERE ; GCE1 MOV #ILSIZ,R1 ;AND ITS SIZE ; GCE1 60$: CMPB R4,(R0)+ ;GOT IT? ; GCE1 BEQ 70$ ;IF SO REJOICE ; GCE1 SOB R1,60$ ;IF NOT KEEP TRYING ; GCE1 ;FAILED SO DO USUAL JUNK MOV (SP)+,R4 MOV (SP)+,R1 MOV (SP)+,R0 ;RESTORE REGS AND LET CMP FAIL ; GCE1 BR 80$ 70$: MOV (SP)+,R4 ;SUCCEEDED SO SKIP COMPARE ; GCE1 MOV (SP)+,R1 MOV (SP)+,R0 BR 30$ ;SKIP COMPARE, CLAIM SUCCESS. 80$: BITB #100,@R4 ;IS SEARCH CHAR UPPERCASE? ;GCE2 BEQ 90$ ;IF NOT, BRANCH ;GCE2 BITB #40,@R4 ;IF SEARCH FOR LOWERCASE LEAVE ;GCE2 BNE 90$ ;ONLY CHECK & FOLD CASES IF U/C SEARCH ;GCE2 BITB #100,@R2 ;IS FILE POSSIBLE LOWERCASE? ;GCE2 BEQ 90$ ;NO, SO LEAVE FILE CHAR ALONE ;GCE2 BICB #40,@R2 ;IF SO, FORCE UPPERCASE FILE CHAR. ;GCE2 90$: ; ;GCE2 CMPB (R2)+,(R4)+ ; CORRECT BYTE? BNE 150$ ; NO 100$: DEC R5 ; YES, SO KEEP GOING BGT 20$ ; AND LOOP OVER THE STRING. 110$: MOV (SP)+,R2 ; MOV COCNT,CNTCTR ; SET UP N EXTRA PRINTS TO DO. ;GCE1 TST LINFLG ; PRINTED FILE NAME? BNE 120$ ; YES CALL PRTFIL ; NO -- PRINT IT. INC LINFLG ; SIGNAL LINE PRINTED. 120$: MOV #LINBUF,R0 ;+002 - BUFFER ADDRESS IN R0 MOV COUNT,R1 ;+002 - LINE NUMBER IN R1 MOV #3,R2 ;+002 - 3 BYTE TO CLEAR (ALSO NZS FLAG) JSR PC,$CBDMG ;+002 - CONVERT COUNT AND PUT IN BUFFER MOV #3,R2 ; LOOP COUNT ; JGD0 130$: MOVB #' ,(R0)+ ;+002 - BLANK 3 BYTES SOB R2,130$ ;+002 MOV FDB+F.NRBD+2,R1 ;+002 - GET BUFFER ADDRESS MOV FDB+F.NRBD,R2 ;+002 - GET BYTE COUNT ADD #10,R2 ;+002 - INCREASE BY 10 MOV R2,-(SP) ;+002 - SAVE IT 140$: MOVB (R1)+,(R0)+ ;+002 - ADD RECORD TO BUFFER SOB R2,140$ ;+002 PUT$ #FDB1,#LINBUF,(SP)+,FILERR ;+001 - PRINT IT JMP LOOK ; AND LEAVE. 150$: DEC CNTCTR ;COUNT DOWN CONTINUES TO DO ;GCE1 TST CNTCTR ;ANY CONTINUATIONS TO PRINT? ;GCE1 BLE 160$ ;IF NONE, GO TO NORMAL PROC. ;GCE1 MOV (SP)+,R2 ;ELSE GET BUFF POINTER OFF STACK ;GCE1 BR 120$ ;AND GO PRINT ONE LINE ;GCE1 160$: CLR CNTCTR ;CLAMP TO ZERO IF NEGATIVE ;GCE1 170$: MOV (SP)+,R2 ; RECOVER BUFFER POINTER. INC R2 ; POINT TO NEXT POSITION. CMP R2,R3 ; OVER TOP OF WHOLE BUFFER? BLO 175$ ; No, Not yet. ;jgd6 JMP LOOK ; AND LOOK AT NEXT RECORD. 175$: JMP 10$ ; no, not yet ;JGD6 180$: MOV #IE.EOF,F.ERR(R0); Requested exit, make it look like EOF;JGD6 DIR$ #DTCH ; Detach terminal ;JGD6 BR EOF ; and skip popping return address ;JGD6 FILERR: TST (SP)+ ; POP OFF RETURN ADDR CLR CNTCTR ;ERROR MEANS NO CONTINUES...GCE1 EOF: CMPB F.ERR(R0),#IE.EOF ; IS IT EOF? ;jgd6 BEQ 10$ ; NO -- ERRPR CALL FERR ; SIGNAL ERROR 10$: CLR CNTCTR ;GCE1 - SAY NO CONTINUATION ACROSS FILES CLOSE$ #FDB ; CLOSE THE FILE. BCC NEXT ; FILE COULD BE OPEND AND CLOSED CALL FERR ; FILE COULD EITHER NOT BE OPEND ; OR CLOSED JMP START ; AND RE-START NEXT: TST WLDFLG ; IS THIS A WILDCARD OPEN? BGT 10$ ; YES, SO SKIP OVER JMP START ; NO ERRORS, SO CHECK FOR MORE 10$: MOV #FDB,R0 ; FDB ADDRESS IN R0 MOV #FDB+F.FNB,R1 ; FNB ADDRESS IN R1 MOV , ; RESET FOR .FIND MOV , ; CLR CNTCTR ;ERROR MEANS NO CONTINUES...GCE1 JMP RETURN ; AND LOOP SOMEMORE PRTFIL: MOV R0,-(SP) MOV R1,-(SP) MOV R2,-(SP) MOV R3,-(SP) JMP FERR1 FERR: MOV R0,-(SP) ;SAVE R0 MOV R1,-(SP) ;SAVE R1 MOV R2,-(SP) ;SAVE R2 MOV R3,-(SP) ; SAVE R3 MOV #M.FCS,R1 ; ADDR OF FCS MSG MOV #L.FCS,R2 ; LENGTH OF FCS MSG CALL .PRFCS ; PRINT FCS MSG FERR1: MOV #DEVMSG,R1 ; POINT TO DEVICE MSG MOVB #12,(R1)+ ;+001 - PUT IN A LINE FEED MOV #40.,R0 ;GET MAX LENGTH. MOV CSIBLK+C.DEVD,R2 ; GET DEVICE SPEC LEN BLE 12$ ; NONE? MOV CSIBLK+C.DEVD+2,R3 ; GET DEVICE SPEC ADDR 10$: MOVB (R3)+,(R1)+ ; MOVE IN DEVICE SPEC DEC R0 ; DEC TOTAL SPACE BLE 80$ ; SKIP OUT ON 0 SOB R2,10$ ; MOVE IN DEVICE SPEC MOVB #':,(R1)+ ; MOVE IN A : DEC R0 ; DEC TOTAL SPACE BLE 80$ ; SKIP OUT ON 0 12$: MOV CSIBLK+C.DIRD,R2 ; GET UIC SPEC LEN BLE 22$ ; NONE? MOV CSIBLK+C.DIRD+2,R3 ; GET UIC SPEC ADDR 20$: MOVB (R3)+,(R1)+ ; MOVE IN UIC SPEC DEC R0 ; DEC TOTAL SPACE BLE 80$ ; SKIP OUT ON 0 SOB R2,20$ ; MOVE IN ALL OF UIC 22$: MOV R0,-(SP) ;SAVE R0 MOV R1,-(SP) ; AND R1 MOV #TEMP,R0 ; POINT TO HEADER BUFFER. MOVB #':,(R0)+ ; BASE PTR MOV FDB+F.FNB+N.FNAM,R1 ; CONVERT FNAM TO RAD50 CLR R2 ; CALL $C5TA ; MOV FDB+F.FNB+N.FNAM+2,R1 CALL $C5TA MOV FDB+F.FNB+N.FNAM+4,R1 CALL $C5TA 30$: CMPB #' ,-(R0) ;IS IT A BLANK? BEQ 30$ ;YES INC R0 ; MOV FDB+F.FNB+N.FTYP,R1 BNE 35$ ; PRINT IT IF SPECIFIED CMP R0,#TEMP+1 ;IS THIS THE BEG. OF STRING? BNE 45$ ; NO -- DON'T PRINT THE . 35$: MOVB #'.,(R0)+ ; MOVE IN A . CALL $C5TA ;TYPE FIELD TO ASCII 40$: CMPB #' ,-(R0) ;IS IT A BLANK? BEQ 40$ ;YES INC R0 ; 45$: MOV FDB+F.FNB+N.FVER,R1 ;GET FILE VERSION BEQ 50$ ;NONE? MOVB #';,(R0)+ ;MOVE IN A ';' CLR R2 ; SUPPRESS 0'S CALL $CBOMG ; CONVERT VERSION # 50$: MOV #TEMP+1,R3 ; SAVE ADDR SUB R3,R0 ; COMPUTE LENGTH MOV R0,R2 ;SAVE IN R2 MOV (SP)+,R1 ;RECOVER R1 MOV (SP)+,R0 ;RECOVER R0 60$: MOVB (R3)+,(R1)+ ; MOVE IN FILE DEC R0 ; DEC TOTAL SPACE BLE 80$ ; SKIP OUT ON 0 SOB R2,60$ ; MOVE IN ENTIRE FILE 80$: SUB #DEVMSG,R1 ;COMPUTE LEN OF MSG PUT$ #FDB1,#DEVMSG,R1,FILERR ;+001 - PRINT IT MOV (SP)+,R3 ;RECOVER R3 MOV (SP)+,R2 ; RECOVER R2 MOV (SP)+,R1 ; RECOVER R1 MOV (SP)+,R0 ; RECOVER R0 RTS PC $TYPE: MOV (R0)+,QIOW+Q.IOPL+2 ;MOVE IN QIO LENGTH MOV R0,QIOW+Q.IOPL ;AND ADDRESS MOV #QIOW,-(SP) CALL .DIRDL ADD -2(R0),R0 ;ADD IN QIO LENGTH INC R0 ;INC R0 TO GET TO EVEN BOUND. BIC #1,R0 ;CLEAR LOW BIT - RTS TO EVEN BOUND. RTS R0 ;AND RETURN TO CALLER. ;+ ;JGD6 ; INPAST ;JGD6 ; Catch an unsolicited input AST. If the user types ;JGD6 ; ^C, Control_Y or Control-Z, close files and exit. ;JGD6 ; Otherwise ignore. ;JGD6 ;- ;JGD6 CTRLC=3 ;JGD6 CTRLY=31 ;JGD6 CTRLZ=32 ;JGD6 INPAST: ;JGD6 BIC #177400,(SP) ; Clear off the high byte ;JGD6 CMP (SP),#CTRLC ; Is it control_C ;JGD6 BEQ 10$ ; If EQ, yes ;JGD6 CMP (SP),#CTRLY ; Is it control_Y? ;JGD6 BEQ 10$ ; If EQ, yes ;JGD6 CMP (SP),#CTRLZ ; Is it Control_Z ;JGD6 BNE 20$ ; If NE, no ;JGD6 10$: INC XITFLG ; Show we should exit ;JGD6 20$: TST (SP)+ ; Otherwise pop stack ;JGD6 ASTX$S ;JGD6 ; TERMINAL QIO QIOW: QIOW$ IO.WVB,3,1,,,,<0,0,40> ATCH: QIOW$ IO.ATA!TF.XCC,3,1,,,, ; JGD6 DTCH: QIOW$ IO.DET,3,1 ; JGD5 XITFLG: .WORD 0 ; JGD6 M.FCS: .ASCII /GRE/ L.FCS = .-M.FCS .EVEN .EVEN ; ERROR MESSAGES DEVMSG: .BLKB 40. .EVEN TEMP: .BLKB 40. .END GREP