/[pcre]/code/tags/pcre-3.3/pcregrep.c
ViewVC logotype

Contents of /code/tags/pcre-3.3/pcregrep.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 50 - (show annotations) (download)
Sat Feb 24 21:39:35 2007 UTC (7 years, 7 months ago) by nigel
File MIME type: text/plain
File size: 4986 byte(s)
Tag code/trunk as code/tags/pcre-3.3.

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

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12