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