/[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 49 - (hide annotations) (download)
Sat Feb 24 21:39:33 2007 UTC (7 years, 9 months ago) by nigel
Original Path: code/trunk/pcregrep.c
File MIME type: text/plain
File size: 4986 byte(s)
Load pcre-3.3 into code/trunk.

1 nigel 49 /*************************************************
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