xref: /freebsd-12.1/gnu/usr.bin/grep/grep.c (revision 7d0fc2f4)
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 <[email protected]>.  */
21 
22 /* $FreeBSD$ */
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 
57 struct 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 */
64 static struct stats stats_base;
65 
66 /* if non-zero, display usage information and exit */
67 static int show_help;
68 
69 /* If non-zero, print the version on standard output and exit.  */
70 static int show_version;
71 
72 /* If nonzero, suppress diagnostics for nonexistent or unreadable files.  */
73 static int suppress_errors;
74 
75 /* If nonzero, use mmap if possible.  */
76 static int mmap_option;
77 
78 /* If zero, output nulls after filenames.  */
79 static int filename_mask;
80 
81 /* If nonzero, use grep_color marker.  */
82 static int color_option;
83 
84 /* If nonzero, show only the part of a line matching the expression. */
85 static 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.  */
89 static const char *grep_color = "01;31";
90 
91 static struct exclude *excluded_patterns;
92 static struct exclude *included_patterns;
93 /* Short options.  */
94 static 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.  */
98 enum
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. */
110 static 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. */
168 int match_icase;
169 int match_words;
170 int match_lines;
171 unsigned char eolbyte;
172 
173 /* For error messages. */
174 /* The name the program was run with, stripped of any leading path. */
175 char *program_name;
176 static char const *filename;
177 static int errseen;
178 
179 /* How to handle directories.  */
180 static enum
181   {
182     READ_DIRECTORIES,
183     RECURSE_DIRECTORIES,
184     SKIP_DIRECTORIES
185   } directories = READ_DIRECTORIES;
186 
187 /* How to handle devices. */
188 static enum
189   {
190     READ_DEVICES,
191     SKIP_DEVICES
192   } devices = READ_DEVICES;
193 
194 static int grepdir PARAMS ((char const *, struct stats const *));
195 #if defined(HAVE_DOS_FILE_CONTENTS)
196 static inline int undossify_input PARAMS ((register char *, size_t));
197 #endif
198 
199 /* Functions we'll use to search. */
200 static void (*compile) PARAMS ((char const *, size_t));
201 static 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.  */
205 static void
206 suppressible_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.  */
216 static void
217 context_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 
233 static char *buffer;		/* Base of buffer. */
234 static size_t bufalloc;		/* Allocated buffer size, counting slop. */
235 #define INITIAL_BUFSIZE 32768	/* Initial buffer size, not counting slop. */
236 static int bufdesc;		/* File descriptor. */
237 static char *bufbeg;		/* Beginning of user-visible stuff. */
238 static char *buflim;		/* Limit of user-visible stuff. */
239 static size_t pagesize;		/* alignment of memory pages */
240 static off_t bufoffset;		/* Read offset; defined on regular files.  */
241 static 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)
246 static int bufmapped;		/* True if buffer is memory-mapped.  */
247 static off_t initial_bufoffset;	/* Initial value of bufoffset. */
248 #else
249 # define bufmapped 0
250 #endif
251 
252 #include <bzlib.h>
253 static BZFILE* bzbufdesc;	/* libbz2 file handle. */
254 static int BZflag;		/* uncompress before searching. */
255 #if HAVE_LIBZ > 0
256 #include <zlib.h>
257 static gzFile gzbufdesc;	/* zlib file descriptor. */
258 static 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. */
270 static int
271 reset (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.  */
349 static int
350 fillbuf (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. */
504 static enum
505 {
506   BINARY_BINARY_FILES,
507   TEXT_BINARY_FILES,
508   WITHOUT_MATCH_BINARY_FILES
509 } binary_files;		/* How to handle binary files.  */
510 
511 static int filename_mask;	/* If zero, output nulls after filenames.  */
512 static int out_quiet;		/* Suppress all normal output. */
513 static int out_invert;		/* Print nonmatching stuff. */
514 static int out_file;		/* Print filenames. */
515 static int out_line;		/* Print line numbers. */
516 static int out_byte;		/* Print byte offsets. */
517 static int out_before;		/* Lines of leading context. */
518 static int out_after;		/* Lines of trailing context. */
519 static int count_matches;	/* Count matching lines.  */
520 static int list_files;		/* List matching files.  */
521 static int no_filenames;	/* Suppress file names.  */
522 static off_t max_count;		/* Stop after outputting this many
523 				   lines from an input file.  */
524 static int line_buffered;       /* If nonzero, use line buffering, i.e.
525 				   fflush everyline out.  */
526 static char *label = NULL;      /* Fake filename for stdin */
527 
528 
529 /* Internal variables to keep track of byte count, context, etc. */
530 static uintmax_t totalcc;	/* Total character count before bufbeg. */
531 static char const *lastnl;	/* Pointer after last newline counted. */
532 static char const *lastout;	/* Pointer after last character output;
533 				   NULL if no character has been output
534 				   or if it's conceptually before bufbeg. */
535 static uintmax_t totalnl;	/* Total newline count before lastnl. */
536 static off_t outleft;		/* Maximum number of lines to be output.  */
537 static int pending;		/* Pending lines of output.
538 				   Always kept 0 if out_quiet is true.  */
539 static int done_on_match;	/* Stop scanning file on first match.  */
540 static 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.  */
548 static uintmax_t
549 add_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 
557 static void
558 nlscan (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.  */
569 static void
570 print_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 
586 static void
587 prline (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.  */
692 static void
693 prpending (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.  */
714 static void
715 prtext (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. */
780 static int
781 grepbuf (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.  */
833 static int
834 grep (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 
984 static int
985 grepfile (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 
1092 static int
1093 grepdir (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\n"), 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 
1151 static void
1152 usage (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 (_("\
1165 Search for PATTERN in each FILE or standard input.\n\
1166 Example: %s -i 'hello world' menu.h main.c\n\
1167 \n\
1168 Regexp 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\
1183 Miscellaneous:\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\
1193 Output 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\
1221 Context 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\
1233 With no FILE, or when FILE is -, read standard input.  If less than\n\
1234 two FILEs given, assume -h.  Exit status is 0 if match, 1 if no match,\n\
1235 and 2 if trouble.\n"));
1236       printf (_("\nReport bugs to <[email protected]>.\n"));
1237     }
1238   exit (status);
1239 }
1240 
1241 /* Set the matcher to M, reporting any conflicts.  */
1242 static void
1243 setmatcher (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.  */
1252 static int
1253 install_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).  */
1301 static int
1302 prepend_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.  */
1330 static void
1331 prepend_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.  */
1353 static int
1354 get_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 
1390 int
1391 main (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 (_("\
1798 Copyright 1988, 1992-1999, 2000, 2001 Free Software Foundation, Inc.\n"));
1799       printf (_("\
1800 This is free software; see the source for copying conditions. There is NO\n\
1801 warranty; 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