/[pcre]/code/tags/pcre-1.07/pgrep.c
ViewVC logotype

Contents of /code/tags/pcre-1.07/pgrep.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 18 - (show annotations) (download)
Sat Feb 24 21:38:31 2007 UTC (7 years, 6 months ago) by nigel
File MIME type: text/plain
File size: 4756 byte(s)
Tag code/trunk as code/tags/pcre-1.07.

1 /*************************************************
2 * PCRE grep program *
3 *************************************************/
4
5 #include <stdio.h>
6 #include <string.h>
7 #include <stdlib.h>
8 #include <errno.h>
9 #include "pcre.h"
10
11
12 #define FALSE 0
13 #define TRUE 1
14
15 typedef int BOOL;
16
17
18
19 /*************************************************
20 * Global variables *
21 *************************************************/
22
23 static pcre *pattern;
24 static pcre_extra *hints;
25
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;
32
33
34
35 #ifdef STRERROR_FROM_ERRLIST
36 /*************************************************
37 * Provide strerror() for non-ANSI libraries *
38 *************************************************/
39
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. */
43
44 extern int sys_nerr;
45 extern char *sys_errlist[];
46
47 char *
48 strerror(int n)
49 {
50 if (n < 0 || n >= sys_nerr) return "unknown error number";
51 return sys_errlist[n];
52 }
53 #endif /* STRERROR_FROM_ERRLIST */
54
55
56
57 /*************************************************
58 * Grep an individual file *
59 *************************************************/
60
61 static int
62 pgrep(FILE *in, char *name)
63 {
64 int rc = 1;
65 int linenumber = 0;
66 int count = 0;
67 int offsets[2];
68 char buffer[BUFSIZ];
69
70 while (fgets(buffer, sizeof(buffer), in) != NULL)
71 {
72 BOOL match;
73 int length = (int)strlen(buffer);
74 if (length > 0 && buffer[length-1] == '\n') buffer[--length] = 0;
75 linenumber++;
76
77 match = pcre_exec(pattern, hints, buffer, length, 0, offsets, 2) >= 0;
78 if (match && whole_lines && offsets[1] != length) match = FALSE;
79
80 if (match != invert)
81 {
82 if (count_only) count++;
83
84 else if (filenames_only)
85 {
86 fprintf(stdout, "%s\n", (name == NULL)? "<stdin>" : name);
87 return 0;
88 }
89
90 else if (silent) return 0;
91
92 else
93 {
94 if (name != NULL) fprintf(stdout, "%s:", name);
95 if (number) fprintf(stdout, "%d:", linenumber);
96 fprintf(stdout, "%s\n", buffer);
97 }
98
99 rc = 0;
100 }
101 }
102
103 if (count_only)
104 {
105 if (name != NULL) fprintf(stdout, "%s:", name);
106 fprintf(stdout, "%d\n", count);
107 }
108
109 return rc;
110 }
111
112
113
114
115 /*************************************************
116 * Usage function *
117 *************************************************/
118
119 static int
120 usage(int rc)
121 {
122 fprintf(stderr, "Usage: pgrep [-chilnsvx] pattern [file] ...\n");
123 return rc;
124 }
125
126
127
128
129 /*************************************************
130 * Main program *
131 *************************************************/
132
133 int
134 main(int argc, char **argv)
135 {
136 int i;
137 int rc = 1;
138 int options = 0;
139 int errptr;
140 const char *error;
141 BOOL filenames = TRUE;
142
143 /* Process the options */
144
145 for (i = 1; i < argc; i++)
146 {
147 char *s;
148 if (argv[i][0] != '-') break;
149 s = argv[i] + 1;
150 while (*s != 0)
151 {
152 switch (*s++)
153 {
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;
162 default:
163 fprintf(stderr, "pgrep: unknown option %c\n", s[-1]);
164 return usage(2);
165 }
166 }
167 }
168
169 /* There must be at least a regexp argument */
170
171 if (i >= argc) return usage(0);
172
173 /* Compile the regular expression. */
174
175 pattern = pcre_compile(argv[i++], options, &error, &errptr);
176 if (pattern == NULL)
177 {
178 fprintf(stderr, "pgrep: error in regex at offset %d: %s\n", errptr, error);
179 return 2;
180 }
181
182 /* Study the regular expression, as we will be running it may times */
183
184 hints = pcre_study(pattern, 0, &error);
185 if (error != NULL)
186 {
187 fprintf(stderr, "pgrep: error while studing regex: %s\n", error);
188 return 2;
189 }
190
191 /* If there are no further arguments, do the business on stdin and exit */
192
193 if (i >= argc) return pgrep(stdin, NULL);
194
195 /* Otherwise, work through the remaining arguments as files. If there is only
196 one, don't give its name on the output. */
197
198 if (i == argc - 1) filenames = FALSE;
199 if (filenames_only) filenames = TRUE;
200
201 for (; i < argc; i++)
202 {
203 FILE *in = fopen(argv[i], "r");
204 if (in == NULL)
205 {
206 fprintf(stderr, "%s: failed to open: %s\n", argv[i], strerror(errno));
207 rc = 2;
208 }
209 else
210 {
211 int frc = pgrep(in, filenames? argv[i] : NULL);
212 if (frc == 0 && rc == 1) rc = 0;
213 fclose(in);
214 }
215 }
216
217 return rc;
218 }
219
220 /* End */

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12