language-Modula2-0.1: examples/Modula-2_Libraries/andrea-m2/applications/fst/search/search.mod
MODULE Search;
(*
Search the file given by argument 1
for any line which contains all of the strings defined by arguments 2,3,...
*)
(* John Andrea, June.27/92 *)
(* This code may be freely distributed, it may not be sold *)
FROM Break IMPORT EnableBreak;
FROM System IMPORT GetArg;
FROM InOut IMPORT Write, WriteString, WriteLn, RedirectInput, Read, WriteCard, Done;
FROM ASCII IMPORT EOL, EOF;
CONST
max_size = 30;
max_args = 11;
max_line = 133;
VAR
i :CARDINAL;
n_args :CARDINAL;
arg :ARRAY [1..max_args] OF ARRAY [1..max_size] OF CHAR;
size :ARRAY [1..max_args] OF CARDINAL;
line :ARRAY [1..max_line] OF CHAR;
len :CARDINAL;
eof :BOOLEAN;
(* ------------------------------------------ *)
PROCEDURE ReadLine;
VAR
c :CHAR;
BEGIN
Read( c );
IF c = EOF THEN
eof := TRUE;
ELSE
len := 1;
WHILE ( len < max_line ) & ( c # EOL ) & ( c # EOF ) DO
line[len] := c;
Read( c );
len := len + 1;
END;
IF len <= max_line THEN
line[len] := 0C;
ELSE
(* finish reading this line, beacuse its too big to fit into the buffer *)
Read( c );
WHILE c # EOL DO
Read( c );
END;
END;
len := len - 1;
END;
END ReadLine;
(* -------------------------------------------------------- *)
PROCEDURE Contains( pattern :ARRAY OF CHAR; len_p :CARDINAL ) :BOOLEAN;
VAR
s, p :CARDINAL;
done, found :BOOLEAN;
BEGIN
IF ( len_p = 0 ) OR ( len_p > len ) THEN
RETURN FALSE;
ELSE
found := FALSE;
done := FALSE;
s := 1;
WHILE ( NOT done ) & ( NOT found ) DO
(* find the next occurance of the first char of the pattern *)
WHILE ( s <= len ) & ( CAP(line[s]) # CAP(pattern[0]) ) DO
s := s + 1;
END;
IF s > len THEN
(* didn't find another first character match *)
done := TRUE;
ELSE
(* try to determine if the pattern fits here *)
IF len - s + 1 < len_p THEN
(* the pattern won't fit in the remainder if the source *)
done := TRUE;
ELSE
(* ok, try to make a match *)
p := 0;
WHILE ( p < len_p ) & ( CAP(line[s+p]) = CAP(pattern[p]) ) DO
p := p + 1;
END;
found := p = len_p;
END;
END;
s := s + 1;
END; (* while *)
RETURN found;
END;
END Contains;
BEGIN EnableBreak;
n_args := 0;
REPEAT
n_args := n_args + 1;
GetArg( arg[n_args], size[n_args] );
UNTIL ( n_args = max_args ) OR ( size[n_args] = 0 );
n_args := n_args - 1;
IF n_args > 1 THEN
eof := FALSE;
RedirectInput( arg[1] );
IF Done THEN
ReadLine;
WHILE NOT eof DO
(* only try to search though the line if is isn't all blank *)
IF len > 0 THEN
(* stop searching if one of the arg strings isn't in this line *)
i := 2;
WHILE ( i <= n_args ) & Contains( arg[i], size[i] ) DO
i := i + 1;
END;
IF i > n_args THEN
WriteString( line ); WriteLn;
END;
END;
ReadLine;
END;
ELSE
WriteString( 'cant open input file ' ); WriteString( arg[1] ); WriteLn;
END;
END;
END Search.