class FIND_WORDS creation go feature extension : STRING -- default equivalent -ext e (alternatively, -ext c, -ext tex, etc -- That is, only searches files with this extension, and -- the default extension is e (eiffel files). This -- string begins with a fullstop. automaton : KMP display_overlap_map ( kmp : KMP ) is local triple : GBN_TRIPLE [ STRING, STRING, STRING ] do triple := kmp . overlap_out io . put_string ("kmp overlap map%N") io . put_string ( triple.item_1 + "%N" ) io . put_string ( triple.item_2 + "%N" ) io . put_string ( triple.item_3 + "%N" ) end match_in_file ( fname : STRING; pad: STRING ) is require automaton_exists : automaton /= Void local file : TEXT_FILE_READ head_written : BOOLEAN do if not file_exists ( fname ) then std_error.put_string ( pad + fname + " unreadable%N") else from !! file.connect_to ( fname ) until file . end_of_input loop file . read_line automaton.install_text_string ( file.last_string ) automaton.find_match if automaton.match_found then if not head_written then io.put_string ( pad + fname + ":%N" ) head_written := true end io.put_string ( io.last_string + "%N" ) end end end end fname_has_extension ( fname : STRING ) : BOOLEAN is -- verifies that fname ends with correct -- extension. local i : INTEGER do if fname.count >= extension.count then from i := 0 Result := true until i >= extension.count loop if fname.item(fname.count-i) = extension.item(extension.count-i) then i := i+1 else Result := false i := extension.count end end end end scan ( a_dir: STRING; pad: STRING ) is -- scans the directory named a_dir, searching -- files which match the extension, and -- recursing into subdirectories. local dir, subdir : DIRECTORY fname : STRING i : INTEGER do !! dir.make !! subdir.make dir.scan ( a_dir ) from i := 1 until i > dir.count loop fname := dir.item(i) if not fname.is_equal(".") and then not fname.is_equal("..") then subdir.scan ( a_dir + "/" + fname ) if subdir.last_scan_status then scan ( a_dir + "/" + fname, pad + " " ) elseif fname_has_extension (fname) then match_in_file ( a_dir + "/" + fname, pad ) end end i := i+1 end end go is local file : TEXT_FILE_READ keys : ARRAY[STRING] i,j : INTEGER do !! extension.copy ( ".e" ) ------------------------------------------------------ -- awful code checking the command line arguments ------------------------------------------------------ if argument_count < 2 then std_error.put_string("find_words expects at least 2 args%N") std_error.put_string("format " + argument(0) + " ..pattern[s].. [-ext ]%N" ) die_with_code ( exit_failure_code ) end if not file_exists (argument(1)) then std_error.put_string ( argument(1) + " unreadable%N") die_with_code ( exit_failure_code ) end if argument(2).is_equal ("-f") then if argument_count = 5 then if argument(4).is_equal("-ext") then !!extension.copy( "." + argument(5)) else std_error.put_string("4th arg expected -ext%N") die_with_code ( exit_failure_code ) end elseif argument_count /= 3 then std_error.put_string( argument(0) + " -f [-ext ]%N" ) die_with_code ( exit_failure_code ) end if not file_exists (argument(3)) then std_error.put_string ( argument(3) + " unreadable%N") die_with_code ( exit_failure_code ) else !! file.connect_to ( argument(3) ) end end ------------------------------------------------------ -- end of awful code checking the command line arguments. -- Next read many keys from the command line but only -- use the first. ------------------------------------------------------ if file = Void then from !! keys.make (1, 0 ) i := 2 j := 0 until i > argument_count loop if argument(i).is_equal("-ext") and i < argument_count then !! extension.copy ( "."+argument(i+1) ) i := i+2 else j := j+1 keys.force ( argument(i), j ) i := i+1 end end else from !! keys.make ( 1, 0 ) i := 1 until file.end_of_input loop file.read_line keys.force ( file.last_string, i ) end end !! automaton.make ( keys . item(1) ) -- display_overlap_map ( automaton ) -- debugging scan ( argument(1), "" ) end end -- class FIND_WORDS