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