(*---------------------------------------------------------------------------
  :Program.    BMSearch
  :Author.     Thomas Igracki
  :Address.    Obstallee 45, D-13593 Berlin
  :E-Mail.     UseNet -> lokai@cs.tu-berlin.de
  :E-Mail.     Z-Netz -> T.Igracki@BAMP.ZER
  :E-Mail.     Fido   -> Thomas_Igracki%2:2403_10.40
  :Version.    1.0
  :Date.       04.07.93
  :Copyright.  Thomas Igracki (If you like to use it, contact me!)
  :Language.   Oberon-2
  :Translator. Amiga Oberon V3.00d
  :Contents.   Ein Programm, das mittels des BoyerMoore Algs, einen String in
  :Contents.   einer Datei sucht.
  :Usage.      BMSearch <file> <Pattern>
  :Remark.     OS2.0+ Only!
  :History.    1.0 
---------------------------------------------------------------------------*)
MODULE BMSearch;
IMPORT
   y: SYSTEM, d: Dos, e: Exec, ol: OberonLib, BM: BoyerMoore;
CONST
   tmp = 'file/A,str/A\o$VER: BMSearch 1.0 (04.07.93) by Thomas Igracki';
TYPE
   BigStrPtr = UNTRACED POINTER TO ARRAY MAX(LONGINT)-1 OF CHAR;
VAR
   pos       : LONGINT;
   fileStart : BigStrPtr;
   fileLen,i : LONGINT;

   RD	     : d.RDArgsPtr;
   args      : STRUCT (dummy: d.ArgsStruct)
   		   file,str: d.ArgString;
   	       END;

(* Load a file into memory *)
PROCEDURE LoadFile (name: ARRAY OF CHAR; VAR mem: BigStrPtr; VAR len: LONGINT): BOOLEAN;
VAR fh: d.FileHandlePtr; e: LONGINT;
BEGIN
     fh := d.Open (name, d.oldFile); IF fh = NIL THEN RETURN FALSE END;

     len := d.Seek(fh, 0, d.end); len := d.Seek(fh, 0, d.beginning);

     ol.New(mem,len+1);
     e := d.Read (fh, mem^, len);
     d.OldClose(fh);

     IF e = -1 THEN y.SETREG(0,d.PrintFault(d.IoErr(),NIL)) 
     ELSIF e # len THEN
        d.PrintF ('Konnte das File %s nicht vollständig laden!\n',y.ADR(name));
     END;
     RETURN (e = len)
END LoadFile;

BEGIN
     RD := d.ReadArgs (tmp,args,NIL);
     IF RD = NIL THEN d.PrintF('Usage: BMSearch <file> <string>\n'); HALT(d.fail) END;

     IF ~LoadFile (args.file^,fileStart,fileLen) THEN
        d.PrintF ('Probs beim laden von %s!\n',args.file); HALT(20)
     END;

     pos := BM.SearchPos (fileStart^,args.str^, 0, fileLen);

     IF pos = -1 THEN d.PrintF('Muster nicht im Text gefunden!\n')
     ELSE
        i := pos+1; WHILE (fileStart[i] # '\n') & (i < fileLen) DO INC(i) END;
        fileStart[i] := 0X;
        d.PrintF('Muster ab %ld. Zeichen: %s\n',pos,y.VAL(LONGINT,fileStart)+pos);
     END;
CLOSE
    IF fileStart # NIL THEN DISPOSE (fileStart) END;
    IF RD # NIL THEN d.FreeArgs(RD) END;
END BMSearch.
