grep.c revision 250823
1/* grep.c - main driver file for grep. 2 Copyright 1992, 1997-1999, 2000 Free Software Foundation, Inc. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2, or (at your option) 7 any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 17 02111-1307, USA. */ 18 19/* Written July 1992 by Mike Haertel. */ 20/* Builtin decompression 1997 by Wolfram Schneider <wosch@FreeBSD.org>. */ 21 22/* $FreeBSD: head/gnu/usr.bin/grep/grep.c 250823 2013-05-20 03:15:25Z pfg $ */ 23 24#ifdef HAVE_CONFIG_H 25# include <config.h> 26#endif 27#include <sys/types.h> 28#include <sys/stat.h> 29#if defined(HAVE_MMAP) 30# include <sys/mman.h> 31#endif 32#if defined(HAVE_SETRLIMIT) 33# include <sys/time.h> 34# include <sys/resource.h> 35#endif 36#if defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H && defined HAVE_MBRTOWC 37/* We can handle multibyte string. */ 38# define MBS_SUPPORT 39# include <wchar.h> 40# include <wctype.h> 41#endif 42#include <stdio.h> 43#include "system.h" 44#include "getopt.h" 45#include "getpagesize.h" 46#include "grep.h" 47#include "savedir.h" 48#include "xstrtol.h" 49#include "xalloc.h" 50#include "error.h" 51#include "exclude.h" 52#include "closeout.h" 53 54#undef MAX 55#define MAX(A,B) ((A) > (B) ? (A) : (B)) 56 57struct stats 58{ 59 struct stats const *parent; 60 struct stat stat; 61}; 62 63/* base of chain of stat buffers, used to detect directory loops */ 64static struct stats stats_base; 65 66/* if non-zero, display usage information and exit */ 67static int show_help; 68 69/* If non-zero, print the version on standard output and exit. */ 70static int show_version; 71 72/* If nonzero, suppress diagnostics for nonexistent or unreadable files. */ 73static int suppress_errors; 74 75/* If nonzero, use mmap if possible. */ 76static int mmap_option; 77 78/* If zero, output nulls after filenames. */ 79static int filename_mask; 80 81/* If nonzero, use grep_color marker. */ 82static int color_option; 83 84/* If nonzero, show only the part of a line matching the expression. */ 85static int only_matching; 86 87/* The color string used. The user can overwrite it using the environment 88 variable GREP_COLOR. The default is to print red. */ 89static const char *grep_color = "01;31"; 90 91static struct exclude *excluded_patterns; 92static struct exclude *included_patterns; 93/* Short options. */ 94static char const short_options[] = 95"0123456789A:B:C:D:EFGHIJPUVX:abcd:e:f:hiKLlm:noqRrsuvwxyZz"; 96 97/* Non-boolean long options that have no corresponding short equivalents. */ 98enum 99{ 100 BINARY_FILES_OPTION = CHAR_MAX + 1, 101 COLOR_OPTION, 102 INCLUDE_OPTION, 103 EXCLUDE_OPTION, 104 EXCLUDE_FROM_OPTION, 105 LINE_BUFFERED_OPTION, 106 LABEL_OPTION 107}; 108 109/* Long options equivalences. */ 110static struct option const long_options[] = 111{ 112 {"after-context", required_argument, NULL, 'A'}, 113 {"basic-regexp", no_argument, NULL, 'G'}, 114 {"before-context", required_argument, NULL, 'B'}, 115 {"binary-files", required_argument, NULL, BINARY_FILES_OPTION}, 116 {"byte-offset", no_argument, NULL, 'b'}, 117 {"context", required_argument, NULL, 'C'}, 118 {"color", optional_argument, NULL, COLOR_OPTION}, 119 {"colour", optional_argument, NULL, COLOR_OPTION}, 120 {"count", no_argument, NULL, 'c'}, 121 {"devices", required_argument, NULL, 'D'}, 122 {"directories", required_argument, NULL, 'd'}, 123 {"extended-regexp", no_argument, NULL, 'E'}, 124 {"exclude", required_argument, NULL, EXCLUDE_OPTION}, 125 {"exclude-from", required_argument, NULL, EXCLUDE_FROM_OPTION}, 126 {"file", required_argument, NULL, 'f'}, 127 {"files-with-matches", no_argument, NULL, 'l'}, 128 {"files-without-match", no_argument, NULL, 'L'}, 129 {"fixed-regexp", no_argument, NULL, 'F'}, 130 {"fixed-strings", no_argument, NULL, 'F'}, 131 {"help", no_argument, &show_help, 1}, 132 {"include", required_argument, NULL, INCLUDE_OPTION}, 133 {"ignore-case", no_argument, NULL, 'i'}, 134 {"label", required_argument, NULL, LABEL_OPTION}, 135 {"line-buffered", no_argument, NULL, LINE_BUFFERED_OPTION}, 136 {"line-number", no_argument, NULL, 'n'}, 137 {"line-regexp", no_argument, NULL, 'x'}, 138 {"max-count", required_argument, NULL, 'm'}, 139 {"mmap", no_argument, &mmap_option, 1}, 140 {"no-filename", no_argument, NULL, 'h'}, 141 {"no-messages", no_argument, NULL, 's'}, 142 {"bz2decompress", no_argument, NULL, 'J'}, 143#if HAVE_LIBZ > 0 144 {"decompress", no_argument, NULL, 'Z'}, 145 {"null", no_argument, &filename_mask, 0}, 146#else 147 {"null", no_argument, NULL, 'Z'}, 148#endif 149 {"null-data", no_argument, NULL, 'z'}, 150 {"only-matching", no_argument, NULL, 'o'}, 151 {"perl-regexp", no_argument, NULL, 'P'}, 152 {"quiet", no_argument, NULL, 'q'}, 153 {"recursive", no_argument, NULL, 'r'}, 154 {"recursive", no_argument, NULL, 'R'}, 155 {"regexp", required_argument, NULL, 'e'}, 156 {"invert-match", no_argument, NULL, 'v'}, 157 {"silent", no_argument, NULL, 'q'}, 158 {"text", no_argument, NULL, 'a'}, 159 {"binary", no_argument, NULL, 'U'}, 160 {"unix-byte-offsets", no_argument, NULL, 'u'}, 161 {"version", no_argument, NULL, 'V'}, 162 {"with-filename", no_argument, NULL, 'H'}, 163 {"word-regexp", no_argument, NULL, 'w'}, 164 {0, 0, 0, 0} 165}; 166 167/* Define flags declared in grep.h. */ 168int match_icase; 169int match_words; 170int match_lines; 171unsigned char eolbyte; 172 173/* For error messages. */ 174/* The name the program was run with, stripped of any leading path. */ 175char *program_name; 176static char const *filename; 177static int errseen; 178 179/* How to handle directories. */ 180static enum 181 { 182 READ_DIRECTORIES, 183 RECURSE_DIRECTORIES, 184 SKIP_DIRECTORIES 185 } directories = READ_DIRECTORIES; 186 187/* How to handle devices. */ 188static enum 189 { 190 READ_DEVICES, 191 SKIP_DEVICES 192 } devices = READ_DEVICES; 193 194static int grepdir PARAMS ((char const *, struct stats const *)); 195#if defined(HAVE_DOS_FILE_CONTENTS) 196static inline int undossify_input PARAMS ((register char *, size_t)); 197#endif 198 199/* Functions we'll use to search. */ 200static void (*compile) PARAMS ((char const *, size_t)); 201static size_t (*execute) PARAMS ((char const *, size_t, size_t *, int)); 202 203/* Like error, but suppress the diagnostic if requested. */ 204static void 205suppressible_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. */ 215static void 216context_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 232static char *buffer; /* Base of buffer. */ 233static size_t bufalloc; /* Allocated buffer size, counting slop. */ 234#define INITIAL_BUFSIZE 32768 /* Initial buffer size, not counting slop. */ 235static int bufdesc; /* File descriptor. */ 236static char *bufbeg; /* Beginning of user-visible stuff. */ 237static char *buflim; /* Limit of user-visible stuff. */ 238static size_t pagesize; /* alignment of memory pages */ 239static off_t bufoffset; /* Read offset; defined on regular files. */ 240static 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) 245static int bufmapped; /* True if buffer is memory-mapped. */ 246static off_t initial_bufoffset; /* Initial value of bufoffset. */ 247#else 248# define bufmapped 0 249#endif 250 251#include <bzlib.h> 252static BZFILE* bzbufdesc; /* libbz2 file handle. */ 253static int BZflag; /* uncompress before searching. */ 254#if HAVE_LIBZ > 0 255#include <zlib.h> 256static gzFile gzbufdesc; /* zlib file descriptor. */ 257static 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. */ 269static int 270reset (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. */ 348static int 349fillbuf (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. */ 503static enum 504{ 505 BINARY_BINARY_FILES, 506 TEXT_BINARY_FILES, 507 WITHOUT_MATCH_BINARY_FILES 508} binary_files; /* How to handle binary files. */ 509 510static int filename_mask; /* If zero, output nulls after filenames. */ 511static int out_quiet; /* Suppress all normal output. */ 512static int out_invert; /* Print nonmatching stuff. */ 513static int out_file; /* Print filenames. */ 514static int out_line; /* Print line numbers. */ 515static int out_byte; /* Print byte offsets. */ 516static int out_before; /* Lines of leading context. */ 517static int out_after; /* Lines of trailing context. */ 518static int count_matches; /* Count matching lines. */ 519static int list_files; /* List matching files. */ 520static int no_filenames; /* Suppress file names. */ 521static off_t max_count; /* Stop after outputting this many 522 lines from an input file. */ 523static int line_buffered; /* If nonzero, use line buffering, i.e. 524 fflush everyline out. */ 525static char *label = NULL; /* Fake filename for stdin */ 526 527 528/* Internal variables to keep track of byte count, context, etc. */ 529static uintmax_t totalcc; /* Total character count before bufbeg. */ 530static char const *lastnl; /* Pointer after last newline counted. */ 531static char const *lastout; /* Pointer after last character output; 532 NULL if no character has been output 533 or if it's conceptually before bufbeg. */ 534static uintmax_t totalnl; /* Total newline count before lastnl. */ 535static off_t outleft; /* Maximum number of lines to be output. */ 536static int pending; /* Pending lines of output. 537 Always kept 0 if out_quiet is true. */ 538static int done_on_match; /* Stop scanning file on first match. */ 539static 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. */ 547static uintmax_t 548add_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 556static void 557nlscan (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. */ 568static void 569print_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 585static void 586prline (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. */ 662static void 663prpending (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. */ 683static void 684prtext (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. */ 748static int 749grepbuf (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. */ 800static int 801grep (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 939static int 940grepfile (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 1051static int 1052grepdir (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 1110static void 1111usage (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 (_("\ 1124Search for PATTERN in each FILE or standard input.\n\ 1125Example: %s -i 'hello world' menu.h main.c\n\ 1126\n\ 1127Regexp 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\ 1142Miscellaneous:\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\ 1152Output 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\ 1180Context 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\ 1192With no FILE, or when FILE is -, read standard input. If less than\n\ 1193two FILEs given, assume -h. Exit status is 0 if match, 1 if no match,\n\ 1194and 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. */ 1201static void 1202setmatcher (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. */ 1211static int 1212install_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). */ 1260static int 1261prepend_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. */ 1289static void 1290prepend_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. */ 1312static int 1313get_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 1349int 1350main (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 (_("\ 1757Copyright 1988, 1992-1999, 2000, 2001 Free Software Foundation, Inc.\n")); 1758 printf (_("\ 1759This is free software; see the source for copying conditions. There is NO\n\ 1760warranty; 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: */ 1866