home *** CD-ROM | disk | FTP | other *** search
- -- MetaWare Professional Pascal 386
- -- (c) Ronald Fischer & toolbox 1991
- -- SUCHE: Suchen von Strings in einer Datei.
- -- Dieses Programm dient der Demonstration der Spracherweite-
- -- rungen von Professional Pascal. Die Datei wird komplett in
- -- ein hinreichend großes Array kopiert, alle Suchoperationen
- -- finden im Speicher statt. Die Suchausdrücke werden von
- -- INPUT gelesen. Aufruf des gebundenen Programmes:
- -- SUCHE dateiname
-
- WITH LOOPHOLES : [RETYPE,SIZEOF];
- PRAGMA INCLUDE('heap.pf');
- WITH HEAP : [MALLOC];
- PROGRAM suche(datei);
-
- CONST max_line= 120; -- Größte Länge Eingabezeile
- CONST max_datei_len = 1000000; -- Max. Dateilänge
- CONST newline= CHR(12); -- Interner Zeilentrenner
- TYPE textzeile = STRING(max_line);
- TYPE mdateipuff =
- PACKED ARRAY [1..max_datei_len] OF CHAR;
- TYPE mdatei = -- "Memory-Datei" - Kopie der Datei
- RECORD -- im Hauptspeicher
- len : CARDINAL; -- Dateilänge
- data : mdateipuff -- Dateiinhalt
- END;
- VAR datei : TEXT; -- Die zu durchsuchende Datei
- VAR m : ^mdatei; -- Die Datei im Speicher
-
- PROCEDURE einlesen(VAR mem : mdatei; VAR fil : TEXT);
- -- Liest die Datei fil auf die Variable mem.
- -- Zeilenenden werden dabei durch newline ersetzt
- BEGIN ------------------ einlesen ---------------
- WITH mem DO BEGIN
- len := 0;
- WHILE NOT EOF(fil) DO
- DECLARE VAR zeile : textzeile; i : 1..max_line
- BEGIN
- READLN(fil, zeile);
- FOR i := 1 TO LENGTH(zeile) DO
- data[len := len+1] := zeile[i];
- data[len := len+1] := newline
- END
- END
- END; ------------------- einlesen ---------------
-
- ITERATOR wortsuch -------------------------------
- (CONST wort : textzeile; CONST m : mdatei)
- :(zeilennr : CARDINAL; zeile : textzeile);
-
- TYPE position = -- Suchposition ind in m
- RECORD -- Zeile znr beginnt bei zp
- znr,ind,zp : CARDINAL;
- erfolg : BOOLEAN -- FALSE wenn Ende
- END;
- FUNCTION wcomp(CONST wort : textzeile; --------
- p1 : CARDINAL; CONST m : mdatei;
- p2 : CARDINAL) :BOOLEAN;
- -- Ist wort gleich m[pos..] ???
- BEGIN -------------- wcomp -----------------
- IF wort[p1] <> m.data[p2] THEN RETURN(FALSE);
- IF p1 = LENGTH(wort) THEN RETURN (TRUE);
- IF p2 = m.len THEN RETURN (FALSE);
- RETURN (wcomp(wort,p1+1,m,p2+1))
- END; --------------- wcomp ------------------
- FUNCTION next(CONST wort: textzeile; --------
- CONST m : mdatei; CONST prev: position)
- : POSITION; -- Position des nächsten Wortes
- BEGIN -------------- next -------------------
- next := prev;
- WHILE TRUE DO WITH next DO BEGIN
- erfolg := FALSE; INC(ind);
- IF m.data[ind] = newline THEN BEGIN
- zp := ind := ind + 1; INC(znr)
- END { Zeilenschaltung! } ;
- IF ind >= m.len THEN RETURN; -- FALSE
- IF erfolg := wcomp(wort,1,m,ind) THEN RETURN; -- TRUE
- END
- END; --------------- next -------------------
- FUNCTION zeile_ab(CONST m: mdatei; p: CARDINAL): textzeile;
- BEGIN -------------- zeile_ab ---------------
- zeile_ab := '';
- REPEAT
- zeile_ab := zeile_ab || m.data[p]
- UNTIL m.data[p := SUCC(p)] = newline;
- END; --------------- zeile_ab ---------------
- VAR control: position;
- BEGIN ------------------ wortsuch ---------------
- control.znr := control.zp := 1; control.ind := 0;
- WHILE (control := next(wort, m, control)).erfolg
- DO yield(control.znr, zeile_ab(m, control.zp))
- END; ------------------- wortsuch ---------------
- BEGIN ------------- Hauptprogramm ---------------
- RESET(datei);
- m := MALLOC(SIZEOF(mdatei)) %RETYPE TYPEOF(m);
- IF m = NIL THEN WRITELN('MALLOC ERROR')
- ELSE DECLARE VAR sw: textzeile; BEGIN
- einlesen(m^,datei);
- writeln(m^.len,' Zeichen gelesen');
- REPEAT
- WRITELN('Suchwort?'); READLN(sw);
- FOR nr,z IN sw %wortsuch m^ DO
- WRITELN(nr,':',z);
- UNTIL LENGTH(sw)=0
- END
- END.