; ************************** AMUS Program Label ****************************** ; Filename: SEARCH.M68 Date: 01/17/96 ; Category: UTIL Hash Code: 151-652-735-533 Version: 3.0(106) ; Initials: ULTR/AM Name: DAVID PALLMANN ; Company: ULTRASOFT CORPORATION Telephone #: 5163484848 ; Related Files: SEARCH.HLP; WLDSCN.LIB (required for assembly/linkage) ; Min. Op. Sys.: AMOSL 1.3B Expertise Level: BEG ; Special: ; Description: Friendly, general-purpose search utility. Lets you specify ; what text to search for and what files to look at. Can output to a file. ; Supports full wildcarding. Very fast. See SEARCH.HLP for details. ; **************************************************************************** ; ;NOTE: Updated to Version 3.0(105) ; ;**************************************************************************** ;* * ;* SEARCH * ;* Text Pattern Search Utility * ;* * ;**************************************************************************** ;Copyright (C) 1989 UltraSoft Corporation. All Rights Reserved. ; ;Written by: David Pallmann ; ;External files required: ; WLDSCN.LIB Hash 275-510-373-412 ; ;Assembly instructions: ; ; 1. .M68 SEARCH assemble with 2.0 assembler ; 2. .LNKLIT SEARCH,WLDSCN.LIB/L link with wildcard scanner ; ;Edit History: ;3.0(100) 18-Nov-89 created. /DFP ;3.0(101) 26-Nov-89 correct problem where Ignore Case didn't work right. /DFP ;3.0(102) 26-Nov-89 add random file processing. /DFP ;3.0(103) 28-Nov-89 fix problem where only one filename was output. /DFP ;3.0(104) 30-Jan-90 fixed problem where a" FILE TYPE MISMATCH" error ; would occur when the last block of file contained ; exactly 510 bytes. / AJC (Finex, NYC NY) ;3.0(105) 31-Jan-90 fixed problem where the last file matching the ; wild-card spec was being skipped. /AJC (Finex, NYC,NY) ;[106] January 16, 1996 04:57 PM Edited by Rob (Meda/Comp) ; Added check for "file in use" so search doesn't crash. Now it will ; stop, beep and tell you which file was in use. A CR is required by ; the user to continue. At least you'll know a file was in use. VMAJOR =3 VMINOR =0 VSUB =0 VEDIT =106. VWHO =0 AUTOEXTERN ASMMSG "After assembly, .LNKLIT SEARCH,WLDSCN.LIB/L" SEARCH SYS SEARCH SYSSYM SEARCH TRM ;wildcard scanner definitions DEFINE WINIT IF NDF,W.INIT,EXTERN W.INIT CALL W.INIT ENDM DEFINE WSPEC EXT IF NDF,W.SPEC,EXTERN W.SPEC CALL W.SPEC IF B,EXT,ASCII /???/ IF NB,EXT,ASCII /'EXT/ BYTE 0 ENDM DEFINE WSCAN IF NDF,W.SCAN,EXTERN W.SCAN CALL W.SCAN ENDM ;constants FI.MAX =10000. ; we can search up to 10,000 files ;ASCII characters TAB =11 LF =12 CR =15 ESC =33 ;file entry .OFINI .OFDEF FI.DEV, 2 ; device code .OFDEF FI.DRV, 2 ; drive number .OFDEF FI.FIL, 4 ; file name .OFDEF FI.EXT, 2 ; extension .OFDEF FI.PPN, 2 ; PPN .OFSIZ FI.SIZ ;variables .OFINI .OFDEF FLDROW, 1 ; field editing - row .OFDEF FLDCOL, 1 ; field editing - column .OFDEF FLDBUF, 4 ; field editing - address of field buffer .OFDEF FLDPOS, 1 ; field editing - position in buffer .OFDEF FLDSIZ, 1 ; field editing - current size of field .OFDEF FLDMIN, 1 ; field editing - min size .OFDEF FLDMAX, 1 ; field editing - max size .OFDEF FLDTYP, 1 ; field editing - field type FE$STR =0 ; string FE$YNO =2 ; yes/no FE$INT =4 ; integer .OFDEF FLDCOD, 1 ; field editing - return code .OFDEF FLDFLG, 2 ; field editing - flags FE$UCS =1 ; upper case .OFDEF FILES, 40. ; option - files to search .OFDEF TEXT1, 40. ; option - text to find 1 .OFDEF TEXT2, 40. ; option - text to find 2 .OFDEF TEXT3, 40. ; option - text to find 3 .OFDEF TEXT4, 40. ; option - text to find 4 .OFDEF TEXT5, 40. ; option - text to find 5 .OFDEF OUTNAM, 40. ; option - output filename .OFDEF SFILES, 2 ; option - show matching lines .OFDEF SLINES, 2 ; option - show matching files .OFDEF WLDCHR, 2 ; option - wildcard character .OFDEF MAXMAT, 4 ; option - matches per file .OFDEF IGNCAS, 2 ; option - ignore case .OFDEF MIDWRD, 2 ; option - mid-word matches .OFDEF IGNSPC, 2 ; option - ignore white space .OFDEF DISROW, 1 ; current display row .OFDEF DISCOL, 1 ; current display column .OFDEF PROCNT, 2 ; files processed .OFDEF FILE, D.DDB ; DDB for file processing .OFDEF FLAGS, 2 ; flags: F$MATCH =1 ; we have a match in current file F$DONE =2 ; we're done w/this file F$CMDLIN=4 ; search parameters given on cmdline F$RANDOM=10 ; we are processing a random file .OFDEF MFCNT, 2 ; matching file count .OFDEF MLCNT, 2 ; matching line count .OFDEF LINE, 512.+3 ; line buffer .OFDEF TXTROW, 1 ; text display row .OFDEF OUTFIL, D.DDB ; output file DDB .OFDEF MATCNT, 2 ; matches in current file .OFDEF FILCNT, 2 ; number of files in file list .OFDEF FILSIZ, 4 ; size of random file [102] .OFDEF FILOFF, 2 ; offset into block [102] .OFDEF FLIST, FI.MAX*FI.SIZ ; file list .OFSIZ MEMSIZ ;macros DEFINE CRT N MOVW #-1_8.+^D,D1 TCRT ENDM DEFINE CURSOR ROW,COL MOVB ROW,D1 ROLW D1,#8. MOVB COL,D1 TCRT ENDM DEFINE EDTFLD ROW,COL,TYPE,MIN,MAX,FLGS,VAR MOVB #ROW,FLDROW(A5) MOVB #COL,FLDCOL(A5) MOVB #TYPE,FLDTYP(A5) MOVB #MIN,FLDMIN(A5) MOVB #MAX,FLDMAX(A5) MOVW #FLGS,FLDFLG(A5) LEA A6,VAR MOV A6,FLDBUF(A5) CALL EDIT.FIELD ENDM DEFINE ONKEY LESC,LUP,LDOWN,LTAB MOVB FLDCOD(A5),D7 BEQ 1$$ CMPB D7,#1 JEQ LESC CMPB D7,#2 JEQ LUP CMPB D7,#3 JEQ LDOWN CMPB D7,#4 JEQ LTAB 1$$: ENDM DEFINE BITW SRC,DST MOVW DST,D7 ANDW SRC,D7 ENDM ;protect people from trying to assemble this with the old (1.x) assembler ;if we didn't have this check, which deliberately generates an error, there ;is a chance it would assemble without displayed errors, but incorrectly. SYMBOL1 =1 SYMBOL2 =2 IF EQ,SYMBOL1-SYMBOL2,ASMERP "?You need the 2.0 assembler to assemble SEARCH (sorry)" ;*********** ;* START * ;*********** ;program header START: PHDR -1,0,PH$REE!PH$REU ; program header ;********** ;* INIT * ;********** ;initialization ;memory allocation INIT: GETIMP MEMSIZ,A5 ; allocate memory for variables WINIT ; init wildcard scanner INIT FILE(A5) ; allocate DDB buffer INIT OUTFIL(A5) ; MOVB #'Y,SFILES(A5) ; MOVB #'Y,SLINES(A5) ; MOVB #'?,WLDCHR(A5) ; CLRB MAXMAT(A5) ; MOVB #'Y,IGNCAS(A5) ; MOVB #'Y,MIDWRD(A5) ; MOVB #'N,IGNSPC(A5) ; ;************ ;* CMDLIN * ;************ ;command line processing ;command line syntax is: ; ; SEARCH {output=} files searchtext CMDLIN: BYP ; bypass leading spaces LIN ; is there a command line? BEQ TERM ; no ;see if we have an output spec MOV A2,A6 ; 10$: MOVB (A6)+,D6 ; BEQ 30$ ; CMPB D6,#'= ; BNE 10$ ; LEA A6,OUTNAM(A5) ; 20$: MOVB (A2)+,D1 ; CMPB D1,#'= ; BEQ 30$ ; PUSH A6 ; UCS ; POP A6 ; MOVB D1,(A6)+ ; BR 20$ ; 30$: ;get files to search BYP ; LIN ; JEQ HELP ; LEA A6,FILES(A5) ; 40$: MOVB (A2)+,D1 ; JEQ HELP ; CMPB D1,#40 ; BEQ 50$ ; PUSH A6 ; UCS ; POP A6 ; MOVB D1,(A6)+ ; BR 40$ ; ;get search text 50$: BYP ; LIN ; JEQ HELP ; LEA A6,TEXT1(A5) ; 60$: LIN ; BEQ 70$ ; MOVB (A2)+,(A6)+ ; BR 60$ ; 70$: ORW #F$CMDLIN,FLAGS(A5) ; ;********** ;* TERM * ;********** ;terminal set-up ;put terminal in single character mode and disable character echo TERM: TRMRST D0 ; read terminal status word ORW #T$DAT!T$ECS!T$XLT,D0 ; set bits we want TRMWST D0 ; write terminal status word ;if running under an ancient version of AMOS, the assembler will give you ;an error on "TRMRST" and "TRMWST". If this happens, comment out the ;section above and uncomment the section below. ; ; TERM: MOV JOBCUR,A6 ; index job control block ; MOV JOBTRM(A6),A6 ; index terminal definition block ; ORW #T$DAT!T$ECS!T$XLT,@A6 ; set bits we want ;************* ;* OPTIONS * ;************* ;Display option screen and allow user editing OPTIONS: BITW #F$CMDLIN,FLAGS(A5) ; parameters on command line? BNE OPNOUT ; yes CALL PUT.SCREEN ; display search option screen CALL PUT.OPTIONS ; display default or current settings GETOPT: CALL EDIT.OPTIONS ; edit option screen CMPB FLDCOD(A5),#1 ; was editing aborted? JEQ QUIT ; yes - quit ;************ ;* CHKOPT * ;************ ;check that options are valid CHKOPT: TSTB TEXT1(A5) ; BNE 10$ ; TSTB TEXT2(A5) ; BNE 10$ ; TSTB TEXT3(A5) ; BNE 10$ ; TSTB TEXT4(A5) ; BNE 10$ ; TSTB TEXT5(A5) ; JEQ GETOPT ; no search text specified ;don't allow filenames & lines to be disabled if there is an output file 10$: TSTB OUTNAM(A5) ; is there an output file? BEQ 20$ ; no CMPB SFILES(A5),#'N ; is Show Files set to N)o? BNE 20$ ; no CMPB SLINES(A5),#'N ; is Show Lines set to N)o too? JEQ GETOPT ; yes 20$: ;************ ;* OPNOUT * ;************ ;Open output file (if one was specified) OPNOUT: LEA A2,OUTNAM(A5) ; BYP ; LIN ; BEQ 20$ ; CLR OUTFIL+D.DVR(A5) ; FSPEC OUTFIL(A5),LST ; LOOKUP OUTFIL(A5) ; BNE 10$ ; DSKDEL OUTFIL(A5) ; 10$: OPENO OUTFIL(A5) ; 20$: ;************ ;* SEARCH * ;************ ;begin the search! SEARCH: CRT 29 ; cursor off CALL PUT.SEARCH ; put up search screen LEA A2,FILES(A5) ; index file specification WSPEC ; process spec JNE QUIT ; error CLRW FILCNT(A5) ; INCW FILCNT(A5) ; [105] LEA A3,FLIST(A5) ; MOV #FI.MAX,D0 ; 10$: WSCAN ; get next file BNE 20$ ; no more MOVW D.DEV(A4),(A3)+ ; MOVW D.DRV(A4),(A3)+ ; MOV D.FIL(A4),(A3)+ ; MOVW D.EXT(A4),(A3)+ ; MOVW D.PPN(A4),(A3)+ ; INCW FILCNT(A5) ; SOB D0,10$ ; 20$: MOVB #10.,DISROW(A5) ; MOVB #1,DISCOL(A5) ; MOVB #19.,TXTROW(A5) ; LEA A3,FLIST(A5) ; CLR D3 ; MOVW FILCNT(A5),D3 ; JEQ DONE ; ;********** ;* LOOP * ;********** ;come here to get next file to search LOOP: DECW D3 ; JEQ DONE ; LEA A6,FILE(A5) ; MOVW (A3)+,D.DEV(A6) ; MOVW (A3)+,D.DRV(A6) ; MOV (A3)+,D.FIL(A6) ; MOVW (A3)+,D.EXT(A6) ; MOVW (A3)+,D.PPN(A6) ; CLR D.DVR(A6) ; ;reject file if size is zero, or if random, or if not found LOOKUP FILE(A5) ; BNE LOOP ; TST FILE+D.FSZ(A5) ; BEQ LOOP ; CMP FILE+D.LSZ(A5),#-1 ; [104] JHI RANDOM ; [102] SEQUENTIAL: ANDW #^C,FLAGS(A5) ; [102] ORB #, FILE+D.FLG(A5) ; We'll handle any errors.[106] OPENI FILE(A5) ; [102] JEQ 10$ ; Error. [106] ANDB #^C, FILE+D.FLG(A5) ; Reset error control bit.[106] CMPB FILE+D.ERR(A5), #D$EFIU ; Is file in use? [106] BNE 5$ ; No. Display the error. [106] MOV #7, D1 ; Bell character. [106] TTY ; Ring the bell. [106] CURSOR #23.,#1 ; Position cursor. [106] TYPESP ; Inform the user. [106] PRNAM FILE+D.FIL(A5) ; [106] ERRMSG FILE+D.ERR(A5), OT$TRM!OT$LSP ; [106] KBD DONE ; [106] CURSOR #23., #1 ; [106] MOV #<-1_8.>+9., D1 ; [106] TCRT ; Clear to end of line. [106] CLRB FILE+D.ERR(A5) ; Clear the error. [106] JMP NEXT ; Continue on. [106] 5$: TYPESP ; Real error. [106] PRNAM FILE+D.FIL(A5) ; [106] ERRMSG FILE+D.ERR(A5), OT$TRM!OT$LSP ; [106] CRLF ; [106] EXIT ; [106] 10$: ANDB #^C, FILE+D.FLG(A5) ; Reset error control bit.[106] BR DO.FILE ; [102] RANDOM: ORW #F$RANDOM,FLAGS(A5) ; [102] MOV FILE+D.FSZ(A5),FILSIZ(A5) ; [102] CLRW FILOFF(A5) ; [102] OPENR FILE(A5) ; [102] CLR FILE+D.REC(A5) ; [102] INPUT FILE(A5) ; [102] DO.FILE: CALL SHOW.FILE ; ;[102] OPENI FILE(A5) ; CALL SEARCH.FILE ; CLOSE FILE(A5) ; ANDW #^C,FLAGS(A5) ; CLRW MATCNT(A5) ; [103] ;********** ;* NEXT * ;********** ;setup to process next file NEXT: INCB DISROW(A5) ; CMPB DISROW(A5),#15. ; BLOS 10$ ; MOVB #10.,DISROW(A5) ; ADDB #15.,DISCOL(A5) ; CMPB DISCOL(A5),#70. ; BLO 10$ ; MOVB #1,DISCOL(A5) ; CURSOR #10.,#1 ; CRT 10 ; CURSOR #17.,#1 ; CALL HLINE ; 10$: JMP LOOP ; ;********** ;* DONE * ;********** ;come here when we are done with search DONE: CURSOR #24.,#1 ; CRT 12 ; CRT 28 ; cursor on CALL CLSFIL ; close current file if open CALL CLSOUT ; close output file if open EXIT ; ;********** ;* HELP * ;********** ;command help HELP: TYPESP UltraSoft SEARCH Utility version VCVT START+2,OT$TRM ; CRLF ; TYPECR Copyright (C) 1989 UltraSoft Corporation. All Rights Reserved. CRLF ; TYPECR For interactive (screen-edited options): CRLF ; TYPECR < .SEARCH> ; CRLF ; TYPECR For batch (command-line options): CRLF ; TYPECR < .SEARCH {output=} files text> CRLF ; EXIT ; ;********** ;* QUIT * ;********** ;come here when user aborts from option screen QUIT: CRT 0 ; clear screen CRT 12 ; high intensity CRT 28 ; cursor on CALL CLSFIL ; close current file if open CALL CLSOUT ; close output file if open EXIT: EXIT ;***************** ;* SEARCH.FILE * ;***************** ;Function: Search file ; ;Inputs: FILE(A5) - opened file DDB SEARCH.FILE: 10$: BITW #F$DONE,FLAGS(A5) ; are we done w/this file? BNE 20$ ; yes TCKI ; character input? BNE 15$ ; no TIN ; yes - get character UCS ; fold to upper case CMPB D1,#40 ; space? JEQ 30$ ; yes - suspend search CMPB D1,#'N ; N)ext? BEQ 20$ ; yes - stop processing file CMPB D1,#'H ; H)elp? JEQ 24$ ; yes CMPB D1,#'S-'@ ; ^S? JEQ 30$ ; yes - suspend search CMPB D1,#'C-'@ ; ^C? JEQ DONE ; yes - abort search CMPB D1,#ESC ; ESC? JEQ DONE ; yes - abort search 15$: CALL GET.LINE ; BNE 20$ ; CALL SEARCH.LINE ; BR 10$ ; 20$: ANDW #^C,FLAGS(A5) ; RTN ; 24$: CURSOR #18.,#1 ; CRT 10 ; CRT 12 ; CURSOR #18.,#21. ; TYPECR CRLF ; TYPECR < N = skip this file and move on the N)ext one> TYPECR TYPECR < ESC = abort search and exit to AMOS command level> CRLF ; CURSOR #24.,#26. ; TYPE <[ Press any key to continue ]> TIN ; CURSOR #18.,#1 ; CRT 10 ; MOVB #19.,TXTROW(A5) ; JMP 10$ ; 30$: CURSOR #24.,#35. ; TYPE SUSPENDED 40$: TIN ; CMPB D1,#'Q-'@ ; BEQ 50$ ; CMPB D1,#40 ; BEQ 50$ ; BR 40$ ; 50$: CURSOR #24.,#1 ; CRT 9 ; JMP 10$ ; ;************** ;* GET.LINE * ;************** ;Function: Get a line from file being search ; ;Inputs: FILE(A5) - open for input ; ;Outputs: Z - set normally; cleared on end of file ; LINE(A5) - loaded with current line GET.LINE: LEA A2,LINE(A5) ; MOV #511.,D0 ; GL.CHR: CALL GETBYT ; get next byte from file BNE GL.EOF ; end of file or error CMPB D1,#LF ; LF? BEQ GL.EOL ; yes CMPB D1,#CR ; CR? BEQ GL.EOL ; yes MOVB D1,(A2)+ ; store in line buffer BEQ GL.EOL ; branch if end of line SOB D0,GL.CHR ; loop GL.EOL: CLRB @A2 ; mark end of buffer LCC #PS.Z ; set Z (we got a line) RTN ; return GL.EOF: LCC #0 ; clear Z (end of file) RTN ; return ;***************** ;* SEARCH.LINE * ;***************** ;Function: Search current line for matches ; ;Inputs: LINE(A5) - line to search, null-terminated ; ;Outputs: Z - set if line contained one or more matches SEARCH.LINE: LEA A0,TEXT1(A5) ; CALL MATCH ; BEQ SL.MAT ; LEA A0,TEXT2(A5) ; CALL MATCH ; BEQ SL.MAT ; LEA A0,TEXT3(A5) ; CALL MATCH ; BEQ SL.MAT ; LEA A0,TEXT4(A5) ; CALL MATCH ; BEQ SL.MAT ; LEA A0,TEXT5(A5) ; CALL MATCH ; BEQ SL.MAT ; SL.ERR: LCC #0 ; RTN ; SL.MAT: LCC #PS.Z ; RTN ; ;*********** ;* MATCH * ;*********** ;Function: Scan line for a match ; ;Inputs: LINE(A5) - line to scan ; A0 - address of text to search for ; ;Outputs: Z - set if line contained a match MATCH: SAVE A3,D3 ; TSTB @A0 ; is there text to match? JEQ MA.ERR ; no LEA A2,LINE(A5) ; ;come here to compare text pattern @A0 with line segment ;A2 is where we are in the line MA.LIN: ;check to see if we are in mid-word CMPB MIDWRD(A5),#'Y ; are we accepting mid-word matches? BEQ 10$ ; yes MOVB @A0,D1 ; get first character of search text CMPB D1,#'A ; does text start w/a letter? BLO 10$ ; no CMPB D1,#'z ; does text start w/a letter? BHI 10$ ; no CMPB D1,#'Z ; does text start w/a letter? BLOS 5$ ; yes CMPB D1,#'a ; does text start w/a letter? BLO 10$ ; no 5$: LEA A6,LINE(A5) ; are we at CMP A6,A2 ; the beginning? BEQ 10$ ; yes MOVB -1(A2),D1 ; get previous character CMPB D1,#'A ; is it a letter? BLO 10$ ; no CMPB D1,#'z ; is it a letter? BHI 10$ ; no CMPB D1,#'Z ; is it a letter? JLOS MA.ADV ; yes CMPB D1,#'a ; is it a letter? JHIS MA.ADV ; no 10$: MOV A0,A1 ; MOV A2,A3 ; TSTB @A3 ; end of line? JEQ MA.ERR ; no ;A1 is copy of pointer to search text ;A3 is current index into line MA.CHK: MOVB (A1)+,D1 ; get next byte of search text BEQ MA.MAT ; end - we have a match MOVB (A3)+,D3 ; get line character JEQ MA.ERR ; end - no match ;ignore spaces and tabs if option set CMPB IGNSPC(A5),#'Y ; BNE 5$ ; 1$: CMPB D1,#40 ; BEQ 2$ ; CMPB D1,#TAB ; BEQ 2$ ; CMPB D3,#40 ; BEQ 4$ ; CMPB D3,#TAB ; BNE 5$ ; 4$: MOVB (A3)+,D3 ; JEQ MA.ERR ; BR 1$ ; 2$: MOVB (A1)+,D1 ; JEQ MA.MAT ; BR 1$ ; ;fold to upper case if option set 5$: CMPB IGNCAS(A5),#'Y ; are we ignoring case? BNE 20$ ; no UCS ; [101] CMPB D3,#'a ; is this a lower case letter? BLO 20$ ; no CMPB D3,#'z ; is this a lower case letter? BHI 20$ ; no 10$: SUBB #'a-'A,D3 ; make character upper case UCS ; 20$: ;check for wildcard character CMPB D1,WLDCHR(A5) ; is this a wildcard character? BEQ MA.CHK ; yes - automatic match ;compare characters CMPB D1,D3 ; compare characters BEQ MA.CHK ; same - keep comparing ;no match - try starting with next character in line MA.ADV: INC A2 ; JMP MA.LIN ; MA.MAT: INCW MATCNT(A5) ; update match count for this file PUSH A2 ; LEA A2,MAXMAT(A5) ; GTDEC ; POP A2 ; TST D1 ; BEQ 5$ ; CMPW D1,MATCNT(A5) ; BHI 5$ ; ORW #F$DONE,FLAGS(A5) ; 5$: BITW #F$MATCH,FLAGS(A5) ; first match in this file? BNE 10$ ; no ORW #F$MATCH,FLAGS(A5) ; CURSOR #20.,#1 ; CRT 10 ; MOVB #19.,TXTROW(A5) ; CRT 12 ; CURSOR DISROW(A5),DISCOL(A5) ; PRNAM FILE+D.FIL(A5) ; show file in high intensity INCW MFCNT(A5) ; update matching file count CURSOR #6,#27. ; CLR D1 ; MOVW MFCNT(A5),D1 ; DCVT 0,OT$TRM ; 10$: INCW MLCNT(A5) ; update matching line count CURSOR #6,#67. ; CLR D1 ; MOVW MLCNT(A5),D1 ; DCVT 0,OT$TRM ; CALL SHOW.MATCH ; show matching line on screen CALL OUTPUT.MATCH ; output matching line to file REST A3,D3 ; LCC #PS.Z ; set Z (match) RTN ; return MA.ERR: REST A3,D3 ; LCC #0 ; RTN ; ;**************** ;* SHOW.MATCH * ;**************** ;Function: Display matching line on screen ; ;Inputs: LINE(A5) - line to display ; TXTROW(A5) - row to display line at ; ;Outputs: TXTROW(A5) - updated for next time SHOW.MATCH: CURSOR TXTROW(A5),#1 ; MOV #79.,D0 ; LEA A2,LINE(A5) ; 10$: MOVB (A2)+,D1 ; BEQ 20$ ; BCALL ECHO ; BNE 10$ ; SOB D0,10$ ; 20$: CRT 9 ; INCB TXTROW(A5) ; CMPB TXTROW(A5),#23. ; BLOS 30$ ; CURSOR #19.,#1 ; CRT 15 ; DECB TXTROW(A5) ; 30$: RTN ; ;echo character in D1 ;screen out unprintable stuff ;set Z if we displayed anything ECHO: CMPB D1,#TAB ; tab? BEQ EC.TAB ; yes CMPB D1,#40 ; BLO EC.SKP ; CMPB D1,#'~ ; BHI EC.SKP ; EC.OUT: TTY ; LCC #PS.Z ; RTN ; EC.TAB: CRT 23 ; CRT 68 ; CRT 24 ; LCC #PS.Z ; RTN ; EC.SKP: LCC #0 ; RTN ; ;****************** ;* OUTPUT.MATCH * ;****************** ;Function: if an output file is open, output matching line to it OUTPUT.MATCH: TSTB OUTFIL+D.OPN(A5) ; is an output file open? JEQ 40$ ; no ;show matching filenames CMPB SFILES(A5),#'Y ; BNE 5$ ; CMPW MATCNT(A5),#1 ; first match? BNE 2$ ; PUSH A2 ; LEA A2,OUTFIL(A5) ; OFILE FILE(A5),OT$DDB ; CMPB FILE+D.ERR(A5), #D$EFIU ; Was file in use? BNE 1$ ; No. ERRMSG FILE+D.ERR(A5), OT$DDB ; Yes. Say so. POP A2 ; Restore stack. RTN ; Back to caller. 1$: POP A2 ; MOVB #CR,D1 ; CR FILOTB OUTFIL(A5) ; MOVB #LF,D1 ; LF FILOTB OUTFIL(A5) ; 2$: ;show matching lines 5$: CMPB SLINES(A5),#'Y ; BNE 40$ ; LEA A2,LINE(A5) ; 10$: MOVB (A2)+,D1 ; BEQ 30$ ; CMPB D1,#TAB ; BEQ 20$ ; CMPB D1,#40 ; BLO 10$ ; CMPB D1,#'~ ; BHI 10$ ; 20$: FILOTB OUTFIL(A5) ; BR 10$ ; 30$: MOVB #CR,D1 ; CR FILOTB OUTFIL(A5) ; MOVB #LF,D1 ; FILOTB OUTFIL(A5) ; 40$: RTN ; ;*************** ;* SHOW.FILE * ;*************** ;Function: show name of file we are working on; update file count SHOW.FILE: CURSOR DISROW(A5),DISCOL(A5) ; CRT 11 ; PRNAM FILE+D.FIL(A5) ; CRT 12 ; CURSOR #5,#55. ; PFILE FILE(A5) ; CRT 9 ; CURSOR #5,#26. ; INCW PROCNT(A5) ; CLR D1 ; MOVW PROCNT(A5),D1 ; DCVT 0,OT$TRM ; RTN ; ;**************** ;* PUT.SCREEN * ;**************** ;Put up option screen PUT.SCREEN: CRT 36 ; screen off CRT 0 ; clear screen CRT 12 ; high intensity CURSOR #1,#52. ; CRT 33 ; reverse off CURSOR #1,#26. ; CRT 32 ; reverse on TYPE < ENTER SEARCH PARAMETERS > ; CRT 33 ; reverse off CRT 11 ; low intensity CURSOR #3,#24. ; TYPE Files to search: ; CURSOR #4,#18. ; TYPE Text to search for: 1. CURSOR #5,#38. ; TYPE 2. ; CURSOR #6,#38. ; TYPE 3. ; CURSOR #7,#38. ; TYPE 4. ; CURSOR #8.,#38. ; TYPE 5. ; CURSOR #9.,#25. ; TYPE Output to file: ; CURSOR #10.,#16. ; TYPE Show matching filenames? CURSOR #11.,#20. ; TYPE Show matching lines? ; CURSOR #12.,#21. ; TYPE Wildcard character: ; CURSOR #13.,#15. ; TYPE Matches to list per file: CURSOR #14.,#28. ; TYPE Ignore case? ; CURSOR #15.,#18. ; TYPE Find mid-word matches? ; CURSOR #16.,#21. ; TYPE Ignore white space? ; CRT 12 ; high intensity CURSOR #22.,#25. ; TYPE [ Press TAB to begin search ] CURSOR #23.,#29. ; TYPE [ Press ESC to quit ] CRT 37 ; RTN ; ;****************** ;* EDIT.OPTIONS * ;****************** ;Function: Edit option screen EDIT.OPTIONS: E1: EDTFLD 03.,41.,FE$STR,01.,38.,FE$UCS,FILES(A5) ONKEY EO.RTN,E14,E2,EO.RTN E2: EDTFLD 04.,41.,FE$STR,01.,38.,0,TEXT1(A5) ONKEY EO.RTN,E1,E3,EO.RTN E3: EDTFLD 05.,41.,FE$STR,01.,38.,0,TEXT2(A5) ONKEY EO.RTN,E2,E4,EO.RTN E4: EDTFLD 06.,41.,FE$STR,01.,38.,0,TEXT3(A5) ONKEY EO.RTN,E3,E5,EO.RTN E5: EDTFLD 07.,41.,FE$STR,01.,38.,0,TEXT4(A5) ONKEY EO.RTN,E4,E6,EO.RTN E6: EDTFLD 08.,41.,FE$STR,01.,38.,0,TEXT5(A5) ONKEY EO.RTN,E5,E7,EO.RTN E7: EDTFLD 09.,41.,FE$STR,01.,38.,FE$UCS,OUTNAM(A5) ONKEY EO.RTN,E6,E8,EO.RTN E8: EDTFLD 10.,41.,FE$YNO,01.,01.,FE$UCS,SFILES(A5) ONKEY EO.RTN,E7,E9,EO.RTN E9: EDTFLD 11.,41.,FE$YNO,01.,01.,FE$UCS,SLINES(A5) ONKEY EO.RTN,E8,E10,EO.RTN E10: EDTFLD 12.,41.,FE$STR,01.,01.,0,WLDCHR(A5) ONKEY EO.RTN,E9,E11,EO.RTN E11: EDTFLD 13.,41.,FE$INT,01.,03.,0,MAXMAT(A5) ONKEY EO.RTN,E10,E12,EO.RTN E12: EDTFLD 14.,41.,FE$YNO,01.,01.,FE$UCS,IGNCAS(A5) ONKEY EO.RTN,E11,E13,EO.RTN E13: EDTFLD 15.,41.,FE$YNO,01.,01.,FE$UCS,MIDWRD(A5) ONKEY EO.RTN,E12,E14,EO.RTN E14: EDTFLD 16.,41.,FE$YNO,01.,01.,FE$UCS,IGNSPC(A5) ONKEY EO.RTN,E13,E1,EO.RTN EO.RTN: RTN ; ;***************** ;* PUT.OPTIONS * ;***************** ;Function: Display current option settings PUT.OPTIONS: CRT 12 ; CURSOR #3,#41. ; TTYL FILES(A5) ; CRT 9 ; CURSOR #4,#41. ; TTYL TEXT1(A5) ; CRT 9 ; CURSOR #5,#41. ; TTYL TEXT2(A5) ; CRT 9 ; CURSOR #6,#41. ; TTYL TEXT3(A5) ; CRT 9 ; CURSOR #7,#41. ; TTYL TEXT4(A5) ; CRT 9 ; CURSOR #8.,#41. ; TTYL TEXT5(A5) ; CRT 9 ; CURSOR #9.,#41. ; TTYL OUTNAM(A5) ; CRT 9 ; CURSOR #10.,#41. ; TTYL SFILES(A5) ; CRT 9 ; CURSOR #11.,#41. ; TTYL SLINES(A5) ; CRT 9 ; CURSOR #12.,#41. ; TTYL WLDCHR(A5) ; CRT 9 ; CURSOR #13.,#41. ; TTYL MAXMAT(A5) ; CRT 9 ; CURSOR #14.,#41. ; TTYL IGNCAS(A5) ; CRT 9 ; CURSOR #15.,#41. ; TTYL MIDWRD(A5) ; CRT 9 ; CURSOR #16.,#41. ; TTYL IGNSPC(A5) ; CRT 9 ; RTN ; ;**************** ;* EDIT.FIELD * ;**************** ;Function: Edit Field ; ;Inputs: FLDROW(A5) - cursor row ; FLDCOL(A5) - cursor column ; ;Outputs: EDIT.FIELD: CLRB FLDPOS(A5) ; MOV FLDBUF(A5),A2 ; EF.SIZ: MOV A2,A6 ; CLRB FLDSIZ(A5) ; 10$: TSTB (A6)+ ; BEQ 20$ ; INCB FLDSIZ(A5) ; BR 10$ ; 20$: EF.POS: CURSOR FLDROW(A5),FLDCOL(A5) ; EF.GET: TIN ; CMPB D1,#40 ; BLO EF.CTL ; CMPB D1,#'~ ; BHI EF.CTL ; EF.TXT: CMMB FLDPOS(A5),FLDMAX(A5) ; BHIS EF.GET ; CALL VALID ; BNE EF.GET ; CALL TRANSFORM ; TTY ; MOVB D1,(A2)+ ; INCB FLDPOS(A5) ; CMMB FLDPOS(A5),FLDSIZ(A5) ; BLOS EF.GET ; MOVB FLDPOS(A5),FLDSIZ(A5) ; BR EF.GET EF.CTL: LEA A0,CTLTBL ; MOV #-2,D0 ; 10$: MOVB (A0)+,D7 ; BEQ EF.GET ; ADD #2,D0 ; CMPB D7,D1 ; BNE 10$ ; MOVW JMPTBL[~D0],D0 ; JMP JMPTBL[~D0] ; DEFINE CASE LABEL=WORD LABEL-JMPTBL JMPTBL: CASE CTRL.H ; ^H (LEFT ARROW) CASE CTRL.I ; ^I (TAB) CASE CTRL.J ; ^J (DOWN ARROW) CASE CTRL.K ; ^K (UP ARROW) CASE CTRL.L ; ^L (RIGHT ARROW) CASE CTRL.M ; ^M (RETURN) CASE CTRL.N ; ^N CASE CTRL.U ; ^U CASE CTRL.Z ; ^Z (DEL LINE) CASE ESCAPE ; ^[ (ESCAPE) CASE RUBOUT ; DEL CTLTBL: BYTE 'H-'@ ; ^H (LEFT ARROW) BYTE 'I-'@ ; ^I (TAB) BYTE 'J-'@ ; ^J (UP ARROW) BYTE 'K-'@ ; ^K (DOWN ARROW) BYTE 'L-'@ ; ^L (RIGHT ARROW) BYTE 'M-'@ ; ^M (RETURN) BYTE 'N-'@ ; ^N BYTE 'U-'@ ; ^U BYTE 'Z-'@ ; ^Z (DEL LINE) BYTE '[-'@ ; ^[ (ESCAPE) BYTE 177 ; DEL BYTE 0 ; ** end of table ** EVEN ; CTRL.H: TSTB FLDPOS(A5) ; at start of field? JEQ EF.GET ; yes CRT 5 ; move left DEC A2 ; DECB FLDPOS(A5) ; JMP EF.GET ; CTRL.I: MOVB #4,FLDCOD(A5) ; return code 4 when TAB pressed RTN ; ESCAPE: MOVB #1,FLDCOD(A5) ; return code 1 when ESCAPE pressed RTN ; CTRL.J: MOVB #3,FLDCOD(A5) ; return code 3 when DOWN ARROW pressed RTN ; CTRL.K: MOVB #2,FLDCOD(A5) ; return code 2 when UP ARROW pressed RTN ; CTRL.L: CMMB FLDPOS(A5),FLDSIZ(A5) ; at end of field? JHIS EF.GET ; yes CRT 6 ; move right INCB FLDPOS(A5) ; INC A2 ; JMP EF.GET ; CTRL.M: CLRB FLDCOD(A5) ; return code of 0 when RETURN pressed RTN ; ;control-N, shift right arrow ;move to end of field CTRL.N: CMMB FLDPOS(A5),FLDSIZ(A5) ; JHIS EF.GET ; CRT 6 ; INC A2 ; INCB FLDPOS(A5) ; BR CTRL.N ; ;control-U, shift left arrow ;move to start of field CTRL.U: TSTB FLDPOS(A5) ; JEQ EF.GET ; CRT 5 ; DEC A2 ; DECB FLDPOS(A5) ; BR CTRL.U ; ;control-Z, DEL LINE ;delete field CTRL.Z: CLR D0 ; MOVB FLDSIZ(A5),D0 ; JEQ EF.GET ; MOV FLDBUF(A5),A2 ; CURSOR FLDROW(A5),FLDCOL(A5) ; 10$: TYPESP ; CLRB (A2)+ ; SOB D0,10$ ; CLRB FLDSIZ(A5) ; CLRB FLDPOS(A5) ; MOV FLDBUF(A5),A2 ; JMP EF.POS ; ;character delete when cursor is at end of field RUBOUT: TSTB FLDPOS(A5) ; JEQ EF.GET ; CMMB FLDPOS(A5),FLDSIZ(A5) ; JNE EF.GET ; CRT 5 ; TYPESP ; CRT 5 ; DECB FLDPOS(A5) ; DECB FLDSIZ(A5) ; CLRB -(A2) ; JMP EF.GET ; ;*********** ;* VALID * ;*********** ;check that character in D1 is valid, set Z if it is VALID: MOVB FLDTYP(A5),D7 ; CMPB D7,#FE$YNO ; BEQ VA.YNO ; CMPB D7,#FE$INT ; BEQ VA.INT ; VA.STR: BR VA.YES ; VA.YNO: UCS ; CMPB D1,#'Y ; BEQ VA.YES ; CMPB D1,#'N ; BEQ VA.YES ; BR VA.NO ; VA.INT: CMPB D1,#'0 ; BLO VA.NO ; CMPB D1,#'9 ; BHI VA.NO ; VA.YES: LCC #PS.Z ; RTN ; VA.NO: LCC #0 ; RTN ; ;*************** ;* TRANSFORM * ;*************** ;transform character in D1 based on flags TRANSFORM: TR.UCS: BITW #FE$UCS,FLDFLG(A5) ; BEQ 10$ ; UCS ; 10$: RTN ; ;**************** ;* PUT.SEARCH * ;**************** ;Function: Put up search screen PUT.SEARCH: CRT 0 ; clear screen CRT 12 ; high intensity CURSOR #1,#49. ; CRT 33 ; reverse off CURSOR #1,#29. ; CRT 32 ; reverse on TYPE < PERFORMING SEARCH > ; CRT 33 ; reverse off CRT 11 ; CURSOR #3,#1 ; CALL HLINE ; CURSOR #5,#1 ; TYPE Number of files scanned: CURSOR #5,#41. ; TYPE Current file: CURSOR #6,#1 ; TYPE Number of matching files: CURSOR #6,#41. ; TYPE Number of matching lines: CRT 12 ; CURSOR #8.,#1 ; CALL HLINE ; CURSOR #17.,#1 ; CALL HLINE ; CURSOR #6,#27. ; TYPE 0 ; CURSOR #6,#67. ; TYPE 0 ; RTN ; ;*********** ;* HLINE * ;*********** ;Function: Draw horizontal graphics line at present cursor position HLINE: CRT 23 ; MOV #80.,D0 ; 10$: CRT 46 ; SOB D0,10$ ; CRT 24 ; RTN ; ;************ ;* CLFILT * ;************ ;Function: close file (if open) CLSFIL: TSTB FILE+D.OPN(A5) ; is file open? BEQ 10$ ; no CLOSE FILE(A5) ; yes - close it 10$: RTN ; ;************ ;* CLSOUT * ;************ ;Function: close output file (if open) CLSOUT: TSTB OUTFIL+D.OPN(A5) ; is output file open? BEQ 10$ ; no CLOSE OUTFIL(A5) ; yes - close it 10$: RTN ; ;************ ;* GETBYT * ;************ ;Function: Reads next byte from FILE(A5) ; ;Outputs: Z - set normally, cleared on end of file condition ; N - set on error condition GETBYT: SAVE A3 ; CLR D1 ; LEA A3,FILE(A5) ; BITW #F$RANDOM,FLAGS(A5) ; random file? [102] BNE GB.RAN ; yes [102] GB.SEQ: MOV D.IDX(A3),A6 ; pick up buffer index [167] CMP A6,D.SIZ(A3) ; check for buffer empty [167] BLO 20$ ; not yet [167] INPUT @A3 ; input next record [167] MOVB D.ERR(A3),D7 ; error? [177] BNE 30$ ; yes! [177] MOV D.IDX(A3),A6 ; did we get anything? [167] CMP A6,D.SIZ(A3) ; [167] BNE 20$ ; REST A3 ; LCC #0 ; RTN ; 20$: ADD D.BUF(A3),A6 ; add buffer base [167] MOVB @A6,D1 ; return the character in D1 [167] INC D.IDX(A3) ; increment the index [167] REST A3 ; LCC #PS.Z ; RTN ; 30$: REST A3 ; LCC #PS.N ; RTN ; GB.RAN: CLR D7 ; [102] MOVW FILOFF(A5),D7 ; [102] CMPW D7,#512. ; [102] BHIS 10$ ; [102] MOV D.BUF(A3),A6 ; [102] ADD D7,A6 ; [102] MOVB @A6,D1 ; [102] INCW FILOFF(A5) ; [102] BR 20$ ; [102] 10$: INC D.REC(A3) ; [102] CMM D.REC(A3),FILSIZ(A5) ; [102] BHIS 30$ ; [102] INPUT @A3 ; [102] CLRW FILOFF(A5) ; [102] BR GB.RAN ; [102] 20$: REST A3 ; [102] LCC #PS.Z ; [102] RTN ; [102] 30$: REST A3 ; [102] LCC #0 ; [102] RTN ; [102] END .