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