1/* grep.c - main driver file for grep.
2   Copyright 1992, 1997-1999, 2000 Free Software Foundation, Inc.
3
4   This program is free software; you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation; either version 2, or (at your option)
7   any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17   02111-1307, USA.  */
18
19/* Written July 1992 by Mike Haertel.  */
20/* Builtin decompression 1997 by Wolfram Schneider <wosch@FreeBSD.org>.  */
21
22/* $FreeBSD$ */
23
24#ifdef HAVE_CONFIG_H
25# include <config.h>
26#endif
27#include <sys/types.h>
28#include <sys/stat.h>
29#if defined(HAVE_MMAP)
30# include <sys/mman.h>
31#endif
32#if defined(HAVE_SETRLIMIT)
33# include <sys/time.h>
34# include <sys/resource.h>
35#endif
36#if defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H && defined HAVE_MBRTOWC
37/* We can handle multibyte string.  */
38# define MBS_SUPPORT
39# include <wchar.h>
40# include <wctype.h>
41#endif
42#include <stdio.h>
43#include "system.h"
44#include "getopt.h"
45#include "getpagesize.h"
46#include "grep.h"
47#include "savedir.h"
48#include "xstrtol.h"
49#include "xalloc.h"
50#include "error.h"
51#include "exclude.h"
52#include "closeout.h"
53
54#undef MAX
55#define MAX(A,B) ((A) > (B) ? (A) : (B))
56
57struct stats
58{
59  struct stats const *parent;
60  struct stat stat;
61};
62
63/* base of chain of stat buffers, used to detect directory loops */
64static struct stats stats_base;
65
66/* if non-zero, display usage information and exit */
67static int show_help;
68
69/* If non-zero, print the version on standard output and exit.  */
70static int show_version;
71
72/* If nonzero, suppress diagnostics for nonexistent or unreadable files.  */
73static int suppress_errors;
74
75/* If nonzero, use mmap if possible.  */
76static int mmap_option;
77
78/* If zero, output nulls after filenames.  */
79static int filename_mask;
80
81/* If nonzero, use grep_color marker.  */
82static int color_option;
83
84/* If nonzero, show only the part of a line matching the expression. */
85static int only_matching;
86
87/* The color string used.  The user can overwrite it using the environment
88   variable GREP_COLOR.  The default is to print red.  */
89static const char *grep_color = "01;31";
90
91static struct exclude *excluded_patterns;
92static struct exclude *included_patterns;
93/* Short options.  */
94static char const short_options[] =
95"0123456789A:B:C:D:EFGHIJPUVX:abcd:e:f:hiKLlm:noqRrsuvwxyZz";
96
97/* Non-boolean long options that have no corresponding short equivalents.  */
98enum
99{
100  BINARY_FILES_OPTION = CHAR_MAX + 1,
101  COLOR_OPTION,
102  INCLUDE_OPTION,
103  EXCLUDE_OPTION,
104  EXCLUDE_FROM_OPTION,
105  LINE_BUFFERED_OPTION,
106  LABEL_OPTION
107};
108
109/* Long options equivalences. */
110static struct option const long_options[] =
111{
112  {"after-context", required_argument, NULL, 'A'},
113  {"basic-regexp", no_argument, NULL, 'G'},
114  {"before-context", required_argument, NULL, 'B'},
115  {"binary-files", required_argument, NULL, BINARY_FILES_OPTION},
116  {"byte-offset", no_argument, NULL, 'b'},
117  {"context", required_argument, NULL, 'C'},
118  {"color", optional_argument, NULL, COLOR_OPTION},
119  {"colour", optional_argument, NULL, COLOR_OPTION},
120  {"count", no_argument, NULL, 'c'},
121  {"devices", required_argument, NULL, 'D'},
122  {"directories", required_argument, NULL, 'd'},
123  {"extended-regexp", no_argument, NULL, 'E'},
124  {"exclude", required_argument, NULL, EXCLUDE_OPTION},
125  {"exclude-from", required_argument, NULL, EXCLUDE_FROM_OPTION},
126  {"file", required_argument, NULL, 'f'},
127  {"files-with-matches", no_argument, NULL, 'l'},
128  {"files-without-match", no_argument, NULL, 'L'},
129  {"fixed-regexp", no_argument, NULL, 'F'},
130  {"fixed-strings", no_argument, NULL, 'F'},
131  {"help", no_argument, &show_help, 1},
132  {"include", required_argument, NULL, INCLUDE_OPTION},
133  {"ignore-case", no_argument, NULL, 'i'},
134  {"label", required_argument, NULL, LABEL_OPTION},
135  {"line-buffered", no_argument, NULL, LINE_BUFFERED_OPTION},
136  {"line-number", no_argument, NULL, 'n'},
137  {"line-regexp", no_argument, NULL, 'x'},
138  {"max-count", required_argument, NULL, 'm'},
139  {"mmap", no_argument, &mmap_option, 1},
140  {"no-filename", no_argument, NULL, 'h'},
141  {"no-messages", no_argument, NULL, 's'},
142  {"bz2decompress", no_argument, NULL, 'J'},
143#if HAVE_LIBZ > 0
144  {"decompress", no_argument, NULL, 'Z'},
145  {"null", no_argument, &filename_mask, 0},
146#else
147  {"null", no_argument, NULL, 'Z'},
148#endif
149  {"null-data", no_argument, NULL, 'z'},
150  {"only-matching", no_argument, NULL, 'o'},
151  {"perl-regexp", no_argument, NULL, 'P'},
152  {"quiet", no_argument, NULL, 'q'},
153  {"recursive", no_argument, NULL, 'r'},
154  {"recursive", no_argument, NULL, 'R'},
155  {"regexp", required_argument, NULL, 'e'},
156  {"invert-match", no_argument, NULL, 'v'},
157  {"silent", no_argument, NULL, 'q'},
158  {"text", no_argument, NULL, 'a'},
159  {"binary", no_argument, NULL, 'U'},
160  {"unix-byte-offsets", no_argument, NULL, 'u'},
161  {"version", no_argument, NULL, 'V'},
162  {"with-filename", no_argument, NULL, 'H'},
163  {"word-regexp", no_argument, NULL, 'w'},
164  {0, 0, 0, 0}
165};
166
167/* Define flags declared in grep.h. */
168int match_icase;
169int match_words;
170int match_lines;
171unsigned char eolbyte;
172
173/* For error messages. */
174/* The name the program was run with, stripped of any leading path. */
175char *program_name;
176static char const *filename;
177static int errseen;
178
179/* How to handle directories.  */
180static enum
181  {
182    READ_DIRECTORIES,
183    RECURSE_DIRECTORIES,
184    SKIP_DIRECTORIES
185  } directories = READ_DIRECTORIES;
186
187/* How to handle devices. */
188static enum
189  {
190    READ_DEVICES,
191    SKIP_DEVICES
192  } devices = READ_DEVICES;
193
194static int grepdir PARAMS ((char const *, struct stats const *));
195#if defined(HAVE_DOS_FILE_CONTENTS)
196static inline int undossify_input PARAMS ((register char *, size_t));
197#endif
198
199/* Functions we'll use to search. */
200static void (*compile) PARAMS ((char const *, size_t));
201static size_t (*execute) PARAMS ((char const *, size_t, size_t *, int));
202
203/* Like error, but suppress the diagnostic if requested.  */
204static void
205suppressible_error (char const *mesg, int errnum)
206{
207  if (! suppress_errors)
208    error (0, errnum, "%s", mesg);
209  errseen = 1;
210}
211
212/* Convert STR to a positive integer, storing the result in *OUT.
213   STR must be a valid context length argument; report an error if it
214   isn't.  */
215static void
216context_length_arg (char const *str, int *out)
217{
218  uintmax_t value;
219  if (! (xstrtoumax (str, 0, 10, &value, "") == LONGINT_OK
220	 && 0 <= (*out = value)
221	 && *out == value))
222    {
223      error (2, 0, "%s: %s\n", str, _("invalid context length argument"));
224    }
225}
226
227
228/* Hairy buffering mechanism for grep.  The intent is to keep
229   all reads aligned on a page boundary and multiples of the
230   page size, unless a read yields a partial page.  */
231
232static char *buffer;		/* Base of buffer. */
233static size_t bufalloc;		/* Allocated buffer size, counting slop. */
234#define INITIAL_BUFSIZE 32768	/* Initial buffer size, not counting slop. */
235static int bufdesc;		/* File descriptor. */
236static char *bufbeg;		/* Beginning of user-visible stuff. */
237static char *buflim;		/* Limit of user-visible stuff. */
238static size_t pagesize;		/* alignment of memory pages */
239static off_t bufoffset;		/* Read offset; defined on regular files.  */
240static off_t after_last_match;	/* Pointer after last matching line that
241				   would have been output if we were
242				   outputting characters. */
243
244#if defined(HAVE_MMAP)
245static int bufmapped;		/* True if buffer is memory-mapped.  */
246static off_t initial_bufoffset;	/* Initial value of bufoffset. */
247#else
248# define bufmapped 0
249#endif
250
251#include <bzlib.h>
252static BZFILE* bzbufdesc;	/* libbz2 file handle. */
253static int BZflag;		/* uncompress before searching. */
254#if HAVE_LIBZ > 0
255#include <zlib.h>
256static gzFile gzbufdesc;	/* zlib file descriptor. */
257static int Zflag;		/* uncompress before searching. */
258#endif
259
260/* Return VAL aligned to the next multiple of ALIGNMENT.  VAL can be
261   an integer or a pointer.  Both args must be free of side effects.  */
262#define ALIGN_TO(val, alignment) \
263  ((size_t) (val) % (alignment) == 0 \
264   ? (val) \
265   : (val) + ((alignment) - (size_t) (val) % (alignment)))
266
267/* Reset the buffer for a new file, returning zero if we should skip it.
268   Initialize on the first time through. */
269static int
270reset (int fd, char const *file, struct stats *stats)
271{
272  if (! pagesize)
273    {
274      pagesize = getpagesize ();
275      if (pagesize == 0 || 2 * pagesize + 1 <= pagesize)
276	abort ();
277      bufalloc = ALIGN_TO (INITIAL_BUFSIZE, pagesize) + pagesize + 1;
278      buffer = xmalloc (bufalloc);
279    }
280  if (BZflag)
281    {
282    bzbufdesc = BZ2_bzdopen(fd, "r");
283    if (bzbufdesc == NULL)
284      error(2, 0, _("memory exhausted"));
285    }
286#if HAVE_LIBZ > 0
287  if (Zflag)
288    {
289    gzbufdesc = gzdopen(fd, "r");
290    if (gzbufdesc == NULL)
291      error(2, 0, _("memory exhausted"));
292    }
293#endif
294
295  bufbeg = buflim = ALIGN_TO (buffer + 1, pagesize);
296  bufbeg[-1] = eolbyte;
297  bufdesc = fd;
298
299  if (fstat (fd, &stats->stat) != 0)
300    {
301      error (0, errno, "fstat");
302      return 0;
303    }
304  if (fd != STDIN_FILENO) {
305    if (directories == SKIP_DIRECTORIES && S_ISDIR (stats->stat.st_mode))
306      return 0;
307#ifndef DJGPP
308    if (devices == SKIP_DEVICES && (S_ISCHR(stats->stat.st_mode) || S_ISBLK(stats->stat.st_mode) || S_ISSOCK(stats->stat.st_mode) || S_ISFIFO(stats->stat.st_mode)))
309#else
310    if (devices == SKIP_DEVICES && (S_ISCHR(stats->stat.st_mode) || S_ISBLK(stats->stat.st_mode)))
311#endif
312      return 0;
313  }
314  if (
315      BZflag ||
316#if HAVE_LIBZ > 0
317      Zflag ||
318#endif
319      S_ISREG (stats->stat.st_mode))
320    {
321      if (file)
322	bufoffset = 0;
323      else
324	{
325	  bufoffset = lseek (fd, 0, SEEK_CUR);
326	  if (bufoffset < 0)
327	    {
328	      error (0, errno, "lseek");
329	      return 0;
330	    }
331	}
332#if defined(HAVE_MMAP)
333      initial_bufoffset = bufoffset;
334      bufmapped = mmap_option && bufoffset % pagesize == 0;
335#endif
336    }
337  else
338    {
339#if defined(HAVE_MMAP)
340      bufmapped = 0;
341#endif
342    }
343  return 1;
344}
345
346/* Read new stuff into the buffer, saving the specified
347   amount of old stuff.  When we're done, 'bufbeg' points
348   to the beginning of the buffer contents, and 'buflim'
349   points just after the end.  Return zero if there's an error.  */
350static int
351fillbuf (size_t save, struct stats const *stats)
352{
353  size_t fillsize = 0;
354  int cc = 1;
355  char *readbuf;
356  size_t readsize;
357
358  /* Offset from start of buffer to start of old stuff
359     that we want to save.  */
360  size_t saved_offset = buflim - save - buffer;
361
362  if (pagesize <= buffer + bufalloc - buflim)
363    {
364      readbuf = buflim;
365      bufbeg = buflim - save;
366    }
367  else
368    {
369      size_t minsize = save + pagesize;
370      size_t newsize;
371      size_t newalloc;
372      char *newbuf;
373
374      /* Grow newsize until it is at least as great as minsize.  */
375      for (newsize = bufalloc - pagesize - 1; newsize < minsize; newsize *= 2)
376	if (newsize * 2 < newsize || newsize * 2 + pagesize + 1 < newsize * 2)
377	  xalloc_die ();
378
379      /* Try not to allocate more memory than the file size indicates,
380	 as that might cause unnecessary memory exhaustion if the file
381	 is large.  However, do not use the original file size as a
382	 heuristic if we've already read past the file end, as most
383	 likely the file is growing.  */
384      if (S_ISREG (stats->stat.st_mode))
385	{
386	  off_t to_be_read = stats->stat.st_size - bufoffset;
387	  off_t maxsize_off = save + to_be_read;
388	  if (0 <= to_be_read && to_be_read <= maxsize_off
389	      && maxsize_off == (size_t) maxsize_off
390	      && minsize <= (size_t) maxsize_off
391	      && (size_t) maxsize_off < newsize)
392	    newsize = maxsize_off;
393	}
394
395      /* Add enough room so that the buffer is aligned and has room
396	 for byte sentinels fore and aft.  */
397      newalloc = newsize + pagesize + 1;
398
399      newbuf = bufalloc < newalloc ? xmalloc (bufalloc = newalloc) : buffer;
400      readbuf = ALIGN_TO (newbuf + 1 + save, pagesize);
401      bufbeg = readbuf - save;
402      memmove (bufbeg, buffer + saved_offset, save);
403      bufbeg[-1] = eolbyte;
404      if (newbuf != buffer)
405	{
406	  free (buffer);
407	  buffer = newbuf;
408	}
409    }
410
411  readsize = buffer + bufalloc - readbuf;
412  readsize -= readsize % pagesize;
413
414#if defined(HAVE_MMAP)
415  if (bufmapped)
416    {
417      size_t mmapsize = readsize;
418
419      /* Don't mmap past the end of the file; some hosts don't allow this.
420	 Use `read' on the last page.  */
421      if (stats->stat.st_size - bufoffset < mmapsize)
422	{
423	  mmapsize = stats->stat.st_size - bufoffset;
424	  mmapsize -= mmapsize % pagesize;
425	}
426
427      if (mmapsize
428	  && (mmap ((caddr_t) readbuf, mmapsize,
429		    PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED,
430		    bufdesc, bufoffset)
431	      != (caddr_t) -1))
432	{
433	  /* Do not bother to use madvise with MADV_SEQUENTIAL or
434	     MADV_WILLNEED on the mmapped memory.  One might think it
435	     would help, but it slows us down about 30% on SunOS 4.1.  */
436	  fillsize = mmapsize;
437	}
438      else
439	{
440	  /* Stop using mmap on this file.  Synchronize the file
441	     offset.  Do not warn about mmap failures.  On some hosts
442	     (e.g. Solaris 2.5) mmap can fail merely because some
443	     other process has an advisory read lock on the file.
444	     There's no point alarming the user about this misfeature.  */
445	  bufmapped = 0;
446	  if (bufoffset != initial_bufoffset
447	      && lseek (bufdesc, bufoffset, SEEK_SET) < 0)
448	    {
449	      error (0, errno, "lseek");
450	      cc = 0;
451	    }
452	}
453    }
454#endif /*HAVE_MMAP*/
455
456  if (! fillsize)
457    {
458      ssize_t bytesread;
459      do
460	if (BZflag && bzbufdesc)
461	  {
462	    int bzerr;
463	    bytesread = BZ2_bzRead (&bzerr, bzbufdesc, readbuf, readsize);
464
465	    switch (bzerr)
466	      {
467	      case BZ_OK:
468	      case BZ_STREAM_END:
469		/* ok */
470		break;
471	      case BZ_DATA_ERROR_MAGIC:
472		BZ2_bzReadClose (&bzerr, bzbufdesc); bzbufdesc = NULL;
473		lseek (bufdesc, 0, SEEK_SET);
474		bytesread = read (bufdesc, readbuf, readsize);
475		break;
476	      default:
477		bytesread = 0;
478		break;
479	      }
480	  }
481	else
482#if HAVE_LIBZ > 0
483	if (Zflag)
484	  bytesread = gzread (gzbufdesc, readbuf, readsize);
485	else
486#endif
487	  bytesread = read (bufdesc, readbuf, readsize);
488      while (bytesread < 0 && errno == EINTR);
489      if (bytesread < 0)
490	cc = 0;
491      else
492	fillsize = bytesread;
493    }
494
495  bufoffset += fillsize;
496#if defined(HAVE_DOS_FILE_CONTENTS)
497  if (fillsize)
498    fillsize = undossify_input (readbuf, fillsize);
499#endif
500  buflim = readbuf + fillsize;
501  return cc;
502}
503
504/* Flags controlling the style of output. */
505static enum
506{
507  BINARY_BINARY_FILES,
508  TEXT_BINARY_FILES,
509  WITHOUT_MATCH_BINARY_FILES
510} binary_files;		/* How to handle binary files.  */
511
512static int filename_mask;	/* If zero, output nulls after filenames.  */
513static int out_quiet;		/* Suppress all normal output. */
514static int out_invert;		/* Print nonmatching stuff. */
515static int out_file;		/* Print filenames. */
516static int out_line;		/* Print line numbers. */
517static int out_byte;		/* Print byte offsets. */
518static int out_before;		/* Lines of leading context. */
519static int out_after;		/* Lines of trailing context. */
520static int count_matches;	/* Count matching lines.  */
521static int list_files;		/* List matching files.  */
522static int no_filenames;	/* Suppress file names.  */
523static off_t max_count;		/* Stop after outputting this many
524				   lines from an input file.  */
525static int line_buffered;       /* If nonzero, use line buffering, i.e.
526				   fflush everyline out.  */
527static char *label = NULL;      /* Fake filename for stdin */
528
529
530/* Internal variables to keep track of byte count, context, etc. */
531static uintmax_t totalcc;	/* Total character count before bufbeg. */
532static char const *lastnl;	/* Pointer after last newline counted. */
533static char const *lastout;	/* Pointer after last character output;
534				   NULL if no character has been output
535				   or if it's conceptually before bufbeg. */
536static uintmax_t totalnl;	/* Total newline count before lastnl. */
537static off_t outleft;		/* Maximum number of lines to be output.  */
538static int pending;		/* Pending lines of output.
539				   Always kept 0 if out_quiet is true.  */
540static int done_on_match;	/* Stop scanning file on first match.  */
541static int exit_on_match;	/* Exit on first match.  */
542
543#if defined(HAVE_DOS_FILE_CONTENTS)
544# include "dosbuf.c"
545#endif
546
547/* Add two numbers that count input bytes or lines, and report an
548   error if the addition overflows.  */
549static uintmax_t
550add_count (uintmax_t a, uintmax_t b)
551{
552  uintmax_t sum = a + b;
553  if (sum < a)
554    error (2, 0, _("input is too large to count"));
555  return sum;
556}
557
558static void
559nlscan (char const *lim)
560{
561  size_t newlines = 0;
562  char const *beg;
563  for (beg = lastnl; beg != lim; beg = memchr (beg, eolbyte, lim - beg), beg++)
564    newlines++;
565  totalnl = add_count (totalnl, newlines);
566  lastnl = lim;
567}
568
569/* Print a byte offset, followed by a character separator.  */
570static void
571print_offset_sep (uintmax_t pos, char sep)
572{
573  /* Do not rely on printf to print pos, since uintmax_t may be longer
574     than long, and long long is not portable.  */
575
576  char buf[sizeof pos * CHAR_BIT];
577  char *p = buf + sizeof buf - 1;
578  *p = sep;
579
580  do
581    *--p = '0' + pos % 10;
582  while ((pos /= 10) != 0);
583
584  fwrite (p, 1, buf + sizeof buf - p, stdout);
585}
586
587static void
588prline (char const *beg, char const *lim, int sep)
589{
590  if (out_file)
591    printf ("%s%c", filename, sep & filename_mask);
592  if (out_line)
593    {
594      nlscan (beg);
595      totalnl = add_count (totalnl, 1);
596      print_offset_sep (totalnl, sep);
597      lastnl = lim;
598    }
599  if (out_byte)
600    {
601      uintmax_t pos = add_count (totalcc, beg - bufbeg);
602#if defined(HAVE_DOS_FILE_CONTENTS)
603      pos = dossified_pos (pos);
604#endif
605      print_offset_sep (pos, sep);
606    }
607  if (only_matching)
608    {
609      size_t match_size;
610      size_t match_offset;
611      while ((match_offset = (*execute) (beg, lim - beg, &match_size, 1))
612	  != (size_t) -1)
613        {
614	  char const *b = beg + match_offset;
615	  if (b == lim)
616	    break;
617	  if (match_size == 0)
618	    break;
619	  if(color_option)
620	    printf("\33[%sm", grep_color);
621	  fwrite(b, sizeof (char), match_size, stdout);
622	  if(color_option)
623	    fputs("\33[00m", stdout);
624	  fputs("\n", stdout);
625	  beg = b + match_size;
626        }
627      lastout = lim;
628      if(line_buffered)
629	fflush(stdout);
630      return;
631    }
632  if (color_option)
633    {
634      size_t match_size;
635      size_t match_offset;
636      while (lim-beg && (match_offset = (*execute) (beg, lim - beg, &match_size, 1))
637	     != (size_t) -1)
638	{
639	  char const *b = beg + match_offset;
640	  /* Avoid matching the empty line at the end of the buffer. */
641	  if (b == lim)
642	    break;
643	  /* Avoid hanging on grep --color "" foo */
644	  if (match_size == 0)
645	    break;
646	  fwrite (beg, sizeof (char), match_offset, stdout);
647	  printf ("\33[%sm", grep_color);
648	  fwrite (b, sizeof (char), match_size, stdout);
649	  fputs ("\33[00m", stdout);
650	  beg = b + match_size;
651	}
652      fputs ("\33[K", stdout);
653    }
654  fwrite (beg, 1, lim - beg, stdout);
655  if (ferror (stdout))
656    error (0, errno, _("writing output"));
657  lastout = lim;
658  if (line_buffered)
659    fflush (stdout);
660}
661
662/* Print pending lines of trailing context prior to LIM. Trailing context ends
663   at the next matching line when OUTLEFT is 0.  */
664static void
665prpending (char const *lim)
666{
667  if (!lastout)
668    lastout = bufbeg;
669  while (pending > 0 && lastout < lim)
670    {
671      char const *nl = memchr (lastout, eolbyte, lim - lastout);
672      size_t match_size;
673      --pending;
674      if (outleft
675	  || (((*execute) (lastout, nl - lastout, &match_size, 0) == (size_t) -1)
676	      == !out_invert))
677	prline (lastout, nl + 1, '-');
678      else
679	pending = 0;
680    }
681}
682
683/* Print the lines between BEG and LIM.  Deal with context crap.
684   If NLINESP is non-null, store a count of lines between BEG and LIM.  */
685static void
686prtext (char const *beg, char const *lim, int *nlinesp)
687{
688  static int used;		/* avoid printing "--" before any output */
689  char const *bp, *p;
690  char eol = eolbyte;
691  int i, n;
692
693  if (!out_quiet && pending > 0)
694    prpending (beg);
695
696  p = beg;
697
698  if (!out_quiet)
699    {
700      /* Deal with leading context crap. */
701
702      bp = lastout ? lastout : bufbeg;
703      for (i = 0; i < out_before; ++i)
704	if (p > bp)
705	  do
706	    --p;
707	  while (p[-1] != eol);
708
709      /* We only print the "--" separator if our output is
710	 discontiguous from the last output in the file. */
711      if ((out_before || out_after) && used && p != lastout)
712	puts ("--");
713
714      while (p < beg)
715	{
716	  char const *nl = memchr (p, eol, beg - p);
717	  nl++;
718	  prline (p, nl, '-');
719	  p = nl;
720	}
721    }
722
723  if (nlinesp)
724    {
725      /* Caller wants a line count. */
726      for (n = 0; p < lim && n < outleft; n++)
727	{
728	  char const *nl = memchr (p, eol, lim - p);
729	  nl++;
730	  if (!out_quiet)
731	    prline (p, nl, ':');
732	  p = nl;
733	}
734      *nlinesp = n;
735
736      /* relying on it that this function is never called when outleft = 0.  */
737      after_last_match = bufoffset - (buflim - p);
738    }
739  else
740    if (!out_quiet)
741      prline (beg, lim, ':');
742
743  pending = out_quiet ? 0 : out_after;
744  used = 1;
745}
746
747/* Scan the specified portion of the buffer, matching lines (or
748   between matching lines if OUT_INVERT is true).  Return a count of
749   lines printed. */
750static int
751grepbuf (char const *beg, char const *lim)
752{
753  int nlines, n;
754  register char const *p;
755  size_t match_offset;
756  size_t match_size;
757
758  nlines = 0;
759  p = beg;
760  while ((match_offset = (*execute) (p, lim - p, &match_size, 0)) != (size_t) -1)
761    {
762      char const *b = p + match_offset;
763      char const *endp = b + match_size;
764      /* Avoid matching the empty line at the end of the buffer. */
765      if (b == lim)
766	break;
767      if (!out_invert)
768	{
769	  prtext (b, endp, (int *) 0);
770	  nlines++;
771          outleft--;
772	  if (!outleft || done_on_match)
773	    {
774	      if (exit_on_match)
775		exit (0);
776	      after_last_match = bufoffset - (buflim - endp);
777	      return nlines;
778	    }
779	}
780      else if (p < b)
781	{
782	  prtext (p, b, &n);
783	  nlines += n;
784          outleft -= n;
785	  if (!outleft)
786	    return nlines;
787	}
788      p = endp;
789    }
790  if (out_invert && p < lim)
791    {
792      prtext (p, lim, &n);
793      nlines += n;
794      outleft -= n;
795    }
796  return nlines;
797}
798
799/* Search a given file.  Normally, return a count of lines printed;
800   but if the file is a directory and we search it recursively, then
801   return -2 if there was a match, and -1 otherwise.  */
802static int
803grep (int fd, char const *file, struct stats *stats)
804{
805  int nlines, i;
806  int not_text;
807  size_t residue, save;
808  char oldc;
809  char *beg;
810  char *lim;
811  char eol = eolbyte;
812
813  if (!reset (fd, file, stats))
814    return 0;
815
816  if (file && directories == RECURSE_DIRECTORIES
817      && S_ISDIR (stats->stat.st_mode))
818    {
819      /* Close fd now, so that we don't open a lot of file descriptors
820	 when we recurse deeply.  */
821      if (BZflag && bzbufdesc)
822	BZ2_bzclose(bzbufdesc);
823      else
824#if HAVE_LIBZ > 0
825      if (Zflag)
826	gzclose(gzbufdesc);
827      else
828#endif
829      if (close (fd) != 0)
830	error (0, errno, "%s", file);
831      return grepdir (file, stats) - 2;
832    }
833
834  totalcc = 0;
835  lastout = 0;
836  totalnl = 0;
837  outleft = max_count;
838  after_last_match = 0;
839  pending = 0;
840
841  nlines = 0;
842  residue = 0;
843  save = 0;
844
845  if (! fillbuf (save, stats))
846    {
847      if (! is_EISDIR (errno, file))
848	suppressible_error (filename, errno);
849      return 0;
850    }
851
852  not_text = (((binary_files == BINARY_BINARY_FILES && !out_quiet)
853	       || binary_files == WITHOUT_MATCH_BINARY_FILES)
854	      && memchr (bufbeg, eol ? '\0' : '\200', buflim - bufbeg));
855  if (not_text && binary_files == WITHOUT_MATCH_BINARY_FILES)
856    return 0;
857  done_on_match += not_text;
858  out_quiet += not_text;
859
860  for (;;)
861    {
862      lastnl = bufbeg;
863      if (lastout)
864	lastout = bufbeg;
865
866      beg = bufbeg + save;
867
868      /* no more data to scan (eof) except for maybe a residue -> break */
869      if (beg == buflim)
870	break;
871
872      /* Determine new residue (the length of an incomplete line at the end of
873         the buffer, 0 means there is no incomplete last line).  */
874      oldc = beg[-1];
875      beg[-1] = eol;
876      for (lim = buflim; lim[-1] != eol; lim--)
877	continue;
878      beg[-1] = oldc;
879      if (lim == beg)
880	lim = beg - residue;
881      beg -= residue;
882      residue = buflim - lim;
883
884      if (beg < lim)
885	{
886	  if (outleft)
887	    nlines += grepbuf (beg, lim);
888	  if (pending)
889	    prpending (lim);
890	  if((!outleft && !pending) || (nlines && done_on_match && !out_invert))
891	    goto finish_grep;
892	}
893
894      /* The last OUT_BEFORE lines at the end of the buffer will be needed as
895	 leading context if there is a matching line at the begin of the
896	 next data. Make beg point to their begin.  */
897      i = 0;
898      beg = lim;
899      while (i < out_before && beg > bufbeg && beg != lastout)
900	{
901	  ++i;
902	  do
903	    --beg;
904	  while (beg[-1] != eol);
905	}
906
907      /* detect if leading context is discontinuous from last printed line.  */
908      if (beg != lastout)
909	lastout = 0;
910
911      /* Handle some details and read more data to scan.  */
912      save = residue + lim - beg;
913      if (out_byte)
914	totalcc = add_count (totalcc, buflim - bufbeg - save);
915      if (out_line)
916	nlscan (beg);
917      if (! fillbuf (save, stats))
918	{
919	  if (! is_EISDIR (errno, file))
920	    suppressible_error (filename, errno);
921	  goto finish_grep;
922	}
923    }
924  if (residue)
925    {
926      *buflim++ = eol;
927      if (outleft)
928	nlines += grepbuf (bufbeg + save - residue, buflim);
929      if (pending)
930        prpending (buflim);
931    }
932
933 finish_grep:
934  done_on_match -= not_text;
935  out_quiet -= not_text;
936  if ((not_text & ~out_quiet) && nlines != 0)
937    printf (_("Binary file %s matches\n"), filename);
938  return nlines;
939}
940
941static int
942grepfile (char const *file, struct stats *stats)
943{
944  int desc;
945  int count;
946  int status;
947  int flags;
948
949  if (! file)
950    {
951      desc = 0;
952      filename = label ? label : _("(standard input)");
953    }
954  else
955    {
956      while ((desc = open (file, O_RDONLY | O_NONBLOCK)) < 0 && errno == EINTR)
957	continue;
958
959      if (desc < 0)
960	{
961	  int e = errno;
962
963	  if (is_EISDIR (e, file) && directories == RECURSE_DIRECTORIES)
964	    {
965	      if (stat (file, &stats->stat) != 0)
966		{
967		  error (0, errno, "%s", file);
968		  return 1;
969		}
970
971	      return grepdir (file, stats);
972	    }
973
974	  if (!suppress_errors)
975	    {
976	      if (directories == SKIP_DIRECTORIES)
977		switch (e)
978		  {
979#if defined(EISDIR)
980		  case EISDIR:
981		    return 1;
982#endif
983		  case EACCES:
984		    /* When skipping directories, don't worry about
985		       directories that can't be opened.  */
986		    if (isdir (file))
987		      return 1;
988		    break;
989		  }
990	    }
991
992	  suppressible_error (file, e);
993	  return 1;
994	}
995
996      flags = fcntl(desc, F_GETFL);
997      flags &= ~O_NONBLOCK;
998      fcntl(desc, F_SETFL, flags);
999      filename = file;
1000    }
1001
1002#if defined(SET_BINARY)
1003  /* Set input to binary mode.  Pipes are simulated with files
1004     on DOS, so this includes the case of "foo | grep bar".  */
1005  if (!isatty (desc))
1006    SET_BINARY (desc);
1007#endif
1008
1009  count = grep (desc, file, stats);
1010  if (count < 0)
1011    status = count + 2;
1012  else
1013    {
1014      if (count_matches)
1015	{
1016	  if (out_file)
1017	    printf ("%s%c", filename, ':' & filename_mask);
1018	  printf ("%d\n", count);
1019	}
1020
1021      status = !count;
1022      if (list_files == 1 - 2 * status)
1023	printf ("%s%c", filename, '\n' & filename_mask);
1024
1025      if (BZflag && bzbufdesc)
1026	BZ2_bzclose(bzbufdesc);
1027      else
1028#if HAVE_LIBZ > 0
1029      if (Zflag)
1030	gzclose(gzbufdesc);
1031      else
1032#endif
1033      if (! file)
1034	{
1035	  off_t required_offset = outleft ? bufoffset : after_last_match;
1036	  if ((bufmapped || required_offset != bufoffset)
1037	      && lseek (desc, required_offset, SEEK_SET) < 0
1038	      && S_ISREG (stats->stat.st_mode))
1039	    error (0, errno, "%s", filename);
1040	}
1041      else
1042	while (close (desc) != 0)
1043	  if (errno != EINTR)
1044	    {
1045	      error (0, errno, "%s", file);
1046	      break;
1047	    }
1048    }
1049
1050  return status;
1051}
1052
1053static int
1054grepdir (char const *dir, struct stats const *stats)
1055{
1056  int status = 1;
1057  struct stats const *ancestor;
1058  char *name_space;
1059
1060  /* Mingw32 does not support st_ino.  No known working hosts use zero
1061     for st_ino, so assume that the Mingw32 bug applies if it's zero.  */
1062  if (stats->stat.st_ino)
1063    for (ancestor = stats;  (ancestor = ancestor->parent) != 0;  )
1064      if (ancestor->stat.st_ino == stats->stat.st_ino
1065	  && ancestor->stat.st_dev == stats->stat.st_dev)
1066	{
1067	  if (!suppress_errors)
1068	    error (0, 0, _("warning: %s: %s"), dir,
1069		   _("recursive directory loop"));
1070	  return 1;
1071	}
1072
1073  name_space = savedir (dir, stats->stat.st_size, included_patterns,
1074			excluded_patterns);
1075
1076  if (! name_space)
1077    {
1078      if (errno)
1079	suppressible_error (dir, errno);
1080      else
1081	xalloc_die ();
1082    }
1083  else
1084    {
1085      size_t dirlen = strlen (dir);
1086      int needs_slash = ! (dirlen == FILESYSTEM_PREFIX_LEN (dir)
1087			   || IS_SLASH (dir[dirlen - 1]));
1088      char *file = NULL;
1089      char const *namep = name_space;
1090      struct stats child;
1091      child.parent = stats;
1092      out_file += !no_filenames;
1093      while (*namep)
1094	{
1095	  size_t namelen = strlen (namep);
1096	  file = xrealloc (file, dirlen + 1 + namelen + 1);
1097	  strcpy (file, dir);
1098	  file[dirlen] = '/';
1099	  strcpy (file + dirlen + needs_slash, namep);
1100	  namep += namelen + 1;
1101	  status &= grepfile (file, &child);
1102	}
1103      out_file -= !no_filenames;
1104      if (file)
1105        free (file);
1106      free (name_space);
1107    }
1108
1109  return status;
1110}
1111
1112static void
1113usage (int status)
1114{
1115  if (status != 0)
1116    {
1117      fprintf (stderr, _("Usage: %s [OPTION]... PATTERN [FILE]...\n"),
1118	       program_name);
1119      fprintf (stderr, _("Try `%s --help' for more information.\n"),
1120	       program_name);
1121    }
1122  else
1123    {
1124      printf (_("Usage: %s [OPTION]... PATTERN [FILE] ...\n"), program_name);
1125      printf (_("\
1126Search for PATTERN in each FILE or standard input.\n\
1127Example: %s -i 'hello world' menu.h main.c\n\
1128\n\
1129Regexp selection and interpretation:\n"), program_name);
1130      printf (_("\
1131  -E, --extended-regexp     PATTERN is an extended regular expression\n\
1132  -F, --fixed-strings       PATTERN is a set of newline-separated strings\n\
1133  -G, --basic-regexp        PATTERN is a basic regular expression\n\
1134  -P, --perl-regexp         PATTERN is a Perl regular expression\n"));
1135      printf (_("\
1136  -e, --regexp=PATTERN      use PATTERN as a regular expression\n\
1137  -f, --file=FILE           obtain PATTERN from FILE\n\
1138  -i, --ignore-case         ignore case distinctions\n\
1139  -w, --word-regexp         force PATTERN to match only whole words\n\
1140  -x, --line-regexp         force PATTERN to match only whole lines\n\
1141  -z, --null-data           a data line ends in 0 byte, not newline\n"));
1142      printf (_("\
1143\n\
1144Miscellaneous:\n\
1145  -s, --no-messages         suppress error messages\n\
1146  -v, --invert-match        select non-matching lines\n\
1147  -V, --version             print version information and exit\n\
1148      --help                display this help and exit\n\
1149  -J, --bz2decompress       decompress bzip2'ed input before searching\n\
1150  -Z, --decompress          decompress input before searching (HAVE_LIBZ=1)\n\
1151      --mmap                use memory-mapped input if possible\n"));
1152      printf (_("\
1153\n\
1154Output control:\n\
1155  -m, --max-count=NUM       stop after NUM matches\n\
1156  -b, --byte-offset         print the byte offset with output lines\n\
1157  -n, --line-number         print line number with output lines\n\
1158      --line-buffered       flush output on every line\n\
1159  -H, --with-filename       print the filename for each match\n\
1160  -h, --no-filename         suppress the prefixing filename on output\n\
1161      --label=LABEL         print LABEL as filename for standard input\n\
1162  -o, --only-matching       show only the part of a line matching PATTERN\n\
1163  -q, --quiet, --silent     suppress all normal output\n\
1164      --binary-files=TYPE   assume that binary files are TYPE\n\
1165                            TYPE is 'binary', 'text', or 'without-match'\n\
1166  -a, --text                equivalent to --binary-files=text\n\
1167  -I                        equivalent to --binary-files=without-match\n\
1168  -d, --directories=ACTION  how to handle directories\n\
1169                            ACTION is 'read', 'recurse', or 'skip'\n\
1170  -D, --devices=ACTION      how to handle devices, FIFOs and sockets\n\
1171                            ACTION is 'read' or 'skip'\n\
1172  -R, -r, --recursive       equivalent to --directories=recurse\n\
1173      --include=PATTERN     files that match PATTERN will be examined\n\
1174      --exclude=PATTERN     files that match PATTERN will be skipped.\n\
1175      --exclude-from=FILE   files that match PATTERN in FILE will be skipped.\n\
1176  -L, --files-without-match only print FILE names containing no match\n\
1177  -l, --files-with-matches  only print FILE names containing matches\n\
1178  -c, --count               only print a count of matching lines per FILE\n\
1179      --null                print 0 byte after FILE name\n"));
1180      printf (_("\
1181\n\
1182Context control:\n\
1183  -B, --before-context=NUM  print NUM lines of leading context\n\
1184  -A, --after-context=NUM   print NUM lines of trailing context\n\
1185  -C, --context=NUM         print NUM lines of output context\n\
1186  -NUM                      same as --context=NUM\n\
1187      --color[=WHEN],\n\
1188      --colour[=WHEN]       use markers to distinguish the matching string\n\
1189                            WHEN may be `always', `never' or `auto'.\n\
1190  -U, --binary              do not strip CR characters at EOL (MSDOS)\n\
1191  -u, --unix-byte-offsets   report offsets as if CRs were not there (MSDOS)\n\
1192\n\
1193`egrep' means `grep -E'.  `fgrep' means `grep -F'.\n\
1194With no FILE, or when FILE is -, read standard input.  If less than\n\
1195two FILEs given, assume -h.  Exit status is 0 if match, 1 if no match,\n\
1196and 2 if trouble.\n"));
1197      printf (_("\nReport bugs to <bug-gnu-utils@gnu.org>.\n"));
1198    }
1199  exit (status);
1200}
1201
1202/* Set the matcher to M, reporting any conflicts.  */
1203static void
1204setmatcher (char const *m)
1205{
1206  if (matcher && strcmp (matcher, m) != 0)
1207    error (2, 0, _("conflicting matchers specified"));
1208  matcher = m;
1209}
1210
1211/* Go through the matchers vector and look for the specified matcher.
1212   If we find it, install it in compile and execute, and return 1.  */
1213static int
1214install_matcher (char const *name)
1215{
1216  int i;
1217#if defined(HAVE_SETRLIMIT)
1218  struct rlimit rlim;
1219#endif
1220
1221  for (i = 0; matchers[i].compile; i++)
1222    if (strcmp (name, matchers[i].name) == 0)
1223      {
1224	compile = matchers[i].compile;
1225	execute = matchers[i].execute;
1226#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_STACK)
1227	/* I think every platform needs to do this, so that regex.c
1228	   doesn't oveflow the stack.  The default value of
1229	   `re_max_failures' is too large for some platforms: it needs
1230	   more than 3MB-large stack.
1231
1232	   The test for HAVE_SETRLIMIT should go into `configure'.  */
1233	if (!getrlimit (RLIMIT_STACK, &rlim))
1234	  {
1235	    long newlim;
1236	    extern long int re_max_failures; /* from regex.c */
1237
1238	    /* Approximate the amount regex.c needs, plus some more.  */
1239	    newlim = re_max_failures * 2 * 20 * sizeof (char *);
1240	    if (newlim > rlim.rlim_max)
1241	      {
1242		newlim = rlim.rlim_max;
1243		re_max_failures = newlim / (2 * 20 * sizeof (char *));
1244	      }
1245	    if (rlim.rlim_cur < newlim)
1246	      {
1247		rlim.rlim_cur = newlim;
1248		setrlimit (RLIMIT_STACK, &rlim);
1249	      }
1250	  }
1251#endif
1252	return 1;
1253      }
1254  return 0;
1255}
1256
1257/* Find the white-space-separated options specified by OPTIONS, and
1258   using BUF to store copies of these options, set ARGV[0], ARGV[1],
1259   etc. to the option copies.  Return the number N of options found.
1260   Do not set ARGV[N] to NULL.  If ARGV is NULL, do not store ARGV[0]
1261   etc.  Backslash can be used to escape whitespace (and backslashes).  */
1262static int
1263prepend_args (char const *options, char *buf, char **argv)
1264{
1265  char const *o = options;
1266  char *b = buf;
1267  int n = 0;
1268
1269  for (;;)
1270    {
1271      while (ISSPACE ((unsigned char) *o))
1272	o++;
1273      if (!*o)
1274	return n;
1275      if (argv)
1276	argv[n] = b;
1277      n++;
1278
1279      do
1280	if ((*b++ = *o++) == '\\' && *o)
1281	  b[-1] = *o++;
1282      while (*o && ! ISSPACE ((unsigned char) *o));
1283
1284      *b++ = '\0';
1285    }
1286}
1287
1288/* Prepend the whitespace-separated options in OPTIONS to the argument
1289   vector of a main program with argument count *PARGC and argument
1290   vector *PARGV.  */
1291static void
1292prepend_default_options (char const *options, int *pargc, char ***pargv)
1293{
1294  if (options)
1295    {
1296      char *buf = xmalloc (strlen (options) + 1);
1297      int prepended = prepend_args (options, buf, (char **) NULL);
1298      int argc = *pargc;
1299      char * const *argv = *pargv;
1300      char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp);
1301      *pargc = prepended + argc;
1302      *pargv = pp;
1303      *pp++ = *argv++;
1304      pp += prepend_args (options, buf, pp);
1305      while ((*pp++ = *argv++))
1306	continue;
1307    }
1308}
1309
1310/* Get the next non-digit option from ARGC and ARGV.
1311   Return -1 if there are no more options.
1312   Process any digit options that were encountered on the way,
1313   and store the resulting integer into *DEFAULT_CONTEXT.  */
1314static int
1315get_nondigit_option (int argc, char *const *argv, int *default_context)
1316{
1317  int opt;
1318  char buf[sizeof (uintmax_t) * CHAR_BIT + 4];
1319  char *p = buf;
1320
1321  /* Set buf[0] to anything but '0', for the leading-zero test below.  */
1322  buf[0] = '\0';
1323
1324  while (opt = getopt_long (argc, argv, short_options, long_options, NULL),
1325	 '0' <= opt && opt <= '9')
1326    {
1327      /* Suppress trivial leading zeros, to avoid incorrect
1328	 diagnostic on strings like 00000000000.  */
1329      p -= buf[0] == '0';
1330
1331      *p++ = opt;
1332      if (p == buf + sizeof buf - 4)
1333	{
1334	  /* Too many digits.  Append "..." to make context_length_arg
1335	     complain about "X...", where X contains the digits seen
1336	     so far.  */
1337	  strcpy (p, "...");
1338	  p += 3;
1339	  break;
1340	}
1341    }
1342  if (p != buf)
1343    {
1344      *p = '\0';
1345      context_length_arg (buf, default_context);
1346    }
1347
1348  return opt;
1349}
1350
1351int
1352main (int argc, char **argv)
1353{
1354  char *keys;
1355  size_t cc, keycc, oldcc, keyalloc;
1356  int with_filenames;
1357  int opt, status;
1358  int default_context;
1359  FILE *fp;
1360  extern char *optarg;
1361  extern int optind;
1362
1363  initialize_main (&argc, &argv);
1364  program_name = argv[0];
1365  if (program_name && strrchr (program_name, '/'))
1366    program_name = strrchr (program_name, '/') + 1;
1367
1368  if (program_name[0] == 'b' && program_name[1] == 'z') {
1369    BZflag = 1;
1370    program_name += 2;
1371  }
1372#if HAVE_LIBZ > 0
1373  else if (program_name[0] == 'z') {
1374    Zflag = 1;
1375    ++program_name;
1376  }
1377#endif
1378
1379#if defined(__MSDOS__) || defined(_WIN32)
1380  /* DOS and MS-Windows use backslashes as directory separators, and usually
1381     have an .exe suffix.  They also have case-insensitive filesystems.  */
1382  if (program_name)
1383    {
1384      char *p = program_name;
1385      char *bslash = strrchr (argv[0], '\\');
1386
1387      if (bslash && bslash >= program_name) /* for mixed forward/backslash case */
1388	program_name = bslash + 1;
1389      else if (program_name == argv[0]
1390	       && argv[0][0] && argv[0][1] == ':') /* "c:progname" */
1391	program_name = argv[0] + 2;
1392
1393      /* Collapse the letter-case, so `strcmp' could be used hence.  */
1394      for ( ; *p; p++)
1395	if (*p >= 'A' && *p <= 'Z')
1396	  *p += 'a' - 'A';
1397
1398      /* Remove the .exe extension, if any.  */
1399      if ((p = strrchr (program_name, '.')) && strcmp (p, ".exe") == 0)
1400	*p = '\0';
1401    }
1402#endif
1403
1404  keys = NULL;
1405  keycc = 0;
1406  with_filenames = 0;
1407  eolbyte = '\n';
1408  filename_mask = ~0;
1409
1410  max_count = TYPE_MAXIMUM (off_t);
1411
1412  /* The value -1 means to use DEFAULT_CONTEXT. */
1413  out_after = out_before = -1;
1414  /* Default before/after context: chaged by -C/-NUM options */
1415  default_context = 0;
1416  /* Changed by -o option */
1417  only_matching = 0;
1418
1419  /* Internationalization. */
1420#if defined(HAVE_SETLOCALE)
1421  setlocale (LC_ALL, "");
1422#endif
1423#if defined(ENABLE_NLS)
1424  bindtextdomain (PACKAGE, LOCALEDIR);
1425  textdomain (PACKAGE);
1426#endif
1427
1428  atexit (close_stdout);
1429
1430  prepend_default_options (getenv ("GREP_OPTIONS"), &argc, &argv);
1431
1432  while ((opt = get_nondigit_option (argc, argv, &default_context)) != -1)
1433    switch (opt)
1434      {
1435      case 'A':
1436	context_length_arg (optarg, &out_after);
1437	break;
1438
1439      case 'B':
1440	context_length_arg (optarg, &out_before);
1441	break;
1442
1443      case 'C':
1444	/* Set output match context, but let any explicit leading or
1445	   trailing amount specified with -A or -B stand. */
1446	context_length_arg (optarg, &default_context);
1447	break;
1448
1449      case 'D':
1450	if (strcmp (optarg, "read") == 0)
1451	  devices = READ_DEVICES;
1452	else if (strcmp (optarg, "skip") == 0)
1453	  devices = SKIP_DEVICES;
1454	else
1455	  error (2, 0, _("unknown devices method"));
1456	break;
1457
1458      case 'E':
1459	setmatcher ("egrep");
1460	break;
1461
1462      case 'F':
1463	setmatcher ("fgrep");
1464	break;
1465
1466      case 'P':
1467	setmatcher ("perl");
1468	break;
1469
1470      case 'G':
1471	setmatcher ("grep");
1472	break;
1473
1474      case 'H':
1475	with_filenames = 1;
1476	break;
1477
1478      case 'I':
1479	binary_files = WITHOUT_MATCH_BINARY_FILES;
1480	break;
1481      case 'J':
1482	if (Zflag)
1483	  {
1484	    printf (_("Cannot mix -Z and -J.\n"));
1485	    usage (2);
1486	  }
1487	BZflag = 1;
1488	break;
1489
1490      case 'U':
1491#if defined(HAVE_DOS_FILE_CONTENTS)
1492	dos_use_file_type = DOS_BINARY;
1493#endif
1494	break;
1495
1496      case 'u':
1497#if defined(HAVE_DOS_FILE_CONTENTS)
1498	dos_report_unix_offset = 1;
1499#endif
1500	break;
1501
1502      case 'V':
1503	show_version = 1;
1504	break;
1505
1506      case 'X':
1507	setmatcher (optarg);
1508	break;
1509
1510      case 'a':
1511	binary_files = TEXT_BINARY_FILES;
1512	break;
1513
1514      case 'b':
1515	out_byte = 1;
1516	break;
1517
1518      case 'c':
1519	count_matches = 1;
1520	break;
1521
1522      case 'd':
1523	if (strcmp (optarg, "read") == 0)
1524	  directories = READ_DIRECTORIES;
1525	else if (strcmp (optarg, "skip") == 0)
1526	  directories = SKIP_DIRECTORIES;
1527	else if (strcmp (optarg, "recurse") == 0)
1528	  directories = RECURSE_DIRECTORIES;
1529	else
1530	  error (2, 0, _("unknown directories method"));
1531	break;
1532
1533      case 'e':
1534	cc = strlen (optarg);
1535	keys = xrealloc (keys, keycc + cc + 1);
1536	strcpy (&keys[keycc], optarg);
1537	keycc += cc;
1538	keys[keycc++] = '\n';
1539	break;
1540
1541      case 'f':
1542	fp = strcmp (optarg, "-") != 0 ? fopen (optarg, "r") : stdin;
1543	if (!fp)
1544	  error (2, errno, "%s", optarg);
1545	for (keyalloc = 1; keyalloc <= keycc + 1; keyalloc *= 2)
1546	  ;
1547	keys = xrealloc (keys, keyalloc);
1548	oldcc = keycc;
1549	while (!feof (fp)
1550	       && (cc = fread (keys + keycc, 1, keyalloc - 1 - keycc, fp)) > 0)
1551	  {
1552	    keycc += cc;
1553	    if (keycc == keyalloc - 1)
1554	      keys = xrealloc (keys, keyalloc *= 2);
1555	  }
1556	if (fp != stdin)
1557	  fclose(fp);
1558	/* Append final newline if file ended in non-newline. */
1559	if (oldcc != keycc && keys[keycc - 1] != '\n')
1560	  keys[keycc++] = '\n';
1561	break;
1562
1563      case 'h':
1564	no_filenames = 1;
1565	break;
1566
1567      case 'i':
1568      case 'y':			/* For old-timers . . . */
1569	match_icase = 1;
1570	break;
1571
1572      case 'L':
1573	/* Like -l, except list files that don't contain matches.
1574	   Inspired by the same option in Hume's gre. */
1575	list_files = -1;
1576	break;
1577
1578      case 'l':
1579	list_files = 1;
1580	break;
1581
1582      case 'm':
1583	{
1584	  uintmax_t value;
1585	  switch (xstrtoumax (optarg, 0, 10, &value, ""))
1586	    {
1587	    case LONGINT_OK:
1588	      max_count = value;
1589	      if (0 <= max_count && max_count == value)
1590		break;
1591	      /* Fall through.  */
1592	    case LONGINT_OVERFLOW:
1593	      max_count = TYPE_MAXIMUM (off_t);
1594	      break;
1595
1596	    default:
1597	      error (2, 0, _("invalid max count"));
1598	    }
1599	}
1600	break;
1601
1602      case 'n':
1603	out_line = 1;
1604	break;
1605
1606      case 'o':
1607	only_matching = 1;
1608	break;
1609
1610      case 'q':
1611	exit_on_match = 1;
1612	close_stdout_set_status(0);
1613	break;
1614
1615      case 'R':
1616      case 'r':
1617	directories = RECURSE_DIRECTORIES;
1618	break;
1619
1620      case 's':
1621	suppress_errors = 1;
1622	break;
1623
1624      case 'v':
1625	out_invert = 1;
1626	break;
1627
1628      case 'w':
1629	match_words = 1;
1630	break;
1631
1632      case 'x':
1633	match_lines = 1;
1634	break;
1635
1636      case 'Z':
1637#if HAVE_LIBZ > 0
1638	if (BZflag)
1639	  {
1640	    printf (_("Cannot mix -J and -Z.\n"));
1641	    usage (2);
1642	  }
1643	Zflag = 1;
1644#else
1645	filename_mask = 0;
1646#endif
1647	break;
1648
1649      case 'z':
1650	eolbyte = '\0';
1651	break;
1652
1653      case BINARY_FILES_OPTION:
1654	if (strcmp (optarg, "binary") == 0)
1655	  binary_files = BINARY_BINARY_FILES;
1656	else if (strcmp (optarg, "text") == 0)
1657	  binary_files = TEXT_BINARY_FILES;
1658	else if (strcmp (optarg, "without-match") == 0)
1659	  binary_files = WITHOUT_MATCH_BINARY_FILES;
1660	else
1661	  error (2, 0, _("unknown binary-files type"));
1662	break;
1663
1664      case COLOR_OPTION:
1665        if(optarg) {
1666          if(!strcasecmp(optarg, "always") || !strcasecmp(optarg, "yes") ||
1667             !strcasecmp(optarg, "force"))
1668            color_option = 1;
1669          else if(!strcasecmp(optarg, "never") || !strcasecmp(optarg, "no") ||
1670                  !strcasecmp(optarg, "none"))
1671            color_option = 0;
1672          else if(!strcasecmp(optarg, "auto") || !strcasecmp(optarg, "tty") ||
1673                  !strcasecmp(optarg, "if-tty"))
1674            color_option = 2;
1675          else
1676            show_help = 1;
1677        } else
1678          color_option = 2;
1679        if(color_option == 2) {
1680          if(isatty(STDOUT_FILENO) && getenv("TERM") &&
1681	     strcmp(getenv("TERM"), "dumb"))
1682                  color_option = 1;
1683          else
1684            color_option = 0;
1685        }
1686	break;
1687
1688      case EXCLUDE_OPTION:
1689	if (!excluded_patterns)
1690	  excluded_patterns = new_exclude ();
1691	add_exclude (excluded_patterns, optarg);
1692	break;
1693
1694      case EXCLUDE_FROM_OPTION:
1695	if (!excluded_patterns)
1696	  excluded_patterns = new_exclude ();
1697        if (add_exclude_file (add_exclude, excluded_patterns, optarg, '\n')
1698	    != 0)
1699          {
1700            error (2, errno, "%s", optarg);
1701          }
1702        break;
1703
1704      case INCLUDE_OPTION:
1705	if (!included_patterns)
1706	  included_patterns = new_exclude ();
1707	add_exclude (included_patterns, optarg);
1708	break;
1709
1710      case LINE_BUFFERED_OPTION:
1711	line_buffered = 1;
1712	break;
1713
1714      case LABEL_OPTION:
1715	label = optarg;
1716	break;
1717
1718      case 0:
1719	/* long options */
1720	break;
1721
1722      default:
1723	usage (2);
1724	break;
1725
1726      }
1727
1728  /* POSIX.2 says that -q overrides -l, which in turn overrides the
1729     other output options.  */
1730  if (exit_on_match)
1731    list_files = 0;
1732  if (exit_on_match | list_files)
1733    {
1734      count_matches = 0;
1735      done_on_match = 1;
1736    }
1737  out_quiet = count_matches | done_on_match;
1738
1739  if (out_after < 0)
1740    out_after = default_context;
1741  if (out_before < 0)
1742    out_before = default_context;
1743
1744  if (color_option)
1745    {
1746      char *userval = getenv ("GREP_COLOR");
1747      if (userval != NULL && *userval != '\0')
1748	grep_color = userval;
1749    }
1750
1751  if (! matcher)
1752    matcher = program_name;
1753
1754  if (show_version)
1755    {
1756      printf (_("%s (GNU grep) %s\n"), matcher, VERSION);
1757      printf ("\n");
1758      printf (_("\
1759Copyright 1988, 1992-1999, 2000, 2001 Free Software Foundation, Inc.\n"));
1760      printf (_("\
1761This is free software; see the source for copying conditions. There is NO\n\
1762warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"));
1763      printf ("\n");
1764      exit (0);
1765    }
1766
1767  if (show_help)
1768    usage (0);
1769
1770  if (keys)
1771    {
1772      if (keycc == 0)
1773	{
1774	  /* No keys were specified (e.g. -f /dev/null).  Match nothing.  */
1775	  out_invert ^= 1;
1776	  match_lines = match_words = 0;
1777	}
1778      else
1779	/* Strip trailing newline. */
1780        --keycc;
1781    }
1782  else
1783    if (optind < argc)
1784      {
1785	keys = argv[optind++];
1786	keycc = strlen (keys);
1787      }
1788    else
1789      usage (2);
1790
1791  if (!install_matcher (matcher) && !install_matcher ("default"))
1792    abort ();
1793
1794#ifdef MBS_SUPPORT
1795  if (MB_CUR_MAX != 1 && match_icase)
1796    {
1797      wchar_t wc;
1798      mbstate_t cur_state, prev_state;
1799      int i, len = strlen(keys);
1800
1801      memset(&cur_state, 0, sizeof(mbstate_t));
1802      for (i = 0; i <= len ;)
1803	{
1804	  size_t mbclen;
1805	  mbclen = mbrtowc(&wc, keys + i, len - i, &cur_state);
1806	  if (mbclen == (size_t) -1 || mbclen == (size_t) -2 || mbclen == 0)
1807	    {
1808	      /* An invalid sequence, or a truncated multibyte character.
1809		 We treat it as a singlebyte character.  */
1810	      mbclen = 1;
1811	    }
1812	  else
1813	    {
1814	      if (iswupper((wint_t)wc))
1815		{
1816		  wc = towlower((wint_t)wc);
1817		  wcrtomb(keys + i, wc, &cur_state);
1818		}
1819	    }
1820	  i += mbclen;
1821	}
1822    }
1823#endif /* MBS_SUPPORT */
1824
1825  (*compile)(keys, keycc);
1826
1827  if ((argc - optind > 1 && !no_filenames) || with_filenames)
1828    out_file = 1;
1829
1830#ifdef SET_BINARY
1831  /* Output is set to binary mode because we shouldn't convert
1832     NL to CR-LF pairs, especially when grepping binary files.  */
1833  if (!isatty (1))
1834    SET_BINARY (1);
1835#endif
1836
1837  if (max_count == 0)
1838    exit (1);
1839
1840  if (optind < argc)
1841    {
1842	status = 1;
1843	do
1844	{
1845	  char *file = argv[optind];
1846	  if ((included_patterns || excluded_patterns)
1847	      && !isdir (file))
1848	    {
1849	      if (included_patterns &&
1850		  ! excluded_filename (included_patterns, file, 0))
1851		continue;
1852	      if (excluded_patterns &&
1853		  excluded_filename (excluded_patterns, file, 0))
1854		continue;
1855	    }
1856	  status &= grepfile (strcmp (file, "-") == 0 ? (char *) NULL : file,
1857			      &stats_base);
1858	}
1859	while ( ++optind < argc);
1860    }
1861  else
1862    status = grepfile ((char *) NULL, &stats_base);
1863
1864  /* We register via atexit() to test stdout.  */
1865  exit (errseen ? 2 : status);
1866}
1867/* vim:set shiftwidth=2: */
1868