grep.c revision 146199
155682Smarkm/* grep.c - main driver file for grep.
255682Smarkm   Copyright 1992, 1997-1999, 2000 Free Software Foundation, Inc.
355682Smarkm
455682Smarkm   This program is free software; you can redistribute it and/or modify
555682Smarkm   it under the terms of the GNU General Public License as published by
655682Smarkm   the Free Software Foundation; either version 2, or (at your option)
755682Smarkm   any later version.
855682Smarkm
955682Smarkm   This program is distributed in the hope that it will be useful,
1055682Smarkm   but WITHOUT ANY WARRANTY; without even the implied warranty of
1155682Smarkm   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1255682Smarkm   GNU General Public License for more details.
1355682Smarkm
1455682Smarkm   You should have received a copy of the GNU General Public License
1555682Smarkm   along with this program; if not, write to the Free Software
1655682Smarkm   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1755682Smarkm   02111-1307, USA.  */
1855682Smarkm
1955682Smarkm/* Written July 1992 by Mike Haertel.  */
2055682Smarkm/* Builtin decompression 1997 by Wolfram Schneider <wosch@FreeBSD.org>.  */
2155682Smarkm
2255682Smarkm/* $FreeBSD: head/gnu/usr.bin/grep/grep.c 146199 2005-05-14 03:02:22Z tjr $ */
2355682Smarkm
2455682Smarkm#ifdef HAVE_CONFIG_H
2555682Smarkm# include <config.h>
2655682Smarkm#endif
2755682Smarkm#include <sys/types.h>
2855682Smarkm#include <sys/stat.h>
2955682Smarkm#if defined(HAVE_MMAP)
3055682Smarkm# include <sys/mman.h>
3155682Smarkm#endif
3255682Smarkm#if defined(HAVE_SETRLIMIT)
3355682Smarkm# include <sys/time.h>
3455682Smarkm# include <sys/resource.h>
3555682Smarkm#endif
3655682Smarkm#if defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H && defined HAVE_MBRTOWC
3755682Smarkm/* We can handle multibyte string.  */
3855682Smarkm# define MBS_SUPPORT
3955682Smarkm# include <wchar.h>
4055682Smarkm# include <wctype.h>
41178825Sdfr#endif
4255682Smarkm#include <stdio.h>
43178825Sdfr#include "system.h"
44178825Sdfr#include "getopt.h"
4555682Smarkm#include "getpagesize.h"
4655682Smarkm#include "grep.h"
4755682Smarkm#include "savedir.h"
4855682Smarkm#include "xstrtol.h"
4955682Smarkm#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      if(match_icase)
635        {
636	  /* Yuck, this is tricky */
637          char *buf = (char*) xmalloc (lim - beg);
638	  char *ibeg = buf;
639	  char *ilim = ibeg + (lim - beg);
640	  int i;
641	  for (i = 0; i < lim - beg; i++)
642	    ibeg[i] = tolower (beg[i]);
643	  while ((match_offset = (*execute) (ibeg, ilim-ibeg, &match_size, 1))
644		 != (size_t) -1)
645	    {
646	      char const *b = beg + match_offset;
647	      if (b == lim)
648		break;
649	      fwrite (beg, sizeof (char), match_offset, stdout);
650	      printf ("\33[%sm", grep_color);
651	      fwrite (b, sizeof (char), match_size, stdout);
652	      fputs ("\33[00m", stdout);
653	      beg = b + match_size;
654	      ibeg = ibeg + match_offset + match_size;
655	    }
656	  fwrite (beg, 1, lim - beg, stdout);
657	  free (buf);
658	  lastout = lim;
659	  return;
660	}
661      while (lim-beg && (match_offset = (*execute) (beg, lim - beg, &match_size, 1))
662	     != (size_t) -1)
663	{
664	  char const *b = beg + match_offset;
665	  /* Avoid matching the empty line at the end of the buffer. */
666	  if (b == lim)
667	    break;
668	  /* Avoid hanging on grep --color "" foo */
669	  if (match_size == 0)
670	    break;
671	  fwrite (beg, sizeof (char), match_offset, stdout);
672	  printf ("\33[%sm", grep_color);
673	  fwrite (b, sizeof (char), match_size, stdout);
674	  fputs ("\33[00m", stdout);
675	  beg = b + match_size;
676	}
677    }
678  fwrite (beg, 1, lim - beg, stdout);
679  if (ferror (stdout))
680    error (0, errno, _("writing output"));
681  lastout = lim;
682  if (line_buffered)
683    fflush (stdout);
684}
685
686/* Print pending lines of trailing context prior to LIM. Trailing context ends
687   at the next matching line when OUTLEFT is 0.  */
688static void
689prpending (char const *lim)
690{
691  if (!lastout)
692    lastout = bufbeg;
693  while (pending > 0 && lastout < lim)
694    {
695      char const *nl = memchr (lastout, eolbyte, lim - lastout);
696      size_t match_size;
697      --pending;
698      if (outleft
699	  || (((*execute) (lastout, nl - lastout, &match_size, 0) == (size_t) -1)
700	      == !out_invert))
701	prline (lastout, nl + 1, '-');
702      else
703	pending = 0;
704    }
705}
706
707/* Print the lines between BEG and LIM.  Deal with context crap.
708   If NLINESP is non-null, store a count of lines between BEG and LIM.  */
709static void
710prtext (char const *beg, char const *lim, int *nlinesp)
711{
712  static int used;		/* avoid printing "--" before any output */
713  char const *bp, *p;
714  char eol = eolbyte;
715  int i, n;
716
717  if (!out_quiet && pending > 0)
718    prpending (beg);
719
720  p = beg;
721
722  if (!out_quiet)
723    {
724      /* Deal with leading context crap. */
725
726      bp = lastout ? lastout : bufbeg;
727      for (i = 0; i < out_before; ++i)
728	if (p > bp)
729	  do
730	    --p;
731	  while (p[-1] != eol);
732
733      /* We only print the "--" separator if our output is
734	 discontiguous from the last output in the file. */
735      if ((out_before || out_after) && used && p != lastout)
736	puts ("--");
737
738      while (p < beg)
739	{
740	  char const *nl = memchr (p, eol, beg - p);
741	  nl++;
742	  prline (p, nl, '-');
743	  p = nl;
744	}
745    }
746
747  if (nlinesp)
748    {
749      /* Caller wants a line count. */
750      for (n = 0; p < lim && n < outleft; n++)
751	{
752	  char const *nl = memchr (p, eol, lim - p);
753	  nl++;
754	  if (!out_quiet)
755	    prline (p, nl, ':');
756	  p = nl;
757	}
758      *nlinesp = n;
759
760      /* relying on it that this function is never called when outleft = 0.  */
761      after_last_match = bufoffset - (buflim - p);
762    }
763  else
764    if (!out_quiet)
765      prline (beg, lim, ':');
766
767  pending = out_quiet ? 0 : out_after;
768  used = 1;
769}
770
771/* Scan the specified portion of the buffer, matching lines (or
772   between matching lines if OUT_INVERT is true).  Return a count of
773   lines printed. */
774static int
775grepbuf (char const *beg, char const *lim)
776{
777  int nlines, n;
778  register char const *p;
779  size_t match_offset;
780  size_t match_size;
781
782  nlines = 0;
783  p = beg;
784  while ((match_offset = (*execute) (p, lim - p, &match_size, 0)) != (size_t) -1)
785    {
786      char const *b = p + match_offset;
787      char const *endp = b + match_size;
788      /* Avoid matching the empty line at the end of the buffer. */
789      if (b == lim)
790	break;
791      if (!out_invert)
792	{
793	  prtext (b, endp, (int *) 0);
794	  nlines++;
795          outleft--;
796	  if (!outleft || done_on_match)
797	    {
798	      if (exit_on_match)
799		exit (0);
800	      after_last_match = bufoffset - (buflim - endp);
801	      return nlines;
802	    }
803	}
804      else if (p < b)
805	{
806	  prtext (p, b, &n);
807	  nlines += n;
808          outleft -= n;
809	  if (!outleft)
810	    return nlines;
811	}
812      p = endp;
813    }
814  if (out_invert && p < lim)
815    {
816      prtext (p, lim, &n);
817      nlines += n;
818      outleft -= n;
819    }
820  return nlines;
821}
822
823/* Search a given file.  Normally, return a count of lines printed;
824   but if the file is a directory and we search it recursively, then
825   return -2 if there was a match, and -1 otherwise.  */
826static int
827grep (int fd, char const *file, struct stats *stats)
828{
829  int nlines, i;
830  int not_text;
831  size_t residue, save;
832  char oldc;
833  char *beg;
834  char *lim;
835  char eol = eolbyte;
836
837  if (!reset (fd, file, stats))
838    return 0;
839
840  if (file && directories == RECURSE_DIRECTORIES
841      && S_ISDIR (stats->stat.st_mode))
842    {
843      /* Close fd now, so that we don't open a lot of file descriptors
844	 when we recurse deeply.  */
845      if (BZflag && bzbufdesc)
846	BZ2_bzclose(bzbufdesc);
847      else
848#if HAVE_LIBZ > 0
849      if (Zflag)
850	gzclose(gzbufdesc);
851      else
852#endif
853      if (close (fd) != 0)
854	error (0, errno, "%s", file);
855      return grepdir (file, stats) - 2;
856    }
857
858  totalcc = 0;
859  lastout = 0;
860  totalnl = 0;
861  outleft = max_count;
862  after_last_match = 0;
863  pending = 0;
864
865  nlines = 0;
866  residue = 0;
867  save = 0;
868
869  if (! fillbuf (save, stats))
870    {
871      if (! is_EISDIR (errno, file))
872	suppressible_error (filename, errno);
873      return 0;
874    }
875
876  not_text = (((binary_files == BINARY_BINARY_FILES && !out_quiet)
877	       || binary_files == WITHOUT_MATCH_BINARY_FILES)
878	      && memchr (bufbeg, eol ? '\0' : '\200', buflim - bufbeg));
879  if (not_text && binary_files == WITHOUT_MATCH_BINARY_FILES)
880    return 0;
881  done_on_match += not_text;
882  out_quiet += not_text;
883
884  for (;;)
885    {
886      lastnl = bufbeg;
887      if (lastout)
888	lastout = bufbeg;
889
890      beg = bufbeg + save;
891
892      /* no more data to scan (eof) except for maybe a residue -> break */
893      if (beg == buflim)
894	break;
895
896      /* Determine new residue (the length of an incomplete line at the end of
897         the buffer, 0 means there is no incomplete last line).  */
898      oldc = beg[-1];
899      beg[-1] = eol;
900      for (lim = buflim; lim[-1] != eol; lim--)
901	continue;
902      beg[-1] = oldc;
903      if (lim == beg)
904	lim = beg - residue;
905      beg -= residue;
906      residue = buflim - lim;
907
908      if (beg < lim)
909	{
910	  if (outleft)
911	    nlines += grepbuf (beg, lim);
912	  if (pending)
913	    prpending (lim);
914	  if((!outleft && !pending) || (nlines && done_on_match && !out_invert))
915	    goto finish_grep;
916	}
917
918      /* The last OUT_BEFORE lines at the end of the buffer will be needed as
919	 leading context if there is a matching line at the begin of the
920	 next data. Make beg point to their begin.  */
921      i = 0;
922      beg = lim;
923      while (i < out_before && beg > bufbeg && beg != lastout)
924	{
925	  ++i;
926	  do
927	    --beg;
928	  while (beg[-1] != eol);
929	}
930
931      /* detect if leading context is discontinuous from last printed line.  */
932      if (beg != lastout)
933	lastout = 0;
934
935      /* Handle some details and read more data to scan.  */
936      save = residue + lim - beg;
937      if (out_byte)
938	totalcc = add_count (totalcc, buflim - bufbeg - save);
939      if (out_line)
940	nlscan (beg);
941      if (! fillbuf (save, stats))
942	{
943	  if (! is_EISDIR (errno, file))
944	    suppressible_error (filename, errno);
945	  goto finish_grep;
946	}
947    }
948  if (residue)
949    {
950      *buflim++ = eol;
951      if (outleft)
952	nlines += grepbuf (bufbeg + save - residue, buflim);
953      if (pending)
954        prpending (buflim);
955    }
956
957 finish_grep:
958  done_on_match -= not_text;
959  out_quiet -= not_text;
960  if ((not_text & ~out_quiet) && nlines != 0)
961    printf (_("Binary file %s matches\n"), filename);
962  return nlines;
963}
964
965static int
966grepfile (char const *file, struct stats *stats)
967{
968  int desc;
969  int count;
970  int status;
971
972  if (! file)
973    {
974      desc = 0;
975      filename = label ? label : _("(standard input)");
976    }
977  else
978    {
979      while ((desc = open (file, O_RDONLY)) < 0 && errno == EINTR)
980	continue;
981
982      if (desc < 0)
983	{
984	  int e = errno;
985
986	  if (is_EISDIR (e, file) && directories == RECURSE_DIRECTORIES)
987	    {
988	      if (stat (file, &stats->stat) != 0)
989		{
990		  error (0, errno, "%s", file);
991		  return 1;
992		}
993
994	      return grepdir (file, stats);
995	    }
996
997	  if (!suppress_errors)
998	    {
999	      if (directories == SKIP_DIRECTORIES)
1000		switch (e)
1001		  {
1002#if defined(EISDIR)
1003		  case EISDIR:
1004		    return 1;
1005#endif
1006		  case EACCES:
1007		    /* When skipping directories, don't worry about
1008		       directories that can't be opened.  */
1009		    if (isdir (file))
1010		      return 1;
1011		    break;
1012		  }
1013	    }
1014
1015	  suppressible_error (file, e);
1016	  return 1;
1017	}
1018
1019      filename = file;
1020    }
1021
1022#if defined(SET_BINARY)
1023  /* Set input to binary mode.  Pipes are simulated with files
1024     on DOS, so this includes the case of "foo | grep bar".  */
1025  if (!isatty (desc))
1026    SET_BINARY (desc);
1027#endif
1028
1029  count = grep (desc, file, stats);
1030  if (count < 0)
1031    status = count + 2;
1032  else
1033    {
1034      if (count_matches)
1035	{
1036	  if (out_file)
1037	    printf ("%s%c", filename, ':' & filename_mask);
1038	  printf ("%d\n", count);
1039	}
1040
1041      status = !count;
1042      if (list_files == 1 - 2 * status)
1043	printf ("%s%c", filename, '\n' & filename_mask);
1044
1045      if (BZflag && bzbufdesc)
1046	BZ2_bzclose(bzbufdesc);
1047      else
1048#if HAVE_LIBZ > 0
1049      if (Zflag)
1050	gzclose(gzbufdesc);
1051      else
1052#endif
1053      if (! file)
1054	{
1055	  off_t required_offset = outleft ? bufoffset : after_last_match;
1056	  if ((bufmapped || required_offset != bufoffset)
1057	      && lseek (desc, required_offset, SEEK_SET) < 0
1058	      && S_ISREG (stats->stat.st_mode))
1059	    error (0, errno, "%s", filename);
1060	}
1061      else
1062	while (close (desc) != 0)
1063	  if (errno != EINTR)
1064	    {
1065	      error (0, errno, "%s", file);
1066	      break;
1067	    }
1068    }
1069
1070  return status;
1071}
1072
1073static int
1074grepdir (char const *dir, struct stats const *stats)
1075{
1076  int status = 1;
1077  struct stats const *ancestor;
1078  char *name_space;
1079
1080  /* Mingw32 does not support st_ino.  No known working hosts use zero
1081     for st_ino, so assume that the Mingw32 bug applies if it's zero.  */
1082  if (stats->stat.st_ino)
1083    for (ancestor = stats;  (ancestor = ancestor->parent) != 0;  )
1084      if (ancestor->stat.st_ino == stats->stat.st_ino
1085	  && ancestor->stat.st_dev == stats->stat.st_dev)
1086	{
1087	  if (!suppress_errors)
1088	    error (0, 0, _("warning: %s: %s"), dir,
1089		   _("recursive directory loop"));
1090	  return 1;
1091	}
1092
1093  name_space = savedir (dir, stats->stat.st_size, included_patterns,
1094			excluded_patterns);
1095
1096  if (! name_space)
1097    {
1098      if (errno)
1099	suppressible_error (dir, errno);
1100      else
1101	xalloc_die ();
1102    }
1103  else
1104    {
1105      size_t dirlen = strlen (dir);
1106      int needs_slash = ! (dirlen == FILESYSTEM_PREFIX_LEN (dir)
1107			   || IS_SLASH (dir[dirlen - 1]));
1108      char *file = NULL;
1109      char const *namep = name_space;
1110      struct stats child;
1111      child.parent = stats;
1112      out_file += !no_filenames;
1113      while (*namep)
1114	{
1115	  size_t namelen = strlen (namep);
1116	  file = xrealloc (file, dirlen + 1 + namelen + 1);
1117	  strcpy (file, dir);
1118	  file[dirlen] = '/';
1119	  strcpy (file + dirlen + needs_slash, namep);
1120	  namep += namelen + 1;
1121	  status &= grepfile (file, &child);
1122	}
1123      out_file -= !no_filenames;
1124      if (file)
1125        free (file);
1126      free (name_space);
1127    }
1128
1129  return status;
1130}
1131
1132static void
1133usage (int status)
1134{
1135  if (status != 0)
1136    {
1137      fprintf (stderr, _("Usage: %s [OPTION]... PATTERN [FILE]...\n"),
1138	       program_name);
1139      fprintf (stderr, _("Try `%s --help' for more information.\n"),
1140	       program_name);
1141    }
1142  else
1143    {
1144      printf (_("Usage: %s [OPTION]... PATTERN [FILE] ...\n"), program_name);
1145      printf (_("\
1146Search for PATTERN in each FILE or standard input.\n\
1147Example: %s -i 'hello world' menu.h main.c\n\
1148\n\
1149Regexp selection and interpretation:\n"), program_name);
1150      printf (_("\
1151  -E, --extended-regexp     PATTERN is an extended regular expression\n\
1152  -F, --fixed-strings       PATTERN is a set of newline-separated strings\n\
1153  -G, --basic-regexp        PATTERN is a basic regular expression\n\
1154  -P, --perl-regexp         PATTERN is a Perl regular expression\n"));
1155      printf (_("\
1156  -e, --regexp=PATTERN      use PATTERN as a regular expression\n\
1157  -f, --file=FILE           obtain PATTERN from FILE\n\
1158  -i, --ignore-case         ignore case distinctions\n\
1159  -w, --word-regexp         force PATTERN to match only whole words\n\
1160  -x, --line-regexp         force PATTERN to match only whole lines\n\
1161  -z, --null-data           a data line ends in 0 byte, not newline\n"));
1162      printf (_("\
1163\n\
1164Miscellaneous:\n\
1165  -s, --no-messages         suppress error messages\n\
1166  -v, --invert-match        select non-matching lines\n\
1167  -V, --version             print version information and exit\n\
1168      --help                display this help and exit\n\
1169  -J, --bz2decompress       decompress bzip2'ed input before searching\n\
1170  -Z, --decompress          decompress input before searching (HAVE_LIBZ=1)\n\
1171      --mmap                use memory-mapped input if possible\n"));
1172      printf (_("\
1173\n\
1174Output control:\n\
1175  -m, --max-count=NUM       stop after NUM matches\n\
1176  -b, --byte-offset         print the byte offset with output lines\n\
1177  -n, --line-number         print line number with output lines\n\
1178      --line-buffered       flush output on every line\n\
1179  -H, --with-filename       print the filename for each match\n\
1180  -h, --no-filename         suppress the prefixing filename on output\n\
1181      --label=LABEL         print LABEL as filename for standard input\n\
1182  -o, --only-matching       show only the part of a line matching PATTERN\n\
1183  -q, --quiet, --silent     suppress all normal output\n\
1184      --binary-files=TYPE   assume that binary files are TYPE\n\
1185                            TYPE is 'binary', 'text', or 'without-match'\n\
1186  -a, --text                equivalent to --binary-files=text\n\
1187  -I                        equivalent to --binary-files=without-match\n\
1188  -d, --directories=ACTION  how to handle directories\n\
1189                            ACTION is 'read', 'recurse', or 'skip'\n\
1190  -D, --devices=ACTION      how to handle devices, FIFOs and sockets\n\
1191                            ACTION is 'read' or 'skip'\n\
1192  -R, -r, --recursive       equivalent to --directories=recurse\n\
1193      --include=PATTERN     files that match PATTERN will be examined\n\
1194      --exclude=PATTERN     files that match PATTERN will be skipped.\n\
1195      --exclude-from=FILE   files that match PATTERN in FILE will be skipped.\n\
1196  -L, --files-without-match only print FILE names containing no match\n\
1197  -l, --files-with-matches  only print FILE names containing matches\n\
1198  -c, --count               only print a count of matching lines per FILE\n\
1199      --null                print 0 byte after FILE name\n"));
1200      printf (_("\
1201\n\
1202Context control:\n\
1203  -B, --before-context=NUM  print NUM lines of leading context\n\
1204  -A, --after-context=NUM   print NUM lines of trailing context\n\
1205  -C, --context=NUM         print NUM lines of output context\n\
1206  -NUM                      same as --context=NUM\n\
1207      --color[=WHEN],\n\
1208      --colour[=WHEN]       use markers to distinguish the matching string\n\
1209                            WHEN may be `always', `never' or `auto'.\n\
1210  -U, --binary              do not strip CR characters at EOL (MSDOS)\n\
1211  -u, --unix-byte-offsets   report offsets as if CRs were not there (MSDOS)\n\
1212\n\
1213`egrep' means `grep -E'.  `fgrep' means `grep -F'.\n\
1214With no FILE, or when FILE is -, read standard input.  If less than\n\
1215two FILEs given, assume -h.  Exit status is 0 if match, 1 if no match,\n\
1216and 2 if trouble.\n"));
1217      printf (_("\nReport bugs to <bug-gnu-utils@gnu.org>.\n"));
1218    }
1219  exit (status);
1220}
1221
1222/* Set the matcher to M, reporting any conflicts.  */
1223static void
1224setmatcher (char const *m)
1225{
1226  if (matcher && strcmp (matcher, m) != 0)
1227    error (2, 0, _("conflicting matchers specified"));
1228  matcher = m;
1229}
1230
1231/* Go through the matchers vector and look for the specified matcher.
1232   If we find it, install it in compile and execute, and return 1.  */
1233static int
1234install_matcher (char const *name)
1235{
1236  int i;
1237#if defined(HAVE_SETRLIMIT)
1238  struct rlimit rlim;
1239#endif
1240
1241  for (i = 0; matchers[i].compile; i++)
1242    if (strcmp (name, matchers[i].name) == 0)
1243      {
1244	compile = matchers[i].compile;
1245	execute = matchers[i].execute;
1246#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_STACK)
1247	/* I think every platform needs to do this, so that regex.c
1248	   doesn't oveflow the stack.  The default value of
1249	   `re_max_failures' is too large for some platforms: it needs
1250	   more than 3MB-large stack.
1251
1252	   The test for HAVE_SETRLIMIT should go into `configure'.  */
1253	if (!getrlimit (RLIMIT_STACK, &rlim))
1254	  {
1255	    long newlim;
1256	    extern long int re_max_failures; /* from regex.c */
1257
1258	    /* Approximate the amount regex.c needs, plus some more.  */
1259	    newlim = re_max_failures * 2 * 20 * sizeof (char *);
1260	    if (newlim > rlim.rlim_max)
1261	      {
1262		newlim = rlim.rlim_max;
1263		re_max_failures = newlim / (2 * 20 * sizeof (char *));
1264	      }
1265	    if (rlim.rlim_cur < newlim)
1266	      {
1267		rlim.rlim_cur = newlim;
1268		setrlimit (RLIMIT_STACK, &rlim);
1269	      }
1270	  }
1271#endif
1272	return 1;
1273      }
1274  return 0;
1275}
1276
1277/* Find the white-space-separated options specified by OPTIONS, and
1278   using BUF to store copies of these options, set ARGV[0], ARGV[1],
1279   etc. to the option copies.  Return the number N of options found.
1280   Do not set ARGV[N] to NULL.  If ARGV is NULL, do not store ARGV[0]
1281   etc.  Backslash can be used to escape whitespace (and backslashes).  */
1282static int
1283prepend_args (char const *options, char *buf, char **argv)
1284{
1285  char const *o = options;
1286  char *b = buf;
1287  int n = 0;
1288
1289  for (;;)
1290    {
1291      while (ISSPACE ((unsigned char) *o))
1292	o++;
1293      if (!*o)
1294	return n;
1295      if (argv)
1296	argv[n] = b;
1297      n++;
1298
1299      do
1300	if ((*b++ = *o++) == '\\' && *o)
1301	  b[-1] = *o++;
1302      while (*o && ! ISSPACE ((unsigned char) *o));
1303
1304      *b++ = '\0';
1305    }
1306}
1307
1308/* Prepend the whitespace-separated options in OPTIONS to the argument
1309   vector of a main program with argument count *PARGC and argument
1310   vector *PARGV.  */
1311static void
1312prepend_default_options (char const *options, int *pargc, char ***pargv)
1313{
1314  if (options)
1315    {
1316      char *buf = xmalloc (strlen (options) + 1);
1317      int prepended = prepend_args (options, buf, (char **) NULL);
1318      int argc = *pargc;
1319      char * const *argv = *pargv;
1320      char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp);
1321      *pargc = prepended + argc;
1322      *pargv = pp;
1323      *pp++ = *argv++;
1324      pp += prepend_args (options, buf, pp);
1325      while ((*pp++ = *argv++))
1326	continue;
1327    }
1328}
1329
1330/* Get the next non-digit option from ARGC and ARGV.
1331   Return -1 if there are no more options.
1332   Process any digit options that were encountered on the way,
1333   and store the resulting integer into *DEFAULT_CONTEXT.  */
1334static int
1335get_nondigit_option (int argc, char *const *argv, int *default_context)
1336{
1337  int opt;
1338  char buf[sizeof (uintmax_t) * CHAR_BIT + 4];
1339  char *p = buf;
1340
1341  /* Set buf[0] to anything but '0', for the leading-zero test below.  */
1342  buf[0] = '\0';
1343
1344  while (opt = getopt_long (argc, argv, short_options, long_options, NULL),
1345	 '0' <= opt && opt <= '9')
1346    {
1347      /* Suppress trivial leading zeros, to avoid incorrect
1348	 diagnostic on strings like 00000000000.  */
1349      p -= buf[0] == '0';
1350
1351      *p++ = opt;
1352      if (p == buf + sizeof buf - 4)
1353	{
1354	  /* Too many digits.  Append "..." to make context_length_arg
1355	     complain about "X...", where X contains the digits seen
1356	     so far.  */
1357	  strcpy (p, "...");
1358	  p += 3;
1359	  break;
1360	}
1361    }
1362  if (p != buf)
1363    {
1364      *p = '\0';
1365      context_length_arg (buf, default_context);
1366    }
1367
1368  return opt;
1369}
1370
1371int
1372main (int argc, char **argv)
1373{
1374  char *keys;
1375  size_t keycc, oldcc, keyalloc;
1376  int with_filenames;
1377  int opt, cc, status;
1378  int default_context;
1379  FILE *fp;
1380  extern char *optarg;
1381  extern int optind;
1382
1383  initialize_main (&argc, &argv);
1384  program_name = argv[0];
1385  if (program_name && strrchr (program_name, '/'))
1386    program_name = strrchr (program_name, '/') + 1;
1387
1388#if HAVE_LIBZ > 0
1389  if (program_name[0] == 'z') {
1390    Zflag = 1;
1391    ++program_name;
1392  }
1393#endif
1394  if (program_name[0] == 'b') {
1395    BZflag = 1;
1396    ++program_name;
1397  }
1398
1399#if defined(__MSDOS__) || defined(_WIN32)
1400  /* DOS and MS-Windows use backslashes as directory separators, and usually
1401     have an .exe suffix.  They also have case-insensitive filesystems.  */
1402  if (program_name)
1403    {
1404      char *p = program_name;
1405      char *bslash = strrchr (argv[0], '\\');
1406
1407      if (bslash && bslash >= program_name) /* for mixed forward/backslash case */
1408	program_name = bslash + 1;
1409      else if (program_name == argv[0]
1410	       && argv[0][0] && argv[0][1] == ':') /* "c:progname" */
1411	program_name = argv[0] + 2;
1412
1413      /* Collapse the letter-case, so `strcmp' could be used hence.  */
1414      for ( ; *p; p++)
1415	if (*p >= 'A' && *p <= 'Z')
1416	  *p += 'a' - 'A';
1417
1418      /* Remove the .exe extension, if any.  */
1419      if ((p = strrchr (program_name, '.')) && strcmp (p, ".exe") == 0)
1420	*p = '\0';
1421    }
1422#endif
1423
1424  keys = NULL;
1425  keycc = 0;
1426  with_filenames = 0;
1427  eolbyte = '\n';
1428  filename_mask = ~0;
1429
1430  max_count = TYPE_MAXIMUM (off_t);
1431
1432  /* The value -1 means to use DEFAULT_CONTEXT. */
1433  out_after = out_before = -1;
1434  /* Default before/after context: chaged by -C/-NUM options */
1435  default_context = 0;
1436  /* Changed by -o option */
1437  only_matching = 0;
1438
1439  /* Internationalization. */
1440#if defined(HAVE_SETLOCALE)
1441  setlocale (LC_ALL, "");
1442#endif
1443#if defined(ENABLE_NLS)
1444  bindtextdomain (PACKAGE, LOCALEDIR);
1445  textdomain (PACKAGE);
1446#endif
1447
1448  atexit (close_stdout);
1449
1450  prepend_default_options (getenv ("GREP_OPTIONS"), &argc, &argv);
1451
1452  while ((opt = get_nondigit_option (argc, argv, &default_context)) != -1)
1453    switch (opt)
1454      {
1455      case 'A':
1456	context_length_arg (optarg, &out_after);
1457	break;
1458
1459      case 'B':
1460	context_length_arg (optarg, &out_before);
1461	break;
1462
1463      case 'C':
1464	/* Set output match context, but let any explicit leading or
1465	   trailing amount specified with -A or -B stand. */
1466	context_length_arg (optarg, &default_context);
1467	break;
1468
1469      case 'D':
1470	if (strcmp (optarg, "read") == 0)
1471	  devices = READ_DEVICES;
1472	else if (strcmp (optarg, "skip") == 0)
1473	  devices = SKIP_DEVICES;
1474	else
1475	  error (2, 0, _("unknown devices method"));
1476	break;
1477
1478      case 'E':
1479	setmatcher ("egrep");
1480	break;
1481
1482      case 'F':
1483	setmatcher ("fgrep");
1484	break;
1485
1486      case 'P':
1487	setmatcher ("perl");
1488	break;
1489
1490      case 'G':
1491	setmatcher ("grep");
1492	break;
1493
1494      case 'H':
1495	with_filenames = 1;
1496	break;
1497
1498      case 'I':
1499	binary_files = WITHOUT_MATCH_BINARY_FILES;
1500	break;
1501      case 'J':
1502	if (Zflag)
1503	  {
1504	    printf (_("Cannot mix -Z and -J.\n"));
1505	    usage (2);
1506	  }
1507	BZflag = 1;
1508	break;
1509
1510      case 'U':
1511#if defined(HAVE_DOS_FILE_CONTENTS)
1512	dos_use_file_type = DOS_BINARY;
1513#endif
1514	break;
1515
1516      case 'u':
1517#if defined(HAVE_DOS_FILE_CONTENTS)
1518	dos_report_unix_offset = 1;
1519#endif
1520	break;
1521
1522      case 'V':
1523	show_version = 1;
1524	break;
1525
1526      case 'X':
1527	setmatcher (optarg);
1528	break;
1529
1530      case 'a':
1531	binary_files = TEXT_BINARY_FILES;
1532	break;
1533
1534      case 'b':
1535	out_byte = 1;
1536	break;
1537
1538      case 'c':
1539	count_matches = 1;
1540	break;
1541
1542      case 'd':
1543	if (strcmp (optarg, "read") == 0)
1544	  directories = READ_DIRECTORIES;
1545	else if (strcmp (optarg, "skip") == 0)
1546	  directories = SKIP_DIRECTORIES;
1547	else if (strcmp (optarg, "recurse") == 0)
1548	  directories = RECURSE_DIRECTORIES;
1549	else
1550	  error (2, 0, _("unknown directories method"));
1551	break;
1552
1553      case 'e':
1554	cc = strlen (optarg);
1555	keys = xrealloc (keys, keycc + cc + 1);
1556	strcpy (&keys[keycc], optarg);
1557	keycc += cc;
1558	keys[keycc++] = '\n';
1559	break;
1560
1561      case 'f':
1562	fp = strcmp (optarg, "-") != 0 ? fopen (optarg, "r") : stdin;
1563	if (!fp)
1564	  error (2, errno, "%s", optarg);
1565	for (keyalloc = 1; keyalloc <= keycc + 1; keyalloc *= 2)
1566	  ;
1567	keys = xrealloc (keys, keyalloc);
1568	oldcc = keycc;
1569	while (!feof (fp)
1570	       && (cc = fread (keys + keycc, 1, keyalloc - 1 - keycc, fp)) > 0)
1571	  {
1572	    keycc += cc;
1573	    if (keycc == keyalloc - 1)
1574	      keys = xrealloc (keys, keyalloc *= 2);
1575	  }
1576	if (fp != stdin)
1577	  fclose(fp);
1578	/* Append final newline if file ended in non-newline. */
1579	if (oldcc != keycc && keys[keycc - 1] != '\n')
1580	  keys[keycc++] = '\n';
1581	break;
1582
1583      case 'h':
1584	no_filenames = 1;
1585	break;
1586
1587      case 'i':
1588      case 'y':			/* For old-timers . . . */
1589	match_icase = 1;
1590	break;
1591
1592      case 'L':
1593	/* Like -l, except list files that don't contain matches.
1594	   Inspired by the same option in Hume's gre. */
1595	list_files = -1;
1596	break;
1597
1598      case 'l':
1599	list_files = 1;
1600	break;
1601
1602      case 'm':
1603	{
1604	  uintmax_t value;
1605	  switch (xstrtoumax (optarg, 0, 10, &value, ""))
1606	    {
1607	    case LONGINT_OK:
1608	      max_count = value;
1609	      if (0 <= max_count && max_count == value)
1610		break;
1611	      /* Fall through.  */
1612	    case LONGINT_OVERFLOW:
1613	      max_count = TYPE_MAXIMUM (off_t);
1614	      break;
1615
1616	    default:
1617	      error (2, 0, _("invalid max count"));
1618	    }
1619	}
1620	break;
1621
1622      case 'n':
1623	out_line = 1;
1624	break;
1625
1626      case 'o':
1627	only_matching = 1;
1628	break;
1629
1630      case 'q':
1631	exit_on_match = 1;
1632	close_stdout_set_status(0);
1633	break;
1634
1635      case 'R':
1636      case 'r':
1637	directories = RECURSE_DIRECTORIES;
1638	break;
1639
1640      case 's':
1641	suppress_errors = 1;
1642	break;
1643
1644      case 'v':
1645	out_invert = 1;
1646	break;
1647
1648      case 'w':
1649	match_words = 1;
1650	break;
1651
1652      case 'x':
1653	match_lines = 1;
1654	break;
1655
1656      case 'Z':
1657#if HAVE_LIBZ > 0
1658	if (BZflag)
1659	  {
1660	    printf (_("Cannot mix -J and -Z.\n"));
1661	    usage (2);
1662	  }
1663	Zflag = 1;
1664#else
1665	filename_mask = 0;
1666#endif
1667	break;
1668
1669      case 'z':
1670	eolbyte = '\0';
1671	break;
1672
1673      case BINARY_FILES_OPTION:
1674	if (strcmp (optarg, "binary") == 0)
1675	  binary_files = BINARY_BINARY_FILES;
1676	else if (strcmp (optarg, "text") == 0)
1677	  binary_files = TEXT_BINARY_FILES;
1678	else if (strcmp (optarg, "without-match") == 0)
1679	  binary_files = WITHOUT_MATCH_BINARY_FILES;
1680	else
1681	  error (2, 0, _("unknown binary-files type"));
1682	break;
1683
1684      case COLOR_OPTION:
1685        if(optarg) {
1686          if(!strcasecmp(optarg, "always") || !strcasecmp(optarg, "yes") ||
1687             !strcasecmp(optarg, "force"))
1688            color_option = 1;
1689          else if(!strcasecmp(optarg, "never") || !strcasecmp(optarg, "no") ||
1690                  !strcasecmp(optarg, "none"))
1691            color_option = 0;
1692          else if(!strcasecmp(optarg, "auto") || !strcasecmp(optarg, "tty") ||
1693                  !strcasecmp(optarg, "if-tty"))
1694            color_option = 2;
1695          else
1696            show_help = 1;
1697        } else
1698          color_option = 2;
1699        if(color_option == 2) {
1700          if(isatty(STDOUT_FILENO) && getenv("TERM") &&
1701	     strcmp(getenv("TERM"), "dumb"))
1702                  color_option = 1;
1703          else
1704            color_option = 0;
1705        }
1706	break;
1707
1708      case EXCLUDE_OPTION:
1709	if (!excluded_patterns)
1710	  excluded_patterns = new_exclude ();
1711	add_exclude (excluded_patterns, optarg);
1712	break;
1713
1714      case EXCLUDE_FROM_OPTION:
1715	if (!excluded_patterns)
1716	  excluded_patterns = new_exclude ();
1717        if (add_exclude_file (add_exclude, excluded_patterns, optarg, '\n')
1718	    != 0)
1719          {
1720            error (2, errno, "%s", optarg);
1721          }
1722        break;
1723
1724      case INCLUDE_OPTION:
1725	if (!included_patterns)
1726	  included_patterns = new_exclude ();
1727	add_exclude (included_patterns, optarg);
1728	break;
1729
1730      case LINE_BUFFERED_OPTION:
1731	line_buffered = 1;
1732	break;
1733
1734      case LABEL_OPTION:
1735	label = optarg;
1736	break;
1737
1738      case 0:
1739	/* long options */
1740	break;
1741
1742      default:
1743	usage (2);
1744	break;
1745
1746      }
1747
1748  /* POSIX.2 says that -q overrides -l, which in turn overrides the
1749     other output options.  */
1750  if (exit_on_match)
1751    list_files = 0;
1752  if (exit_on_match | list_files)
1753    {
1754      count_matches = 0;
1755      done_on_match = 1;
1756    }
1757  out_quiet = count_matches | done_on_match;
1758
1759  if (out_after < 0)
1760    out_after = default_context;
1761  if (out_before < 0)
1762    out_before = default_context;
1763
1764  if (color_option)
1765    {
1766      char *userval = getenv ("GREP_COLOR");
1767      if (userval != NULL && *userval != '\0')
1768	grep_color = userval;
1769    }
1770
1771  if (! matcher)
1772    matcher = program_name;
1773
1774  if (show_version)
1775    {
1776      printf (_("%s (GNU grep) %s\n"), matcher, VERSION);
1777      printf ("\n");
1778      printf (_("\
1779Copyright 1988, 1992-1999, 2000, 2001 Free Software Foundation, Inc.\n"));
1780      printf (_("\
1781This is free software; see the source for copying conditions. There is NO\n\
1782warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"));
1783      printf ("\n");
1784      exit (0);
1785    }
1786
1787  if (show_help)
1788    usage (0);
1789
1790  if (keys)
1791    {
1792      if (keycc == 0)
1793	{
1794	  /* No keys were specified (e.g. -f /dev/null).  Match nothing.  */
1795	  out_invert ^= 1;
1796	  match_lines = match_words = 0;
1797	}
1798      else
1799	/* Strip trailing newline. */
1800        --keycc;
1801    }
1802  else
1803    if (optind < argc)
1804      {
1805	keys = argv[optind++];
1806	keycc = strlen (keys);
1807      }
1808    else
1809      usage (2);
1810
1811  if (!install_matcher (matcher) && !install_matcher ("default"))
1812    abort ();
1813
1814#ifdef MBS_SUPPORT
1815  if (MB_CUR_MAX != 1 && match_icase)
1816    {
1817      wchar_t wc;
1818      mbstate_t cur_state, prev_state;
1819      int i, len = strlen(keys);
1820
1821      memset(&cur_state, 0, sizeof(mbstate_t));
1822      for (i = 0; i <= len ;)
1823	{
1824	  size_t mbclen;
1825	  mbclen = mbrtowc(&wc, keys + i, len - i, &cur_state);
1826	  if (mbclen == (size_t) -1 || mbclen == (size_t) -2 || mbclen == 0)
1827	    {
1828	      /* An invalid sequence, or a truncated multibyte character.
1829		 We treat it as a singlebyte character.  */
1830	      mbclen = 1;
1831	    }
1832	  else
1833	    {
1834	      if (iswupper((wint_t)wc))
1835		{
1836		  wc = towlower((wint_t)wc);
1837		  wcrtomb(keys + i, wc, &cur_state);
1838		}
1839	    }
1840	  i += mbclen;
1841	}
1842    }
1843#endif /* MBS_SUPPORT */
1844
1845  (*compile)(keys, keycc);
1846
1847  if ((argc - optind > 1 && !no_filenames) || with_filenames)
1848    out_file = 1;
1849
1850#ifdef SET_BINARY
1851  /* Output is set to binary mode because we shouldn't convert
1852     NL to CR-LF pairs, especially when grepping binary files.  */
1853  if (!isatty (1))
1854    SET_BINARY (1);
1855#endif
1856
1857  if (max_count == 0)
1858    exit (1);
1859
1860  if (optind < argc)
1861    {
1862	status = 1;
1863	do
1864	{
1865	  char *file = argv[optind];
1866	  if ((included_patterns || excluded_patterns)
1867	      && !isdir (file))
1868	    {
1869	      if (included_patterns &&
1870		  ! excluded_filename (included_patterns, file, 0))
1871		continue;
1872	      if (excluded_patterns &&
1873		  excluded_filename (excluded_patterns, file, 0))
1874		continue;
1875	    }
1876	  status &= grepfile (strcmp (file, "-") == 0 ? (char *) NULL : file,
1877			      &stats_base);
1878	}
1879	while ( ++optind < argc);
1880    }
1881  else
1882    status = grepfile ((char *) NULL, &stats_base);
1883
1884  /* We register via atexit() to test stdout.  */
1885  exit (errseen ? 2 : status);
1886}
1887/* vim:set shiftwidth=2: */
1888