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