home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / jËzyki_programowania / oberon / system / find.mod (.txt) < prev    next >
Oberon Text  |  1977-12-31  |  7KB  |  196 lines

  1. Syntax10.Scn.Fnt
  2. StampElems
  3. Alloc
  4. 28 Aug 94
  5. FoldElems
  6. Syntax10i.Scn.Fnt
  7. Syntax10b.Scn.Fnt
  8. MODULE Find;    (* HM 
  9. (*--------------------------------------------------------------------------
  10. Find.Domain ~
  11.     Specify the files in which Find.All should search for a pattern.
  12. Find.All ^
  13.     Searches the selection in the files specified with Find.Domain.
  14.     Lists all lines containing the pattern.
  15. Find.Diff ^
  16.     Compares two texts starting from the two most recent selections
  17.     Sets new selections at the first position where the two texts differ.
  18. --------------------------------------------------------------------------*)
  19. IMPORT Display, Files, Oberon, Viewers, MenuViewers, TextFrames, Texts;
  20. CONST
  21.     stdMenu = "System.Close  System.Copy  System.Grow  Edit.Search  Edit.Store ";
  22.     File = POINTER TO FileDesc;
  23.     FileDesc = RECORD
  24.         name: ARRAY 32 OF CHAR;
  25.         next: File
  26.     END;
  27.     file: File;
  28.     w: Texts.Writer;
  29.     out: Texts.Text;
  30. PROCEDURE ScanPar (VAR s: Texts.Scanner);    
  31.     VAR v: Viewers.Viewer; t: Texts.Text; beg, end, time: LONGINT;
  32. BEGIN
  33.     Texts.OpenScanner(s, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(s);
  34.     IF (s.class = Texts.Char) & (s.c = "^") THEN
  35.         Oberon.GetSelection(t, beg, end, time);
  36.         IF time >= 0 THEN
  37.             Texts.OpenScanner(s, t, beg); Texts.Scan(s)
  38.         END
  39. END ScanPar;
  40. PROCEDURE OpenViewer(name: ARRAY OF CHAR; t: Texts.Text);    
  41.     VAR v: MenuViewers.Viewer; x, y: INTEGER; t1: Texts.Text; menu: TextFrames.Frame; buf: Texts.Buffer;
  42. BEGIN
  43.     IF Files.Old("Edit.Menu.Text") = NIL THEN menu := TextFrames.NewMenu(name, stdMenu)
  44.     ELSE menu := TextFrames.NewMenu(name, "");
  45.         NEW(t1); Texts.Open(t1, "Edit.Menu.Text");
  46.         NEW(buf); Texts.OpenBuf(buf); Texts.Save(t1, 0, t1.len, buf); Texts.Append(menu.text, buf)
  47.     END;
  48.     Oberon.AllocateUserViewer(0, x, y);
  49.     v := MenuViewers.New(menu, TextFrames.NewText(t, 0), TextFrames.menuH, x, y)
  50. END OpenViewer;
  51. PROCEDURE Search (fn: ARRAY OF CHAR; pat: ARRAY OF CHAR; m: INTEGER);    
  52.     CONST
  53.         bufSize = 31744; (*2**15 - 1024*)
  54.         CR = 0DX; TAB = 09X;
  55.         textTag = 496; oldTextTag = -4095;
  56.         f: Files.File; r: Files.Rider;
  57.         n, pos: LONGINT;
  58.         i, j, i0: INTEGER;
  59.         ch, patj: CHAR;
  60.         found: BOOLEAN;
  61.         tab: ARRAY 265 OF SHORTINT;
  62.         text: ARRAY bufSize OF CHAR;
  63. BEGIN
  64.     (*----- open file *)
  65.     f := Files.Old(fn);
  66.     IF f = NIL THEN RETURN END;
  67.     Files.Set(r, f, 0); Files.ReadInt(r, i);
  68.     IF (i = textTag) OR (i = oldTextTag) THEN
  69.         pos := 0; (*Files.ReadLInt(r, pos); -- modified to search also in collapsed Fold segments*)
  70.         (*----- initialize tab *)
  71.         Texts.WriteString(w, "--- "); Texts.WriteString(w, fn); Texts.WriteLn(w);
  72.         FOR i := 0 TO 255 DO tab[i] := SHORT(m) END;
  73.         FOR i := 0 TO m-2 DO tab[ORD(pat[i])] := SHORT(m - i - 1) END;
  74.         patj := pat[m-1]; found := FALSE;
  75.         LOOP
  76.             (*----- read text[0..n-1] *)
  77.             n := Files.Length(f) - pos;
  78.             IF n > bufSize THEN n := bufSize END;
  79.             IF n < m THEN EXIT END;
  80.             Files.Set(r, f, pos); Files.ReadBytes(r, text, n);
  81.             (*----- search pat in text[0..n-1] *)
  82.             i := m - 1; j := i;
  83.             WHILE i < n DO
  84.                 IF text[i] = patj THEN i0 := i;
  85.                     REPEAT DEC(i); DEC(j) UNTIL (j < 0) OR (text[i] # pat[j]);
  86.                     IF j < 0 THEN
  87.                         (*------ found: print result *)
  88.                         found := TRUE;
  89.                         WHILE (i >= 0) & (text[i] # CR) & (text[i] >= TAB) DO DEC(i) END;
  90.                         INC(i);
  91.                         Files.Set(r, f, pos + i);
  92.                         REPEAT Files.Read(r, ch); Texts.Write(w, ch); INC(i) UNTIL (ch = CR) OR (ch < TAB) OR (r.eof)
  93.                     ELSE i := i + tab[ORD(text[i])]
  94.                     END;
  95.                     IF i <= i0 THEN i := i0 + 1 END;
  96.                     j := m - 1
  97.                 ELSE i := i + tab[ORD(text[i])]
  98.                 END
  99.             END;
  100.             pos := pos + i - m + 1
  101.         END;
  102.         IF found THEN Texts.WriteLn(w); Texts.Append(out, w.buf) ELSE Texts.OpenWriter(w) END
  103.     ELSE
  104.         Texts.WriteString(w, fn); Texts.WriteString(w, " is no text file"); Texts.WriteLn(w);
  105.         Texts.Append(Oberon.Log, w.buf)
  106. END Search;
  107. (* -- commands -- *)
  108. PROCEDURE Domain*;    (* {filename} ~ *)    
  109.     VAR s: Texts.Scanner; f, last: File;
  110. BEGIN file := NIL; last := NIL;
  111.     ScanPar(s);
  112.     WHILE s.class = Texts.Name DO
  113.         NEW(f); f.next := NIL;
  114.         IF last = NIL THEN file := f ELSE last.next := f END;
  115.         last := f;
  116.         COPY(s.s, f.name);
  117.         Texts.Scan(s);
  118.         WHILE (s.class = Texts.Char) & (s.c = "/") DO Texts.Scan(s); Texts.Scan(s) END
  119. END Domain;
  120. PROCEDURE All*;    (* ^ *)    
  121.     VAR pat: ARRAY 128 OF CHAR; m: INTEGER; f: File;
  122.     PROCEDURE ReadPattern (VAR pat: ARRAY OF CHAR; VAR m: INTEGER);    
  123.         VAR t: Texts.Text; r: Texts.Reader; beg, end, time: LONGINT; ch: CHAR;
  124.     BEGIN
  125.         Oberon.GetSelection(t, beg, end, time);
  126.         IF time > 0 THEN
  127.             Texts.OpenReader(r, t, beg); m := 0;
  128.             WHILE beg < end DO Texts.Read(r, ch);
  129.                 IF m < 127 THEN pat[m] := ch END;
  130.                 INC(m); INC(beg)
  131.             END;
  132.             pat[m] := 0X
  133.         END;
  134.     END ReadPattern;
  135. BEGIN
  136.     ReadPattern(pat, m);
  137.     out := TextFrames.Text("");
  138.     OpenViewer(pat, out); f := file;
  139.     WHILE f # NIL DO
  140.         Search(f.name, pat, m);
  141.         f := f.next
  142. END All;
  143. PROCEDURE Diff*;    (*- compares two texts from the last two selections; sets selection to first difference *)    
  144.     VAR f1, f2: TextFrames.Frame; p1, p2: LONGINT; r1, r2: Texts.Reader; ch1, ch2: CHAR;
  145.     PROCEDURE GetSelection(VAR F: TextFrames.Frame; VAR pos: LONGINT);    
  146.         VAR time: LONGINT; v: Viewers.Viewer; x: INTEGER; f: Display.Frame;
  147.     BEGIN
  148.         time := -1; x := 0; F := NIL;
  149.         WHILE x < Display.Width DO
  150.             v := Viewers.This(x, 0);
  151.             WHILE v.state > 1 DO
  152.                 f := v.dsc.next;
  153.                 WITH f: TextFrames.Frame DO
  154.                     IF f.hasSel & (f.time > time) THEN F := f; pos := f.selbeg.pos; time := f.time END
  155.                 ELSE
  156.                 END;
  157.                 v := Viewers.Next(v)
  158.             END;
  159.             x := x + v.W
  160.         END;
  161.         IF F # NIL THEN TextFrames.RemoveSelection(F); TextFrames.RemoveCaret(F) END
  162.     END GetSelection;
  163.     PROCEDURE ShowSelection(f: TextFrames.Frame; pos: LONGINT);    
  164.         VAR x: LONGINT;
  165.     BEGIN
  166.         IF pos > TextFrames.Pos(f, f.X + f.W - 1, f.Y) THEN 
  167.             x := pos - 150; IF x < 0 THEN x := 0 END;
  168.             TextFrames.Show(f, x)
  169.         END;
  170.         TextFrames.SetSelection(f, pos, pos+1)
  171.     END ShowSelection;
  172. BEGIN
  173.     GetSelection(f1, p1); GetSelection(f2, p2);
  174.     IF (f1 # NIL) & (f2 # NIL) THEN
  175.         Texts.OpenReader(r1, f1.text, p1); 
  176.         Texts.OpenReader(r2, f2.text, p2); 
  177.         REPEAT
  178.             Texts.Read(r1, ch1); INC(p1); Texts.Read(r2, ch2); INC(p2);
  179.         UNTIL (ch1 # ch2) OR (ch1 = 0X);
  180.         IF (ch1 = 0X) OR (ch2 = 0X) THEN DEC(p1); DEC(p2) END;
  181.         ShowSelection(f1, p1-1); ShowSelection(f2, p2-1)
  182. END Diff;
  183. BEGIN
  184.     file := NIL; Texts.OpenWriter(w)
  185. END Find.
  186. (*--------------------------------------------------------------------------
  187. Find.Domain ~
  188.     Specify the files in which Find.All should search for a pattern.
  189. Find.All ^
  190.     Searches the selection in the files specified with Find.Domain.
  191.     Lists all lines containing the pattern.
  192. Find.Diff ^
  193.     Compares two texts starting from the two most recent selections
  194.     Sets new selections at the first position where the two texts differ.
  195. --------------------------------------------------------------------------*)
  196.