/[pcre]/code/trunk/pgrep.c
ViewVC logotype

Contents of /code/trunk/pgrep.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 37 - (hide annotations) (download)
Sat Feb 24 21:39:09 2007 UTC (7 years, 1 month ago) by nigel
File MIME type: text/plain
File size: 4859 byte(s)
Load pcre-2.07 into code/trunk.

1 nigel 3 /*************************************************
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 nigel 23 int offsets[99];
68 nigel 3 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 nigel 35 match = pcre_exec(pattern, hints, buffer, length, 0, 0, offsets, 99) >= 0;
78 nigel 3 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 nigel 37 fprintf(stderr, "Usage: pgrep [-Vchilnsvx] pattern [file] ...\n");
123 nigel 3 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 nigel 7 const char *error;
141 nigel 3 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 nigel 37
163     case 'V':
164     fprintf(stderr, "PCRE version %s\n", pcre_version());
165     break;
166    
167 nigel 3 default:
168     fprintf(stderr, "pgrep: unknown option %c\n", s[-1]);
169     return usage(2);
170     }
171     }
172     }
173    
174     /* There must be at least a regexp argument */
175    
176     if (i >= argc) return usage(0);
177    
178     /* Compile the regular expression. */
179    
180 nigel 25 pattern = pcre_compile(argv[i++], options, &error, &errptr, NULL);
181 nigel 3 if (pattern == NULL)
182     {
183     fprintf(stderr, "pgrep: error in regex at offset %d: %s\n", errptr, error);
184     return 2;
185     }
186    
187     /* Study the regular expression, as we will be running it may times */
188    
189     hints = pcre_study(pattern, 0, &error);
190     if (error != NULL)
191     {
192     fprintf(stderr, "pgrep: error while studing regex: %s\n", error);
193     return 2;
194     }
195    
196     /* If there are no further arguments, do the business on stdin and exit */
197    
198     if (i >= argc) return pgrep(stdin, NULL);
199    
200     /* Otherwise, work through the remaining arguments as files. If there is only
201     one, don't give its name on the output. */
202    
203     if (i == argc - 1) filenames = FALSE;
204     if (filenames_only) filenames = TRUE;
205    
206     for (; i < argc; i++)
207     {
208     FILE *in = fopen(argv[i], "r");
209     if (in == NULL)
210     {
211     fprintf(stderr, "%s: failed to open: %s\n", argv[i], strerror(errno));
212     rc = 2;
213     }
214     else
215     {
216     int frc = pgrep(in, filenames? argv[i] : NULL);
217     if (frc == 0 && rc == 1) rc = 0;
218     fclose(in);
219     }
220     }
221    
222     return rc;
223     }
224    
225     /* End */

webmaster@exim.org
ViewVC Help
Powered by ViewVC 1.1.12