1
/*************************************************
3
*************************************************/
19
/*************************************************
21
*************************************************/
24
static pcre_extra *hints;
26
static BOOL count_only = FALSE;
27
static BOOL filenames_only = FALSE;
28
static BOOL invert = FALSE;
29
static BOOL number = FALSE;
30
static BOOL silent = FALSE;
31
static BOOL whole_lines = FALSE;
36
/*************************************************
37
* Provide strerror() for non-ANSI libraries *
38
*************************************************/
40
/* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror()
41
in their libraries, but can provide the same facility by this simple
42
alternative function. */
45
extern char *sys_errlist[];
50
if (n < 0 || n >= sys_nerr) return "unknown error number";
51
return sys_errlist[n];
53
#endif /* HAVE_STRERROR */
57
/*************************************************
58
* Grep an individual file *
59
*************************************************/
62
pgrep(FILE *in, char *name)
70
while (fgets(buffer, sizeof(buffer), in) != NULL)
73
int length = (int)strlen(buffer);
74
if (length > 0 && buffer[length-1] == '\n') buffer[--length] = 0;
77
match = pcre_exec(pattern, hints, buffer, length, 0, 0, offsets, 99) >= 0;
78
if (match && whole_lines && offsets[1] != length) match = FALSE;
82
if (count_only) count++;
84
else if (filenames_only)
86
fprintf(stdout, "%s\n", (name == NULL)? "<stdin>" : name);
90
else if (silent) return 0;
94
if (name != NULL) fprintf(stdout, "%s:", name);
95
if (number) fprintf(stdout, "%d:", linenumber);
96
fprintf(stdout, "%s\n", buffer);
105
if (name != NULL) fprintf(stdout, "%s:", name);
106
fprintf(stdout, "%d\n", count);
115
/*************************************************
117
*************************************************/
122
fprintf(stderr, "Usage: pgrep [-Vchilnsvx] pattern [file] ...\n");
129
/*************************************************
131
*************************************************/
134
main(int argc, char **argv)
141
BOOL filenames = TRUE;
143
/* Process the options */
145
for (i = 1; i < argc; i++)
148
if (argv[i][0] != '-') break;
154
case 'c': count_only = TRUE; break;
155
case 'h': filenames = FALSE; break;
156
case 'i': options |= PCRE_CASELESS; break;
157
case 'l': filenames_only = TRUE;
158
case 'n': number = TRUE; break;
159
case 's': silent = TRUE; break;
160
case 'v': invert = TRUE; break;
161
case 'x': whole_lines = TRUE; options |= PCRE_ANCHORED; break;
164
fprintf(stderr, "PCRE version %s\n", pcre_version());
168
fprintf(stderr, "pgrep: unknown option %c\n", s[-1]);
174
/* There must be at least a regexp argument */
176
if (i >= argc) return usage(0);
178
/* Compile the regular expression. */
180
pattern = pcre_compile(argv[i++], options, &error, &errptr, NULL);
183
fprintf(stderr, "pgrep: error in regex at offset %d: %s\n", errptr, error);
187
/* Study the regular expression, as we will be running it may times */
189
hints = pcre_study(pattern, 0, &error);
192
fprintf(stderr, "pgrep: error while studing regex: %s\n", error);
196
/* If there are no further arguments, do the business on stdin and exit */
198
if (i >= argc) return pgrep(stdin, NULL);
200
/* Otherwise, work through the remaining arguments as files. If there is only
201
one, don't give its name on the output. */
203
if (i == argc - 1) filenames = FALSE;
204
if (filenames_only) filenames = TRUE;
206
for (; i < argc; i++)
208
FILE *in = fopen(argv[i], "r");
211
fprintf(stderr, "%s: failed to open: %s\n", argv[i], strerror(errno));
216
int frc = pgrep(in, filenames? argv[i] : NULL);
217
if (frc == 0 && rc == 1) rc = 0;