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