]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - gnu/usr.bin/grep/grep.c
Introduce svnlite so that we can check out our source code again.
[FreeBSD/FreeBSD.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) || S_ISFIFO(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   int flags;
946
947   if (! file)
948     {
949       desc = 0;
950       filename = label ? label : _("(standard input)");
951     }
952   else
953     {
954       while ((desc = open (file, O_RDONLY | O_NONBLOCK)) < 0 && errno == EINTR)
955         continue;
956
957       if (desc < 0)
958         {
959           int e = errno;
960
961           if (is_EISDIR (e, file) && directories == RECURSE_DIRECTORIES)
962             {
963               if (stat (file, &stats->stat) != 0)
964                 {
965                   error (0, errno, "%s", file);
966                   return 1;
967                 }
968
969               return grepdir (file, stats);
970             }
971
972           if (!suppress_errors)
973             {
974               if (directories == SKIP_DIRECTORIES)
975                 switch (e)
976                   {
977 #if defined(EISDIR)
978                   case EISDIR:
979                     return 1;
980 #endif
981                   case EACCES:
982                     /* When skipping directories, don't worry about
983                        directories that can't be opened.  */
984                     if (isdir (file))
985                       return 1;
986                     break;
987                   }
988             }
989
990           suppressible_error (file, e);
991           return 1;
992         }
993
994       flags = fcntl(desc, F_GETFL);
995       flags &= ~O_NONBLOCK;
996       fcntl(desc, F_SETFL, flags);
997       filename = file;
998     }
999
1000 #if defined(SET_BINARY)
1001   /* Set input to binary mode.  Pipes are simulated with files
1002      on DOS, so this includes the case of "foo | grep bar".  */
1003   if (!isatty (desc))
1004     SET_BINARY (desc);
1005 #endif
1006
1007   count = grep (desc, file, stats);
1008   if (count < 0)
1009     status = count + 2;
1010   else
1011     {
1012       if (count_matches)
1013         {
1014           if (out_file)
1015             printf ("%s%c", filename, ':' & filename_mask);
1016           printf ("%d\n", count);
1017         }
1018
1019       status = !count;
1020       if (list_files == 1 - 2 * status)
1021         printf ("%s%c", filename, '\n' & filename_mask);
1022
1023       if (BZflag && bzbufdesc)
1024         BZ2_bzclose(bzbufdesc);
1025       else
1026 #if HAVE_LIBZ > 0
1027       if (Zflag)
1028         gzclose(gzbufdesc);
1029       else
1030 #endif
1031       if (! file)
1032         {
1033           off_t required_offset = outleft ? bufoffset : after_last_match;
1034           if ((bufmapped || required_offset != bufoffset)
1035               && lseek (desc, required_offset, SEEK_SET) < 0
1036               && S_ISREG (stats->stat.st_mode))
1037             error (0, errno, "%s", filename);
1038         }
1039       else
1040         while (close (desc) != 0)
1041           if (errno != EINTR)
1042             {
1043               error (0, errno, "%s", file);
1044               break;
1045             }
1046     }
1047
1048   return status;
1049 }
1050
1051 static int
1052 grepdir (char const *dir, struct stats const *stats)
1053 {
1054   int status = 1;
1055   struct stats const *ancestor;
1056   char *name_space;
1057
1058   /* Mingw32 does not support st_ino.  No known working hosts use zero
1059      for st_ino, so assume that the Mingw32 bug applies if it's zero.  */
1060   if (stats->stat.st_ino)
1061     for (ancestor = stats;  (ancestor = ancestor->parent) != 0;  )
1062       if (ancestor->stat.st_ino == stats->stat.st_ino
1063           && ancestor->stat.st_dev == stats->stat.st_dev)
1064         {
1065           if (!suppress_errors)
1066             error (0, 0, _("warning: %s: %s"), dir,
1067                    _("recursive directory loop"));
1068           return 1;
1069         }
1070
1071   name_space = savedir (dir, stats->stat.st_size, included_patterns,
1072                         excluded_patterns);
1073
1074   if (! name_space)
1075     {
1076       if (errno)
1077         suppressible_error (dir, errno);
1078       else
1079         xalloc_die ();
1080     }
1081   else
1082     {
1083       size_t dirlen = strlen (dir);
1084       int needs_slash = ! (dirlen == FILESYSTEM_PREFIX_LEN (dir)
1085                            || IS_SLASH (dir[dirlen - 1]));
1086       char *file = NULL;
1087       char const *namep = name_space;
1088       struct stats child;
1089       child.parent = stats;
1090       out_file += !no_filenames;
1091       while (*namep)
1092         {
1093           size_t namelen = strlen (namep);
1094           file = xrealloc (file, dirlen + 1 + namelen + 1);
1095           strcpy (file, dir);
1096           file[dirlen] = '/';
1097           strcpy (file + dirlen + needs_slash, namep);
1098           namep += namelen + 1;
1099           status &= grepfile (file, &child);
1100         }
1101       out_file -= !no_filenames;
1102       if (file)
1103         free (file);
1104       free (name_space);
1105     }
1106
1107   return status;
1108 }
1109
1110 static void
1111 usage (int status)
1112 {
1113   if (status != 0)
1114     {
1115       fprintf (stderr, _("Usage: %s [OPTION]... PATTERN [FILE]...\n"),
1116                program_name);
1117       fprintf (stderr, _("Try `%s --help' for more information.\n"),
1118                program_name);
1119     }
1120   else
1121     {
1122       printf (_("Usage: %s [OPTION]... PATTERN [FILE] ...\n"), program_name);
1123       printf (_("\
1124 Search for PATTERN in each FILE or standard input.\n\
1125 Example: %s -i 'hello world' menu.h main.c\n\
1126 \n\
1127 Regexp selection and interpretation:\n"), program_name);
1128       printf (_("\
1129   -E, --extended-regexp     PATTERN is an extended regular expression\n\
1130   -F, --fixed-strings       PATTERN is a set of newline-separated strings\n\
1131   -G, --basic-regexp        PATTERN is a basic regular expression\n\
1132   -P, --perl-regexp         PATTERN is a Perl regular expression\n"));
1133       printf (_("\
1134   -e, --regexp=PATTERN      use PATTERN as a regular expression\n\
1135   -f, --file=FILE           obtain PATTERN from FILE\n\
1136   -i, --ignore-case         ignore case distinctions\n\
1137   -w, --word-regexp         force PATTERN to match only whole words\n\
1138   -x, --line-regexp         force PATTERN to match only whole lines\n\
1139   -z, --null-data           a data line ends in 0 byte, not newline\n"));
1140       printf (_("\
1141 \n\
1142 Miscellaneous:\n\
1143   -s, --no-messages         suppress error messages\n\
1144   -v, --invert-match        select non-matching lines\n\
1145   -V, --version             print version information and exit\n\
1146       --help                display this help and exit\n\
1147   -J, --bz2decompress       decompress bzip2'ed input before searching\n\
1148   -Z, --decompress          decompress input before searching (HAVE_LIBZ=1)\n\
1149       --mmap                use memory-mapped input if possible\n"));
1150       printf (_("\
1151 \n\
1152 Output control:\n\
1153   -m, --max-count=NUM       stop after NUM matches\n\
1154   -b, --byte-offset         print the byte offset with output lines\n\
1155   -n, --line-number         print line number with output lines\n\
1156       --line-buffered       flush output on every line\n\
1157   -H, --with-filename       print the filename for each match\n\
1158   -h, --no-filename         suppress the prefixing filename on output\n\
1159       --label=LABEL         print LABEL as filename for standard input\n\
1160   -o, --only-matching       show only the part of a line matching PATTERN\n\
1161   -q, --quiet, --silent     suppress all normal output\n\
1162       --binary-files=TYPE   assume that binary files are TYPE\n\
1163                             TYPE is 'binary', 'text', or 'without-match'\n\
1164   -a, --text                equivalent to --binary-files=text\n\
1165   -I                        equivalent to --binary-files=without-match\n\
1166   -d, --directories=ACTION  how to handle directories\n\
1167                             ACTION is 'read', 'recurse', or 'skip'\n\
1168   -D, --devices=ACTION      how to handle devices, FIFOs and sockets\n\
1169                             ACTION is 'read' or 'skip'\n\
1170   -R, -r, --recursive       equivalent to --directories=recurse\n\
1171       --include=PATTERN     files that match PATTERN will be examined\n\
1172       --exclude=PATTERN     files that match PATTERN will be skipped.\n\
1173       --exclude-from=FILE   files that match PATTERN in FILE will be skipped.\n\
1174   -L, --files-without-match only print FILE names containing no match\n\
1175   -l, --files-with-matches  only print FILE names containing matches\n\
1176   -c, --count               only print a count of matching lines per FILE\n\
1177       --null                print 0 byte after FILE name\n"));
1178       printf (_("\
1179 \n\
1180 Context control:\n\
1181   -B, --before-context=NUM  print NUM lines of leading context\n\
1182   -A, --after-context=NUM   print NUM lines of trailing context\n\
1183   -C, --context=NUM         print NUM lines of output context\n\
1184   -NUM                      same as --context=NUM\n\
1185       --color[=WHEN],\n\
1186       --colour[=WHEN]       use markers to distinguish the matching string\n\
1187                             WHEN may be `always', `never' or `auto'.\n\
1188   -U, --binary              do not strip CR characters at EOL (MSDOS)\n\
1189   -u, --unix-byte-offsets   report offsets as if CRs were not there (MSDOS)\n\
1190 \n\
1191 `egrep' means `grep -E'.  `fgrep' means `grep -F'.\n\
1192 With no FILE, or when FILE is -, read standard input.  If less than\n\
1193 two FILEs given, assume -h.  Exit status is 0 if match, 1 if no match,\n\
1194 and 2 if trouble.\n"));
1195       printf (_("\nReport bugs to <bug-gnu-utils@gnu.org>.\n"));
1196     }
1197   exit (status);
1198 }
1199
1200 /* Set the matcher to M, reporting any conflicts.  */
1201 static void
1202 setmatcher (char const *m)
1203 {
1204   if (matcher && strcmp (matcher, m) != 0)
1205     error (2, 0, _("conflicting matchers specified"));
1206   matcher = m;
1207 }
1208
1209 /* Go through the matchers vector and look for the specified matcher.
1210    If we find it, install it in compile and execute, and return 1.  */
1211 static int
1212 install_matcher (char const *name)
1213 {
1214   int i;
1215 #if defined(HAVE_SETRLIMIT)
1216   struct rlimit rlim;
1217 #endif
1218
1219   for (i = 0; matchers[i].compile; i++)
1220     if (strcmp (name, matchers[i].name) == 0)
1221       {
1222         compile = matchers[i].compile;
1223         execute = matchers[i].execute;
1224 #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_STACK)
1225         /* I think every platform needs to do this, so that regex.c
1226            doesn't oveflow the stack.  The default value of
1227            `re_max_failures' is too large for some platforms: it needs
1228            more than 3MB-large stack.
1229
1230            The test for HAVE_SETRLIMIT should go into `configure'.  */
1231         if (!getrlimit (RLIMIT_STACK, &rlim))
1232           {
1233             long newlim;
1234             extern long int re_max_failures; /* from regex.c */
1235
1236             /* Approximate the amount regex.c needs, plus some more.  */
1237             newlim = re_max_failures * 2 * 20 * sizeof (char *);
1238             if (newlim > rlim.rlim_max)
1239               {
1240                 newlim = rlim.rlim_max;
1241                 re_max_failures = newlim / (2 * 20 * sizeof (char *));
1242               }
1243             if (rlim.rlim_cur < newlim)
1244               {
1245                 rlim.rlim_cur = newlim;
1246                 setrlimit (RLIMIT_STACK, &rlim);
1247               }
1248           }
1249 #endif
1250         return 1;
1251       }
1252   return 0;
1253 }
1254
1255 /* Find the white-space-separated options specified by OPTIONS, and
1256    using BUF to store copies of these options, set ARGV[0], ARGV[1],
1257    etc. to the option copies.  Return the number N of options found.
1258    Do not set ARGV[N] to NULL.  If ARGV is NULL, do not store ARGV[0]
1259    etc.  Backslash can be used to escape whitespace (and backslashes).  */
1260 static int
1261 prepend_args (char const *options, char *buf, char **argv)
1262 {
1263   char const *o = options;
1264   char *b = buf;
1265   int n = 0;
1266
1267   for (;;)
1268     {
1269       while (ISSPACE ((unsigned char) *o))
1270         o++;
1271       if (!*o)
1272         return n;
1273       if (argv)
1274         argv[n] = b;
1275       n++;
1276
1277       do
1278         if ((*b++ = *o++) == '\\' && *o)
1279           b[-1] = *o++;
1280       while (*o && ! ISSPACE ((unsigned char) *o));
1281
1282       *b++ = '\0';
1283     }
1284 }
1285
1286 /* Prepend the whitespace-separated options in OPTIONS to the argument
1287    vector of a main program with argument count *PARGC and argument
1288    vector *PARGV.  */
1289 static void
1290 prepend_default_options (char const *options, int *pargc, char ***pargv)
1291 {
1292   if (options)
1293     {
1294       char *buf = xmalloc (strlen (options) + 1);
1295       int prepended = prepend_args (options, buf, (char **) NULL);
1296       int argc = *pargc;
1297       char * const *argv = *pargv;
1298       char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp);
1299       *pargc = prepended + argc;
1300       *pargv = pp;
1301       *pp++ = *argv++;
1302       pp += prepend_args (options, buf, pp);
1303       while ((*pp++ = *argv++))
1304         continue;
1305     }
1306 }
1307
1308 /* Get the next non-digit option from ARGC and ARGV.
1309    Return -1 if there are no more options.
1310    Process any digit options that were encountered on the way,
1311    and store the resulting integer into *DEFAULT_CONTEXT.  */
1312 static int
1313 get_nondigit_option (int argc, char *const *argv, int *default_context)
1314 {
1315   int opt;
1316   char buf[sizeof (uintmax_t) * CHAR_BIT + 4];
1317   char *p = buf;
1318
1319   /* Set buf[0] to anything but '0', for the leading-zero test below.  */
1320   buf[0] = '\0';
1321
1322   while (opt = getopt_long (argc, argv, short_options, long_options, NULL),
1323          '0' <= opt && opt <= '9')
1324     {
1325       /* Suppress trivial leading zeros, to avoid incorrect
1326          diagnostic on strings like 00000000000.  */
1327       p -= buf[0] == '0';
1328
1329       *p++ = opt;
1330       if (p == buf + sizeof buf - 4)
1331         {
1332           /* Too many digits.  Append "..." to make context_length_arg
1333              complain about "X...", where X contains the digits seen
1334              so far.  */
1335           strcpy (p, "...");
1336           p += 3;
1337           break;
1338         }
1339     }
1340   if (p != buf)
1341     {
1342       *p = '\0';
1343       context_length_arg (buf, default_context);
1344     }
1345
1346   return opt;
1347 }
1348
1349 int
1350 main (int argc, char **argv)
1351 {
1352   char *keys;
1353   size_t cc, keycc, oldcc, keyalloc;
1354   int with_filenames;
1355   int opt, status;
1356   int default_context;
1357   FILE *fp;
1358   extern char *optarg;
1359   extern int optind;
1360
1361   initialize_main (&argc, &argv);
1362   program_name = argv[0];
1363   if (program_name && strrchr (program_name, '/'))
1364     program_name = strrchr (program_name, '/') + 1;
1365
1366   if (program_name[0] == 'b' && program_name[1] == 'z') {
1367     BZflag = 1;
1368     program_name += 2;
1369   }
1370 #if HAVE_LIBZ > 0
1371   else if (program_name[0] == 'z') {
1372     Zflag = 1;
1373     ++program_name;
1374   }
1375 #endif
1376
1377 #if defined(__MSDOS__) || defined(_WIN32)
1378   /* DOS and MS-Windows use backslashes as directory separators, and usually
1379      have an .exe suffix.  They also have case-insensitive filesystems.  */
1380   if (program_name)
1381     {
1382       char *p = program_name;
1383       char *bslash = strrchr (argv[0], '\\');
1384
1385       if (bslash && bslash >= program_name) /* for mixed forward/backslash case */
1386         program_name = bslash + 1;
1387       else if (program_name == argv[0]
1388                && argv[0][0] && argv[0][1] == ':') /* "c:progname" */
1389         program_name = argv[0] + 2;
1390
1391       /* Collapse the letter-case, so `strcmp' could be used hence.  */
1392       for ( ; *p; p++)
1393         if (*p >= 'A' && *p <= 'Z')
1394           *p += 'a' - 'A';
1395
1396       /* Remove the .exe extension, if any.  */
1397       if ((p = strrchr (program_name, '.')) && strcmp (p, ".exe") == 0)
1398         *p = '\0';
1399     }
1400 #endif
1401
1402   keys = NULL;
1403   keycc = 0;
1404   with_filenames = 0;
1405   eolbyte = '\n';
1406   filename_mask = ~0;
1407
1408   max_count = TYPE_MAXIMUM (off_t);
1409
1410   /* The value -1 means to use DEFAULT_CONTEXT. */
1411   out_after = out_before = -1;
1412   /* Default before/after context: chaged by -C/-NUM options */
1413   default_context = 0;
1414   /* Changed by -o option */
1415   only_matching = 0;
1416
1417   /* Internationalization. */
1418 #if defined(HAVE_SETLOCALE)
1419   setlocale (LC_ALL, "");
1420 #endif
1421 #if defined(ENABLE_NLS)
1422   bindtextdomain (PACKAGE, LOCALEDIR);
1423   textdomain (PACKAGE);
1424 #endif
1425
1426   atexit (close_stdout);
1427
1428   prepend_default_options (getenv ("GREP_OPTIONS"), &argc, &argv);
1429
1430   while ((opt = get_nondigit_option (argc, argv, &default_context)) != -1)
1431     switch (opt)
1432       {
1433       case 'A':
1434         context_length_arg (optarg, &out_after);
1435         break;
1436
1437       case 'B':
1438         context_length_arg (optarg, &out_before);
1439         break;
1440
1441       case 'C':
1442         /* Set output match context, but let any explicit leading or
1443            trailing amount specified with -A or -B stand. */
1444         context_length_arg (optarg, &default_context);
1445         break;
1446
1447       case 'D':
1448         if (strcmp (optarg, "read") == 0)
1449           devices = READ_DEVICES;
1450         else if (strcmp (optarg, "skip") == 0)
1451           devices = SKIP_DEVICES;
1452         else
1453           error (2, 0, _("unknown devices method"));
1454         break;
1455
1456       case 'E':
1457         setmatcher ("egrep");
1458         break;
1459
1460       case 'F':
1461         setmatcher ("fgrep");
1462         break;
1463
1464       case 'P':
1465         setmatcher ("perl");
1466         break;
1467
1468       case 'G':
1469         setmatcher ("grep");
1470         break;
1471
1472       case 'H':
1473         with_filenames = 1;
1474         break;
1475
1476       case 'I':
1477         binary_files = WITHOUT_MATCH_BINARY_FILES;
1478         break;
1479       case 'J':
1480         if (Zflag)
1481           {
1482             printf (_("Cannot mix -Z and -J.\n"));
1483             usage (2);
1484           }
1485         BZflag = 1;
1486         break;
1487
1488       case 'U':
1489 #if defined(HAVE_DOS_FILE_CONTENTS)
1490         dos_use_file_type = DOS_BINARY;
1491 #endif
1492         break;
1493
1494       case 'u':
1495 #if defined(HAVE_DOS_FILE_CONTENTS)
1496         dos_report_unix_offset = 1;
1497 #endif
1498         break;
1499
1500       case 'V':
1501         show_version = 1;
1502         break;
1503
1504       case 'X':
1505         setmatcher (optarg);
1506         break;
1507
1508       case 'a':
1509         binary_files = TEXT_BINARY_FILES;
1510         break;
1511
1512       case 'b':
1513         out_byte = 1;
1514         break;
1515
1516       case 'c':
1517         count_matches = 1;
1518         break;
1519
1520       case 'd':
1521         if (strcmp (optarg, "read") == 0)
1522           directories = READ_DIRECTORIES;
1523         else if (strcmp (optarg, "skip") == 0)
1524           directories = SKIP_DIRECTORIES;
1525         else if (strcmp (optarg, "recurse") == 0)
1526           directories = RECURSE_DIRECTORIES;
1527         else
1528           error (2, 0, _("unknown directories method"));
1529         break;
1530
1531       case 'e':
1532         cc = strlen (optarg);
1533         keys = xrealloc (keys, keycc + cc + 1);
1534         strcpy (&keys[keycc], optarg);
1535         keycc += cc;
1536         keys[keycc++] = '\n';
1537         break;
1538
1539       case 'f':
1540         fp = strcmp (optarg, "-") != 0 ? fopen (optarg, "r") : stdin;
1541         if (!fp)
1542           error (2, errno, "%s", optarg);
1543         for (keyalloc = 1; keyalloc <= keycc + 1; keyalloc *= 2)
1544           ;
1545         keys = xrealloc (keys, keyalloc);
1546         oldcc = keycc;
1547         while (!feof (fp)
1548                && (cc = fread (keys + keycc, 1, keyalloc - 1 - keycc, fp)) > 0)
1549           {
1550             keycc += cc;
1551             if (keycc == keyalloc - 1)
1552               keys = xrealloc (keys, keyalloc *= 2);
1553           }
1554         if (fp != stdin)
1555           fclose(fp);
1556         /* Append final newline if file ended in non-newline. */
1557         if (oldcc != keycc && keys[keycc - 1] != '\n')
1558           keys[keycc++] = '\n';
1559         break;
1560
1561       case 'h':
1562         no_filenames = 1;
1563         break;
1564
1565       case 'i':
1566       case 'y':                 /* For old-timers . . . */
1567         match_icase = 1;
1568         break;
1569
1570       case 'L':
1571         /* Like -l, except list files that don't contain matches.
1572            Inspired by the same option in Hume's gre. */
1573         list_files = -1;
1574         break;
1575
1576       case 'l':
1577         list_files = 1;
1578         break;
1579
1580       case 'm':
1581         {
1582           uintmax_t value;
1583           switch (xstrtoumax (optarg, 0, 10, &value, ""))
1584             {
1585             case LONGINT_OK:
1586               max_count = value;
1587               if (0 <= max_count && max_count == value)
1588                 break;
1589               /* Fall through.  */
1590             case LONGINT_OVERFLOW:
1591               max_count = TYPE_MAXIMUM (off_t);
1592               break;
1593
1594             default:
1595               error (2, 0, _("invalid max count"));
1596             }
1597         }
1598         break;
1599
1600       case 'n':
1601         out_line = 1;
1602         break;
1603
1604       case 'o':
1605         only_matching = 1;
1606         break;
1607
1608       case 'q':
1609         exit_on_match = 1;
1610         close_stdout_set_status(0);
1611         break;
1612
1613       case 'R':
1614       case 'r':
1615         directories = RECURSE_DIRECTORIES;
1616         break;
1617
1618       case 's':
1619         suppress_errors = 1;
1620         break;
1621
1622       case 'v':
1623         out_invert = 1;
1624         break;
1625
1626       case 'w':
1627         match_words = 1;
1628         break;
1629
1630       case 'x':
1631         match_lines = 1;
1632         break;
1633
1634       case 'Z':
1635 #if HAVE_LIBZ > 0
1636         if (BZflag)
1637           {
1638             printf (_("Cannot mix -J and -Z.\n"));
1639             usage (2);
1640           }
1641         Zflag = 1;
1642 #else
1643         filename_mask = 0;
1644 #endif
1645         break;
1646
1647       case 'z':
1648         eolbyte = '\0';
1649         break;
1650
1651       case BINARY_FILES_OPTION:
1652         if (strcmp (optarg, "binary") == 0)
1653           binary_files = BINARY_BINARY_FILES;
1654         else if (strcmp (optarg, "text") == 0)
1655           binary_files = TEXT_BINARY_FILES;
1656         else if (strcmp (optarg, "without-match") == 0)
1657           binary_files = WITHOUT_MATCH_BINARY_FILES;
1658         else
1659           error (2, 0, _("unknown binary-files type"));
1660         break;
1661
1662       case COLOR_OPTION:
1663         if(optarg) {
1664           if(!strcasecmp(optarg, "always") || !strcasecmp(optarg, "yes") ||
1665              !strcasecmp(optarg, "force"))
1666             color_option = 1;
1667           else if(!strcasecmp(optarg, "never") || !strcasecmp(optarg, "no") ||
1668                   !strcasecmp(optarg, "none"))
1669             color_option = 0;
1670           else if(!strcasecmp(optarg, "auto") || !strcasecmp(optarg, "tty") ||
1671                   !strcasecmp(optarg, "if-tty"))
1672             color_option = 2;
1673           else
1674             show_help = 1;
1675         } else
1676           color_option = 2;
1677         if(color_option == 2) {
1678           if(isatty(STDOUT_FILENO) && getenv("TERM") &&
1679              strcmp(getenv("TERM"), "dumb"))
1680                   color_option = 1;
1681           else
1682             color_option = 0;
1683         }
1684         break;
1685
1686       case EXCLUDE_OPTION:
1687         if (!excluded_patterns)
1688           excluded_patterns = new_exclude ();
1689         add_exclude (excluded_patterns, optarg);
1690         break;
1691
1692       case EXCLUDE_FROM_OPTION:
1693         if (!excluded_patterns)
1694           excluded_patterns = new_exclude ();
1695         if (add_exclude_file (add_exclude, excluded_patterns, optarg, '\n')
1696             != 0)
1697           {
1698             error (2, errno, "%s", optarg);
1699           }
1700         break;
1701
1702       case INCLUDE_OPTION:
1703         if (!included_patterns)
1704           included_patterns = new_exclude ();
1705         add_exclude (included_patterns, optarg);
1706         break;
1707
1708       case LINE_BUFFERED_OPTION:
1709         line_buffered = 1;
1710         break;
1711
1712       case LABEL_OPTION:
1713         label = optarg;
1714         break;
1715
1716       case 0:
1717         /* long options */
1718         break;
1719
1720       default:
1721         usage (2);
1722         break;
1723
1724       }
1725
1726   /* POSIX.2 says that -q overrides -l, which in turn overrides the
1727      other output options.  */
1728   if (exit_on_match)
1729     list_files = 0;
1730   if (exit_on_match | list_files)
1731     {
1732       count_matches = 0;
1733       done_on_match = 1;
1734     }
1735   out_quiet = count_matches | done_on_match;
1736
1737   if (out_after < 0)
1738     out_after = default_context;
1739   if (out_before < 0)
1740     out_before = default_context;
1741
1742   if (color_option)
1743     {
1744       char *userval = getenv ("GREP_COLOR");
1745       if (userval != NULL && *userval != '\0')
1746         grep_color = userval;
1747     }
1748
1749   if (! matcher)
1750     matcher = program_name;
1751
1752   if (show_version)
1753     {
1754       printf (_("%s (GNU grep) %s\n"), matcher, VERSION);
1755       printf ("\n");
1756       printf (_("\
1757 Copyright 1988, 1992-1999, 2000, 2001 Free Software Foundation, Inc.\n"));
1758       printf (_("\
1759 This is free software; see the source for copying conditions. There is NO\n\
1760 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"));
1761       printf ("\n");
1762       exit (0);
1763     }
1764
1765   if (show_help)
1766     usage (0);
1767
1768   if (keys)
1769     {
1770       if (keycc == 0)
1771         {
1772           /* No keys were specified (e.g. -f /dev/null).  Match nothing.  */
1773           out_invert ^= 1;
1774           match_lines = match_words = 0;
1775         }
1776       else
1777         /* Strip trailing newline. */
1778         --keycc;
1779     }
1780   else
1781     if (optind < argc)
1782       {
1783         keys = argv[optind++];
1784         keycc = strlen (keys);
1785       }
1786     else
1787       usage (2);
1788
1789   if (!install_matcher (matcher) && !install_matcher ("default"))
1790     abort ();
1791
1792 #ifdef MBS_SUPPORT
1793   if (MB_CUR_MAX != 1 && match_icase)
1794     {
1795       wchar_t wc;
1796       mbstate_t cur_state, prev_state;
1797       int i, len = strlen(keys);
1798
1799       memset(&cur_state, 0, sizeof(mbstate_t));
1800       for (i = 0; i <= len ;)
1801         {
1802           size_t mbclen;
1803           mbclen = mbrtowc(&wc, keys + i, len - i, &cur_state);
1804           if (mbclen == (size_t) -1 || mbclen == (size_t) -2 || mbclen == 0)
1805             {
1806               /* An invalid sequence, or a truncated multibyte character.
1807                  We treat it as a singlebyte character.  */
1808               mbclen = 1;
1809             }
1810           else
1811             {
1812               if (iswupper((wint_t)wc))
1813                 {
1814                   wc = towlower((wint_t)wc);
1815                   wcrtomb(keys + i, wc, &cur_state);
1816                 }
1817             }
1818           i += mbclen;
1819         }
1820     }
1821 #endif /* MBS_SUPPORT */
1822
1823   (*compile)(keys, keycc);
1824
1825   if ((argc - optind > 1 && !no_filenames) || with_filenames)
1826     out_file = 1;
1827
1828 #ifdef SET_BINARY
1829   /* Output is set to binary mode because we shouldn't convert
1830      NL to CR-LF pairs, especially when grepping binary files.  */
1831   if (!isatty (1))
1832     SET_BINARY (1);
1833 #endif
1834
1835   if (max_count == 0)
1836     exit (1);
1837
1838   if (optind < argc)
1839     {
1840         status = 1;
1841         do
1842         {
1843           char *file = argv[optind];
1844           if ((included_patterns || excluded_patterns)
1845               && !isdir (file))
1846             {
1847               if (included_patterns &&
1848                   ! excluded_filename (included_patterns, file, 0))
1849                 continue;
1850               if (excluded_patterns &&
1851                   excluded_filename (excluded_patterns, file, 0))
1852                 continue;
1853             }
1854           status &= grepfile (strcmp (file, "-") == 0 ? (char *) NULL : file,
1855                               &stats_base);
1856         }
1857         while ( ++optind < argc);
1858     }
1859   else
1860     status = grepfile ((char *) NULL, &stats_base);
1861
1862   /* We register via atexit() to test stdout.  */
1863   exit (errseen ? 2 : status);
1864 }
1865 /* vim:set shiftwidth=2: */