home *** CD-ROM | disk | FTP | other *** search
- /*
-
- findf
-
- A very fast case-sensitive grep-style search program using
- async i/o and the Boyer-Moore search algorithm.
-
- Usage - same as 'c:search' for the commands implemented.
-
- Michael Zucchi 1994
-
- */
-
-
- MODULE 'dos/dos', 'dos/dosasl',
- 'locale',
- 'tools/async'
-
- DEF skip[256]:ARRAY OF CHAR, -> skip array
- line[1024]:ARRAY OF CHAR, -> input buffer
- buffer[1024]:ARRAY OF CHAR, -> for case-sensitive searches
- m, -> length of string
- string:PTR TO CHAR, -> string to match
- uppertable[256]:ARRAY OF CHAR,-> lower->upper conversion table
- quiet, nonum, quick, ncase -> settings
-
-
- PROC main()
- DEF args:PTR TO LONG, rdargs, p:PTR TO LONG, an:PTR TO anchorpath,go,
- fib:PTR TO fileinfoblock, loc, i
-
- args:=[0,0,0,0,0,0,0];
-
- IF rdargs:=ReadArgs('FROM/M,SEARCH/A,ALL/S,NONUM/S,QUIET/S,QUICK/S,CASE/S', args, 0)
- string:=args[1];
- nonum:=args[3];
- quiet:=args[4];
- quick:=args[5];
- ncase:=args[6]=0;
-
- IF ncase
- IF localebase:=OpenLibrary('locale.library', 0)
- IF loc:=OpenLocale(0);
- FOR i:=0 TO 255 DO uppertable[i]:=ConvToUpper(loc, i);
- CloseLocale(loc);
- ELSE
- FOR i:=0 TO 255 DO uppertable[i]:=IF i>="a" AND i<="z" THEN i-32 ELSE i
- ENDIF
- ELSE
- FOR i:=0 TO 255 DO uppertable[i]:=IF i>="a" AND i<="z" THEN i-32 ELSE i
- ENDIF
- CloseLibrary(localebase);
- MOVE.L uppertable,A0
- MOVE.L string,A1
- MOVEQ #0,D0
- mn_up: MOVE.B (A1),D0
- MOVE.B 0(A0,D0.W),(A1)+
- BNE.S mn_up
- ENDIF
-
- initskip();
-
- IF an:=New(SIZEOF anchorpath + 256)
- an.strlen:=255
- an.breakbits:=SIGBREAKF_CTRL_C;
- fib:=an.info
- p:=args[0];
- go:=0
- WHILE p[] AND (go=0)
- go:=MatchFirst(p[], an);
- WHILE go=0
- IF (fib.direntrytype) <0
- go:=scanfile(an+SIZEOF anchorpath);
- ELSE
- IF args[2]
- IF (an.flags AND APF_DIRCHANGED)=0 THEN an.flags:=an.flags OR APF_DODIR
- ENDIF
- ENDIF
- IF go=0 THEN go:=MatchNext(an);
- ENDWHILE
- p++
- ENDWHILE
- IF quick THEN WriteF('\e[M');
- Dispose(an);
- ENDIF
- FreeArgs(rdargs);
- ELSE
- WriteF('FindF, Michael Zucchi 1994.\nERROR: bad args\n'+
- ' FROM/M files/patterns to search\n'+
- ' SEARCH/A text to search for\n'+
- ' ALL/S recursively scan subdirectories\n'+
- ' NONUM/S do not output line numbers\n'+
- ' QUIET/S do not output matched lines\n'+
- ' QUICK/S faster file-scan display\n'+
- ' CASE/S do a case-sensitive search\n');
- ENDIF
- ENDPROC
-
-
- /*
- search a single file, by filename, line at a time
- */
-
- PROC scanfile(name)
- DEF number, file, found=0,go=0
-
- IF quick
- WriteF('\s\e[K\b', name);
- ELSE
- IF quiet=0 THEN WriteF('\s\n', name);
- ENDIF
-
- number:=1;
- IF (file:=as_Open(name, MODE_OLDFILE, 3, 10240))
- WHILE as_FGetS(file, line, 1023) AND (go=0)
- IF testmatch()
- IF quiet
- IF found=0 THEN WriteF('\s\n', name);
- JUMP close
- ELSEIF nonum
- -> IF quick AND found=0 THEN WriteF('\n');
- WriteF('\s', line);
- ELSE
- -> IF quick AND found=0 THEN WriteF('\n');
- WriteF('\d[6] \s', number, line);
- ENDIF
- found:=1
- ENDIF
- number++
- go:=CheckSignal(SIGBREAKF_CTRL_C)
- ENDWHILE
- close:
- as_Close(file);
- ENDIF
-
- ENDPROC go
-
-
-
- /*
- Initialise the skip table for a given search string
- */
-
- PROC initskip()
- DEF i
-
- m:=StrLen(string);
-
- -> initialise skip table for all characters
- FOR i:=0 TO 255
- skip[i]:=m+1;
- ENDFOR
-
- -> set skip table for characters in the string
- FOR i:=0 TO m-1
- skip[string[i]]:=m-i;
- ENDFOR
-
- ENDPROC
-
- /*
- Looks for a match in a given line
- */
-
- PROC testmatch()
-
- IF m<1 THEN RETURN
-
- MOVEM.L A4-A5,-(A7)
-
- MOVE.L m,D7
- SUBQ.L #1,D7
-
- TST.L ncase
- BEQ.S tm_case
-
- -> non case-sensitive
-
- MOVE.L line,A3
- MOVE.L buffer,A0
- LEA 1(A0,D7.L),A2
- MOVE.L uppertable,A1
- MOVEQ #0,D0
- tp_up: MOVE.B (A3)+,D0
- MOVE.B 0(A1,D0.W),(A0)+
- BNE.S tp_up
- BRA.S tp_match
-
- -> case sensitive
- tm_case:
- MOVE.L line,A0
- LEA 1(A0,D7.L),A2 -> a[i]
- tm_scan:
- TST.B (A0)+ -> <hack> find end of string
- BNE.S tm_scan
-
- tp_match:
- MOVE.L string,A1
- MOVE.L A1,A5
- LEA 1(A1,D7.L),A1 -> p[j]
-
- MOVE.L skip,A4
-
- MOVE.L D7,D3
- ADDQ.L #2,D3
- MOVEQ #0,D1
- tm_loop0:
- MOVE.L D7,D2
- MOVE.L A1,A3
- tm_loop:
- MOVE.B -(A2),D1
- CMP.B -(A3),D1
- BEQ.S tm_matchchar
-
- MOVE.L A5,D0
- SUB.L A3,D0 -> -j
- ADD.L D3,D0 -> M-j+1
-
- MOVE.B 0(A4,D1.W),D1 -> skip[character]
- CMP.L D0,D1
- BLT.S tm_add0
-
- ADD.L D1,A2
-
- tm_ok: CMPA.L A0,A2
- BLT.S tm_loop0
-
- MOVEQ #0,D0
- BRA.S tm_exit
-
- tm_add0:
- ADD.L D0,A2
- BRA.S tm_ok
-
- tm_matchchar:
- DBF D2,tm_loop
-
- MOVEQ #-1,D0
- tm_exit:
- MOVEM.L (A7)+,A4-A5
-
- ENDPROC D0
-
-
-