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