1 2(********************************************************************) 3(* *) 4(* find7.sd7 Utility to search for files and file contents. *) 5(* Copyright (C) 2016 Thomas Mertes *) 6(* *) 7(* This program is free software; you can redistribute it and/or *) 8(* modify it under the terms of the GNU General Public License as *) 9(* published by the Free Software Foundation; either version 2 of *) 10(* the License, or (at your option) any later version. *) 11(* *) 12(* This program is distributed in the hope that it will be useful, *) 13(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) 14(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) 15(* GNU General Public License for more details. *) 16(* *) 17(* You should have received a copy of the GNU General Public *) 18(* License along with this program; if not, write to the *) 19(* Free Software Foundation, Inc., 51 Franklin Street, *) 20(* Fifth Floor, Boston, MA 02110-1301, USA. *) 21(* *) 22(********************************************************************) 23 24 25$ include "seed7_05.s7i"; 26 include "osfiles.s7i"; 27 include "console.s7i"; 28 include "getf.s7i"; 29 30 31const proc: writeMatchingLines (in string: filePath, in string: stringSearched) is func 32 local 33 var string: content is ""; 34 var integer: pos is 0; 35 var integer: startPos is 0; 36 var integer: endPos is 0; 37 begin 38 content := getf(filePath); 39 pos := pos(content, stringSearched); 40 if pos <> 0 then 41 writeln(filePath <& ":"); 42 startPos := rpos(content, '\n', pos); 43 incr(startPos); 44 endPos := pos(content, '\n', pos); 45 if endPos = 0 then 46 endPos := length(content); 47 else 48 decr(endPos); 49 end if; 50 writeln(content[startPos .. endPos]); 51 end if; 52 end func; 53 54 55const proc: searchDir (in string: dirPath, 56 in string: partOfFileName, in string: stringSearched) is func 57 local 58 var array string: dirElements is 0 times ""; 59 var string: fileName is ""; 60 var string: filePath is ""; 61 begin 62 block 63 dirElements := readDir(dirPath); 64 exception 65 catch FILE_ERROR: 66 writeln(" *** Cannot read directory " <& dirPath); 67 end block; 68 for fileName range dirElements do 69 if dirPath = "/" then 70 filePath := "/" & fileName; 71 else 72 filePath := dirPath & "/" & fileName; 73 end if; 74 if partOfFileName = "" or 75 pos(lower(fileName), partOfFileName) <> 0 then 76 if stringSearched = "" then 77 writeln(filePath); 78 else 79 writeMatchingLines(filePath, stringSearched); 80 end if; 81 end if; 82 case fileType(filePath) of 83 when {FILE_DIR}: 84 if fileTypeSL(filePath) = FILE_SYMLINK and 85 startsWith(dirPath, toAbsPath(dirPath, readLink(filePath))) then 86 writeln(" *** Symbolic link loop " <& filePath); 87 else 88 searchDir(filePath, partOfFileName, stringSearched); 89 end if; 90 when {FILE_SYMLINK}: 91 writeln(" *** Cannot follow symbolic link " <& filePath); 92 end case; 93 end for; 94 end func; 95 96 97const proc: main is func 98 local 99 var string: dirPath is ""; 100 var string: partOfFileName is ""; 101 var string: stringSearched is ""; 102 begin 103 OUT := STD_CONSOLE; 104 if length(argv(PROGRAM)) < 2 then 105 writeln("Find7 Version 1.0 - Utility to search for files and file contents."); 106 writeln("Copyright (C) 2016 Thomas Mertes"); 107 writeln("This is free software; see the source for copying conditions. There is NO"); 108 writeln("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."); 109 writeln("Find7 is written in the Seed7 programming language"); 110 writeln("Homepage: http://seed7.sourceforge.net"); 111 writeln; 112 writeln("usage: find7 directory partOfFileName [stringSearched]"); 113 writeln; 114 writeln("Examples:"); 115 writeln(" find7 . .sd7"); 116 writeln(" Search for files with a name that contains .sd7 in the current"); 117 writeln(" working directory and its subdirectories."); 118 writeln(" find7 ../lib .s7i decompose"); 119 writeln(" Search if .s7i files in the ../lib directory contain the word"); 120 writeln(" decompose."); 121 writeln(" find7 ../doc \"\" \"Seed7 program\""); 122 writeln(" Search if any file in the ../doc directory contains the phrase"); 123 writeln(" Seed7 program."); 124 else 125 dirPath := convDosPath(argv(PROGRAM)[1]); 126 partOfFileName := lower(argv(PROGRAM)[2]); 127 if length(argv(PROGRAM)) >= 3 then 128 stringSearched := argv(PROGRAM)[3]; 129 end if; 130 searchDir(dirPath, partOfFileName, stringSearched); 131 end if; 132 end func; 133