| 163 |
static int DEE_action = DEE_READ; |
static int DEE_action = DEE_READ; |
| 164 |
static int error_count = 0; |
static int error_count = 0; |
| 165 |
static int filenames = FN_DEFAULT; |
static int filenames = FN_DEFAULT; |
| 166 |
|
static int only_matching = -1; |
| 167 |
static int process_options = 0; |
static int process_options = 0; |
| 168 |
|
|
| 169 |
static unsigned long int match_limit = 0; |
static unsigned long int match_limit = 0; |
| 179 |
static BOOL multiline = FALSE; |
static BOOL multiline = FALSE; |
| 180 |
static BOOL number = FALSE; |
static BOOL number = FALSE; |
| 181 |
static BOOL omit_zero_count = FALSE; |
static BOOL omit_zero_count = FALSE; |
|
static BOOL only_matching = FALSE; |
|
| 182 |
static BOOL resource_error = FALSE; |
static BOOL resource_error = FALSE; |
| 183 |
static BOOL quiet = FALSE; |
static BOOL quiet = FALSE; |
| 184 |
static BOOL silent = FALSE; |
static BOOL silent = FALSE; |
| 244 |
{ OP_NODATA, 'M', NULL, "multiline", "run in multiline mode" }, |
{ OP_NODATA, 'M', NULL, "multiline", "run in multiline mode" }, |
| 245 |
{ OP_STRING, 'N', &newline, "newline=type", "set newline type (CR, LF, CRLF, ANYCRLF or ANY)" }, |
{ OP_STRING, 'N', &newline, "newline=type", "set newline type (CR, LF, CRLF, ANYCRLF or ANY)" }, |
| 246 |
{ OP_NODATA, 'n', NULL, "line-number", "print line number with output lines" }, |
{ OP_NODATA, 'n', NULL, "line-number", "print line number with output lines" }, |
| 247 |
{ OP_NODATA, 'o', NULL, "only-matching", "show only the part of the line that matched" }, |
{ OP_OP_NUMBER, 'o', &only_matching, "only-matching=n", "show only the part of the line that matched" }, |
| 248 |
{ OP_NODATA, 'q', NULL, "quiet", "suppress output, just set return code" }, |
{ OP_NODATA, 'q', NULL, "quiet", "suppress output, just set return code" }, |
| 249 |
{ OP_NODATA, 'r', NULL, "recursive", "recursively scan sub-directories" }, |
{ OP_NODATA, 'r', NULL, "recursive", "recursively scan sub-directories" }, |
| 250 |
{ OP_STRING, N_EXCLUDE,&exclude_pattern, "exclude=pattern","exclude matching files when recursing" }, |
{ OP_STRING, N_EXCLUDE,&exclude_pattern, "exclude=pattern","exclude matching files when recursing" }, |
| 1174 |
|
|
| 1175 |
else if (quiet) return 0; |
else if (quiet) return 0; |
| 1176 |
|
|
| 1177 |
/* The --only-matching option prints just the substring that matched, and |
/* The --only-matching option prints just the substring that matched, or a |
| 1178 |
the --file-offsets and --line-offsets options output offsets for the |
captured portion of it, as long as this string is not empty, and the |
| 1179 |
matching substring (they both force --only-matching). None of these options |
--file-offsets and --line-offsets options output offsets for the matching |
| 1180 |
|
substring (they both force --only-matching = 0). None of these options |
| 1181 |
prints any context. Afterwards, adjust the start and length, and then jump |
prints any context. Afterwards, adjust the start and length, and then jump |
| 1182 |
back to look for further matches in the same line. If we are in invert |
back to look for further matches in the same line. If we are in invert |
| 1183 |
mode, however, nothing is printed - this could be still useful because the |
mode, however, nothing is printed and we do not restart - this could still |
| 1184 |
return code is set. */ |
be useful because the return code is set. */ |
| 1185 |
|
|
| 1186 |
else if (only_matching) |
else if (only_matching >= 0) |
| 1187 |
{ |
{ |
| 1188 |
if (!invert) |
if (!invert) |
| 1189 |
{ |
{ |
| 1190 |
if (printname != NULL) fprintf(stdout, "%s:", printname); |
if (printname != NULL) fprintf(stdout, "%s:", printname); |
| 1191 |
if (number) fprintf(stdout, "%d:", linenumber); |
if (number) fprintf(stdout, "%d:", linenumber); |
| 1192 |
if (line_offsets) |
if (line_offsets) |
| 1193 |
fprintf(stdout, "%d,%d", (int)(matchptr + offsets[0] - ptr), |
fprintf(stdout, "%d,%d\n", (int)(matchptr + offsets[0] - ptr), |
| 1194 |
offsets[1] - offsets[0]); |
offsets[1] - offsets[0]); |
| 1195 |
else if (file_offsets) |
else if (file_offsets) |
| 1196 |
fprintf(stdout, "%d,%d", (int)(filepos + matchptr + offsets[0] - ptr), |
fprintf(stdout, "%d,%d\n", |
| 1197 |
|
(int)(filepos + matchptr + offsets[0] - ptr), |
| 1198 |
offsets[1] - offsets[0]); |
offsets[1] - offsets[0]); |
| 1199 |
else |
else if (only_matching < mrc) |
| 1200 |
{ |
{ |
| 1201 |
if (do_colour) fprintf(stdout, "%c[%sm", 0x1b, colour_string); |
int plen = offsets[2*only_matching + 1] - offsets[2*only_matching]; |
| 1202 |
FWRITE(matchptr + offsets[0], 1, offsets[1] - offsets[0], stdout); |
if (plen > 0) |
| 1203 |
if (do_colour) fprintf(stdout, "%c[00m", 0x1b); |
{ |
| 1204 |
|
if (do_colour) fprintf(stdout, "%c[%sm", 0x1b, colour_string); |
| 1205 |
|
FWRITE(matchptr + offsets[only_matching*2], 1, plen, stdout); |
| 1206 |
|
if (do_colour) fprintf(stdout, "%c[00m", 0x1b); |
| 1207 |
|
fprintf(stdout, "\n"); |
| 1208 |
|
} |
| 1209 |
} |
} |
| 1210 |
fprintf(stdout, "\n"); |
else if (printname != NULL || number) fprintf(stdout, "\n"); |
| 1211 |
matchptr += offsets[1]; |
matchptr += offsets[1]; |
| 1212 |
length -= offsets[1]; |
length -= offsets[1]; |
| 1213 |
match = FALSE; |
match = FALSE; |
| 1472 |
/* End of file; print final "after" lines if wanted; do_after_lines sets |
/* End of file; print final "after" lines if wanted; do_after_lines sets |
| 1473 |
hyphenpending if it prints something. */ |
hyphenpending if it prints something. */ |
| 1474 |
|
|
| 1475 |
if (!only_matching && !count_only) |
if (only_matching < 0 && !count_only) |
| 1476 |
{ |
{ |
| 1477 |
do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname); |
do_after_lines(lastmatchnumber, lastmatchrestart, endptr, printname); |
| 1478 |
hyphenpending |= endhyphenpending; |
hyphenpending |= endhyphenpending; |
| 1821 |
case 'L': filenames = FN_NOMATCH_ONLY; break; |
case 'L': filenames = FN_NOMATCH_ONLY; break; |
| 1822 |
case 'M': multiline = TRUE; options |= PCRE_MULTILINE|PCRE_FIRSTLINE; break; |
case 'M': multiline = TRUE; options |= PCRE_MULTILINE|PCRE_FIRSTLINE; break; |
| 1823 |
case 'n': number = TRUE; break; |
case 'n': number = TRUE; break; |
| 1824 |
case 'o': only_matching = TRUE; break; |
case 'o': only_matching = 0; break; |
| 1825 |
case 'q': quiet = TRUE; break; |
case 'q': quiet = TRUE; break; |
| 1826 |
case 'r': dee_action = dee_RECURSE; break; |
case 'r': dee_action = dee_RECURSE; break; |
| 1827 |
case 's': silent = TRUE; break; |
case 's': silent = TRUE; break; |
| 2161 |
while (*s != 0) |
while (*s != 0) |
| 2162 |
{ |
{ |
| 2163 |
for (op = optionlist; op->one_char != 0; op++) |
for (op = optionlist; op->one_char != 0; op++) |
| 2164 |
{ if (*s == op->one_char) break; } |
{ |
| 2165 |
|
if (*s == op->one_char) break; |
| 2166 |
|
} |
| 2167 |
if (op->one_char == 0) |
if (op->one_char == 0) |
| 2168 |
{ |
{ |
| 2169 |
fprintf(stderr, "pcregrep: Unknown option letter '%c' in \"%s\"\n", |
fprintf(stderr, "pcregrep: Unknown option letter '%c' in \"%s\"\n", |
| 2170 |
*s, argv[i]); |
*s, argv[i]); |
| 2171 |
pcregrep_exit(usage(2)); |
pcregrep_exit(usage(2)); |
| 2172 |
} |
} |
| 2173 |
if (op->type != OP_NODATA || s[1] == 0) |
|
| 2174 |
{ |
/* Check for a single-character option that has data: OP_OP_NUMBER |
| 2175 |
option_data = s+1; |
is used for one that either has a numerical number or defaults, i.e. the |
| 2176 |
break; |
data is optional. If a digit follows, there is data; if not, carry on |
| 2177 |
|
with other single-character options in the same string. */ |
| 2178 |
|
|
| 2179 |
|
option_data = s+1; |
| 2180 |
|
if (op->type == OP_OP_NUMBER) |
| 2181 |
|
{ |
| 2182 |
|
if (isdigit((unsigned char)s[1])) break; |
| 2183 |
} |
} |
| 2184 |
|
else /* Check for end or a dataless option */ |
| 2185 |
|
{ |
| 2186 |
|
if (op->type != OP_NODATA || s[1] == 0) break; |
| 2187 |
|
} |
| 2188 |
|
|
| 2189 |
|
/* Handle a single-character option with no data, then loop for the |
| 2190 |
|
next character in the string. */ |
| 2191 |
|
|
| 2192 |
pcre_options = handle_option(*s++, pcre_options); |
pcre_options = handle_option(*s++, pcre_options); |
| 2193 |
} |
} |
| 2194 |
} |
} |
| 2205 |
|
|
| 2206 |
/* If the option type is OP_OP_STRING or OP_OP_NUMBER, it's an option that |
/* If the option type is OP_OP_STRING or OP_OP_NUMBER, it's an option that |
| 2207 |
either has a value or defaults to something. It cannot have data in a |
either has a value or defaults to something. It cannot have data in a |
| 2208 |
separate item. At the moment, the only such options are "colo(u)r" and |
separate item. At the moment, the only such options are "colo(u)r", |
| 2209 |
Jeffrey Friedl's special -S debugging option. */ |
"only-matching", and Jeffrey Friedl's special -S debugging option. */ |
| 2210 |
|
|
| 2211 |
if (*option_data == 0 && |
if (*option_data == 0 && |
| 2212 |
(op->type == OP_OP_STRING || op->type == OP_OP_NUMBER)) |
(op->type == OP_OP_STRING || op->type == OP_OP_NUMBER)) |
| 2216 |
case N_COLOUR: |
case N_COLOUR: |
| 2217 |
colour_option = (char *)"auto"; |
colour_option = (char *)"auto"; |
| 2218 |
break; |
break; |
| 2219 |
|
|
| 2220 |
|
case 'o': |
| 2221 |
|
only_matching = 0; |
| 2222 |
|
break; |
| 2223 |
|
|
| 2224 |
#ifdef JFRIEDL_DEBUG |
#ifdef JFRIEDL_DEBUG |
| 2225 |
case 'S': |
case 'S': |
| 2226 |
S_arg = 0; |
S_arg = 0; |
| 2302 |
} |
} |
| 2303 |
|
|
| 2304 |
/* Only one of --only-matching, --file-offsets, or --line-offsets is permitted. |
/* Only one of --only-matching, --file-offsets, or --line-offsets is permitted. |
| 2305 |
However, the latter two set the only_matching flag. */ |
However, the latter two set only_matching. */ |
| 2306 |
|
|
| 2307 |
if ((only_matching && (file_offsets || line_offsets)) || |
if ((only_matching >= 0 && (file_offsets || line_offsets)) || |
| 2308 |
(file_offsets && line_offsets)) |
(file_offsets && line_offsets)) |
| 2309 |
{ |
{ |
| 2310 |
fprintf(stderr, "pcregrep: Cannot mix --only-matching, --file-offsets " |
fprintf(stderr, "pcregrep: Cannot mix --only-matching, --file-offsets " |
| 2312 |
pcregrep_exit(usage(2)); |
pcregrep_exit(usage(2)); |
| 2313 |
} |
} |
| 2314 |
|
|
| 2315 |
if (file_offsets || line_offsets) only_matching = TRUE; |
if (file_offsets || line_offsets) only_matching = 0; |
| 2316 |
|
|
| 2317 |
/* If a locale has not been provided as an option, see if the LC_CTYPE or |
/* If a locale has not been provided as an option, see if the LC_CTYPE or |
| 2318 |
LC_ALL environment variable is set, and if so, use it. */ |
LC_ALL environment variable is set, and if so, use it. */ |