; Search a list of files for a string ; ; FIND 2.0 ; (c) 1986,1987,1988 By Ami Bar-Yadin ; AMUS ID: AMI/AM ; ;-All commercial rights reserved, etc. ;-No warranties and/or guarranties of any kind, etc. ;-Not responsible for damages resulting from the use of this program, etc. ;-My employer (United Fashions) has nothing to do with this program and ; should not be blamed for it. ; ; I can be reached at: ; United Fashions of Texas, Inc. ; 200 Ash Ave. ; McAllen, TX 78501 ; (512) 631-2277/2276 ; 8am-6pm ; ; ; Syntax: FIND {=}[...]{/switch} ; Output will go to terminal if no output file is specified ; ; Switches: ; D-opr Data mode. Don't output matching lines. Valid only ; if using an output file. The output file will only contain ; the names of files with a match. ;(def) NOD-opr NODELETE, don't allow output file to be overwritten ; DE-opr DELETE, allow file to be overwritten ;(def) C-fil Cut line, only show from match to end of line ;(def) F-fil Fold upper/lower case in match (use UCS on both sides) ; L-fil Include last BASIC label in output ;(def) R-fil Include record (line) numbers in output ; ; VMAJOR=2 VEDIT=3 SYM SEARCH SYS SEARCH SYSSYM SEARCH TRM RADIX 16. DEFAULT VEDIT,1 DEFAULT $$MFLG,PV$RSM!PV$WSM DEFAULT $$SFLG,PH$REE!PH$REU DEFAULT $$SFLG,0 DEFAULT $$LFLG,-1 PHDR $$LFLG,$$MFLG,$$SFLG ; ; CR = 13. LF = 10. TAB = 9. ; Local macros ; DEFINE OUTA2 ADR LEA A2,OUTDDB(A5) MOV OUTFIL(A5),D6 OUTL ADR ENDM ; DEFINE SWENT NAME,ADDR WORD 1$$-. WORD ADDR-. ASCII NAME BYTE 0 EVEN 1$$: ENDM ; Impure definition ; init impure DEFINE IMPINI START DSECT IF B,START, .=0 IF NB,START, .=START ENDM ; define label DEFINE IMPDEF LBL,SIZE IF NB,SIZE LBL: BLKB SIZE IFF LBL: BLKB 0 ENDC ENDM ; define size label DEFINE IMPSIZ LBL IF NB,LBL LBL: ENDC PSECT ENDM DEFINE IMPGET SIZE,IDX,NOMEM,MODNM1,MODNM2,MODEXT PUSH SIZE ;(MAC:SYS.M68: PUSH #SIZE) PUSH GETMEM @SP IF B,NOMEM BEQ 10$$ EXIT 10$$: IFF JNE NOMEM ENDC POP IDX POP IF NB,MODNM1, MOVW #[MODNM1],M.NAM-ZID(IDX) IF NB,MODNM2, MOVW #[MODNM2],M.NAM+2-ZID(IDX) IF NB,MODEXT, MOVW #[MODEXT],M.EXT-ZID(IDX) ENDM ; allocate memory ; DEFINE SW$ON SWITCH= MOVB #-1,SWITCH(A5) DEFINE SW$OFF SWITCH= CLRB SWITCH(A5) DEFINE SW$TST SWITCH= TSTB SWITCH(A5) ; DEFINE VECTOR OFFSET,ADDRESS LEA A1,ADDRESS MOV A1,0C+<4*>(A5) ENDM DEFINE FOLD SW$TST SW$FOL BEQ 1$$ UCS 1$$: ENDM ; MACRO FOR DEBUGGING ONLY DEFINE ENTRY NUM ; OUTCHR #''NUM ; IF EQ,NUM-7, TAB ENDM ; ; Impure area layout ; DSECT ; SCNWLD interface block SCNWLD: BLKB 0380 SCNWL1 = 0 ; SCNWLD vectors - set by calling SCNWLD at SCNWL2 = 4 ; its load address (+0A to skip header) SCNWL3 = 8 ; with A5->SCNWL1 IM000C = 0C ; local vectors IM0010 = 010 IM0014 = 014 IM0018 = 018 IM001C = 01C IM0020 = 020 IM0024 = 024 IM0028 = 028 IM002C = 02C DDB1 = 030 ; DDB #1 IM00A2 = 0A2 ; Disk I/O buffer (?) IM02A2 = 02A2 IM02A4 = 02A4 IM02AA = 02AA IM02AE = 02AE IM02B2 = 02B2 IM02B6 = 02B6 IM02BA = 02BA IM02C4 = 02C4 IM02E8 = 02E8 IM02F0 = 02F0 ; DDB #2 IM0358 = 0358 IM035C = 035C IM0360 = 0360 IM0364 = 0364 IM0366 = 0366 ; LAST POINT REFERENCED BY SCNWLD.SYS ; END OF SCNWLD INTERFACE BLOCK ; IMPDEF OUTFIL,4 IMPDEF LINNUM,4 IMPDEF FILNUM,4 IMPDEF STTIME,4 IMPDEF ENTIME,4 IMPDEF CNTFIL,4 IMPDEF CNTLIN,4 IMPDEF BUFBAS,4 IMPDEF BUFBLK,4 IMPDEF BUFCNT,4 IMPDEF OUTDDB,D.DDB IMPDEF ASCBUF,80. IMPDEF LBLBUF,80. IMPDEF DOTNUM,1 IMPDEF SW$DEL,1 IMPDEF DF$CUT,1 IMPDEF SW$CUT,1 IMPDEF DF$FOL,1 IMPDEF SW$FOL,1 IMPDEF DF$LBL,1 IMPDEF SW$LBL,1 IMPDEF SW$DAT,1 IMPDEF DF$REC,1 IMPDEF SW$REC,1 IMPDEF SEARCH,512. IMPDEF LINBUF,512. CMDSIZ=256. IMPDEF CMDBUF,CMDSIZ IMPDEF FL$EOF,1 IMPDEF F$MTCH,1 IMPDEF FL$NAM,1 IMPDEF FL$CNT,1 IMPSIZ SIZIMP ;------------------------ ; FIND: CALL SETUP CALL GTSRCH ; GET SEARCH STRING MOV SCNWL1(A5),A6 CALL @A6 EXIT: GTIMEI ENTIME(A5) MOV FILNUM(A5),D1 CALL ASCNUM OUTA2 FILES$ MOV CNTLIN(A5),D1 CALL ASCNUM OUTA2 MLINE$ MOV CNTFIL(A5),D1 CALL ASCNUM OUTA2 MFILE$ CMP OUTFIL(A5),#OT$DDB BNE 1$ CLOSE OUTDDB(A5) 1$: MOV #OT$TRM,OUTFIL(A5) MOV ENTIME(A5),D1 SUB STTIME(A5),D1 CALL ASCNUM OUTA2 TIME$ EXIT ABORT: OUTA2 ABORT$ JMP EXIT SWTBL: SWENT 'DATA',$DATA SWENT 'NODATA',$NODAT SWENT 'DELETE',$DELET SWENT 'NODELETE',$NODEL SWENT 'CUT',$CUT SWENT 'NOCUT',$NOCUT SWENT 'FOLD',$FOLD SWENT 'NOFOLD',$NOFOL SWENT 'LABEL',$LABEL SWENT 'NOLABEL',$NOLBL SWENT 'RECORD',$RECNO SWENT 'NORECORD',$NOREC WORD 0 ; ;D-opr DATA mode. Don't output matching lines. Valid only ; if using an output file. The output file will only contain ; the names of files with a match. ;NOD NOP ;D-opr DELETE, allow file to be overwritten ;NODE-opr NODELETE, don't allow output file to be overwritten ;C-fil CUT line, only show from match to end of line ;F-fil FOLD upper/lower case in match (use UCS on both sides) ;L-fil LABEL Include last BASIC label in output ;R-fil RECNO Include record (line) numbers in output ;Defaults: NODELETE, CUT, FOLD, RECNO ; $DELET: SW$ON SW$DEL RTN $NODEL: SW$OFF SW$DEL RTN $CUT: SW$ON SW$CUT TSTW IM0358(A5) BEQ 1$ SW$ON DF$CUT 1$: RTN $NOCUT: SW$OFF SW$CUT TSTW IM0358(A5) BEQ 1$ SW$OFF DF$CUT 1$: RTN $FOLD: SW$ON SW$FOL TSTW IM0358(A5) BEQ 1$ SW$ON DF$FOL 1$: RTN $NOFOL: SW$OFF SW$FOL TSTW IM0358(A5) BEQ 1$ SW$OFF DF$FOL 1$: RTN $LABEL: SW$ON SW$LBL TSTW IM0358(A5) BEQ 1$ SW$ON DF$LBL 1$: RTN $NOLBL: SW$OFF SW$LBL TSTW IM0358(A5) BEQ 1$ SW$OFF DF$LBL 1$: RTN $RECNO: SW$ON SW$REC TSTW IM0358(A5) BEQ 1$ SW$ON DF$REC 1$: RTN $NOREC: SW$OFF SW$REC TSTW IM0358(A5) BEQ 1$ SW$OFF DF$REC 1$: RTN $DATA: SW$ON SW$DAT RTN $NODAT: RTN ; ; ENTRY1: ENTRY 1 MOV #OT$TRM,OUTFIL(A5) SW$OFF SW$DEL SW$OFF DF$CUT SW$OFF SW$CUT SW$ON DF$FOL SW$ON SW$FOL SW$ON SW$REC SW$OFF SW$DAT MOVW #[TRM],OUTDDB+D.DEV(A5) CLR OUTDDB+D.FIL(A5) RTN ENTRY2: ENTRY 2 CMP IM035C(A5),#1 BNE 1$ TYPE <(SET)> SW$OFF DF$CUT SW$ON DF$FOL 1$: JOBIDX MOVW JOBDEV(A6),IM02A2(A5) MOVW JOBDRV(A6),IM02A4(A5) MOVW #-1,IM0364(A5) MOVW JOBUSR(A6),IM0366(A5) RTN ENTRY3: ENTRY 3 CMP IM0360(A5),#1 BEQ 1$ TYPECR EXIT 1$: SAVE D0,A1,A2 LEA A1,IM02A2(A5) LEA A2,IM02C4(A5) MOV #7,D0 2$: MOV (A1)+,(A2)+ DEC D0 BNE 2$ MOVW #[FND],DDB1+D.FIL(A5) MOVW #[OUT],DDB1+D.FIL+2(A5) MOVW #[LST],DDB1+D.EXT(A5) MOV SCNWL3(A5),A6 CALL @A6 MOVW DDB1+D.DEV(A5),OUTDDB+D.DEV(A5) MOVW DDB1+D.DRV(A5),OUTDDB+D.DRV(A5) MOVW DDB1+D.FIL(A5),OUTDDB+D.FIL(A5) MOVW DDB1+D.FIL+2(A5),OUTDDB+D.FIL+2(A5) MOVW DDB1+D.EXT(A5),OUTDDB+D.EXT(A5) MOVW DDB1+D.PPN(A5),OUTDDB+D.PPN(A5) INIT OUTDDB(A5) CMPW OUTDDB+D.DEV(A5),#[TRM] BNE 10$ TST OUTDDB+D.FIL(A5) BEQ 20$ 10$: INIT OUTDDB(A5) SW$TST SW$DEL BEQ 11$ ORW #0300,OUTDDB(A5) DSKDEL OUTDDB(A5) ANDW #0FCFF,OUTDDB(A5) 11$: OPENO OUTDDB(A5) TYPE PFILE OUTDDB(A5) CRLF MOV #OT$DDB,OUTFIL(A5) 20$: REST A2,A1,D0 RTN ENTRY4: ENTRY 4 SW$TST SW$DAT BEQ 1$ ; IF NOT DATA MODE OUTPUT CMP OUTFIL(A5),#OT$DDB BEQ 1$ ; IF OUTPUT >> FILE TYPECR EXIT 1$: MOV SCNWL2(A5),A6 ; PROCESS FILE SPEC JMP @A6 ; EXPANDING * AND ? IF ANY ENTRY5: ENTRY 5 MOVB DF$CUT(A5),SW$CUT(A5) MOVB DF$FOL(A5),SW$FOL(A5) CLR IM02AA(A5) CLR IM02AE(A5) CLR IM02B2(A5) CLR IM02B6(A5) CLR IM02BA(A5) RTN ENTRY6: ENTRY 6 RTN ENTRY7: SAVE A0-A6,D0-D7 ENTRY 7 CLRB LBLBUF(A5) INC FILNUM(A5) CALL ASCFIL SW$OFF FL$NAM SW$OFF FL$CNT CMP OUTFIL(A5),#OT$DDB BNE 0$ OUTL ASCBUF(A5),OT$TRM CLRB DOTNUM(A5) BR 1$ 0$: OUTA2 ASCBUF(A5) OUTA2 CR$ SW$ON FL$NAM ; FILE NAME HAS BEEN PRINTED 1$: USREND D5 USRFRE A6 MOV A6,BUFBAS(A5) MOV A6,D.BUF+DDB1(A5) ORB #D$INI,D.FLG+DDB1(A5) SUB A6,D5 LSR D5,#8 LSR D5,#1 MOV D5,BUFBLK(A5) OPENI DDB1(A5) CLR LINNUM(A5) SW$OFF FL$EOF ; TURN OFF EOF FLAG CLR D3 2$: SW$TST FL$EOF JNE 4$ ; IF EOF CALL GTLINE CMP OUTFIL(A5),#OT$DDB BNE 21$ INCB DOTNUM(A5) CMPB DOTNUM(A5),#100. BNE 21$ MOVB #'.,D1 TTY CLRB DOTNUM(A5) 21$: CALL MATCH SW$TST F$MTCH BEQ 2$ ;MATCH INC CNTLIN(A5) SW$TST FL$CNT BNE 22$ INC CNTFIL(A5) SW$ON FL$CNT 22$: SW$TST FL$NAM BNE 23$ CALL ASCFIL OUTA2 ASCBUF(A5) OUTA2 CR$ SW$ON FL$NAM ; FILE NAME HAS BEEN PRINTED 23$: SW$TST SW$DAT ; IF DATA MODE OUTPUT BNE 31$ ; SKIP OUTPUT OF MATCHING LINE PUSH A3 SW$TST SW$REC BEQ 24$ MOV LINNUM(A5),D1 CALL ASCNUM OUTA2 COL$ ; OUTPUT COLON AND TAB 24$: SW$TST SW$LBL BEQ 25$ ; IF NOT INCLUDING LABELS OUTA2 LBLBUF(A5) OUTA2 COL$ 25$: POP A6 SW$TST SW$CUT BNE 3$ LEA A6,LINBUF(A5) 3$: OUTA2 @A6 OUTA2 CR$ 31$: JMP 2$ 4$: SW$TST FL$NAM BEQ 41$ SW$TST SW$DAT ; IF DATA MODE OUTPUT BNE 41$ MOV LINNUM(A5),D1 CALL ASCNUM OUTA2 LINES$ 41$: CMP OUTFIL(A5),#OT$DDB BNE 42$ CRLF 42$: REST A0-A6,D0-D7 RTN ; ASCII MESSAGES PRC$: ASCIZ /Processing File: / SEP$: ASCIZ /, / TIME$: ASCII / seconds elapsed real time/ BYTE 0D,0 ABORT$: ASCII /Program aborted by ^C/ BYTE 0D,0 LINES$: ASCII / Line(s) were read/ CR2$: BYTE 0D,0D,0 FILES$: ASCII / File(s) were processed./ CR$: BYTE 0D,0 MLINE$: ASCIZ / Line(s) in / MFILE$: ASCII / File(s) contained target string./ BYTE 0D,0 COL$: BYTE ': TAB$: BYTE 9,0 EVEN ; GTLINE: LEA A2,LINBUF(A5) PUSH A2 CTRLC ABORT 1$: TST D3 BNE 99$ CALL FILL BEQ 2$ MOV BUFBAS(A5),A0 99$: MOVB (A0)+,D1 DEC D3 CMPB D1,#CR BEQ 1$ ; IGNORE CR CMPB D1,#LF BEQ 3$ ; USE LF TO DELIMIT LINES MOVB D1,(A2)+ ; COPY ALL OTHER CHARACTERS BR 1$ 2$: SW$ON FL$EOF ; SET EOF FLAG 3$: INC LINNUM(A5) CLRB @A2 SW$TST SW$LBL BNE 10$ ; IF INCLUDING LABEL POP A2 RTN 10$: MOV @SP,A2 BYP ; SKIP WHITE SPACE 11$: TSTB @A2 BEQ 13$ ALF BEQ 14$ NUM BEQ 14$ CMPB @A2,#'' BEQ 14$ CMPB @A2,#': BNE 13$ CLRB @A2 POP A2 BYP ; check if label begins with AB00 JSR CHKABL BNE 4$ RTN 4$: LEA A1,LBLBUF(A5) 12$: MOVB (A2)+,(A1)+ BNE 12$ MOVB #':,-(A2) RTN 13$: POP A2 RTN 14$: INC A2 BR 11$ ; Check for AlphaBase preprocessor generated label ; (label begining with AB00) ; Z flag set if so CHKABL: CMPB @A2,#'A BNE 1$ CMPB 1(A2),#'B BNE 1$ CMPB 2(A2),#'0 BNE 1$ CMPB 3(A2),#'0 1$: RTN FILL: SAVE D5,D1 CLR D3 MOV BUFBAS(A5),A0 SUB #2,A0 MOV BUFBLK(A5),D5 1$: DEC D5 BEQ 2$ MOV A0,D.BUF+DDB1(A5) MOVB 0(A0),D0 MOVB 1(A0),D1 INPUT DDB1(A5) MOVB D0,0(A0) MOVB D1,1(A0) MOV D.SIZ+DDB1(A5),D1 BEQ 2$ SUB #2,D1 ADD D1,D3 ADD D1,A0 BR 1$ 2$: REST D5,D1 MOV D3,BUFCNT(A5) RTN MATCH: ; LINBUF - File line buffer ; SEARCH - Search string buffer LEA A3,LINBUF(A5) LEA A2,SEARCH(A5) SW$OFF F$MTCH ; MOVB (A2)+,D1 FOLD ; FOLD D1 TO UPPER CASE IF FOLD SWITCH=ON MOVB D1,D0 10$:; CTRLC ABORT MOVB (A3)+,D1 BEQ 32$ ; END OF LINE BUFFER (NO MATCH) FOLD CMPB D1,D0 BNE 10$ ; 1ST CHAR MATCH SAVE A3,A2,D0 20$:; CTRLC ABORT MOVB (A2)+,D1 BEQ 30$ ; END IF SEARCH STRING (GOOD MATCH) FOLD MOVB D1,D0 MOVB (A3)+,D1 BEQ 31$ ; END OF LINE BUFFER (NO MATCH) FOLD CMPB D1,D0 BEQ 20$ ; LOOP UNTIL END OF EITHER BUFFER REST A3,A2,D0 ; NO MATCH BR 10$ 30$: SW$ON F$MTCH ; A3->START OF MATCH IN LINE BUFFER 31$: REST A3,A2,D0 DEC A3 32$: RTN ; UNPACK NUMBER IN D1 TO ASCII AT A2 AND OUTPUT IT ASCNUM: SAVE A0,D1,A2 LEA A2,ASCBUF(A5) DCVT 5,OT$MEM+OT$ZER CLRB @A2 OUTA2 ASCBUF(A5) REST A0,D1,A2 RTN ; ; UNPACK DEV(DDB1) TO ASCII AT A2 ASCDEV: SAVE D1,A0,A1 LEA A1,DDB1+D.DEV(A5) UNPACK CLR D1 MOVW @A1,D1 CMPW D1,#-1 BEQ 1$ MOVW #0800,D6 OCVT 1$: MOVB #':,(A2)+ REST D1,A0,A1 RTN ; ; UNPACK PPN(DDB1) TO ASCII AT A2 ASCPPN: SAVE D1,A0 CLR D1 MOVW DDB1+D.PPN(A5),D1 BEQ 1$ JOBIDX A0 PUSHW 2(A0) MOVW #-011,D7 ANDW D7,2(A0) MOVB #'[,(A2)+ PUSHW D1 LSRW D1,#8 MOVW #04800,D6 OCVT MOVB #',,(A2)+ POPW D1 AND #0FF,D1 MOVW #04800,D6 OCVT MOVB #'],(A2)+ JOBIDX A0 POPW 2(A0) 1$: REST A0,D1 RTN ; ; UNPACK FIL(DDB1) TO ASCII AT A2 ASCNAM: SAVE D1,A0,A1 LEA A1,DDB1+D.FIL(A5) UNPACK UNPACK 1$: CMPB -(A2),#020 BEQ 1$ INC A2 MOVB #'.,(A2)+ TSTW @A1 BEQ 3$ UNPACK 2$: CMPB -(A2),#020 BEQ 2$ INC A2 3$: REST D1,A0,A1 RTN ; ; UNPACK ENTIRE FILE SPEC OF DDB1 TO ASCBUF ASCFIL: LEA A2,ASCBUF(A5) CALL ASCDEV CALL ASCNAM CALL ASCPPN CLRB @A2 RTN ; ; SETUP: BYP CMPB @A2,#'? JEQ HELP GETIMP SIZIMP,A5 LEA A1,CMDBUF(A5) MOV #CMDSIZ-1,D7 0$: MOVB (A2)+,(A1)+ BEQ 1$ SOB D7,0$ 1$: LEA A2,CMDBUF(A5) SAVE A2 CLRB LBLBUF(A5) CLR FILNUM(A5) CLR CNTFIL(A5) CLR CNTLIN(A5) GTIMEI STTIME(A5) LEA A2,10$ FSPEC DDB1(A5) INIT DDB1(A5) PUSH DDB1+D.BUF(A5) FETCH DDB1(A5),A0,0 BEQ 20$ TTYI ASCII /?Cannot find / 10$: ASCII /DSK0:SCNWLD.SYS[1,4] or MEM:SCNWLD.SYS/ BYTE 0D,0 EVEN EXIT 20$: POP DDB1+D.BUF(A5) MOV #0200,DDB1+D.SIZ(A5) ADD #0A,A0 CALL @A0 VECTOR 1,ENTRY1 VECTOR 2,ENTRY2 VECTOR 3,ENTRY3 ; OUTPUT FILE SPEC VECTOR 4,ENTRY4 ; END OF 1ST SCAN (?) VECTOR 5,ENTRY5 ; COPY DEFAULT TO FILE SWITCHS VECTOR 6,ENTRY6 VECTOR 7,ENTRY7 ; PROCESS A FILE VECTOR 8,ENTRY8 VECTOR 9,SWTBL REST A2 RTN ; GTSRCH: SAVE A1,A2,D1,D7 JOBIDX A1 MOV JOBTRM(A1),A1 LEA A1,T.STS(A1) MOVW @A1,D1 ORW #T$ILC,T.STS(A1) SAVE D1,A1 TYPECR KBD ABORT REST D1,A1 MOVW D1,@A1 LEA A1,SEARCH(A5) MOV #510.,D7 1$: MOVB (A2)+,D1 CMPB D1,#TAB ; ACCEPT A TAB INTO SEARCH STRING BEQ 11$ CMPB D1,#31. BLE 2$ ; STOP COPY ON ANY CONTROL CHAR 11$: MOVB D1,(A1)+ DBF D7,1$ 2$: CLRB @A1 REST A1,A2,D1,D7 RTN ENTRY8: ENTRY 8 RTN ; HELP: TTYI ASCII "Syntax: FIND {=}[...]{/switch}" BYTE CR ASCII /Switches: (can be preceeded by NO)/ BYTE CR ASCII /DE-opr DELETE, allow file to be overwritten/ BYTE CR ASCII /C-fil CUT line, only show from match to end of line/ BYTE CR ASCII /D-opr DATA mode. Don't output matching lines. Valid only/ BYTE CR ASCII / if using an output file. The output file will only contain/ BYTE CR ASCII / the names of files with a match./ BYTE CR ASCII "F-fil FOLD upper/lower case in match" BYTE CR ASCII /L-fil LABLE Include last BASIC label in output/ BYTE CR ASCII /R-fil RECNO Include record (line) numbers in output/ BYTE CR ASCII /Defaults: NODELETE, CUT, FOLD, RECNO/ BYTE CR ASCII /Output will go to terminal if no output file is specified/ BYTE CR,0 EVEN EXIT ; ; END .