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