grep.c revision 146199
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 146199 2005-05-14 03:02:22Z 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#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 if(match_icase) 635 { 636 /* Yuck, this is tricky */ 637 char *buf = (char*) xmalloc (lim - beg); 638 char *ibeg = buf; 639 char *ilim = ibeg + (lim - beg); 640 int i; 641 for (i = 0; i < lim - beg; i++) 642 ibeg[i] = tolower (beg[i]); 643 while ((match_offset = (*execute) (ibeg, ilim-ibeg, &match_size, 1)) 644 != (size_t) -1) 645 { 646 char const *b = beg + match_offset; 647 if (b == lim) 648 break; 649 fwrite (beg, sizeof (char), match_offset, stdout); 650 printf ("\33[%sm", grep_color); 651 fwrite (b, sizeof (char), match_size, stdout); 652 fputs ("\33[00m", stdout); 653 beg = b + match_size; 654 ibeg = ibeg + match_offset + match_size; 655 } 656 fwrite (beg, 1, lim - beg, stdout); 657 free (buf); 658 lastout = lim; 659 return; 660 } 661 while (lim-beg && (match_offset = (*execute) (beg, lim - beg, &match_size, 1)) 662 != (size_t) -1) 663 { 664 char const *b = beg + match_offset; 665 /* Avoid matching the empty line at the end of the buffer. */ 666 if (b == lim) 667 break; 668 /* Avoid hanging on grep --color "" foo */ 669 if (match_size == 0) 670 break; 671 fwrite (beg, sizeof (char), match_offset, stdout); 672 printf ("\33[%sm", grep_color); 673 fwrite (b, sizeof (char), match_size, stdout); 674 fputs ("\33[00m", stdout); 675 beg = b + match_size; 676 } 677 } 678 fwrite (beg, 1, lim - beg, stdout); 679 if (ferror (stdout)) 680 error (0, errno, _("writing output")); 681 lastout = lim; 682 if (line_buffered) 683 fflush (stdout); 684} 685 686/* Print pending lines of trailing context prior to LIM. Trailing context ends 687 at the next matching line when OUTLEFT is 0. */ 688static void 689prpending (char const *lim) 690{ 691 if (!lastout) 692 lastout = bufbeg; 693 while (pending > 0 && lastout < lim) 694 { 695 char const *nl = memchr (lastout, eolbyte, lim - lastout); 696 size_t match_size; 697 --pending; 698 if (outleft 699 || (((*execute) (lastout, nl - lastout, &match_size, 0) == (size_t) -1) 700 == !out_invert)) 701 prline (lastout, nl + 1, '-'); 702 else 703 pending = 0; 704 } 705} 706 707/* Print the lines between BEG and LIM. Deal with context crap. 708 If NLINESP is non-null, store a count of lines between BEG and LIM. */ 709static void 710prtext (char const *beg, char const *lim, int *nlinesp) 711{ 712 static int used; /* avoid printing "--" before any output */ 713 char const *bp, *p; 714 char eol = eolbyte; 715 int i, n; 716 717 if (!out_quiet && pending > 0) 718 prpending (beg); 719 720 p = beg; 721 722 if (!out_quiet) 723 { 724 /* Deal with leading context crap. */ 725 726 bp = lastout ? lastout : bufbeg; 727 for (i = 0; i < out_before; ++i) 728 if (p > bp) 729 do 730 --p; 731 while (p[-1] != eol); 732 733 /* We only print the "--" separator if our output is 734 discontiguous from the last output in the file. */ 735 if ((out_before || out_after) && used && p != lastout) 736 puts ("--"); 737 738 while (p < beg) 739 { 740 char const *nl = memchr (p, eol, beg - p); 741 nl++; 742 prline (p, nl, '-'); 743 p = nl; 744 } 745 } 746 747 if (nlinesp) 748 { 749 /* Caller wants a line count. */ 750 for (n = 0; p < lim && n < outleft; n++) 751 { 752 char const *nl = memchr (p, eol, lim - p); 753 nl++; 754 if (!out_quiet) 755 prline (p, nl, ':'); 756 p = nl; 757 } 758 *nlinesp = n; 759 760 /* relying on it that this function is never called when outleft = 0. */ 761 after_last_match = bufoffset - (buflim - p); 762 } 763 else 764 if (!out_quiet) 765 prline (beg, lim, ':'); 766 767 pending = out_quiet ? 0 : out_after; 768 used = 1; 769} 770 771/* Scan the specified portion of the buffer, matching lines (or 772 between matching lines if OUT_INVERT is true). Return a count of 773 lines printed. */ 774static int 775grepbuf (char const *beg, char const *lim) 776{ 777 int nlines, n; 778 register char const *p; 779 size_t match_offset; 780 size_t match_size; 781 782 nlines = 0; 783 p = beg; 784 while ((match_offset = (*execute) (p, lim - p, &match_size, 0)) != (size_t) -1) 785 { 786 char const *b = p + match_offset; 787 char const *endp = b + match_size; 788 /* Avoid matching the empty line at the end of the buffer. */ 789 if (b == lim) 790 break; 791 if (!out_invert) 792 { 793 prtext (b, endp, (int *) 0); 794 nlines++; 795 outleft--; 796 if (!outleft || done_on_match) 797 { 798 if (exit_on_match) 799 exit (0); 800 after_last_match = bufoffset - (buflim - endp); 801 return nlines; 802 } 803 } 804 else if (p < b) 805 { 806 prtext (p, b, &n); 807 nlines += n; 808 outleft -= n; 809 if (!outleft) 810 return nlines; 811 } 812 p = endp; 813 } 814 if (out_invert && p < lim) 815 { 816 prtext (p, lim, &n); 817 nlines += n; 818 outleft -= n; 819 } 820 return nlines; 821} 822 823/* Search a given file. Normally, return a count of lines printed; 824 but if the file is a directory and we search it recursively, then 825 return -2 if there was a match, and -1 otherwise. */ 826static int 827grep (int fd, char const *file, struct stats *stats) 828{ 829 int nlines, i; 830 int not_text; 831 size_t residue, save; 832 char oldc; 833 char *beg; 834 char *lim; 835 char eol = eolbyte; 836 837 if (!reset (fd, file, stats)) 838 return 0; 839 840 if (file && directories == RECURSE_DIRECTORIES 841 && S_ISDIR (stats->stat.st_mode)) 842 { 843 /* Close fd now, so that we don't open a lot of file descriptors 844 when we recurse deeply. */ 845 if (BZflag && bzbufdesc) 846 BZ2_bzclose(bzbufdesc); 847 else 848#if HAVE_LIBZ > 0 849 if (Zflag) 850 gzclose(gzbufdesc); 851 else 852#endif 853 if (close (fd) != 0) 854 error (0, errno, "%s", file); 855 return grepdir (file, stats) - 2; 856 } 857 858 totalcc = 0; 859 lastout = 0; 860 totalnl = 0; 861 outleft = max_count; 862 after_last_match = 0; 863 pending = 0; 864 865 nlines = 0; 866 residue = 0; 867 save = 0; 868 869 if (! fillbuf (save, stats)) 870 { 871 if (! is_EISDIR (errno, file)) 872 suppressible_error (filename, errno); 873 return 0; 874 } 875 876 not_text = (((binary_files == BINARY_BINARY_FILES && !out_quiet) 877 || binary_files == WITHOUT_MATCH_BINARY_FILES) 878 && memchr (bufbeg, eol ? '\0' : '\200', buflim - bufbeg)); 879 if (not_text && binary_files == WITHOUT_MATCH_BINARY_FILES) 880 return 0; 881 done_on_match += not_text; 882 out_quiet += not_text; 883 884 for (;;) 885 { 886 lastnl = bufbeg; 887 if (lastout) 888 lastout = bufbeg; 889 890 beg = bufbeg + save; 891 892 /* no more data to scan (eof) except for maybe a residue -> break */ 893 if (beg == buflim) 894 break; 895 896 /* Determine new residue (the length of an incomplete line at the end of 897 the buffer, 0 means there is no incomplete last line). */ 898 oldc = beg[-1]; 899 beg[-1] = eol; 900 for (lim = buflim; lim[-1] != eol; lim--) 901 continue; 902 beg[-1] = oldc; 903 if (lim == beg) 904 lim = beg - residue; 905 beg -= residue; 906 residue = buflim - lim; 907 908 if (beg < lim) 909 { 910 if (outleft) 911 nlines += grepbuf (beg, lim); 912 if (pending) 913 prpending (lim); 914 if((!outleft && !pending) || (nlines && done_on_match && !out_invert)) 915 goto finish_grep; 916 } 917 918 /* The last OUT_BEFORE lines at the end of the buffer will be needed as 919 leading context if there is a matching line at the begin of the 920 next data. Make beg point to their begin. */ 921 i = 0; 922 beg = lim; 923 while (i < out_before && beg > bufbeg && beg != lastout) 924 { 925 ++i; 926 do 927 --beg; 928 while (beg[-1] != eol); 929 } 930 931 /* detect if leading context is discontinuous from last printed line. */ 932 if (beg != lastout) 933 lastout = 0; 934 935 /* Handle some details and read more data to scan. */ 936 save = residue + lim - beg; 937 if (out_byte) 938 totalcc = add_count (totalcc, buflim - bufbeg - save); 939 if (out_line) 940 nlscan (beg); 941 if (! fillbuf (save, stats)) 942 { 943 if (! is_EISDIR (errno, file)) 944 suppressible_error (filename, errno); 945 goto finish_grep; 946 } 947 } 948 if (residue) 949 { 950 *buflim++ = eol; 951 if (outleft) 952 nlines += grepbuf (bufbeg + save - residue, buflim); 953 if (pending) 954 prpending (buflim); 955 } 956 957 finish_grep: 958 done_on_match -= not_text; 959 out_quiet -= not_text; 960 if ((not_text & ~out_quiet) && nlines != 0) 961 printf (_("Binary file %s matches\n"), filename); 962 return nlines; 963} 964 965static int 966grepfile (char const *file, struct stats *stats) 967{ 968 int desc; 969 int count; 970 int status; 971 972 if (! file) 973 { 974 desc = 0; 975 filename = label ? label : _("(standard input)"); 976 } 977 else 978 { 979 while ((desc = open (file, O_RDONLY)) < 0 && errno == EINTR) 980 continue; 981 982 if (desc < 0) 983 { 984 int e = errno; 985 986 if (is_EISDIR (e, file) && directories == RECURSE_DIRECTORIES) 987 { 988 if (stat (file, &stats->stat) != 0) 989 { 990 error (0, errno, "%s", file); 991 return 1; 992 } 993 994 return grepdir (file, stats); 995 } 996 997 if (!suppress_errors) 998 { 999 if (directories == SKIP_DIRECTORIES) 1000 switch (e) 1001 { 1002#if defined(EISDIR) 1003 case EISDIR: 1004 return 1; 1005#endif 1006 case EACCES: 1007 /* When skipping directories, don't worry about 1008 directories that can't be opened. */ 1009 if (isdir (file)) 1010 return 1; 1011 break; 1012 } 1013 } 1014 1015 suppressible_error (file, e); 1016 return 1; 1017 } 1018 1019 filename = file; 1020 } 1021 1022#if defined(SET_BINARY) 1023 /* Set input to binary mode. Pipes are simulated with files 1024 on DOS, so this includes the case of "foo | grep bar". */ 1025 if (!isatty (desc)) 1026 SET_BINARY (desc); 1027#endif 1028 1029 count = grep (desc, file, stats); 1030 if (count < 0) 1031 status = count + 2; 1032 else 1033 { 1034 if (count_matches) 1035 { 1036 if (out_file) 1037 printf ("%s%c", filename, ':' & filename_mask); 1038 printf ("%d\n", count); 1039 } 1040 1041 status = !count; 1042 if (list_files == 1 - 2 * status) 1043 printf ("%s%c", filename, '\n' & filename_mask); 1044 1045 if (BZflag && bzbufdesc) 1046 BZ2_bzclose(bzbufdesc); 1047 else 1048#if HAVE_LIBZ > 0 1049 if (Zflag) 1050 gzclose(gzbufdesc); 1051 else 1052#endif 1053 if (! file) 1054 { 1055 off_t required_offset = outleft ? bufoffset : after_last_match; 1056 if ((bufmapped || required_offset != bufoffset) 1057 && lseek (desc, required_offset, SEEK_SET) < 0 1058 && S_ISREG (stats->stat.st_mode)) 1059 error (0, errno, "%s", filename); 1060 } 1061 else 1062 while (close (desc) != 0) 1063 if (errno != EINTR) 1064 { 1065 error (0, errno, "%s", file); 1066 break; 1067 } 1068 } 1069 1070 return status; 1071} 1072 1073static int 1074grepdir (char const *dir, struct stats const *stats) 1075{ 1076 int status = 1; 1077 struct stats const *ancestor; 1078 char *name_space; 1079 1080 /* Mingw32 does not support st_ino. No known working hosts use zero 1081 for st_ino, so assume that the Mingw32 bug applies if it's zero. */ 1082 if (stats->stat.st_ino) 1083 for (ancestor = stats; (ancestor = ancestor->parent) != 0; ) 1084 if (ancestor->stat.st_ino == stats->stat.st_ino 1085 && ancestor->stat.st_dev == stats->stat.st_dev) 1086 { 1087 if (!suppress_errors) 1088 error (0, 0, _("warning: %s: %s"), dir, 1089 _("recursive directory loop")); 1090 return 1; 1091 } 1092 1093 name_space = savedir (dir, stats->stat.st_size, included_patterns, 1094 excluded_patterns); 1095 1096 if (! name_space) 1097 { 1098 if (errno) 1099 suppressible_error (dir, errno); 1100 else 1101 xalloc_die (); 1102 } 1103 else 1104 { 1105 size_t dirlen = strlen (dir); 1106 int needs_slash = ! (dirlen == FILESYSTEM_PREFIX_LEN (dir) 1107 || IS_SLASH (dir[dirlen - 1])); 1108 char *file = NULL; 1109 char const *namep = name_space; 1110 struct stats child; 1111 child.parent = stats; 1112 out_file += !no_filenames; 1113 while (*namep) 1114 { 1115 size_t namelen = strlen (namep); 1116 file = xrealloc (file, dirlen + 1 + namelen + 1); 1117 strcpy (file, dir); 1118 file[dirlen] = '/'; 1119 strcpy (file + dirlen + needs_slash, namep); 1120 namep += namelen + 1; 1121 status &= grepfile (file, &child); 1122 } 1123 out_file -= !no_filenames; 1124 if (file) 1125 free (file); 1126 free (name_space); 1127 } 1128 1129 return status; 1130} 1131 1132static void 1133usage (int status) 1134{ 1135 if (status != 0) 1136 { 1137 fprintf (stderr, _("Usage: %s [OPTION]... PATTERN [FILE]...\n"), 1138 program_name); 1139 fprintf (stderr, _("Try `%s --help' for more information.\n"), 1140 program_name); 1141 } 1142 else 1143 { 1144 printf (_("Usage: %s [OPTION]... PATTERN [FILE] ...\n"), program_name); 1145 printf (_("\ 1146Search for PATTERN in each FILE or standard input.\n\ 1147Example: %s -i 'hello world' menu.h main.c\n\ 1148\n\ 1149Regexp selection and interpretation:\n"), program_name); 1150 printf (_("\ 1151 -E, --extended-regexp PATTERN is an extended regular expression\n\ 1152 -F, --fixed-strings PATTERN is a set of newline-separated strings\n\ 1153 -G, --basic-regexp PATTERN is a basic regular expression\n\ 1154 -P, --perl-regexp PATTERN is a Perl regular expression\n")); 1155 printf (_("\ 1156 -e, --regexp=PATTERN use PATTERN as a regular expression\n\ 1157 -f, --file=FILE obtain PATTERN from FILE\n\ 1158 -i, --ignore-case ignore case distinctions\n\ 1159 -w, --word-regexp force PATTERN to match only whole words\n\ 1160 -x, --line-regexp force PATTERN to match only whole lines\n\ 1161 -z, --null-data a data line ends in 0 byte, not newline\n")); 1162 printf (_("\ 1163\n\ 1164Miscellaneous:\n\ 1165 -s, --no-messages suppress error messages\n\ 1166 -v, --invert-match select non-matching lines\n\ 1167 -V, --version print version information and exit\n\ 1168 --help display this help and exit\n\ 1169 -J, --bz2decompress decompress bzip2'ed input before searching\n\ 1170 -Z, --decompress decompress input before searching (HAVE_LIBZ=1)\n\ 1171 --mmap use memory-mapped input if possible\n")); 1172 printf (_("\ 1173\n\ 1174Output control:\n\ 1175 -m, --max-count=NUM stop after NUM matches\n\ 1176 -b, --byte-offset print the byte offset with output lines\n\ 1177 -n, --line-number print line number with output lines\n\ 1178 --line-buffered flush output on every line\n\ 1179 -H, --with-filename print the filename for each match\n\ 1180 -h, --no-filename suppress the prefixing filename on output\n\ 1181 --label=LABEL print LABEL as filename for standard input\n\ 1182 -o, --only-matching show only the part of a line matching PATTERN\n\ 1183 -q, --quiet, --silent suppress all normal output\n\ 1184 --binary-files=TYPE assume that binary files are TYPE\n\ 1185 TYPE is 'binary', 'text', or 'without-match'\n\ 1186 -a, --text equivalent to --binary-files=text\n\ 1187 -I equivalent to --binary-files=without-match\n\ 1188 -d, --directories=ACTION how to handle directories\n\ 1189 ACTION is 'read', 'recurse', or 'skip'\n\ 1190 -D, --devices=ACTION how to handle devices, FIFOs and sockets\n\ 1191 ACTION is 'read' or 'skip'\n\ 1192 -R, -r, --recursive equivalent to --directories=recurse\n\ 1193 --include=PATTERN files that match PATTERN will be examined\n\ 1194 --exclude=PATTERN files that match PATTERN will be skipped.\n\ 1195 --exclude-from=FILE files that match PATTERN in FILE will be skipped.\n\ 1196 -L, --files-without-match only print FILE names containing no match\n\ 1197 -l, --files-with-matches only print FILE names containing matches\n\ 1198 -c, --count only print a count of matching lines per FILE\n\ 1199 --null print 0 byte after FILE name\n")); 1200 printf (_("\ 1201\n\ 1202Context control:\n\ 1203 -B, --before-context=NUM print NUM lines of leading context\n\ 1204 -A, --after-context=NUM print NUM lines of trailing context\n\ 1205 -C, --context=NUM print NUM lines of output context\n\ 1206 -NUM same as --context=NUM\n\ 1207 --color[=WHEN],\n\ 1208 --colour[=WHEN] use markers to distinguish the matching string\n\ 1209 WHEN may be `always', `never' or `auto'.\n\ 1210 -U, --binary do not strip CR characters at EOL (MSDOS)\n\ 1211 -u, --unix-byte-offsets report offsets as if CRs were not there (MSDOS)\n\ 1212\n\ 1213`egrep' means `grep -E'. `fgrep' means `grep -F'.\n\ 1214With no FILE, or when FILE is -, read standard input. If less than\n\ 1215two FILEs given, assume -h. Exit status is 0 if match, 1 if no match,\n\ 1216and 2 if trouble.\n")); 1217 printf (_("\nReport bugs to <bug-gnu-utils@gnu.org>.\n")); 1218 } 1219 exit (status); 1220} 1221 1222/* Set the matcher to M, reporting any conflicts. */ 1223static void 1224setmatcher (char const *m) 1225{ 1226 if (matcher && strcmp (matcher, m) != 0) 1227 error (2, 0, _("conflicting matchers specified")); 1228 matcher = m; 1229} 1230 1231/* Go through the matchers vector and look for the specified matcher. 1232 If we find it, install it in compile and execute, and return 1. */ 1233static int 1234install_matcher (char const *name) 1235{ 1236 int i; 1237#if defined(HAVE_SETRLIMIT) 1238 struct rlimit rlim; 1239#endif 1240 1241 for (i = 0; matchers[i].compile; i++) 1242 if (strcmp (name, matchers[i].name) == 0) 1243 { 1244 compile = matchers[i].compile; 1245 execute = matchers[i].execute; 1246#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_STACK) 1247 /* I think every platform needs to do this, so that regex.c 1248 doesn't oveflow the stack. The default value of 1249 `re_max_failures' is too large for some platforms: it needs 1250 more than 3MB-large stack. 1251 1252 The test for HAVE_SETRLIMIT should go into `configure'. */ 1253 if (!getrlimit (RLIMIT_STACK, &rlim)) 1254 { 1255 long newlim; 1256 extern long int re_max_failures; /* from regex.c */ 1257 1258 /* Approximate the amount regex.c needs, plus some more. */ 1259 newlim = re_max_failures * 2 * 20 * sizeof (char *); 1260 if (newlim > rlim.rlim_max) 1261 { 1262 newlim = rlim.rlim_max; 1263 re_max_failures = newlim / (2 * 20 * sizeof (char *)); 1264 } 1265 if (rlim.rlim_cur < newlim) 1266 { 1267 rlim.rlim_cur = newlim; 1268 setrlimit (RLIMIT_STACK, &rlim); 1269 } 1270 } 1271#endif 1272 return 1; 1273 } 1274 return 0; 1275} 1276 1277/* Find the white-space-separated options specified by OPTIONS, and 1278 using BUF to store copies of these options, set ARGV[0], ARGV[1], 1279 etc. to the option copies. Return the number N of options found. 1280 Do not set ARGV[N] to NULL. If ARGV is NULL, do not store ARGV[0] 1281 etc. Backslash can be used to escape whitespace (and backslashes). */ 1282static int 1283prepend_args (char const *options, char *buf, char **argv) 1284{ 1285 char const *o = options; 1286 char *b = buf; 1287 int n = 0; 1288 1289 for (;;) 1290 { 1291 while (ISSPACE ((unsigned char) *o)) 1292 o++; 1293 if (!*o) 1294 return n; 1295 if (argv) 1296 argv[n] = b; 1297 n++; 1298 1299 do 1300 if ((*b++ = *o++) == '\\' && *o) 1301 b[-1] = *o++; 1302 while (*o && ! ISSPACE ((unsigned char) *o)); 1303 1304 *b++ = '\0'; 1305 } 1306} 1307 1308/* Prepend the whitespace-separated options in OPTIONS to the argument 1309 vector of a main program with argument count *PARGC and argument 1310 vector *PARGV. */ 1311static void 1312prepend_default_options (char const *options, int *pargc, char ***pargv) 1313{ 1314 if (options) 1315 { 1316 char *buf = xmalloc (strlen (options) + 1); 1317 int prepended = prepend_args (options, buf, (char **) NULL); 1318 int argc = *pargc; 1319 char * const *argv = *pargv; 1320 char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp); 1321 *pargc = prepended + argc; 1322 *pargv = pp; 1323 *pp++ = *argv++; 1324 pp += prepend_args (options, buf, pp); 1325 while ((*pp++ = *argv++)) 1326 continue; 1327 } 1328} 1329 1330/* Get the next non-digit option from ARGC and ARGV. 1331 Return -1 if there are no more options. 1332 Process any digit options that were encountered on the way, 1333 and store the resulting integer into *DEFAULT_CONTEXT. */ 1334static int 1335get_nondigit_option (int argc, char *const *argv, int *default_context) 1336{ 1337 int opt; 1338 char buf[sizeof (uintmax_t) * CHAR_BIT + 4]; 1339 char *p = buf; 1340 1341 /* Set buf[0] to anything but '0', for the leading-zero test below. */ 1342 buf[0] = '\0'; 1343 1344 while (opt = getopt_long (argc, argv, short_options, long_options, NULL), 1345 '0' <= opt && opt <= '9') 1346 { 1347 /* Suppress trivial leading zeros, to avoid incorrect 1348 diagnostic on strings like 00000000000. */ 1349 p -= buf[0] == '0'; 1350 1351 *p++ = opt; 1352 if (p == buf + sizeof buf - 4) 1353 { 1354 /* Too many digits. Append "..." to make context_length_arg 1355 complain about "X...", where X contains the digits seen 1356 so far. */ 1357 strcpy (p, "..."); 1358 p += 3; 1359 break; 1360 } 1361 } 1362 if (p != buf) 1363 { 1364 *p = '\0'; 1365 context_length_arg (buf, default_context); 1366 } 1367 1368 return opt; 1369} 1370 1371int 1372main (int argc, char **argv) 1373{ 1374 char *keys; 1375 size_t keycc, oldcc, keyalloc; 1376 int with_filenames; 1377 int opt, cc, status; 1378 int default_context; 1379 FILE *fp; 1380 extern char *optarg; 1381 extern int optind; 1382 1383 initialize_main (&argc, &argv); 1384 program_name = argv[0]; 1385 if (program_name && strrchr (program_name, '/')) 1386 program_name = strrchr (program_name, '/') + 1; 1387 1388#if HAVE_LIBZ > 0 1389 if (program_name[0] == 'z') { 1390 Zflag = 1; 1391 ++program_name; 1392 } 1393#endif 1394 if (program_name[0] == 'b') { 1395 BZflag = 1; 1396 ++program_name; 1397 } 1398 1399#if defined(__MSDOS__) || defined(_WIN32) 1400 /* DOS and MS-Windows use backslashes as directory separators, and usually 1401 have an .exe suffix. They also have case-insensitive filesystems. */ 1402 if (program_name) 1403 { 1404 char *p = program_name; 1405 char *bslash = strrchr (argv[0], '\\'); 1406 1407 if (bslash && bslash >= program_name) /* for mixed forward/backslash case */ 1408 program_name = bslash + 1; 1409 else if (program_name == argv[0] 1410 && argv[0][0] && argv[0][1] == ':') /* "c:progname" */ 1411 program_name = argv[0] + 2; 1412 1413 /* Collapse the letter-case, so `strcmp' could be used hence. */ 1414 for ( ; *p; p++) 1415 if (*p >= 'A' && *p <= 'Z') 1416 *p += 'a' - 'A'; 1417 1418 /* Remove the .exe extension, if any. */ 1419 if ((p = strrchr (program_name, '.')) && strcmp (p, ".exe") == 0) 1420 *p = '\0'; 1421 } 1422#endif 1423 1424 keys = NULL; 1425 keycc = 0; 1426 with_filenames = 0; 1427 eolbyte = '\n'; 1428 filename_mask = ~0; 1429 1430 max_count = TYPE_MAXIMUM (off_t); 1431 1432 /* The value -1 means to use DEFAULT_CONTEXT. */ 1433 out_after = out_before = -1; 1434 /* Default before/after context: chaged by -C/-NUM options */ 1435 default_context = 0; 1436 /* Changed by -o option */ 1437 only_matching = 0; 1438 1439 /* Internationalization. */ 1440#if defined(HAVE_SETLOCALE) 1441 setlocale (LC_ALL, ""); 1442#endif 1443#if defined(ENABLE_NLS) 1444 bindtextdomain (PACKAGE, LOCALEDIR); 1445 textdomain (PACKAGE); 1446#endif 1447 1448 atexit (close_stdout); 1449 1450 prepend_default_options (getenv ("GREP_OPTIONS"), &argc, &argv); 1451 1452 while ((opt = get_nondigit_option (argc, argv, &default_context)) != -1) 1453 switch (opt) 1454 { 1455 case 'A': 1456 context_length_arg (optarg, &out_after); 1457 break; 1458 1459 case 'B': 1460 context_length_arg (optarg, &out_before); 1461 break; 1462 1463 case 'C': 1464 /* Set output match context, but let any explicit leading or 1465 trailing amount specified with -A or -B stand. */ 1466 context_length_arg (optarg, &default_context); 1467 break; 1468 1469 case 'D': 1470 if (strcmp (optarg, "read") == 0) 1471 devices = READ_DEVICES; 1472 else if (strcmp (optarg, "skip") == 0) 1473 devices = SKIP_DEVICES; 1474 else 1475 error (2, 0, _("unknown devices method")); 1476 break; 1477 1478 case 'E': 1479 setmatcher ("egrep"); 1480 break; 1481 1482 case 'F': 1483 setmatcher ("fgrep"); 1484 break; 1485 1486 case 'P': 1487 setmatcher ("perl"); 1488 break; 1489 1490 case 'G': 1491 setmatcher ("grep"); 1492 break; 1493 1494 case 'H': 1495 with_filenames = 1; 1496 break; 1497 1498 case 'I': 1499 binary_files = WITHOUT_MATCH_BINARY_FILES; 1500 break; 1501 case 'J': 1502 if (Zflag) 1503 { 1504 printf (_("Cannot mix -Z and -J.\n")); 1505 usage (2); 1506 } 1507 BZflag = 1; 1508 break; 1509 1510 case 'U': 1511#if defined(HAVE_DOS_FILE_CONTENTS) 1512 dos_use_file_type = DOS_BINARY; 1513#endif 1514 break; 1515 1516 case 'u': 1517#if defined(HAVE_DOS_FILE_CONTENTS) 1518 dos_report_unix_offset = 1; 1519#endif 1520 break; 1521 1522 case 'V': 1523 show_version = 1; 1524 break; 1525 1526 case 'X': 1527 setmatcher (optarg); 1528 break; 1529 1530 case 'a': 1531 binary_files = TEXT_BINARY_FILES; 1532 break; 1533 1534 case 'b': 1535 out_byte = 1; 1536 break; 1537 1538 case 'c': 1539 count_matches = 1; 1540 break; 1541 1542 case 'd': 1543 if (strcmp (optarg, "read") == 0) 1544 directories = READ_DIRECTORIES; 1545 else if (strcmp (optarg, "skip") == 0) 1546 directories = SKIP_DIRECTORIES; 1547 else if (strcmp (optarg, "recurse") == 0) 1548 directories = RECURSE_DIRECTORIES; 1549 else 1550 error (2, 0, _("unknown directories method")); 1551 break; 1552 1553 case 'e': 1554 cc = strlen (optarg); 1555 keys = xrealloc (keys, keycc + cc + 1); 1556 strcpy (&keys[keycc], optarg); 1557 keycc += cc; 1558 keys[keycc++] = '\n'; 1559 break; 1560 1561 case 'f': 1562 fp = strcmp (optarg, "-") != 0 ? fopen (optarg, "r") : stdin; 1563 if (!fp) 1564 error (2, errno, "%s", optarg); 1565 for (keyalloc = 1; keyalloc <= keycc + 1; keyalloc *= 2) 1566 ; 1567 keys = xrealloc (keys, keyalloc); 1568 oldcc = keycc; 1569 while (!feof (fp) 1570 && (cc = fread (keys + keycc, 1, keyalloc - 1 - keycc, fp)) > 0) 1571 { 1572 keycc += cc; 1573 if (keycc == keyalloc - 1) 1574 keys = xrealloc (keys, keyalloc *= 2); 1575 } 1576 if (fp != stdin) 1577 fclose(fp); 1578 /* Append final newline if file ended in non-newline. */ 1579 if (oldcc != keycc && keys[keycc - 1] != '\n') 1580 keys[keycc++] = '\n'; 1581 break; 1582 1583 case 'h': 1584 no_filenames = 1; 1585 break; 1586 1587 case 'i': 1588 case 'y': /* For old-timers . . . */ 1589 match_icase = 1; 1590 break; 1591 1592 case 'L': 1593 /* Like -l, except list files that don't contain matches. 1594 Inspired by the same option in Hume's gre. */ 1595 list_files = -1; 1596 break; 1597 1598 case 'l': 1599 list_files = 1; 1600 break; 1601 1602 case 'm': 1603 { 1604 uintmax_t value; 1605 switch (xstrtoumax (optarg, 0, 10, &value, "")) 1606 { 1607 case LONGINT_OK: 1608 max_count = value; 1609 if (0 <= max_count && max_count == value) 1610 break; 1611 /* Fall through. */ 1612 case LONGINT_OVERFLOW: 1613 max_count = TYPE_MAXIMUM (off_t); 1614 break; 1615 1616 default: 1617 error (2, 0, _("invalid max count")); 1618 } 1619 } 1620 break; 1621 1622 case 'n': 1623 out_line = 1; 1624 break; 1625 1626 case 'o': 1627 only_matching = 1; 1628 break; 1629 1630 case 'q': 1631 exit_on_match = 1; 1632 close_stdout_set_status(0); 1633 break; 1634 1635 case 'R': 1636 case 'r': 1637 directories = RECURSE_DIRECTORIES; 1638 break; 1639 1640 case 's': 1641 suppress_errors = 1; 1642 break; 1643 1644 case 'v': 1645 out_invert = 1; 1646 break; 1647 1648 case 'w': 1649 match_words = 1; 1650 break; 1651 1652 case 'x': 1653 match_lines = 1; 1654 break; 1655 1656 case 'Z': 1657#if HAVE_LIBZ > 0 1658 if (BZflag) 1659 { 1660 printf (_("Cannot mix -J and -Z.\n")); 1661 usage (2); 1662 } 1663 Zflag = 1; 1664#else 1665 filename_mask = 0; 1666#endif 1667 break; 1668 1669 case 'z': 1670 eolbyte = '\0'; 1671 break; 1672 1673 case BINARY_FILES_OPTION: 1674 if (strcmp (optarg, "binary") == 0) 1675 binary_files = BINARY_BINARY_FILES; 1676 else if (strcmp (optarg, "text") == 0) 1677 binary_files = TEXT_BINARY_FILES; 1678 else if (strcmp (optarg, "without-match") == 0) 1679 binary_files = WITHOUT_MATCH_BINARY_FILES; 1680 else 1681 error (2, 0, _("unknown binary-files type")); 1682 break; 1683 1684 case COLOR_OPTION: 1685 if(optarg) { 1686 if(!strcasecmp(optarg, "always") || !strcasecmp(optarg, "yes") || 1687 !strcasecmp(optarg, "force")) 1688 color_option = 1; 1689 else if(!strcasecmp(optarg, "never") || !strcasecmp(optarg, "no") || 1690 !strcasecmp(optarg, "none")) 1691 color_option = 0; 1692 else if(!strcasecmp(optarg, "auto") || !strcasecmp(optarg, "tty") || 1693 !strcasecmp(optarg, "if-tty")) 1694 color_option = 2; 1695 else 1696 show_help = 1; 1697 } else 1698 color_option = 2; 1699 if(color_option == 2) { 1700 if(isatty(STDOUT_FILENO) && getenv("TERM") && 1701 strcmp(getenv("TERM"), "dumb")) 1702 color_option = 1; 1703 else 1704 color_option = 0; 1705 } 1706 break; 1707 1708 case EXCLUDE_OPTION: 1709 if (!excluded_patterns) 1710 excluded_patterns = new_exclude (); 1711 add_exclude (excluded_patterns, optarg); 1712 break; 1713 1714 case EXCLUDE_FROM_OPTION: 1715 if (!excluded_patterns) 1716 excluded_patterns = new_exclude (); 1717 if (add_exclude_file (add_exclude, excluded_patterns, optarg, '\n') 1718 != 0) 1719 { 1720 error (2, errno, "%s", optarg); 1721 } 1722 break; 1723 1724 case INCLUDE_OPTION: 1725 if (!included_patterns) 1726 included_patterns = new_exclude (); 1727 add_exclude (included_patterns, optarg); 1728 break; 1729 1730 case LINE_BUFFERED_OPTION: 1731 line_buffered = 1; 1732 break; 1733 1734 case LABEL_OPTION: 1735 label = optarg; 1736 break; 1737 1738 case 0: 1739 /* long options */ 1740 break; 1741 1742 default: 1743 usage (2); 1744 break; 1745 1746 } 1747 1748 /* POSIX.2 says that -q overrides -l, which in turn overrides the 1749 other output options. */ 1750 if (exit_on_match) 1751 list_files = 0; 1752 if (exit_on_match | list_files) 1753 { 1754 count_matches = 0; 1755 done_on_match = 1; 1756 } 1757 out_quiet = count_matches | done_on_match; 1758 1759 if (out_after < 0) 1760 out_after = default_context; 1761 if (out_before < 0) 1762 out_before = default_context; 1763 1764 if (color_option) 1765 { 1766 char *userval = getenv ("GREP_COLOR"); 1767 if (userval != NULL && *userval != '\0') 1768 grep_color = userval; 1769 } 1770 1771 if (! matcher) 1772 matcher = program_name; 1773 1774 if (show_version) 1775 { 1776 printf (_("%s (GNU grep) %s\n"), matcher, VERSION); 1777 printf ("\n"); 1778 printf (_("\ 1779Copyright 1988, 1992-1999, 2000, 2001 Free Software Foundation, Inc.\n")); 1780 printf (_("\ 1781This is free software; see the source for copying conditions. There is NO\n\ 1782warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n")); 1783 printf ("\n"); 1784 exit (0); 1785 } 1786 1787 if (show_help) 1788 usage (0); 1789 1790 if (keys) 1791 { 1792 if (keycc == 0) 1793 { 1794 /* No keys were specified (e.g. -f /dev/null). Match nothing. */ 1795 out_invert ^= 1; 1796 match_lines = match_words = 0; 1797 } 1798 else 1799 /* Strip trailing newline. */ 1800 --keycc; 1801 } 1802 else 1803 if (optind < argc) 1804 { 1805 keys = argv[optind++]; 1806 keycc = strlen (keys); 1807 } 1808 else 1809 usage (2); 1810 1811 if (!install_matcher (matcher) && !install_matcher ("default")) 1812 abort (); 1813 1814#ifdef MBS_SUPPORT 1815 if (MB_CUR_MAX != 1 && match_icase) 1816 { 1817 wchar_t wc; 1818 mbstate_t cur_state, prev_state; 1819 int i, len = strlen(keys); 1820 1821 memset(&cur_state, 0, sizeof(mbstate_t)); 1822 for (i = 0; i <= len ;) 1823 { 1824 size_t mbclen; 1825 mbclen = mbrtowc(&wc, keys + i, len - i, &cur_state); 1826 if (mbclen == (size_t) -1 || mbclen == (size_t) -2 || mbclen == 0) 1827 { 1828 /* An invalid sequence, or a truncated multibyte character. 1829 We treat it as a singlebyte character. */ 1830 mbclen = 1; 1831 } 1832 else 1833 { 1834 if (iswupper((wint_t)wc)) 1835 { 1836 wc = towlower((wint_t)wc); 1837 wcrtomb(keys + i, wc, &cur_state); 1838 } 1839 } 1840 i += mbclen; 1841 } 1842 } 1843#endif /* MBS_SUPPORT */ 1844 1845 (*compile)(keys, keycc); 1846 1847 if ((argc - optind > 1 && !no_filenames) || with_filenames) 1848 out_file = 1; 1849 1850#ifdef SET_BINARY 1851 /* Output is set to binary mode because we shouldn't convert 1852 NL to CR-LF pairs, especially when grepping binary files. */ 1853 if (!isatty (1)) 1854 SET_BINARY (1); 1855#endif 1856 1857 if (max_count == 0) 1858 exit (1); 1859 1860 if (optind < argc) 1861 { 1862 status = 1; 1863 do 1864 { 1865 char *file = argv[optind]; 1866 if ((included_patterns || excluded_patterns) 1867 && !isdir (file)) 1868 { 1869 if (included_patterns && 1870 ! excluded_filename (included_patterns, file, 0)) 1871 continue; 1872 if (excluded_patterns && 1873 excluded_filename (excluded_patterns, file, 0)) 1874 continue; 1875 } 1876 status &= grepfile (strcmp (file, "-") == 0 ? (char *) NULL : file, 1877 &stats_base); 1878 } 1879 while ( ++optind < argc); 1880 } 1881 else 1882 status = grepfile ((char *) NULL, &stats_base); 1883 1884 /* We register via atexit() to test stdout. */ 1885 exit (errseen ? 2 : status); 1886} 1887/* vim:set shiftwidth=2: */ 1888