1/* $OpenBSD: grep.c,v 1.42 2010/07/02 22:18:03 tedu Exp $ */
2
3/*-
4 * Copyright (c) 1999 James Howard and Dag-Erling Co�dan Sm�rgrav
5 * Copyright (C) 2008-2009 Gabor Kovesdan <gabor@FreeBSD.org>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
--- 14 unchanged lines hidden (view full) ---
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/usr.bin/grep/grep.c 210578 2010-07-29 00:11:14Z gabor $");
32
33#include <sys/stat.h>
34#include <sys/types.h>
35
36#include <ctype.h>
37#include <err.h>
38#include <errno.h>
39#include <getopt.h>
--- 40 unchanged lines hidden (view full) ---
80
81/* Searching patterns */
82unsigned int patterns, pattern_sz;
83char **pattern;
84regex_t *r_pattern;
85fastgrep_t *fg_pattern;
86
87/* Filename exclusion/inclusion patterns */
88unsigned int fpatterns, fpattern_sz;
89unsigned int dpatterns, dpattern_sz;
90struct epat *dpattern, *fpattern;
91
92/* For regex errors */
93char re_error[RE_ERROR_BUF + 1];
94
95/* Command-line flags */
96unsigned long long Aflag; /* -A x: print x lines trailing each match */
97unsigned long long Bflag; /* -B x: print x lines leading each match */
98bool Hflag; /* -H: always print file name */
--- 9 unchanged lines hidden (view full) ---
108bool oflag; /* -o: print only matching part */
109bool qflag; /* -q: quiet mode (don't output anything) */
110bool sflag; /* -s: silent mode (ignore errors) */
111bool vflag; /* -v: only show non-matching lines */
112bool wflag; /* -w: pattern must start and end on word boundaries */
113bool xflag; /* -x: pattern must match entire line */
114bool lbflag; /* --line-buffered */
115bool nullflag; /* --null */
116char *label; /* --label */
117const char *color; /* --color */
118int grepbehave = GREP_BASIC; /* -EFGP: type of the regex */
119int binbehave = BINFILE_BIN; /* -aIU: handling of binary files */
120int filebehave = FILE_STDIO; /* -JZ: normal, gzip or bzip2 file */
121int devbehave = DEV_READ; /* -D: handling of devices */
122int dirbehave = DIR_READ; /* -dRr: handling of directories */
123int linkbehave = LINK_READ; /* -OpS: handling of symlinks */
124
125bool dexclude, dinclude; /* --exclude amd --include */
126bool fexclude, finclude; /* --exclude-dir and --include-dir */
127
128enum {
129 BIN_OPT = CHAR_MAX + 1,
130 COLOR_OPT,
131 HELP_OPT,
132 MMAP_OPT,
133 LINEBUF_OPT,
134 LABEL_OPT,
135 NULL_OPT,
--- 96 unchanged lines hidden (view full) ---
232 pattern_sz *= 2;
233 pattern = grep_realloc(pattern, ++pattern_sz *
234 sizeof(*pattern));
235 }
236 if (len > 0 && pat[len - 1] == '\n')
237 --len;
238 /* pat may not be NUL-terminated */
239 pattern[patterns] = grep_malloc(len + 1);
240 strlcpy(pattern[patterns], pat, len + 1);
241 ++patterns;
242}
243
244/*
245 * Adds a file include/exclude pattern to the internal array.
246 */
247static void
248add_fpattern(const char *pat, int mode)
249{
250
251 /* Increase size if necessary */
252 if (fpatterns == fpattern_sz) {
253 fpattern_sz *= 2;
254 fpattern = grep_realloc(fpattern, ++fpattern_sz *
255 sizeof(struct epat));
256 }
257 fpattern[fpatterns].pat = grep_strdup(pat);
258 fpattern[fpatterns].mode = mode;
259 ++fpatterns;
260}
261
262/*
263 * Adds a directory include/exclude pattern to the internal array.
264 */
265static void
266add_dpattern(const char *pat, int mode)
267{
268
269 /* Increase size if necessary */
270 if (dpatterns == dpattern_sz) {
271 dpattern_sz *= 2;
272 dpattern = grep_realloc(dpattern, ++dpattern_sz *
273 sizeof(struct epat));
274 }
275 dpattern[dpatterns].pat = grep_strdup(pat);
276 dpattern[dpatterns].mode = mode;
277 ++dpatterns;
278}
279
280/*
281 * Reads searching patterns from a file and adds them with add_pattern().
282 */
283static void
284read_patterns(const char *fn)
285{
286 FILE *f;
287 char *line;
288 size_t len;
--- 312 unchanged lines hidden (view full) ---
601 break;
602 case LINEBUF_OPT:
603 lbflag = true;
604 break;
605 case NULL_OPT:
606 nullflag = true;
607 break;
608 case R_INCLUDE_OPT:
609 finclude = true;
610 add_fpattern(optarg, INCL_PAT);
611 break;
612 case R_EXCLUDE_OPT:
613 fexclude = true;
614 add_fpattern(optarg, EXCL_PAT);
615 break;
616 case R_DINCLUDE_OPT:
617 dexclude = true;
618 add_dpattern(optarg, INCL_PAT);
619 break;
620 case R_DEXCLUDE_OPT:
621 dinclude = true;
622 add_dpattern(optarg, EXCL_PAT);
623 break;
624 case HELP_OPT:
625 default:
626 usage();
627 }
628 lastc = c;
629 newarg = optind != prevoptind;
630 prevoptind = optind;
--- 55 unchanged lines hidden (view full) ---
686 hflag = true;
687
688 if (aargc == 0)
689 exit(!procfile("-"));
690
691 if (dirbehave == DIR_RECURSE)
692 c = grep_tree(aargv);
693 else
694 for (c = 0; aargc--; ++aargv) {
695 if ((finclude || fexclude) && !file_matching(*aargv))
696 continue;
697 c+= procfile(*aargv);
698 }
699
700#ifndef WITHOUT_NLS
701 catclose(catalog);
702#endif
703
704 /* Find out the correct return value according to the
705 results and the command line option. */
706 exit(c ? (notfound ? (qflag ? 0 : 2) : 0) : (notfound ? 2 : 1));
707}
2
3/*-
4 * Copyright (c) 1999 James Howard and Dag-Erling Co�dan Sm�rgrav
5 * Copyright (C) 2008-2009 Gabor Kovesdan <gabor@FreeBSD.org>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
--- 14 unchanged lines hidden (view full) ---
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/usr.bin/grep/grep.c 210578 2010-07-29 00:11:14Z gabor $");
32
33#include <sys/stat.h>
34#include <sys/types.h>
35
36#include <ctype.h>
37#include <err.h>
38#include <errno.h>
39#include <getopt.h>
--- 40 unchanged lines hidden (view full) ---
80
81/* Searching patterns */
82unsigned int patterns, pattern_sz;
83char **pattern;
84regex_t *r_pattern;
85fastgrep_t *fg_pattern;
86
87/* Filename exclusion/inclusion patterns */
88unsigned int fpatterns, fpattern_sz;
89unsigned int dpatterns, dpattern_sz;
90struct epat *dpattern, *fpattern;
91
92/* For regex errors */
93char re_error[RE_ERROR_BUF + 1];
94
95/* Command-line flags */
96unsigned long long Aflag; /* -A x: print x lines trailing each match */
97unsigned long long Bflag; /* -B x: print x lines leading each match */
98bool Hflag; /* -H: always print file name */
--- 9 unchanged lines hidden (view full) ---
108bool oflag; /* -o: print only matching part */
109bool qflag; /* -q: quiet mode (don't output anything) */
110bool sflag; /* -s: silent mode (ignore errors) */
111bool vflag; /* -v: only show non-matching lines */
112bool wflag; /* -w: pattern must start and end on word boundaries */
113bool xflag; /* -x: pattern must match entire line */
114bool lbflag; /* --line-buffered */
115bool nullflag; /* --null */
116char *label; /* --label */
117const char *color; /* --color */
118int grepbehave = GREP_BASIC; /* -EFGP: type of the regex */
119int binbehave = BINFILE_BIN; /* -aIU: handling of binary files */
120int filebehave = FILE_STDIO; /* -JZ: normal, gzip or bzip2 file */
121int devbehave = DEV_READ; /* -D: handling of devices */
122int dirbehave = DIR_READ; /* -dRr: handling of directories */
123int linkbehave = LINK_READ; /* -OpS: handling of symlinks */
124
125bool dexclude, dinclude; /* --exclude amd --include */
126bool fexclude, finclude; /* --exclude-dir and --include-dir */
127
128enum {
129 BIN_OPT = CHAR_MAX + 1,
130 COLOR_OPT,
131 HELP_OPT,
132 MMAP_OPT,
133 LINEBUF_OPT,
134 LABEL_OPT,
135 NULL_OPT,
--- 96 unchanged lines hidden (view full) ---
232 pattern_sz *= 2;
233 pattern = grep_realloc(pattern, ++pattern_sz *
234 sizeof(*pattern));
235 }
236 if (len > 0 && pat[len - 1] == '\n')
237 --len;
238 /* pat may not be NUL-terminated */
239 pattern[patterns] = grep_malloc(len + 1);
240 strlcpy(pattern[patterns], pat, len + 1);
241 ++patterns;
242}
243
244/*
245 * Adds a file include/exclude pattern to the internal array.
246 */
247static void
248add_fpattern(const char *pat, int mode)
249{
250
251 /* Increase size if necessary */
252 if (fpatterns == fpattern_sz) {
253 fpattern_sz *= 2;
254 fpattern = grep_realloc(fpattern, ++fpattern_sz *
255 sizeof(struct epat));
256 }
257 fpattern[fpatterns].pat = grep_strdup(pat);
258 fpattern[fpatterns].mode = mode;
259 ++fpatterns;
260}
261
262/*
263 * Adds a directory include/exclude pattern to the internal array.
264 */
265static void
266add_dpattern(const char *pat, int mode)
267{
268
269 /* Increase size if necessary */
270 if (dpatterns == dpattern_sz) {
271 dpattern_sz *= 2;
272 dpattern = grep_realloc(dpattern, ++dpattern_sz *
273 sizeof(struct epat));
274 }
275 dpattern[dpatterns].pat = grep_strdup(pat);
276 dpattern[dpatterns].mode = mode;
277 ++dpatterns;
278}
279
280/*
281 * Reads searching patterns from a file and adds them with add_pattern().
282 */
283static void
284read_patterns(const char *fn)
285{
286 FILE *f;
287 char *line;
288 size_t len;
--- 312 unchanged lines hidden (view full) ---
601 break;
602 case LINEBUF_OPT:
603 lbflag = true;
604 break;
605 case NULL_OPT:
606 nullflag = true;
607 break;
608 case R_INCLUDE_OPT:
609 finclude = true;
610 add_fpattern(optarg, INCL_PAT);
611 break;
612 case R_EXCLUDE_OPT:
613 fexclude = true;
614 add_fpattern(optarg, EXCL_PAT);
615 break;
616 case R_DINCLUDE_OPT:
617 dexclude = true;
618 add_dpattern(optarg, INCL_PAT);
619 break;
620 case R_DEXCLUDE_OPT:
621 dinclude = true;
622 add_dpattern(optarg, EXCL_PAT);
623 break;
624 case HELP_OPT:
625 default:
626 usage();
627 }
628 lastc = c;
629 newarg = optind != prevoptind;
630 prevoptind = optind;
--- 55 unchanged lines hidden (view full) ---
686 hflag = true;
687
688 if (aargc == 0)
689 exit(!procfile("-"));
690
691 if (dirbehave == DIR_RECURSE)
692 c = grep_tree(aargv);
693 else
694 for (c = 0; aargc--; ++aargv) {
695 if ((finclude || fexclude) && !file_matching(*aargv))
696 continue;
697 c+= procfile(*aargv);
698 }
699
700#ifndef WITHOUT_NLS
701 catclose(catalog);
702#endif
703
704 /* Find out the correct return value according to the
705 results and the command line option. */
706 exit(c ? (notfound ? (qflag ? 0 : 2) : 0) : (notfound ? 2 : 1));
707}