Annotation of src/usr.bin/grep/util.c, Revision 1.2
1.1 deraadt 1: /*-
2: * Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: *
14: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24: * SUCH DAMAGE.
25: *
26: * $Id$
27: */
28:
29: #include <sys/types.h>
30: #include <sys/stat.h>
31:
32: #include <ctype.h>
33: #include <err.h>
34: #include <errno.h>
35: #include <fts.h>
36: #include <regex.h>
37: #include <stdio.h>
38: #include <stdlib.h>
39: #include <string.h>
40: #include <unistd.h>
41: #include <zlib.h>
42:
43: #include "grep.h"
44:
45: /*
46: * Process a file line by line...
47: */
48:
49: static int linesqueued;
50: static int procline(str_t *l);
51:
1.2 ! deraadt 52: int
1.1 deraadt 53: grep_tree(char **argv)
54: {
55: FTS *fts;
56: FTSENT *p;
57: int c, fts_flags;
58:
59: c = fts_flags = 0;
60:
61: if (Hflag)
62: fts_flags = FTS_COMFOLLOW;
63: if (Pflag)
64: fts_flags = FTS_PHYSICAL;
65: if (Sflag)
66: fts_flags = FTS_LOGICAL;
67:
68: fts_flags |= FTS_NOSTAT | FTS_NOCHDIR;
69:
70: if (!(fts = fts_open(argv, fts_flags, (int (*) ()) NULL)))
71: err(1, NULL);
72: while ((p = fts_read(fts)) != NULL) {
73: switch (p->fts_info) {
74: case FTS_DNR:
75: break;
76: case FTS_ERR:
77: errx(1, "%s: %s", p->fts_path, strerror(p->fts_errno));
78: break;
79: case FTS_DP:
80: break;
81: default:
82: c += procfile(p->fts_path);
83: break;
84: }
85: }
86:
87: return c;
88: }
89:
90: int
91: procfile(char *fn)
92: {
93: str_t ln;
94: file_t *f;
95: int c, t, z;
96:
97: if (fn == NULL) {
98: fn = "(standard input)";
99: f = grep_fdopen(STDIN_FILENO, "r");
100: } else {
101: f = grep_open(fn, "r");
102: }
103: if (f == NULL) {
104: if (!sflag)
105: warn("%s", fn);
106: return 0;
107: }
108: if (aflag && grep_bin_file(f)) {
109: grep_close(f);
110: return 0;
111: }
112:
113: ln.file = fn;
114: ln.line_no = 0;
115: linesqueued = 0;
116: ln.off = -1;
117:
118: if (Bflag > 0)
119: initqueue();
120: for (c = 0; !(lflag && c);) {
121: ln.off += ln.len + 1;
122: if ((ln.dat = grep_fgetln(f, &ln.len)) == NULL)
123: break;
124: if (ln.len > 0 && ln.dat[ln.len - 1] == '\n')
125: --ln.len;
126: ln.line_no++;
127:
128: z = tail;
1.2 ! deraadt 129:
1.1 deraadt 130: if ((t = procline(&ln)) == 0 && Bflag > 0 && z == 0) {
131: enqueue(&ln);
132: linesqueued++;
133: }
134: c += t;
135: }
136: if (Bflag > 0)
137: clearqueue();
138: grep_close(f);
139:
140: if (cflag) {
141: if (!hflag)
142: printf("%s:", ln.file);
143: printf("%u\n", c);
144: }
145: if (lflag && c != 0)
146: printf("%s\n", fn);
147: if (Lflag && c == 0)
148: printf("%s\n", fn);
149: return c;
150: }
151:
152:
153: /*
154: * Process an individual line in a file. Return non-zero if it matches.
155: */
156:
157: #define isword(x) (isalnum(x) || (x) == '_')
158:
159: static int
160: procline(str_t *l)
161: {
162: regmatch_t pmatch;
163: int c, i, r, t;
164:
165: if (matchall) {
166: c = !vflag;
167: goto print;
168: }
1.2 ! deraadt 169:
1.1 deraadt 170: t = vflag ? REG_NOMATCH : 0;
171: pmatch.rm_so = 0;
172: pmatch.rm_eo = l->len;
173: for (c = i = 0; i < patterns; i++) {
174: r = regexec(&r_pattern[i], l->dat, 0, &pmatch, eflags);
175: if (r == REG_NOMATCH && t == 0)
176: continue;
177: if (r == 0) {
178: if (wflag) {
179: if ((pmatch.rm_so != 0 && isword(l->dat[pmatch.rm_so - 1]))
180: || (pmatch.rm_eo != l->len && isword(l->dat[pmatch.rm_eo])))
181: r = REG_NOMATCH;
182: }
183: if (xflag) {
184: if (pmatch.rm_so != 0 || pmatch.rm_eo != l->len)
185: r = REG_NOMATCH;
186: }
187: }
188: if (r == t) {
189: c++;
190: break;
191: }
192: }
1.2 ! deraadt 193:
1.1 deraadt 194: print:
195: if ((tail > 0 || c) && !cflag && !qflag) {
196: if (c) {
197: if (first > 0 && tail == 0 && (Bflag < linesqueued) && (Aflag || Bflag))
198: printf("--\n");
199: first = 1;
200: tail = Aflag;
201: if (Bflag > 0)
202: printqueue();
203: linesqueued = 0;
204: printline(l, ':');
205: } else {
206: printline(l, '-');
207: tail--;
208: }
209: }
210: return c;
211: }
212:
213: void *
214: grep_malloc(size_t size)
215: {
216: void *ptr;
217:
218: if ((ptr = malloc(size)) == NULL)
219: err(1, "malloc");
220: return ptr;
221: }
222:
223: void *
224: grep_realloc(void *ptr, size_t size)
225: {
226: if ((ptr = realloc(ptr, size)) == NULL)
227: err(1, "realloc");
228: return ptr;
229: }
230:
231: void
232: printline(str_t *line, int sep)
233: {
234: int n;
1.2 ! deraadt 235:
1.1 deraadt 236: n = 0;
237: if (!hflag) {
238: fputs(line->file, stdout);
239: ++n;
240: }
241: if (nflag) {
242: if (n)
243: putchar(sep);
244: printf("%d", line->line_no);
245: ++n;
246: }
247: if (bflag) {
248: if (n)
249: putchar(sep);
250: printf("%lu", (unsigned long)line->off);
251: }
252: if (n)
253: putchar(sep);
254: fwrite(line->dat, line->len, 1, stdout);
255: putchar('\n');
256: }