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