source: trunk/minix/commands/simple/cgrep.c@ 15

Last change on this file since 15 was 9, checked in by Mattia Monga, 14 years ago

Minix 3.1.2a

File size: 9.1 KB
Line 
1/* cgrep - grep and display context Author: Mark Mallet */
2
3/*
4 Nov 19 1984 Mark Mallett (mem@zinn.MV.COM)
5
6mem 860224 Modified to do r/e (regular expression) parsing on unix
7mem 860324 Added -f, -n; added code to number lines correctly on output.
8mem 870325 Added support for regcmp()/regex() style regular expression
9 library; redid some conditionals to provide better mix'n'match.
10mem 870326 Don't try to print the filename if reading from stdin.
11 Add -w option. Fix a small problem which occasionally allowed
12 the separator to come out between adjacent lines of the file.
13mem 871119 Fix semantics of call to regcmp(): the NULL terminating the
14 argument list was missing. It worked, but probably only
15 due to some bizarre coincidence.
16dro 890109 Minor mods to compile under Minix
17
18*/
19
20#define OS_UNIX /* Define this for unix systems */
21 /* #define REGEX *//* Define this for re_comp/re_exec library */
22#define REGCMP /* Define this to use regcmp/regex */
23 /* #define OS_CPM *//* Define this for CP/M-80 */
24
25
26/* Don't touch these */
27#define NOREGEXP /* Set this for no regular expression */
28#ifdef REGEX
29#undef NOREGEXP
30#endif /* REGEX */
31
32#ifdef REGCMP
33#undef NOREGEXP
34#endif /* REGCMP */
35
36
37#ifdef OS_CPM
38#include "stdio.h"
39#include "ctype.h"
40#endif /* OS_CPM */
41
42#ifdef OS_UNIX
43#include <sys/types.h>
44#include <sys/dir.h> /* Either here or in sys directory - dro */
45#include <ctype.h>
46#include <limits.h> /* should have this - dro */
47#include <regexp.h> /* should have this - dro */
48#include <stdlib.h>
49#include <stdio.h>
50#endif /* OS_UNIX */
51
52
53/* Local definitions */
54
55#ifndef NULL
56#define NULL ((char *)0)
57#endif /* NULL */
58
59#ifndef NUL
60#define NUL '\000'
61#endif
62
63#ifndef TRUE
64#define TRUE 1
65#define FALSE 0
66#endif
67
68
69/* Internal data declared global */
70
71
72/* Internal routines */
73
74_PROTOTYPE(int main, (int argc, char **argv));
75_PROTOTYPE(void dosrch, (char *ifnm));
76_PROTOTYPE(void shwlin, (char *fnm, int linnum, char *line));
77_PROTOTYPE(int matlin, (char *line));
78_PROTOTYPE(void regerror, (const char *s));
79
80/* External data */
81
82
83/* Local data */
84
85static int Debug = {FALSE}; /* Debug enabled flag */
86static int Lcur = {0}; /* Current line (in Lines array) */
87static char **Lines = {NULL}; /* Lines pointer array */
88static int Linlen = {100}; /* Line length */
89static int Lone = {0}; /* Line one (in Lines array) */
90static int Nmr = {0}; /* Number of matched regions */
91static char *Pat = {NULL}; /* Pattern */
92static char Shwfile = {TRUE}; /* Show file name... */
93static char Shwline = {TRUE}; /* Show line number */
94static int Waft = {0}; /* Window after */
95static int Wbef = {0}; /* Window before */
96static int Wsiz = {0}; /* Window size */
97
98regexp *Re; /* Result from reg compilation */
99
100int main(argc, argv)
101int argc; /* Argument count */
102char **argv; /* Argument values */
103
104{
105 int i; /* Scratch */
106 int n; /* Scratch again */
107 int c; /* A character */
108 char *aptr; /* Argument pointer */
109 int nf; /* number of files on command line */
110
111 nf = 0; /* No files on line */
112
113 for (i = 1; i < argc; i++) { /* Look at args */
114 if (argv[i][0] != '-') {/* If option */
115 if (Pat == NULL) { /* If no pattern yet given */
116 Pat = argv[i]; /* point here */
117#ifdef REGEX
118 if ((Re = re_comp(Pat)) != NULL) {
119 fprintf(stderr, "cgrep: %s\n", re);
120 exit(1);
121 }
122#endif /* REGEX */
123
124#ifdef REGCMP
125 if ((Re = regcomp(Pat)) == NULL) {
126 fprintf(stderr, "cgrep: error in regular expression.\n");
127 exit(1);
128 }
129#endif /* REGCMP */
130
131 } else { /* This must be a file to search */
132 nf++; /* Count it */
133 dosrch(argv[i]); /* Search */
134 }
135 } else { /* Option char */
136 c = argv[i][1]; /* Get option char */
137 if (isupper(c)) /* Trap idiot definition of tolower */
138 c = tolower(c); /* Don't care about case */
139 n = i;
140 aptr = NULL; /* Find arg, if any */
141 if (argv[i][2] != NUL) {
142 aptr = &argv[i][2];
143 n = i; /* Where to set i if we use this arg */
144 } else if (i < argc - 1) { /* use next.. */
145 n = i + 1;
146 aptr = argv[n];
147 }
148 switch (c) { /* Process the option */
149 case 'a': /* Lines after */
150 Waft = atoi(aptr);
151 Lines = NULL;
152 i = n;
153 break;
154
155 case 'b': /* Lines before */
156 Wbef = atoi(aptr);
157 Lines = NULL;
158 i = n;
159 break;
160
161/* Disable debug output
162 case 'd': Debug = TRUE; break;
163*/
164
165 case 'f': /* Suppress filename on output */
166 Shwfile = FALSE;
167 break;
168
169 case 'l': /* Line length */
170 Linlen = atoi(aptr);
171 Lines = NULL;
172 i = n;
173 break;
174
175 case 'n': /* Suppress line number on output */
176 Shwline = FALSE;
177 break;
178
179 case 'w': /* Window: lines before and after */
180 Waft = Wbef = atoi(aptr);
181 Lines = NULL;
182 i = n;
183 break;
184
185 default:
186 fprintf(stderr, "Invalid option %s\n", argv[i]);
187 exit(1);
188 }
189 }
190 }
191
192 if (Pat == NULL) { /* If no pattern given */
193 fprintf(stderr,
194 "Usage: cgrep [-a n] [-b n] [-f] [-l n] [-n] [-w n] pattern [filename... ]\n");
195 exit(1);
196 }
197 if (nf == 0) /* No files processed ? */
198 dosrch((char *)NULL); /* Do standard input */
199 return(0);
200}
201
202 /* Dosrch (ifnm) Perform the search
203 * Accepts :
204 *
205 * ifn Input file name
206 *
207 *
208 * Returns :
209 *
210 *
211 */
212
213void dosrch(ifnm)
214char *ifnm; /* Input filelname */
215
216{
217 FILE *ifp; /* Input fp */
218 char *lptr; /* Line pointer */
219 int i; /* Scratch */
220 int prtaft; /* Print-after count */
221 int linnum; /* Line number */
222 int nlb; /* Number of lines buffered */
223
224 if (ifnm != NULL) { /* If file name given */
225 ifp = fopen(ifnm, "r"); /* Open it for read access */
226 if (ifp == NULL) {
227 fprintf(stderr, "Can not open file %s\n", ifnm);
228 return;
229 }
230 } else
231 ifp = stdin;
232
233 if (Lines == NULL) { /* If no line table allocated.. */
234 Wsiz = Wbef + 2; /* Determine total window size */
235 Lines = (char **) calloc((size_t)Wsiz, sizeof(char *));
236 /* Allocate pointer table */
237 for (i = 0; i < Wsiz; i++) /* Allocate line buffers */
238 Lines[i] = (char *) calloc((size_t)Linlen, sizeof(char));
239 }
240 Lcur = Lone = 0; /* Setup line pointers */
241 nlb = 0; /* No lines buffered */
242 linnum = 0; /* Line number is zero */
243 prtaft = -(Wbef + 1); /* Make sure separator given first time */
244
245 for (;;) { /* Loop through the file */
246 lptr = Lines[Lcur]; /* Get pointer to current line */
247 if (++Lcur == Wsiz) /* Bump curr pointer and wrap */
248 Lcur = 0; /* if hit end */
249 if (Lone == Lcur) /* If wrapped to beginning of window */
250 if (++Lone == Wsiz) /* Bump beginning */
251 Lone = 0; /* and wrap if hit end */
252
253 if (fgets(lptr, Linlen, ifp) != lptr) break; /* if end of file */
254
255 linnum++; /* Count line number */
256 if (matlin(lptr)) { /* If matching line */
257 if (prtaft < (-Wbef)) /* Check for separator needed */
258 if ((Nmr++ > 0) && ((Wbef > 0) || (Waft > 0)))
259 printf("----------------------------------------------------------------------------\n");
260 while (Lone != Lcur) { /* Until we close the window */
261 shwlin(ifnm, linnum - nlb, Lines[Lone]);
262 /* Show the line */
263 if (++Lone == Wsiz) Lone = 0;
264 nlb--;
265 }
266 nlb = 0; /* No lines buffered */
267 prtaft = Waft; /* Print n lines after */
268 } else { /* Didn't match */
269 if (prtaft-- > 0) { /* If must print lines after */
270 shwlin(ifnm, linnum, lptr);
271 /* Show the line */
272 Lone = Lcur; /* Match pointers */
273 } else if (nlb < Wbef) /* Count lines buffered */
274 nlb++;
275 }
276 }
277
278 if (ifnm != NULL) fclose(ifp);
279}
280
281 /* Shwlin (fnm, linnum, line) Show a matching line
282 *
283 * Accepts :
284 *
285 * fnm File name
286 *
287 * linnum Line number
288 *
289 * line Line to show
290 *
291 *
292 * Returns :
293 *
294 *
295 */
296
297void shwlin(fnm, linnum, line)
298char *fnm; /* File name */
299int linnum; /* Line number */
300char *line; /* Line (with newline at end) to print */
301
302{
303 if (Shwfile && (fnm != NULL)) printf("%s%s", fnm, Shwline ? " " : ":");
304 if (Shwline) printf("@%05d:", linnum);
305 printf("%s", line);
306}
307
308 /* Matlin (line) Perform match against pattern and line
309 *
310 * Accepts :
311 *
312 * line Address of line to match
313 *
314 *
315 * Returns :
316 *
317 * <value> TRUE if match FALSE if not
318 *
319 *
320 */
321
322
323int matlin(line)
324char *line; /* Line to match */
325
326{
327 int rtncode; /* Return value from this routine */
328
329
330#ifdef NOREGEXP
331 char *pptr, *lptr, *tlptr;
332 int c1, c2;
333#endif /* NOREGEXP */
334
335 if (Debug) printf("Matching %s against %s", Pat, line);
336
337#ifdef REGEX
338 rtncode = re_exec(line); /* Hand off to r/e evaluator */
339#endif /* REGEX */
340
341#ifdef REGCMP
342 rtncode = (regexec(Re, line, TRUE) != 0);
343#endif /* REGCMP */
344
345#ifdef NOREGEX /* Have to do menial comparison.. */
346 lptr = line; /* Init line pointer */
347
348 for (rtncode = -1; rtncode < 0;) {
349 tlptr = lptr++; /* Get temp ptr to line */
350 pptr = Pat; /* Get ptr to pattern */
351 while (TRUE) {
352 if ((c1 = *pptr++) == NUL) {
353 rtncode = 1; /* GOOD return value */
354 break;
355 }
356 if ((c2 = *tlptr++) == NUL) {
357 rtncode = 0; /* BAD return value */
358 break;
359 }
360 if (isupper(c1)) c1 = tolower(c1);
361 if (isupper(c2)) c2 = tolower(c2);
362 if (c1 != c2) break;
363 }
364 }
365#endif /* NOREGEX */
366
367
368 if (Debug) printf("matlin returned %s\n", rtncode ? "TRUE" : "FALSE");
369 return(rtncode);
370}
371
372
373
374void regerror(s)
375const char *s;
376{
377 printf("%s\n", (char *) s);
378 exit(1);
379}
Note: See TracBrowser for help on using the repository browser.