grep.c revision 151534
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 151534 2005-10-21 15:17:18Z jkim $ */
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)))
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
946  if (! file)
947    {
948      desc = 0;
949      filename = label ? label : _("(standard input)");
950    }
951  else
952    {
953      while ((desc = open (file, O_RDONLY)) < 0 && errno == EINTR)
954	continue;
955
956      if (desc < 0)
957	{
958	  int e = errno;
959
960	  if (is_EISDIR (e, file) && directories == RECURSE_DIRECTORIES)
961	    {
962	      if (stat (file, &stats->stat) != 0)
963		{
964		  error (0, errno, "%s", file);
965		  return 1;
966		}
967
968	      return grepdir (file, stats);
969	    }
970
971	  if (!suppress_errors)
972	    {
973	      if (directories == SKIP_DIRECTORIES)
974		switch (e)
975		  {
976#if defined(EISDIR)
977		  case EISDIR:
978		    return 1;
979#endif
980		  case EACCES:
981		    /* When skipping directories, don't worry about
982		       directories that can't be opened.  */
983		    if (isdir (file))
984		      return 1;
985		    break;
986		  }
987	    }
988
989	  suppressible_error (file, e);
990	  return 1;
991	}
992
993      filename = file;
994    }
995
996#if defined(SET_BINARY)
997  /* Set input to binary mode.  Pipes are simulated with files
998     on DOS, so this includes the case of "foo | grep bar".  */
999  if (!isatty (desc))
1000    SET_BINARY (desc);
1001#endif
1002
1003  count = grep (desc, file, stats);
1004  if (count < 0)
1005    status = count + 2;
1006  else
1007    {
1008      if (count_matches)
1009	{
1010	  if (out_file)
1011	    printf ("%s%c", filename, ':' & filename_mask);
1012	  printf ("%d\n", count);
1013	}
1014
1015      status = !count;
1016      if (list_files == 1 - 2 * status)
1017	printf ("%s%c", filename, '\n' & filename_mask);
1018
1019      if (BZflag && bzbufdesc)
1020	BZ2_bzclose(bzbufdesc);
1021      else
1022#if HAVE_LIBZ > 0
1023      if (Zflag)
1024	gzclose(gzbufdesc);
1025      else
1026#endif
1027      if (! file)
1028	{
1029	  off_t required_offset = outleft ? bufoffset : after_last_match;
1030	  if ((bufmapped || required_offset != bufoffset)
1031	      && lseek (desc, required_offset, SEEK_SET) < 0
1032	      && S_ISREG (stats->stat.st_mode))
1033	    error (0, errno, "%s", filename);
1034	}
1035      else
1036	while (close (desc) != 0)
1037	  if (errno != EINTR)
1038	    {
1039	      error (0, errno, "%s", file);
1040	      break;
1041	    }
1042    }
1043
1044  return status;
1045}
1046
1047static int
1048grepdir (char const *dir, struct stats const *stats)
1049{
1050  int status = 1;
1051  struct stats const *ancestor;
1052  char *name_space;
1053
1054  /* Mingw32 does not support st_ino.  No known working hosts use zero
1055     for st_ino, so assume that the Mingw32 bug applies if it's zero.  */
1056  if (stats->stat.st_ino)
1057    for (ancestor = stats;  (ancestor = ancestor->parent) != 0;  )
1058      if (ancestor->stat.st_ino == stats->stat.st_ino
1059	  && ancestor->stat.st_dev == stats->stat.st_dev)
1060	{
1061	  if (!suppress_errors)
1062	    error (0, 0, _("warning: %s: %s"), dir,
1063		   _("recursive directory loop"));
1064	  return 1;
1065	}
1066
1067  name_space = savedir (dir, stats->stat.st_size, included_patterns,
1068			excluded_patterns);
1069
1070  if (! name_space)
1071    {
1072      if (errno)
1073	suppressible_error (dir, errno);
1074      else
1075	xalloc_die ();
1076    }
1077  else
1078    {
1079      size_t dirlen = strlen (dir);
1080      int needs_slash = ! (dirlen == FILESYSTEM_PREFIX_LEN (dir)
1081			   || IS_SLASH (dir[dirlen - 1]));
1082      char *file = NULL;
1083      char const *namep = name_space;
1084      struct stats child;
1085      child.parent = stats;
1086      out_file += !no_filenames;
1087      while (*namep)
1088	{
1089	  size_t namelen = strlen (namep);
1090	  file = xrealloc (file, dirlen + 1 + namelen + 1);
1091	  strcpy (file, dir);
1092	  file[dirlen] = '/';
1093	  strcpy (file + dirlen + needs_slash, namep);
1094	  namep += namelen + 1;
1095	  status &= grepfile (file, &child);
1096	}
1097      out_file -= !no_filenames;
1098      if (file)
1099        free (file);
1100      free (name_space);
1101    }
1102
1103  return status;
1104}
1105
1106static void
1107usage (int status)
1108{
1109  if (status != 0)
1110    {
1111      fprintf (stderr, _("Usage: %s [OPTION]... PATTERN [FILE]...\n"),
1112	       program_name);
1113      fprintf (stderr, _("Try `%s --help' for more information.\n"),
1114	       program_name);
1115    }
1116  else
1117    {
1118      printf (_("Usage: %s [OPTION]... PATTERN [FILE] ...\n"), program_name);
1119      printf (_("\
1120Search for PATTERN in each FILE or standard input.\n\
1121Example: %s -i 'hello world' menu.h main.c\n\
1122\n\
1123Regexp selection and interpretation:\n"), program_name);
1124      printf (_("\
1125  -E, --extended-regexp     PATTERN is an extended regular expression\n\
1126  -F, --fixed-strings       PATTERN is a set of newline-separated strings\n\
1127  -G, --basic-regexp        PATTERN is a basic regular expression\n\
1128  -P, --perl-regexp         PATTERN is a Perl regular expression\n"));
1129      printf (_("\
1130  -e, --regexp=PATTERN      use PATTERN as a regular expression\n\
1131  -f, --file=FILE           obtain PATTERN from FILE\n\
1132  -i, --ignore-case         ignore case distinctions\n\
1133  -w, --word-regexp         force PATTERN to match only whole words\n\
1134  -x, --line-regexp         force PATTERN to match only whole lines\n\
1135  -z, --null-data           a data line ends in 0 byte, not newline\n"));
1136      printf (_("\
1137\n\
1138Miscellaneous:\n\
1139  -s, --no-messages         suppress error messages\n\
1140  -v, --invert-match        select non-matching lines\n\
1141  -V, --version             print version information and exit\n\
1142      --help                display this help and exit\n\
1143  -J, --bz2decompress       decompress bzip2'ed input before searching\n\
1144  -Z, --decompress          decompress input before searching (HAVE_LIBZ=1)\n\
1145      --mmap                use memory-mapped input if possible\n"));
1146      printf (_("\
1147\n\
1148Output control:\n\
1149  -m, --max-count=NUM       stop after NUM matches\n\
1150  -b, --byte-offset         print the byte offset with output lines\n\
1151  -n, --line-number         print line number with output lines\n\
1152      --line-buffered       flush output on every line\n\
1153  -H, --with-filename       print the filename for each match\n\
1154  -h, --no-filename         suppress the prefixing filename on output\n\
1155      --label=LABEL         print LABEL as filename for standard input\n\
1156  -o, --only-matching       show only the part of a line matching PATTERN\n\
1157  -q, --quiet, --silent     suppress all normal output\n\
1158      --binary-files=TYPE   assume that binary files are TYPE\n\
1159                            TYPE is 'binary', 'text', or 'without-match'\n\
1160  -a, --text                equivalent to --binary-files=text\n\
1161  -I                        equivalent to --binary-files=without-match\n\
1162  -d, --directories=ACTION  how to handle directories\n\
1163                            ACTION is 'read', 'recurse', or 'skip'\n\
1164  -D, --devices=ACTION      how to handle devices, FIFOs and sockets\n\
1165                            ACTION is 'read' or 'skip'\n\
1166  -R, -r, --recursive       equivalent to --directories=recurse\n\
1167      --include=PATTERN     files that match PATTERN will be examined\n\
1168      --exclude=PATTERN     files that match PATTERN will be skipped.\n\
1169      --exclude-from=FILE   files that match PATTERN in FILE will be skipped.\n\
1170  -L, --files-without-match only print FILE names containing no match\n\
1171  -l, --files-with-matches  only print FILE names containing matches\n\
1172  -c, --count               only print a count of matching lines per FILE\n\
1173      --null                print 0 byte after FILE name\n"));
1174      printf (_("\
1175\n\
1176Context control:\n\
1177  -B, --before-context=NUM  print NUM lines of leading context\n\
1178  -A, --after-context=NUM   print NUM lines of trailing context\n\
1179  -C, --context=NUM         print NUM lines of output context\n\
1180  -NUM                      same as --context=NUM\n\
1181      --color[=WHEN],\n\
1182      --colour[=WHEN]       use markers to distinguish the matching string\n\
1183                            WHEN may be `always', `never' or `auto'.\n\
1184  -U, --binary              do not strip CR characters at EOL (MSDOS)\n\
1185  -u, --unix-byte-offsets   report offsets as if CRs were not there (MSDOS)\n\
1186\n\
1187`egrep' means `grep -E'.  `fgrep' means `grep -F'.\n\
1188With no FILE, or when FILE is -, read standard input.  If less than\n\
1189two FILEs given, assume -h.  Exit status is 0 if match, 1 if no match,\n\
1190and 2 if trouble.\n"));
1191      printf (_("\nReport bugs to <bug-gnu-utils@gnu.org>.\n"));
1192    }
1193  exit (status);
1194}
1195
1196/* Set the matcher to M, reporting any conflicts.  */
1197static void
1198setmatcher (char const *m)
1199{
1200  if (matcher && strcmp (matcher, m) != 0)
1201    error (2, 0, _("conflicting matchers specified"));
1202  matcher = m;
1203}
1204
1205/* Go through the matchers vector and look for the specified matcher.
1206   If we find it, install it in compile and execute, and return 1.  */
1207static int
1208install_matcher (char const *name)
1209{
1210  int i;
1211#if defined(HAVE_SETRLIMIT)
1212  struct rlimit rlim;
1213#endif
1214
1215  for (i = 0; matchers[i].compile; i++)
1216    if (strcmp (name, matchers[i].name) == 0)
1217      {
1218	compile = matchers[i].compile;
1219	execute = matchers[i].execute;
1220#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_STACK)
1221	/* I think every platform needs to do this, so that regex.c
1222	   doesn't oveflow the stack.  The default value of
1223	   `re_max_failures' is too large for some platforms: it needs
1224	   more than 3MB-large stack.
1225
1226	   The test for HAVE_SETRLIMIT should go into `configure'.  */
1227	if (!getrlimit (RLIMIT_STACK, &rlim))
1228	  {
1229	    long newlim;
1230	    extern long int re_max_failures; /* from regex.c */
1231
1232	    /* Approximate the amount regex.c needs, plus some more.  */
1233	    newlim = re_max_failures * 2 * 20 * sizeof (char *);
1234	    if (newlim > rlim.rlim_max)
1235	      {
1236		newlim = rlim.rlim_max;
1237		re_max_failures = newlim / (2 * 20 * sizeof (char *));
1238	      }
1239	    if (rlim.rlim_cur < newlim)
1240	      {
1241		rlim.rlim_cur = newlim;
1242		setrlimit (RLIMIT_STACK, &rlim);
1243	      }
1244	  }
1245#endif
1246	return 1;
1247      }
1248  return 0;
1249}
1250
1251/* Find the white-space-separated options specified by OPTIONS, and
1252   using BUF to store copies of these options, set ARGV[0], ARGV[1],
1253   etc. to the option copies.  Return the number N of options found.
1254   Do not set ARGV[N] to NULL.  If ARGV is NULL, do not store ARGV[0]
1255   etc.  Backslash can be used to escape whitespace (and backslashes).  */
1256static int
1257prepend_args (char const *options, char *buf, char **argv)
1258{
1259  char const *o = options;
1260  char *b = buf;
1261  int n = 0;
1262
1263  for (;;)
1264    {
1265      while (ISSPACE ((unsigned char) *o))
1266	o++;
1267      if (!*o)
1268	return n;
1269      if (argv)
1270	argv[n] = b;
1271      n++;
1272
1273      do
1274	if ((*b++ = *o++) == '\\' && *o)
1275	  b[-1] = *o++;
1276      while (*o && ! ISSPACE ((unsigned char) *o));
1277
1278      *b++ = '\0';
1279    }
1280}
1281
1282/* Prepend the whitespace-separated options in OPTIONS to the argument
1283   vector of a main program with argument count *PARGC and argument
1284   vector *PARGV.  */
1285static void
1286prepend_default_options (char const *options, int *pargc, char ***pargv)
1287{
1288  if (options)
1289    {
1290      char *buf = xmalloc (strlen (options) + 1);
1291      int prepended = prepend_args (options, buf, (char **) NULL);
1292      int argc = *pargc;
1293      char * const *argv = *pargv;
1294      char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp);
1295      *pargc = prepended + argc;
1296      *pargv = pp;
1297      *pp++ = *argv++;
1298      pp += prepend_args (options, buf, pp);
1299      while ((*pp++ = *argv++))
1300	continue;
1301    }
1302}
1303
1304/* Get the next non-digit option from ARGC and ARGV.
1305   Return -1 if there are no more options.
1306   Process any digit options that were encountered on the way,
1307   and store the resulting integer into *DEFAULT_CONTEXT.  */
1308static int
1309get_nondigit_option (int argc, char *const *argv, int *default_context)
1310{
1311  int opt;
1312  char buf[sizeof (uintmax_t) * CHAR_BIT + 4];
1313  char *p = buf;
1314
1315  /* Set buf[0] to anything but '0', for the leading-zero test below.  */
1316  buf[0] = '\0';
1317
1318  while (opt = getopt_long (argc, argv, short_options, long_options, NULL),
1319	 '0' <= opt && opt <= '9')
1320    {
1321      /* Suppress trivial leading zeros, to avoid incorrect
1322	 diagnostic on strings like 00000000000.  */
1323      p -= buf[0] == '0';
1324
1325      *p++ = opt;
1326      if (p == buf + sizeof buf - 4)
1327	{
1328	  /* Too many digits.  Append "..." to make context_length_arg
1329	     complain about "X...", where X contains the digits seen
1330	     so far.  */
1331	  strcpy (p, "...");
1332	  p += 3;
1333	  break;
1334	}
1335    }
1336  if (p != buf)
1337    {
1338      *p = '\0';
1339      context_length_arg (buf, default_context);
1340    }
1341
1342  return opt;
1343}
1344
1345int
1346main (int argc, char **argv)
1347{
1348  char *keys;
1349  size_t keycc, oldcc, keyalloc;
1350  int with_filenames;
1351  int opt, cc, status;
1352  int default_context;
1353  FILE *fp;
1354  extern char *optarg;
1355  extern int optind;
1356
1357  initialize_main (&argc, &argv);
1358  program_name = argv[0];
1359  if (program_name && strrchr (program_name, '/'))
1360    program_name = strrchr (program_name, '/') + 1;
1361
1362  if (program_name[0] == 'b' && program_name[1] == 'z') {
1363    BZflag = 1;
1364    program_name += 2;
1365  }
1366#if HAVE_LIBZ > 0
1367  else if (program_name[0] == 'z') {
1368    Zflag = 1;
1369    ++program_name;
1370  }
1371#endif
1372
1373#if defined(__MSDOS__) || defined(_WIN32)
1374  /* DOS and MS-Windows use backslashes as directory separators, and usually
1375     have an .exe suffix.  They also have case-insensitive filesystems.  */
1376  if (program_name)
1377    {
1378      char *p = program_name;
1379      char *bslash = strrchr (argv[0], '\\');
1380
1381      if (bslash && bslash >= program_name) /* for mixed forward/backslash case */
1382	program_name = bslash + 1;
1383      else if (program_name == argv[0]
1384	       && argv[0][0] && argv[0][1] == ':') /* "c:progname" */
1385	program_name = argv[0] + 2;
1386
1387      /* Collapse the letter-case, so `strcmp' could be used hence.  */
1388      for ( ; *p; p++)
1389	if (*p >= 'A' && *p <= 'Z')
1390	  *p += 'a' - 'A';
1391
1392      /* Remove the .exe extension, if any.  */
1393      if ((p = strrchr (program_name, '.')) && strcmp (p, ".exe") == 0)
1394	*p = '\0';
1395    }
1396#endif
1397
1398  keys = NULL;
1399  keycc = 0;
1400  with_filenames = 0;
1401  eolbyte = '\n';
1402  filename_mask = ~0;
1403
1404  max_count = TYPE_MAXIMUM (off_t);
1405
1406  /* The value -1 means to use DEFAULT_CONTEXT. */
1407  out_after = out_before = -1;
1408  /* Default before/after context: chaged by -C/-NUM options */
1409  default_context = 0;
1410  /* Changed by -o option */
1411  only_matching = 0;
1412
1413  /* Internationalization. */
1414#if defined(HAVE_SETLOCALE)
1415  setlocale (LC_ALL, "");
1416#endif
1417#if defined(ENABLE_NLS)
1418  bindtextdomain (PACKAGE, LOCALEDIR);
1419  textdomain (PACKAGE);
1420#endif
1421
1422  atexit (close_stdout);
1423
1424  prepend_default_options (getenv ("GREP_OPTIONS"), &argc, &argv);
1425
1426  while ((opt = get_nondigit_option (argc, argv, &default_context)) != -1)
1427    switch (opt)
1428      {
1429      case 'A':
1430	context_length_arg (optarg, &out_after);
1431	break;
1432
1433      case 'B':
1434	context_length_arg (optarg, &out_before);
1435	break;
1436
1437      case 'C':
1438	/* Set output match context, but let any explicit leading or
1439	   trailing amount specified with -A or -B stand. */
1440	context_length_arg (optarg, &default_context);
1441	break;
1442
1443      case 'D':
1444	if (strcmp (optarg, "read") == 0)
1445	  devices = READ_DEVICES;
1446	else if (strcmp (optarg, "skip") == 0)
1447	  devices = SKIP_DEVICES;
1448	else
1449	  error (2, 0, _("unknown devices method"));
1450	break;
1451
1452      case 'E':
1453	setmatcher ("egrep");
1454	break;
1455
1456      case 'F':
1457	setmatcher ("fgrep");
1458	break;
1459
1460      case 'P':
1461	setmatcher ("perl");
1462	break;
1463
1464      case 'G':
1465	setmatcher ("grep");
1466	break;
1467
1468      case 'H':
1469	with_filenames = 1;
1470	break;
1471
1472      case 'I':
1473	binary_files = WITHOUT_MATCH_BINARY_FILES;
1474	break;
1475      case 'J':
1476	if (Zflag)
1477	  {
1478	    printf (_("Cannot mix -Z and -J.\n"));
1479	    usage (2);
1480	  }
1481	BZflag = 1;
1482	break;
1483
1484      case 'U':
1485#if defined(HAVE_DOS_FILE_CONTENTS)
1486	dos_use_file_type = DOS_BINARY;
1487#endif
1488	break;
1489
1490      case 'u':
1491#if defined(HAVE_DOS_FILE_CONTENTS)
1492	dos_report_unix_offset = 1;
1493#endif
1494	break;
1495
1496      case 'V':
1497	show_version = 1;
1498	break;
1499
1500      case 'X':
1501	setmatcher (optarg);
1502	break;
1503
1504      case 'a':
1505	binary_files = TEXT_BINARY_FILES;
1506	break;
1507
1508      case 'b':
1509	out_byte = 1;
1510	break;
1511
1512      case 'c':
1513	count_matches = 1;
1514	break;
1515
1516      case 'd':
1517	if (strcmp (optarg, "read") == 0)
1518	  directories = READ_DIRECTORIES;
1519	else if (strcmp (optarg, "skip") == 0)
1520	  directories = SKIP_DIRECTORIES;
1521	else if (strcmp (optarg, "recurse") == 0)
1522	  directories = RECURSE_DIRECTORIES;
1523	else
1524	  error (2, 0, _("unknown directories method"));
1525	break;
1526
1527      case 'e':
1528	cc = strlen (optarg);
1529	keys = xrealloc (keys, keycc + cc + 1);
1530	strcpy (&keys[keycc], optarg);
1531	keycc += cc;
1532	keys[keycc++] = '\n';
1533	break;
1534
1535      case 'f':
1536	fp = strcmp (optarg, "-") != 0 ? fopen (optarg, "r") : stdin;
1537	if (!fp)
1538	  error (2, errno, "%s", optarg);
1539	for (keyalloc = 1; keyalloc <= keycc + 1; keyalloc *= 2)
1540	  ;
1541	keys = xrealloc (keys, keyalloc);
1542	oldcc = keycc;
1543	while (!feof (fp)
1544	       && (cc = fread (keys + keycc, 1, keyalloc - 1 - keycc, fp)) > 0)
1545	  {
1546	    keycc += cc;
1547	    if (keycc == keyalloc - 1)
1548	      keys = xrealloc (keys, keyalloc *= 2);
1549	  }
1550	if (fp != stdin)
1551	  fclose(fp);
1552	/* Append final newline if file ended in non-newline. */
1553	if (oldcc != keycc && keys[keycc - 1] != '\n')
1554	  keys[keycc++] = '\n';
1555	break;
1556
1557      case 'h':
1558	no_filenames = 1;
1559	break;
1560
1561      case 'i':
1562      case 'y':			/* For old-timers . . . */
1563	match_icase = 1;
1564	break;
1565
1566      case 'L':
1567	/* Like -l, except list files that don't contain matches.
1568	   Inspired by the same option in Hume's gre. */
1569	list_files = -1;
1570	break;
1571
1572      case 'l':
1573	list_files = 1;
1574	break;
1575
1576      case 'm':
1577	{
1578	  uintmax_t value;
1579	  switch (xstrtoumax (optarg, 0, 10, &value, ""))
1580	    {
1581	    case LONGINT_OK:
1582	      max_count = value;
1583	      if (0 <= max_count && max_count == value)
1584		break;
1585	      /* Fall through.  */
1586	    case LONGINT_OVERFLOW:
1587	      max_count = TYPE_MAXIMUM (off_t);
1588	      break;
1589
1590	    default:
1591	      error (2, 0, _("invalid max count"));
1592	    }
1593	}
1594	break;
1595
1596      case 'n':
1597	out_line = 1;
1598	break;
1599
1600      case 'o':
1601	only_matching = 1;
1602	break;
1603
1604      case 'q':
1605	exit_on_match = 1;
1606	close_stdout_set_status(0);
1607	break;
1608
1609      case 'R':
1610      case 'r':
1611	directories = RECURSE_DIRECTORIES;
1612	break;
1613
1614      case 's':
1615	suppress_errors = 1;
1616	break;
1617
1618      case 'v':
1619	out_invert = 1;
1620	break;
1621
1622      case 'w':
1623	match_words = 1;
1624	break;
1625
1626      case 'x':
1627	match_lines = 1;
1628	break;
1629
1630      case 'Z':
1631#if HAVE_LIBZ > 0
1632	if (BZflag)
1633	  {
1634	    printf (_("Cannot mix -J and -Z.\n"));
1635	    usage (2);
1636	  }
1637	Zflag = 1;
1638#else
1639	filename_mask = 0;
1640#endif
1641	break;
1642
1643      case 'z':
1644	eolbyte = '\0';
1645	break;
1646
1647      case BINARY_FILES_OPTION:
1648	if (strcmp (optarg, "binary") == 0)
1649	  binary_files = BINARY_BINARY_FILES;
1650	else if (strcmp (optarg, "text") == 0)
1651	  binary_files = TEXT_BINARY_FILES;
1652	else if (strcmp (optarg, "without-match") == 0)
1653	  binary_files = WITHOUT_MATCH_BINARY_FILES;
1654	else
1655	  error (2, 0, _("unknown binary-files type"));
1656	break;
1657
1658      case COLOR_OPTION:
1659        if(optarg) {
1660          if(!strcasecmp(optarg, "always") || !strcasecmp(optarg, "yes") ||
1661             !strcasecmp(optarg, "force"))
1662            color_option = 1;
1663          else if(!strcasecmp(optarg, "never") || !strcasecmp(optarg, "no") ||
1664                  !strcasecmp(optarg, "none"))
1665            color_option = 0;
1666          else if(!strcasecmp(optarg, "auto") || !strcasecmp(optarg, "tty") ||
1667                  !strcasecmp(optarg, "if-tty"))
1668            color_option = 2;
1669          else
1670            show_help = 1;
1671        } else
1672          color_option = 2;
1673        if(color_option == 2) {
1674          if(isatty(STDOUT_FILENO) && getenv("TERM") &&
1675	     strcmp(getenv("TERM"), "dumb"))
1676                  color_option = 1;
1677          else
1678            color_option = 0;
1679        }
1680	break;
1681
1682      case EXCLUDE_OPTION:
1683	if (!excluded_patterns)
1684	  excluded_patterns = new_exclude ();
1685	add_exclude (excluded_patterns, optarg);
1686	break;
1687
1688      case EXCLUDE_FROM_OPTION:
1689	if (!excluded_patterns)
1690	  excluded_patterns = new_exclude ();
1691        if (add_exclude_file (add_exclude, excluded_patterns, optarg, '\n')
1692	    != 0)
1693          {
1694            error (2, errno, "%s", optarg);
1695          }
1696        break;
1697
1698      case INCLUDE_OPTION:
1699	if (!included_patterns)
1700	  included_patterns = new_exclude ();
1701	add_exclude (included_patterns, optarg);
1702	break;
1703
1704      case LINE_BUFFERED_OPTION:
1705	line_buffered = 1;
1706	break;
1707
1708      case LABEL_OPTION:
1709	label = optarg;
1710	break;
1711
1712      case 0:
1713	/* long options */
1714	break;
1715
1716      default:
1717	usage (2);
1718	break;
1719
1720      }
1721
1722  /* POSIX.2 says that -q overrides -l, which in turn overrides the
1723     other output options.  */
1724  if (exit_on_match)
1725    list_files = 0;
1726  if (exit_on_match | list_files)
1727    {
1728      count_matches = 0;
1729      done_on_match = 1;
1730    }
1731  out_quiet = count_matches | done_on_match;
1732
1733  if (out_after < 0)
1734    out_after = default_context;
1735  if (out_before < 0)
1736    out_before = default_context;
1737
1738  if (color_option)
1739    {
1740      char *userval = getenv ("GREP_COLOR");
1741      if (userval != NULL && *userval != '\0')
1742	grep_color = userval;
1743    }
1744
1745  if (! matcher)
1746    matcher = program_name;
1747
1748  if (show_version)
1749    {
1750      printf (_("%s (GNU grep) %s\n"), matcher, VERSION);
1751      printf ("\n");
1752      printf (_("\
1753Copyright 1988, 1992-1999, 2000, 2001 Free Software Foundation, Inc.\n"));
1754      printf (_("\
1755This is free software; see the source for copying conditions. There is NO\n\
1756warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"));
1757      printf ("\n");
1758      exit (0);
1759    }
1760
1761  if (show_help)
1762    usage (0);
1763
1764  if (keys)
1765    {
1766      if (keycc == 0)
1767	{
1768	  /* No keys were specified (e.g. -f /dev/null).  Match nothing.  */
1769	  out_invert ^= 1;
1770	  match_lines = match_words = 0;
1771	}
1772      else
1773	/* Strip trailing newline. */
1774        --keycc;
1775    }
1776  else
1777    if (optind < argc)
1778      {
1779	keys = argv[optind++];
1780	keycc = strlen (keys);
1781      }
1782    else
1783      usage (2);
1784
1785  if (!install_matcher (matcher) && !install_matcher ("default"))
1786    abort ();
1787
1788#ifdef MBS_SUPPORT
1789  if (MB_CUR_MAX != 1 && match_icase)
1790    {
1791      wchar_t wc;
1792      mbstate_t cur_state, prev_state;
1793      int i, len = strlen(keys);
1794
1795      memset(&cur_state, 0, sizeof(mbstate_t));
1796      for (i = 0; i <= len ;)
1797	{
1798	  size_t mbclen;
1799	  mbclen = mbrtowc(&wc, keys + i, len - i, &cur_state);
1800	  if (mbclen == (size_t) -1 || mbclen == (size_t) -2 || mbclen == 0)
1801	    {
1802	      /* An invalid sequence, or a truncated multibyte character.
1803		 We treat it as a singlebyte character.  */
1804	      mbclen = 1;
1805	    }
1806	  else
1807	    {
1808	      if (iswupper((wint_t)wc))
1809		{
1810		  wc = towlower((wint_t)wc);
1811		  wcrtomb(keys + i, wc, &cur_state);
1812		}
1813	    }
1814	  i += mbclen;
1815	}
1816    }
1817#endif /* MBS_SUPPORT */
1818
1819  (*compile)(keys, keycc);
1820
1821  if ((argc - optind > 1 && !no_filenames) || with_filenames)
1822    out_file = 1;
1823
1824#ifdef SET_BINARY
1825  /* Output is set to binary mode because we shouldn't convert
1826     NL to CR-LF pairs, especially when grepping binary files.  */
1827  if (!isatty (1))
1828    SET_BINARY (1);
1829#endif
1830
1831  if (max_count == 0)
1832    exit (1);
1833
1834  if (optind < argc)
1835    {
1836	status = 1;
1837	do
1838	{
1839	  char *file = argv[optind];
1840	  if ((included_patterns || excluded_patterns)
1841	      && !isdir (file))
1842	    {
1843	      if (included_patterns &&
1844		  ! excluded_filename (included_patterns, file, 0))
1845		continue;
1846	      if (excluded_patterns &&
1847		  excluded_filename (excluded_patterns, file, 0))
1848		continue;
1849	    }
1850	  status &= grepfile (strcmp (file, "-") == 0 ? (char *) NULL : file,
1851			      &stats_base);
1852	}
1853	while ( ++optind < argc);
1854    }
1855  else
1856    status = grepfile ((char *) NULL, &stats_base);
1857
1858  /* We register via atexit() to test stdout.  */
1859  exit (errseen ? 2 : status);
1860}
1861/* vim:set shiftwidth=2: */
1862