10 #include "wvstringlist.h"
16 #define VERSION "0.1.0"
18 static void output_filename(WvStringParm filename,
19 char suffix,
bool display_nulls)
21 wvout->print(!!filename? filename:
WvFastString(
"(standard input)"));
23 wvout->
write(
"\0", 1);
25 wvout->
write(&suffix, 1);
29 static int match(
const WvRegex ®ex, WvStringParm filename,
WvStream *file,
30 bool invert_match,
bool display_filename,
bool display_line_number,
31 bool display_nulls,
bool display_nothing,
bool end_on_first_match)
38 if (line == NULL)
break;
41 bool result = regex.match(line);
42 if (invert_match) result = !result;
47 if (end_on_first_match)
return count;
50 if (!result || display_nothing)
continue;
53 output_filename(filename,
':', display_nulls);
54 if (display_line_number)
55 wvout->print(
"%s:", lineno);
56 wvout->print(
"%s\n", line);
62 int main(
int argc,
char **argv)
66 args.
set_version(
"wvgrep (WvStreams grep) " VERSION
"\n");
67 args.
set_email(
"<" WVPACKAGE_BUGREPORT
">");
69 bool opt_count =
false;
72 bool opt_extended_regexp =
false;
76 args.
add_option(
'e',
"regexp", WvString::null, WvString::null, opt_regexp);
78 bool opt_basic_regexp =
false;
81 bool opt_with_filename =
false;
84 bool opt_no_filename =
false;
87 bool opt_ignore_case =
false;
91 bool opt_files_without_match =
false;
92 args.
add_set_bool_option(
'L',
"files-without-match", WvString::null, opt_files_without_match);
94 bool opt_files_with_matches =
false;
95 args.
add_set_bool_option(
'l',
"files-with-matches", WvString::null, opt_files_with_matches);
97 bool opt_line_number =
false;
100 bool opt_quiet =
false;
104 bool opt_no_messages =
false;
107 bool opt_invert_match =
false;
110 bool opt_line_regexp =
false;
113 bool opt_null =
false;
119 args.
set_help_header(
"Search for PATTERN in each FILE or standard input.");
120 args.
set_help_footer(
"With no FILE, this program reads standard input.");
123 args.
process(argc, argv, &remaining_args);
125 if (!opt_regexp && !remaining_args.isempty())
126 opt_regexp = remaining_args.
popstr();
129 WvRegex::EXTENDED: WvRegex::BASIC;
130 if (opt_extended_regexp) cflags = WvRegex::EXTENDED;
131 if (opt_basic_regexp) cflags = WvRegex::BASIC;
132 if (opt_ignore_case) cflags |= WvRegex::ICASE;
136 regex_str =
WvString(
"^%s$", opt_regexp);
137 else regex_str = opt_regexp;
139 WvRegex regex(regex_str, cflags);
143 wverr->print(
"%s: Invalid regular expression", argv[0]);
144 if (!!errstr) wverr->print(errstr);
145 wverr->
write(
"\n", 1);
149 bool display_filename = remaining_args.count() >= 2;
150 if (opt_with_filename) display_filename =
true;
151 if (opt_no_filename) display_filename =
false;
153 if (remaining_args.isempty())
154 remaining_args.append(WvString::null);
156 bool found_match =
false;
157 WvStringList::Iter filename(remaining_args);
158 for (filename.rewind(); filename.next(); )
162 file =
new WvFile(*filename, O_RDONLY);
168 if (!opt_no_messages)
169 wverr->print(
"%s: %s: %s\n", argv[0],
170 *filename, file->errstr());
171 if (!!*filename) WVRELEASE(file);
175 int count = match(regex, *filename, file,
176 opt_invert_match, display_filename, opt_line_number, opt_null,
177 opt_count || opt_files_without_match || opt_files_with_matches,
180 if (!!*filename) WVRELEASE(file);
182 if (opt_files_with_matches || opt_files_without_match)
184 bool display = opt_files_with_matches? count>0: count==0;
186 output_filename(*filename,
'\n', opt_null);
190 if (display_filename)
191 output_filename(*filename,
':', opt_null);
192 wvout->print(
"%s\n", count);
195 found_match = found_match || count > 0;
196 if (opt_quiet && found_match)
break;
199 return found_match? 0: 1;