From:	MERC::"uunet!WKUVX1.BITNET!FILESERV-Mgr" 12-JUN-1992 15:44:21.32
To:	galaxy::gleeve
CC:	
Subj:	GREP.07_OF_12

-+-+-+-+-+-+-+-+ START OF PART 7 -+-+-+-+-+-+-+-+
X`09trailing_context = 10 * trailing_context + c - '0';
X`09leading_context = 10 * leading_context + c - '0';
X`09break;
X
X      case 'A':
X`09if (! sscanf(optarg, "%d", &trailing_context)
X`09    `7C`7C trailing_context < 0)
X`09  usage_and_die();
X`09break;
X
X      case 'B':
X`09if (! sscanf(optarg, "%d", &leading_context)
X`09    `7C`7C leading_context < 0)
X`09  usage_and_die();
X`09break;
X
X      case 'C':
X`09trailing_context = leading_context = 2;
X`09break;
X
X      case 'V':
X`09fprintf(stderr, "%s\n", version);
X`09break;
X
X      case 'b':
X`09byte_count = 1;
X`09break;
X
X      case 'c':
X`09count_lines = 1;
X`09silent = 1;
X`09break;
X
X      case 'e':
X`09/* It doesn't make sense to mix -f and -e. */
X`09if (regexp_file)
X`09  usage_and_die();
X`09the_regexp = optarg;
X`09break;
X
X      case 'f':
X`09/* It doesn't make sense to mix -f and -e. */
X`09if (the_regexp)
X`09  usage_and_die();
X`09regexp_file = optarg;
X`09break;
X
X      case 'h':
X`09no_filenames = 1;
X`09break;
X
X      case 'i':
X`09ignore_case = 1;
X`09for (c = 0; c < _NOTCHAR; ++c)
X`09  if (isupper(c))
X`09    translate`5Bc`5D = tolower(c);
X`09  else
X`09    translate`5Bc`5D = c;
X`09regex.translate = translate;
X`09break;
X
X      case 'l':
X`09list_files = 1;
X`09silent = 1;
X`09break;
X
X      case 'n':
X`09line_numbers = 1;
X`09break;
X
X      case 's':
X`09silent = 1;
X`09break;
X
X      case 'v':
X`09nonmatching_lines = 1;
X`09break;
X
X      case 'w':
X`09whole_word = 1;
X`09break;
X
X      case 'x':
X`09whole_line = 1;
X`09break;
X
X      default:
X`09/* This can't happen. */
X`09fprintf(stderr, "%s: getopt(3) let one by!\n", prog);
X`09usage_and_die();
X`09break;
X      `7D
X
X  /* Set the syntax depending on whether we are EGREP or not. */
X#ifdef EGREP
X  regsyntax(RE_SYNTAX_EGREP, ignore_case);
X  re_set_syntax(RE_SYNTAX_EGREP);
X#else
X  regsyntax(RE_SYNTAX_GREP, ignore_case);
X  re_set_syntax(RE_SYNTAX_GREP);
X#endif
X
X  /* Compile the regexp according to all the options. */
X  if (regexp_file)
X    `7B
X      FILE *fp = fopen(regexp_file, "r");
X      int len = 256;
X      int i = 0;
X
X      if (! fp)
X`09`7B
X`09  fprintf(stderr, "%s: %s: %s\n", prog, regexp_file,
X#ifdef VMS
X`09`09  strerror(errno,vaxc$errno));
X#else
X`09`09  sys_errlist`5Berrno`5D);
X#endif
X`09  exit(ERROR);
X`09`7D
X
X      the_regexp = malloc(len);
X      while ((c = getc(fp)) != EOF)
X`09`7B
X`09  the_regexp`5Bi++`5D = c;
X`09  if (i == len)
X`09    the_regexp = realloc(the_regexp, len *= 2);
X`09`7D
X      fclose(fp);
X      /* Nuke the concluding newline so we won't match the empty string. */
X      if (i > 0 && the_regexp`5Bi - 1`5D == '\n')
X`09--i;
X      regexp_len = i;
X    `7D
X  else if (! the_regexp)
X    `7B
X      if (optind >= argc)
X`09usage_and_die();
X      the_regexp = argv`5Boptind++`5D;
X      regexp_len = strlen(the_regexp);
X    `7D
X  else
X    regexp_len = strlen(the_regexp);
X `20
X  if (whole_word `7C`7C whole_line)
X    `7B
X      /* In the whole-word case, we use the pattern:
X`09 (`5E`7C`5B`5EA-Za-z_`5D)(userpattern)(`5B`5EA-Za-z_`5D`7C$).
X`09 In the whole-line case, we use the pattern:
X`09 `5E(userpattern)$.
X`09 BUG: Using `5BA-Za-z_`5D is locale-dependent!  */
X
X      char *n = malloc(regexp_len + 50);
X      int i = 0;
X
X#ifdef EGREP
X      if (whole_word)
X`09strcpy(n, "(`5E`7C`5B`5EA-Za-z_`5D)(");
X      else
X`09strcpy(n, "`5E(");
X#else
X      /* Todo:  Make *sure* this is the right syntax.  Down with grep! */
X      if (whole_word)
X`09strcpy(n, "\\(`5E\\`7C`5B`5EA-Za-z_`5D\\)\\(");
X      else
X`09strcpy(n, "`5E\\(");
X#endif
X      i = strlen(n);
X      bcopy(the_regexp, n + i, regexp_len);
X      i += regexp_len;
X#ifdef EGREP
X      if (whole_word)
X`09strcpy(n + i, ")(`5B`5EA-Za-z_`5D`7C$)");
X      else
X`09strcpy(n + i, ")$");
X#else
X      if (whole_word)
X`09strcpy(n + i, "\\)\\(`5B`5EA-Za-z_`5D\\`7C$\\)");
X      else
X`09strcpy(n + i, "\\)$");
X#endif
X      i += strlen(n + i);
X      regcompile(n, i, &reg, 1);
X    `7D
X  else
X    regcompile(the_regexp, regexp_len, &reg, 1);
X
X `20
X  if (regex_errmesg = re_compile_pattern(the_regexp, regexp_len, &regex))
X    regerror(regex_errmesg);
X `20
X  /*
X    Find the longest metacharacter-free string which must occur in the
X    regexpr, before short-circuiting regexecute() with Boyer-Moore-Gosper.
X    (Conjecture:  The problem in general is NP-complete.)  If there is no
X    such string (like for many alternations), then default to full automaton
X    search.  regmust() code and heuristics `5Bsee dfa.c`5D courtesy
X    Arthur David Olson.
X    */
X  if (line_numbers == 0 && nonmatching_lines == 0)
X    `7B
X      if (reg.mustn == 0 `7C`7C reg.mustn == MUST_MAX `7C`7C
X#ifdef VMS
X  `09  (char *) index(reg.must, '\0') != reg.must + reg.mustn)
X#else
X`09  index(reg.must, '\0') != reg.must + reg.mustn)
X#endif
X`09bmgexec = 0;
X      else
X`09`7B
X`09  reg.must`5Breg.mustn`5D = '\0';
X`09  if (getenv("MUSTDEBUG") != NULL)
X`09    (void) printf("must have: \"%s\"\n", reg.must);
X`09  bmg_setup(reg.must, ignore_case);
X`09  bmgexec = 1;
X`09`7D
X    `7D
X `20
X  if (argc - optind < 2)
X    no_filenames = 1;
X
X  initialize_buffer();
X
X  if (argc > optind)
X    while (optind < argc)
X      `7B
X`09bufprev = eof = 0;
X`09filename = argv`5Boptind++`5D;
X#ifdef VMS
X`09fd = open(filename, 0, 0, "shr=get,put,del,upd");
X#else
X`09fd = open(filename, 0, 0);
X#endif
X`09if (fd < 0)
X`09  `7B
X`09    fprintf(stderr, "%s: %s: %s\n", prog, filename,
X#ifdef VMS
X`09`09    strerror(errno,vaxc$errno));
X#else
X`09`09    sys_errlist`5Berrno`5D);
X#endif
X`09    error = 1;
X`09    continue;
X`09  `7D
X`09if (line_count = grep())
X`09  matches_found = 1;
X`09close(fd);
X`09if (count_lines)
X`09  if (!no_filenames)
X`09    printf("%s:%d\n", filename, line_count);
X`09  else
X`09    printf("%d\n", line_count);
X`09else if (list_files && line_count)
X`09  printf("%s\n", filename);
X      `7D
X  else
X    `7B
X      if (line_count = grep())
X`09matches_found = 1;
X      if (count_lines)
X`09printf("%d\n", line_count);
X      else if (list_files && line_count)
X`09printf("<stdin>\n");
X    `7D
X
X  if (error)
X    exit(ERROR);
X  if (matches_found)
X    exit(MATCHES_FOUND);
X  exit(NO_MATCHES_FOUND);
X  return NO_MATCHES_FOUND;
X`7D
X
X/* Needed by the regexp routines.  This could be fancier, especially when
X   dealing with parallel regexps in files. */
Xvoid
Xregerror(s)
X     const char *s;
X`7B
X  fprintf(stderr, "%s: %s\n", prog, s);
X  exit(ERROR);
X`7D
X
X/*
X   bmg_setup() and bmg_search() adapted from:
X     Boyer/Moore/Gosper-assisted 'egrep' search, with delta0 table as in
X     original paper (CACM, October, 1977).  No delta1 or delta2.  According
V to
X     experiment (Horspool, Soft. Prac. Exp., 1982), delta2 is of minimal
X     practical value.  However, to improve for worst case input, integrating
X     the improved Galil strategies (Apostolico/Giancarlo, Siam. J. Comput.,
X     February 1986) deserves consideration.
X
X     James A. Woods`09`09`09`09Copyleft (C) 1986, 1988
X     NASA Ames Research Center
X*/
X
Xchar *
Xexecute(r, begin, end, newline, count, try_backref)
X  struct regexp *r;
X  char *begin;
X  char *end;
X  int newline;
X  int *count;
X  int *try_backref;
X`7B
X  register char *p, *s;
X  char *match;
X  char *start = begin;
X  char save;`09`09`09/* regexecute() sentinel */
X  int len;
X  char *bmg_search();
X
X  if (!bmgexec)`09`09`09/* full automaton search */
X    return(regexecute(r, begin, end, newline, count, try_backref));
X  else
X    `7B
X      len = end - begin;`20
X      while ((match = bmg_search((unsigned char *) start, len)) != NULL)
X`09`7B
X`09  p = match;`09`09/* narrow search range to submatch line */
X`09  while (p > begin && *p != '\n')
X`09    p--;
X`09  s = match;
X`09  while (s < end && *s != '\n')
X`09    s++;
X`09  s++;
X
X`09  save = *s;
X`09  *s = '\0';
X`09  match = regexecute(r, p, s, newline, count, try_backref);
X`09  *s = save;
X
X`09  if (match != NULL)
X`09    return((char *) match);
X`09  else
X`09    `7B
X`09      start = s;
X`09      len = end - start;
X`09    `7D
X`09`7D
X      return(NULL);
X    `7D
X`7D
X
Xint`09`09delta0`5B256`5D;
Xunsigned char   cmap`5B256`5D;`09`09/* (un)folded characters */
Xunsigned char`09pattern`5B5000`5D;
Xint`09`09patlen;
X
Xchar *
Xbmg_search(buffer, buflen)
X  unsigned char *buffer;
X  int buflen;
X`7B
X  register unsigned char *k, *strend, *s, *buflim;
X  register int t;
X  int j;
X
X  if (patlen > buflen)
X    return NULL;
X
X  buflim = buffer + buflen;
X  if (buflen > patlen * 4)
X    strend = buflim - patlen * 4;
X  else
X    strend = buffer;
X
X  s = buffer;
X  k = buffer + patlen - 1;
X
X  for (;;)
X    `7B
X      /* The dreaded inner loop, revisited. */
X      while (k < strend && (t = delta0`5B*k`5D))
X`09`7B
X`09  k += t;
X`09  k += delta0`5B*k`5D;
X`09  k += delta0`5B*k`5D;
X`09`7D
X      while (k < buflim && delta0`5B*k`5D)
X`09++k;
X      if (k == buflim)
X`09break;
X   `20
X      j = patlen - 1;
X      s = k;
X      while (--j >= 0 && cmap`5B*--s`5D == pattern`5Bj`5D)
X`09;
X      /*`20
X`09delta-less shortcut for literati, but`20
X`09short shrift for genetic engineers.
X      */
X      if (j >= 0)
X`09k++;
X      else `09`09/* submatch */
X`09return ((char *)k);
X    `7D
X  return(NULL);
X`7D
X
Xint
Xbmg_setup(pat, folded)`09`09`09/* compute "boyer-moore" delta table */
X  char *pat;
X  int folded;
X`7B`09`09`09`09`09/* ... HAKMEM lives ... */
X  int j;
X
X  patlen = strlen(pat);
X
X  if (folded) `09`09`09`09/* fold case while saving pattern */
X    for (j = 0; j < patlen; j++)`20
X      pattern`5Bj`5D = (isupper((int) pat`5Bj`5D) ?
X`09(char) tolower((int) pat`5Bj`5D) : pat`5Bj`5D);
X  else
X      bcopy(pat, pattern, patlen);
X
X  for (j = 0; j < 256; j++)
X    `7B
X      delta0`5Bj`5D = patlen;
X      cmap`5Bj`5D = (char) j;`09`09/* could be done at compile time */
X    `7D
X  for (j = 0; j < patlen - 1; j++)
X    delta0`5Bpattern`5Bj`5D`5D = patlen - j - 1;
X  delta0`5Bpattern`5Bpatlen - 1`5D`5D = 0;
X
X  if (folded)
X    `7B
X      for (j = 0; j < patlen - 1; j++)
X`09if (islower((int) pattern`5Bj`5D))
X`09  delta0`5Btoupper((int) pattern`5Bj`5D)`5D = patlen - j - 1;
X`09if (islower((int) pattern`5Bpatlen - 1`5D))
X`09  delta0`5Btoupper((int) pattern`5Bpatlen - 1`5D)`5D = 0;
X      for (j = 'A'; j <= 'Z'; j++)
X`09cmap`5Bj`5D = (char) tolower((int) j);
X    `7D
X`7D
$ CALL UNPACK [.GREP016]GREP.C;1 2086703233
$ create 'f'
X!
X!  CLD file for defining grep and egrep commands as DCL commands
X!
X!  To install for all users, modify the dev:`5Bdir`5D strings below and
X!  execute the following commands:
X!
X!`09$ SET COMMAND GREP.CLD/TABLE=SYS$LIBRARY:DCLTABLES.EXE-
X!`09`09/OUTPUT=SYS$COMMON:`5BSYSLIB`5DDCLTABLES.EXE
X!`09$ INSTALL :== $INSTALL/COMMAND
X!`09$ INSTALL REPLACE SYS$LIBRARY:DCLTABLES.EXE
X!
XDEFINE VERB grep
X`09image dev:`5Bdir`5Dgrep.exe`09`09!**** Local
X`09cliflags(foreign)
X
XDEFINE VERB egrep`09`09`09!**** Local
X`09image dev:`5Bdir`5Degrep.exe
X`09cliflags(foreign)
$ CALL UNPACK [.GREP016]GREP.CLD;1 307654495
$ create 'f'
XX-NEWS: wkuvx1 comp.os.vms: 1901
XRelay-Version: VMS News - V6.0-3 14/03/90 VAX/VMS V5.4; site wkuvx1.bitnet
XPath: wkuvx1.bitnet!vlsi!ukma!widener!iggy.GW.Vitalink.COM!lll-winken!sun-ba
Vrr!ccut!wnoc-tyo-news!sranha!anprda!akira
XNewsgroups: comp.os.vms
XSubject: Re: How about SEARCH on U**x
XMessage-ID: <1683@anprda.atson.asahi-np.co.jp>
XFrom: akira@atson.asahi-np.co.jp (Akira Takiguchi)
XDate: 17 Sep 91 05:13:12 GMT
XReply-To: akira@necom830.cc.titech.ac.jp
XReferences: <9109121805.AA18665@ucbvax.Berkeley.EDU>
XOrganization: ATSON, Inc. (a subsidiary of the Asahi Shimbun)
XLines: 44
X
XIn article <9109121805.AA18665@ucbvax.Berkeley.EDU>
X     SKELTON@vax.lse.ac.uk writes:
X>We've had some discussion about grep for VMS, but no-one has mentioned what
X>I miss on U**x, which is SEARCH. I'm asking here because only a hardened VM
VS
X>user would dare to suggest that SEARCH might be better than grep :-)
X
X     GNU egrep from Free Software Foundation, which I believe is ported
Xto VMS as well as unix, can satisfy most things from your wishlist.
X
X>What I particulary miss is the /WINDOW qualifier
X
X     egrep -A<num> -B<num> <regexp> files
X     ... prints num lines After and Before matching line.  or more simply:
X     egrep -C <regexp> files
X
X>, and then in order of
X>importance (to me) /MATCH (especially /MATCH=NAND),
X
X     Regexp used in egrep enables you to say:
X
X     egrep 'A`7CB`7CC' files
X     ... A or B or C.
X     egrep -v 'A`7CB`7CC' files
X     ... this is your favorite /MATCH=NAND.
X
X>/NOEXACT,
X
X     egrep -i <regexp> files
X
X>/REMAINING
X
X     This, sed or awk can do better.  For example, with sed:
X
X     sed -n -e '/regexp/,$p' file
X
X>and /FORMAT.
X
X     You should write a simple script with sed.  Perl (is also distributed
Xfreely under GPL license;  see comp.lang.perl) is better, because it can
Xhandle any binary file, which no grep nor sed can handle.
X--`20
X            Akira Takiguchi  at ATSON, Inc. (a subsidiary of the Asahi Shimb
Vun)
X                        WAKO GINZA bldg.  8-10-4 Ginza Chuo-ku Tokyo 104  Ja
Vpan
X    +81 3 3289 7051(voice) 7066(fax)  EMAIL TO <akira@necom830.cc.titech.ac.
Vjp>
$ CALL UNPACK [.GREP016]GREP.EXAMPLES;1 1333210391
$ create 'f'
X.TH GREP 1 "1988 December 13" "GNU Project" \" -*- nroff -*-
X.UC 4
X.SH NAME
Xgrep, egrep \- print lines matching a regular expression
X.SH SYNOPSIS
X.B grep
X`5B
X.B \-CVbchilnsvwx
X`5D `5B
X.BI \- num
X`5D `5B
X.B \-AB
X.I num
X`5D `5B `5B
X.B \-e
X`5D
X.I expr
X`7C
X.B \-f
X.I file
X`5D `5B
X.I "files ..."
X`5D
X.SH DESCRIPTION
X.I Grep
Xsearches the files listed in the arguments (or standard
Xinput if no files are given) for all lines that contain a match for
Xthe given
X.IR expr .
XIf any lines match, they are printed.
X.PP
XAlso, if any matches were found,
X.I grep
Xexits with a status of 0, but if no matches were found it exits
Xwith a status of 1.  This is useful for building shell scripts that
Xuse
X.I grep
Xas a condition for, for example, the
X.I if
Xstatement.
X.PP
XWhen invoked as
X.I egrep
Xthe syntax of the
X.I expr
Xis slightly different; See below.
X.br
X.SH "REGULAR EXPRESSIONS"
X.RS 2.5i
X.ta 1i 2i
X.sp
X.ti -2.0i
X(grep)`09(egrep)`09`09(explanation)
X.sp
X.ti -2.0i
X\fIc\fP`09\fIc\fP`09a single (non-meta) character matches itself.
X.sp
X.ti -2.0i
X\&.`09.`09matches any single character except newline.
X.sp
X.ti -2.0i
X\\?`09?`09postfix operator; preceeding item is optional.
X.sp
X.ti -2.0i
X\(**`09\(**`09postfix operator; preceeding item 0 or
Xmore times.
X.sp
X.ti -2.0i
X\\+`09+`09postfix operator; preceeding item 1 or
Xmore times.
X.sp
X.ti -2.0i
X\\`7C`09`7C`09infix operator; matches either
Xargument.
X.sp
X.ti -2.0i
X`5E`09`5E`09matches the empty string at the beginning of a line.
X.sp
X.ti -2.0i
X$`09$`09matches the empty string at the end of a line.
X.sp
X.ti -2.0i
X\\<`09\\<`09matches the empty string at the beginning of a word.
X.sp
X.ti -2.0i
X\\>`09\\>`09matches the empty string at the end of a word.
X.sp
X.ti -2.0i
X`5B\fIchars\fP`5D`09`5B\fIchars\fP`5D`09match any character in the given cla
Vss; if the
Xfirst character after `5B is `5E, match any character
Xnot in the given class; a range of characters may
Xbe specified by \fIfirst\-last\fP; for example, \\W
X(below) is equivalent to the class `5B`5EA\-Za\-z0\-9`5D
X.sp
X.ti -2.0i
X\\( \\)`09( )`09parentheses are used to override operator precedence.
X.sp
X.ti -2.0i
X\\\fIdigit\fP`09\\\fIdigit\fP`09\\\fIn\fP matches a repeat of the text
Xmatched earlier in the regexp by the subexpression inside the nth
Xopening parenthesis.
X.sp
X.ti -2.0i
X\\`09\\`09any special character may be preceded
Xby a backslash to match it literally.
X.sp
X.ti -2.0i
X(the following are for compatibility with GNU Emacs)
X.sp
X.ti -2.0i
X\\b`09\\b`09matches the empty string at the edge of a word.
X.sp
X.ti -2.0i
X\\B`09\\B`09matches the empty string if not at the edge of a word.
X.sp
X.ti -2.0i
X\\w`09\\w`09matches word-constituent characters (letters & digits).
X.sp
X.ti -2.0i
X\\W`09\\W`09matches characters that are not word-constituent.
X.RE
X.PP
XOperator precedence is (highest to lowest) ?, \(**, and +, concatenation,
Xand finally `7C.  All other constructs are syntactically identical to
Xnormal characters.  For the truly interested, the file dfa.c describes
X(and implements) the exact grammar understood by the parser.
X.SH OPTIONS
X.TP
X.BI \-A " num"
Xprint <num> lines of context after every matching line
X.TP
X.BI \-B " num"
Xprint
X.I num
Xlines of context before every matching line
X.TP
X.B \-C
Xprint 2 lines of context on each side of every match
X.TP
X.BI \- num
Xprint
X.I num
Xlines of context on each side of every match
X.TP
X.B \-V
Xprint the version number on the diagnostic output
X.TP
X.B \-b
Xprint every match preceded by its byte offset
X.TP
X.B \-c
Xprint a total count of matching lines only
X.TP
X.BI \-e " expr"
Xsearch for
X.IR expr ;
Xuseful if
X.I expr
Xbegins with \-
X.TP
X.BI \-f " file"
Xsearch for the expression contained in
X.I file
X.TP
X.B \-h
Xdon't display filenames on matches
X.TP
X.B \-i
Xignore case difference when comparing strings
X.TP
X.B \-l
Xlist files containing matches only
X.TP
X.B \-n
Xprint each match preceded by its line number
X.TP
X.B \-s
Xrun silently producing no output except error messages
X.TP
X.B \-v
Xprint only lines that contain no matches for the <expr>
X.TP
X.B \-w
Xprint only lines where the match is a complete word
X.TP
X.B \-x
Xprint only lines where the match is a whole line
X.SH "SEE ALSO"
Xemacs(1), ed(1), sh(1),
X.I "GNU Emacs Manual"
X.SH INCOMPATIBILITIES
XThe following incompatibilities with UNIX
X.I grep
Xexist:
X.PP
X.RS 0.5i
XThe context-dependent meaning of \(** is not quite the same (grep only).
X.PP
X.B \-b
Xprints a byte offset instead of a block offset.
X.PP
XThe `7B\fIm,n\fP`7D construct of System V grep is not implemented.
X.PP
X.SH BUGS
XGNU \fIe?grep\fP has been thoroughly debugged and tested over a period
Xof several years; we think it's a reliable beast or we wouldn't
Xdistribute it.  If by some fluke of the universe you discover a bug,
Xsend a detailed description (including options, regular expressions,
Xand a copy of an input file that can reproduce it) to mike@ai.mit.edu.
X.PP
X.SH AUTHORS
XMike Haertel wrote the deterministic regexp code and the bulk
Xof the program.
X.PP
XJames A. Woods is responsible for the hybridized search strategy
Xof using Boyer-Moore-Gosper fixed-string search as a filter
Xbefore calling the general regexp matcher.
X.PP
XArthur David Olson contributed code that finds fixed strings for
Xthe aforementioned BMG search for a large class of regexps.
X.PP
XRichard Stallman wrote the backtracking regexp matcher that is used
Xfor \\\fIdigit\fP backreferences, as well as the GNU getopt.  The
Xbacktracking matcher was originally written for GNU Emacs.
X.PP
XD. A. Gwyn wrote the C alloca emulation that is provided so
XSystem V machines can run this program.  (Alloca is used only
Xby RMS' backtracking matcher, and then only rarely, so there
Xis no loss if your machine doesn't have a "real" alloca.)
X.PP
XScott Anderson and Henry Spencer designed the regression tests
Xused in the "regress" script.
X.PP
XPaul Placeway wrote the original version of this manual page.
$ CALL UNPACK [.GREP016]GREP.MAN;1 90325944
$ create 'f'
XSYS$SHARE:VAXCRTL.EXE/SHARE
$ CALL UNPACK [.GREP016]GREP.OPT;1 1929406956
$ create 'f'
X.!
X.!  File:`09GREP.RNH
X.!
X.!  Author:`09Hunter Goatley
X.!
X.!  Date:`09September 11, 1991
X.!
X.!  Description:
X.!
X.!`09RUNOFF source file for GNU grep on-line help.
X.!
X.!`09To build:`09$ RUNOFF GREP.RNH
X.!`09`09`09$ LIBR/HELP/INSERT libr GREP
X.!
X.!  Modification history:
X.!
X.!`0901-003`09`09Hunter Goatley`09`0911-JUN-1992 16:46
X.!`09`09Minor mods (author info) for v1.6.
X.!
X.!`0901-002`09`09Hunter Goatley`09`0917-SEP-1991 08:44
X.!`09`09Added fgrep.
X.!
X.!`0901-001`09`09Hunter Goatley`09`0911-SEP-1991 09:24
X.!`09`09Genesis.
X.!
X.noflags
X.lm4 .rm72
X.indent -4
X1 GREP
X.br
XGREP is GNU grep, the Free Software Foundation's implementation of
Xgrep, which prints lines matching a regular expression.
XThe command syntax is UNIX-like, not VMS-like.
X.sk
XGrep searches the files listed in the arguments (or SYS$INPUT: if no files
Xare given) for all lines that contain a match for
Xthe given expression.  If any lines match, they are printed.
X.sk
XAlso, if any matches were found, grep exits with a status of 1, but if no
Xmatches found it exits with a status of 3.  This is useful for building
Xcommand procedures that use grep as a condition for, for example, the
XIF statement.
X.sk
XThe grep family also includes EGREP and FGREP.
XWhen invoked as egrep, the syntax of the expression is slightly different;
XSee the subtopic "Options".
X.sk
XWhen invoked as fgrep, the expression can consist only of a fixed string
X(regular expressions cannot be used).  Multiple search strings can be used
Xwith fgrep by creating a file containing one string per line and using
Xthe "-f" option.
X.sk
XFormat:
X.sk;.lm+1;.literal
Xgrep `5B-options`5D `5B-num`5D `5B-AB num`5D `5B`5B-e`5D expr`7C-f file`5D `
V5B"files ..."`5D
X.end literal;.lm-1
X.!--------------------------------------------------------------------------
V----
X.indent -4
X2 Options
X.literal
X-A <num>     print <num> lines of context after every matching line
X-B <num>     print <num> lines of context before every matching line
X-C           print 2 lines of context on each side of every match
X-<num>       print <num> lines of context on each side of every match
X-V           print the version number on the diagnostic output
X-b           print every match preceded by its byte offset
X-c           print a total count of matching lines only
X-e <expr>    search for <expr>; useful if <expr> begins with -
X-f <file>    search for the expression contained in file
X-h           don't display filenames on matches
X-i           ignore case difference when comparing strings
X-l           list files containing matches only
X-n           print each match preceded by its line number
X-s           run silently producing no output except error messages
X-v           print only lines that contain no matches for the <expr>
X-w           print only lines where the match is a complete word
X-x           print only lines where the match is a whole line
X.end literal
X.!--------------------------------------------------------------------------
V----
X.indent -4
X2 Regular_Expressions
X.br
XThe grep expression can include the following characters:
X.sk
X.literal
Xgrep    egrep   Explanation
X----    -----   -----------
Xc       c       a single (non-meta) character matches itself.
X.       .       matches any single character except newline.
X\?      ?       postfix operator; preceeding item is optional.
X*       *       postfix operator; preceeding item 0 or more times.
X\+      +       postfix operator; preceeding item 1 or more times.
X\`7C      `7C       infix operator; matches either argument.
X`5E       `5E       matches the empty string at the beginning of a line.
X$       $       matches the empty string at the end of a line.
X\<      \<      matches the empty string at the beginning of a word.
X\>      \>      matches the empty string at the end of a word.
X`5Bchars`5D `5Bchars`5D match any character in the given class; if the
X                first character after `5B is `5E, match any character
X                not in the given class; a range of characters may
X                be specified by "first-last"; for example, \W
X                (below) is equivalent to the class `5B`5EA-Za-z0-9`5D
X\( \)   ( )     parentheses are used to override operator precedence.
X\digit  \digit  \n matches a repeat of the text matched earlier in the
X                regexp by the subexpression inside the nth opening
X                parenthesis.
X\       \       any special character may be preceded by a backslash
X                to match it literally.
X
X(the following are for compatibility with GNU Emacs)
X
X\b      \b      matches the empty string at the edge of a word.
X\B      \B      matches the empty string if not at the edge of a word.
X\w      \w      matches word-constituent characters (letters & digits).
X\W      \W      matches characters that are not word-constituent.
X.end literal
X.sk
XOperator precedence is (highest to lowest) ?, **, and +, concatenation,
Xand finally `7C.  All other constructs are syntactically identical to
Xnormal characters.  For the truly interested, the file dfa.c describes
X(and implements) the exact grammar understood by the parser.
X.!--------------------------------------------------------------------------
V----
X.indent -4
X2 Incompatibilities
X.br
XThe following incompatibilities with UNIX grep exist:
X.br;.list 1,"o"
X.le;The context-dependent meaning of ** is not quite the same (grep only).
X.le;-b prints a byte offset instead of a block offset.
X.le;The `7Bm,nfP`7D construct of System V grep is not implemented.
X.le;Exit statuses are different from UNIX grep:
X.sk
X.literal
X        Meaning                  UNIX       VMS
X        -------                  ----       ---
X        matches found               0         1
X        no matches found            1         3
X        error                       2        44 (SS$_ABORT)
X.end literal
X.end list
X.!--------------------------------------------------------------------------
V----
X.indent -4
X2 Bugs
X.br
XGNU e?grep has been thoroughly debugged and tested over a period
Xof several years; we think it's a reliable beast or we wouldn't
Xdistribute it.  If by some fluke of the universe you discover a bug,
Xsend a detailed description (including options, regular expressions,
Xand a copy of an input file that can reproduce it) to mike@ai.mit.edu.
X.!--------------------------------------------------------------------------
V----
X.indent -4
X2 Availability
X.br
XGNU grep is free; anyone may redistribute copies of grep to anyone under the
Xterms stated in the  GNU General Public License, a copy of which may be foun
Vd in
Xeach copy of  "GNU Emacs". See also the comment at the beginning of the sour
Vce
Xcode file grep.c.
X.sk
XCopies of GNU grep may sometimes be received packaged with distributions of
V Unix
Xsystems, but it is never included in the scope of any license covering those
Xsystems.  Such inclusion violates the terms on which distribution is permitt
Ved.`20
XIn fact, the primary purpose of the General Public License is to prohibit an
Vyone
Xfrom attaching any other restrictions to redistribution of any of the Free
XSoftware Foundation programs.
X.!--------------------------------------------------------------------------
V----
X.indent-4
X2 Authors
X.br
XMike Haertel wrote the deterministic regexp code and the bulk
Xof the program.  Mike also wrote fgrep.
X.sk
XJames A. Woods is responsible for the hybridized search strategy
Xof using Boyer-Moore-Gosper fixed-string search as a filter
Xbefore calling the general regexp matcher.
X.sk
XArthur David Olson contributed code that finds fixed strings for
Xthe aforementioned BMG search for a large class of regexps.
X.sk
XRichard Stallman wrote the backtracking regexp matcher that is
Xused for \digit backreferences, as well as the getopt that
Xis provided for 4.2BSD sites.  The backtracking matcher was
Xoriginally written for GNU Emacs.
X.sk
XD. A. Gwyn wrote the C alloca emulation that is provided so
XSystem V machines can run this program.  (Alloca is used only
Xby RMS' backtracking matcher, and then only rarely, so there
Xis no loss if your machine doesn't have a "real" alloca.)
X.sk
XScott Anderson and Henry Spencer designed the regression tests
Xused in the "regress" script.
X.sk
XPaul Placeway wrote the original version of this manual page.
X.sk
XHunter Goatley ported grep 1.6 and fgrep 1.1 to VMS and produced the on-line
Xhelp for VMS.
X.sk;.indent -4
X2 Examples
X.br;
X.literal
X1.  $ grep int *.c
X.end literal
X.sk
XIn this example, all files with the extension .C will be searched for the
Xstring "int".
X.sk
X.literal
X2.  $ grep -i "`5E..int" *.c
X.end literal
X.sk
XIn this example, all files with the extension .C are searched for lines that
Xbegin with any two characters followed by "int".  The "-i" option tells grep
Xto ignore case.
X.sk
X.literal
X3.  $ grep -ih "`5E..int" *.c
X.end literal
X.sk
XIn this example, the "h" option is specified to prevent grep from displaying
+-+-+-+-+-+-+-+-  END  OF PART 7 +-+-+-+-+-+-+-+-
