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