34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz/***********************************************************************
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* This software is part of the ast package *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* Copyright (c) 1995-2009 AT&T Knowledge Ventures *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* and is licensed under the *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* Common Public License, Version 1.0 *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* by AT&T Knowledge Ventures *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* A copy of the License is available at *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* http://www.opensource.org/licenses/cpl1.0.txt *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* Information and Software Systems Research *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* AT&T Research *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* Florham Park NJ *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* Glenn Fowler <gsf@research.att.com> *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz* *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz***********************************************************************/
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#pragma prototyped
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic const char usage[] =
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[-?\n@(#)$Id: grep (AT&T Research) 2006-06-14 $\n]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland MainzUSAGE_LICENSE
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+NAME?grep - search lines in files for matching patterns]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+DESCRIPTION?The \bgrep\b commands search the named input files"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" for lines containing a match for the given \apatterns\a."
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" Matching lines are printed by default. The standard input is searched"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" if no files are given or when the file \b-\b is specified.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+?There are six variants of \bgrep\b, each one using a different form of"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" \apattern\a, controlled either by option or the command path"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" base name. Details of each variant may be found in \bregex\b(3).]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" {"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" [+grep?The default basic regular expressions (no alternations.)]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" [+egrep?Extended regular expressions (alternations, one or more.)]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" [+pgrep?\bperl\b(1) regular expressions (lenient extended.)]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" [+xgrep?Augmented regular expressions (conjunction, negation.)]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" [+fgrep?Fixed string expressions.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" [+agrep?Approximate regular expressions (not implemented.)]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" }"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[G:basic-regexp?\bgrep\b mode (default): basic regular expression \apatterns\a.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[E:extended-regexp?\begrep\b mode: extended regular expression \apatterns\a.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[X:augmented-regexp?\bxgrep\b mode: augmented regular expression \apatterns\a.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[P:perl-regexp?\bpgrep\b mode: \bperl\b(1) regular expression \apatterns\a.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[F:fixed-string?\bfgrep\b mode: fixed string \apatterns\a.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[A:approximate-regexp?\bagrep\b mode: approximate regular expression \apatterns\a (not implemented.)]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[C:context?Set the matched line context \abefore\a and \aafter\a count."
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" By default only matched lines are printed.]:?"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" [before[,after]]:=2,2]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[c:count?Only print a matching line count for each file.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[e:expression|pattern|regexp?Specify a matching \apattern\a. More than one"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" \apattern\a implies alternation. If this option is specified"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" then the command line \apattern\a must be omitted.]:"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" [pattern]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[f:file?Each line in \apattern-file\a is a \apattern\a, placed into a single"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" alternating expression.]:"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" [pattern-file]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[H:filename|with-filename?Prefix each matched line with the containing file name.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[h:no-filename?Suppress containing file name prefix for each matched line.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[i:ignore-case?Ignore case when matching.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[l:files-with-matches?Only print file names with at least one match.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[L:files-without-matches?Only print file names with no matches.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[b:highlight?Highlight matches using the ansi terminal bold sequence.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[v:invert-match|revert-match?Invert the \apattern\a match sense.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[m:label?All patterns must be of the form \alabel\a:\apattern\a. Match and"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" count output will be prefixed by the corresponding \alabel\a:.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[O:lenient?Enable lenient \apattern\a interpretation. This is the default.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[x:line-match|line-regexp?Force \apatterns\a to match complete lines.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[n:number|line-number?Prefix each matched line with its line number.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[N:name?Set the standard input file name prefix to"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" \aname\a.]:[name:=empty]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[q:quiet|silent?Do not print matching lines.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[S:strict?Enable strict \apattern\a interpretation with diagnostics.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[s:suppress|no-messages?Suppress error and warning messages.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[t:total?Only print a single matching line count for all files.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[T:test?Enable implementation specific tests.]:"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" [test]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[w:word-match|word-regexp?Force \apatterns\a to match complete words.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[a?Ignored for GNU compatibility.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"\n"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"\n[ pattern ] [ file ... ]\n"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"\n"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+DIAGNOSTICS?Exit status 0 if matches were found, 1 if no matches were found,"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" where \b-v\b invertes the exit status. Exit status 2 for other"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" errors that are accompanied by a message on the standard error.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+SEE ALSO?\bed\b(1), \bsed\b(1), \bperl\b(1), \bregex\b(3)]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+CAVEATS?Some expressions of necessity require exponential space"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" and/or time.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz"[+BUGS?Some expressions may use sub-optimal algorithms. For example,"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz" don't use this implementation to compute primes.]"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#include <ast.h>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#include <ctype.h>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#include <ccode.h>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#include <error.h>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#include <regex.h>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#ifndef EISDIR
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#define EISDIR (-1)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz/*
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * snarfed from Doug McElroy's C++ version
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz *
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * this grep is based on the Posix re package.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * unfortunately it has to have a nonstandard interface.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * 1. fgrep does not have usual operators. REG_LITERAL
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * caters for this.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * 2. grep allows null expressions, hence REG_NULL.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * 3. it may be possible to combine the multiple
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * patterns of grep into single patterns. important
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * special cases are handled by regcomb().
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * 4. anchoring by -x has to be done separately from
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * compilation (remember that fgrep has no ^ or $ operator),
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * hence REG_LEFT|REG_RIGHT. (An honest, but slow alternative:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * run regexec with REG_NOSUB off and nmatch=1 and check
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * whether the match is full length)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainztypedef struct Item_s /* list item - sue me for waste */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz struct Item_s* next; /* next in list */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz regex_t re; /* compiled re */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Sfulong_t hits; /* labeled pattern matches */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Sfulong_t total; /* total hits */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char string[1]; /* string value */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz} Item_t;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainztypedef struct List_s /* generic list */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Item_t* head; /* list head */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Item_t* tail; /* list tail */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz} List_t;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainztypedef struct State_s /* program state */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz struct
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char* base; /* sfsetbuf buffer */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz size_t size; /* sfsetbuf size */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int noshare; /* turn off SF_SHARE */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz } buffer;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz List_t file; /* pattern file list */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz List_t pattern; /* pattern list */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz List_t re; /* re list */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz regmatch_t posvec[1]; /* match position vector */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz regmatch_t* pos; /* match position pointer */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int posnum; /* number of match positions */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int any; /* if any pattern hit */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int list; /* list files with hits */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int notfound; /* some input file not found */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int options; /* regex options */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Sfulong_t hits; /* total matched pattern count */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz unsigned char byline; /* multiple pattern line by line*/
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz unsigned char count; /* count number of hits */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz unsigned char label; /* all patterns labeled */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz unsigned char match; /* match sense */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz unsigned char query; /* return status but no output */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz unsigned char number; /* line numbers */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz unsigned char prefix; /* print file prefix */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz unsigned char suppress; /* no unopenable file messages */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz unsigned char words; /* word matches only */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz} State_s;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic void
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzaddre(State_s *state, List_t* p, char* s)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int c;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char* b;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Item_t* x;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Sfio_t* t;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz b = s;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->label)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(s = strchr(s, ':')))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(3, "%s: label:pattern expected", b);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz c = s - b;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s++;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz c = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(x = newof(0, Item_t, 1, c)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(ERROR_SYSTEM|3, "out of space (pattern `%s')", b);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (c)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz memcpy(x->string, b, c);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->words)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(t = sfstropen()))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(ERROR_SYSTEM|3, "out of space (word pattern `%s')", s);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(state->options & REG_AUGMENTED))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfputc(t, '\\');
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfputc(t, '<');
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfputr(t, s, -1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(state->options & REG_AUGMENTED))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfputc(t, '\\');
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfputc(t, '>');
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(s = sfstruse(t)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(ERROR_SYSTEM|3, "out of space");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz t = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (c = regcomp(&x->re, s, state->options|REG_MULTIPLE))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz regfatal(&x->re, 3, c);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (t)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfstrclose(t);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!p->head)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz p->head = p->tail = x;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->number || !regrecord(&x->re))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state->byline = 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if (state->label || regcomb(&p->tail->re, &x->re))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz p->tail = p->tail->next = x;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!state->byline && (state->number || !state->label || !regrecord(&x->re)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state->byline = 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz free(x);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic void
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzaddstring(State_s *state, List_t* p, char* s)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Item_t* x;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(x = newof(0, Item_t, 1, strlen(s))))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(ERROR_SYSTEM|3, "out of space (string `%s')", s);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz strcpy(x->string, s);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (p->head)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz p->tail->next = x;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz p->head = x;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz p->tail = x;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic void
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzcompile(State_s *state)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int line;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz size_t n;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char* s;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char* t;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char* file;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Item_t* x;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Sfio_t* f;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz for (x = state->pattern.head; x; x = x->next)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz addre(state, &state->re, x->string);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz for (x = state->file.head; x; x = x->next)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s = x->string;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(f = sfopen(NiL, s, "r")))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(ERROR_SYSTEM|4, "%s: cannot open", s);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz file = error_info.file;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error_info.file = s;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz line = error_info.line;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error_info.line = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while (s = (char*)sfreserve(f, SF_UNBOUND, SF_LOCKR))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(n = sfvalue(f)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (s[n - 1] != '\n')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz for (t = s + n; t > s && *--t != '\n'; t--);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (t == s)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfread(f, s, 0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz n = t - s + 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s[n - 1] = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz addre(state, &state->re, s);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s[n - 1] = '\n';
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfread(f, s, n);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while ((s = sfgetr(f, '\n', 1)) || (s = sfgetr(f, '\n', -1)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error_info.line++;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz addre(state, &state->re, s);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error_info.file = file;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error_info.line = line;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfclose(f);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!state->re.head)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(3, "no pattern");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic void
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzhighlight(Sfio_t* sp, const char* s, int n, int so, int eo)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz static const char bold[] = {CC_esc,'[','1','m'};
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz static const char normal[] = {CC_esc,'[','0','m'};
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfwrite(sp, s, so);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfwrite(sp, bold, sizeof(bold));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfwrite(sp, s + so, eo - so);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfwrite(sp, normal, sizeof(normal));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfwrite(sp, s + eo, n - eo);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainztypedef struct
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz State_s *state;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Item_t *item;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz} record_handle;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic int
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzrecord(void* handle, const char* s, size_t len)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz record_handle *r_x = (record_handle *)handle;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz State_s *state = r_x->state;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Item_t *item = r_x->item;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz item->hits++;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->query || state->list)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return -1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!state->count)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->prefix)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstdout, "%s:", error_info.file);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->label)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstdout, "%s:", item->string);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->pos)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz highlight(sfstdout, s, len + 1, state->pos[0].rm_so, state->pos[0].rm_eo);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfwrite(sfstdout, s, len + 1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic void
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzexecute(State_s *state, Sfio_t* input, char* name)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register char* s;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char* file;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Item_t* x;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz size_t len;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int result;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int line;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Sfulong_t hits = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->buffer.noshare)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfset(input, SF_SHARE, 0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->buffer.size)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfsetbuf(input, state->buffer.base, state->buffer.size);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!name)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz name = "/dev/stdin";
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz file = error_info.file;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error_info.file = name;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz line = error_info.line;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error_info.line = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->byline)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz for (;;)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error_info.line++;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (s = sfgetr(input, '\n', 0))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz len = sfvalue(input) - 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if (s = sfgetr(input, '\n', -1))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz len = sfvalue(input);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s[len] = '\n';
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#if _you_like_the_noise
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(1, "newline appended");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (sferror(input) && errno != EISDIR)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(ERROR_SYSTEM|2, "read error");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz x = state->re.head;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz do
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(result = regnexec(&x->re, s, len, state->posnum, state->pos, 0)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!state->label)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz x->hits++;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->query || state->list)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz goto done;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!state->count)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->prefix)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstdout, "%s:", name);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->number)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstdout, "%d:", error_info.line);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstdout, "%s:", x->string);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->pos)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz highlight(sfstdout, s, len + 1, state->pos[0].rm_so, state->pos[0].rm_eo);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfwrite(sfstdout, s, len + 1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if (result != REG_NOMATCH)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz regfatal(&x->re, 3, result);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz } while (x = x->next);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!state->label && (x != 0) == state->match)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz hits++;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->query || state->list)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!state->count)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->prefix)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstdout, "%s:", name);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->number)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstdout, "%d:", error_info.line);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->pos)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz highlight(sfstdout, s, len + 1, state->pos[0].rm_so, state->pos[0].rm_eo);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfwrite(sfstdout, s, len + 1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register char* e;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register char* t;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char* r;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz static char* span = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz static size_t spansize = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s = e = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz for (;;)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (s < e)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz t = span;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz for (;;)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz len = 2 * (e - s) + t - span + 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz len = roundof(len, SF_BUFSIZE);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (spansize < len)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz spansize = len;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz len = t - span;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(span = newof(span, char, spansize, 0)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(ERROR_SYSTEM|3, "%s: line longer than %lu characters", name, len + e - s);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz t = span + len;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz len = e - s;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz memcpy(t, s, len);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz t += len;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(s = sfreserve(input, SF_UNBOUND, 0)) || (len = sfvalue(input)) <= 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if ((sfvalue(input) || sferror(input)) && errno != EISDIR)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(ERROR_SYSTEM|2, "%s: read error", name);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if (!(e = memchr(s, '\n', len)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz e = s + len;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz r = s + len;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz len = (e - s) + t - span;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz len = roundof(len, SF_BUFSIZE);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (spansize < len)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz spansize = len;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz len = t - span;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(span = newof(span, char, spansize, 0)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(ERROR_SYSTEM|3, "%s: line longer than %lu characters", name, len + e - s);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz t = span + len;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz len = e - s;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz memcpy(t, s, len);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz t += len;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s += len + 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz e = r;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz *t = '\n';
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz x = state->re.head;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz do
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz record_handle r_x = { state, x };
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if ((result = regrexec(&x->re, span, t - span, state->posnum, state->pos, state->options, '\n', (void*)&r_x, record)) < 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz goto done;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (result && result != REG_NOMATCH)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz regfatal(&x->re, 3, result);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz } while (x = x->next);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!s)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(s = sfreserve(input, SF_UNBOUND, 0)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if ((sfvalue(input) || sferror(input)) && errno != EISDIR)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(ERROR_SYSTEM|2, "%s: read error", name);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if ((len = sfvalue(input)) <= 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz e = s + len;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz t = e;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while (t > s)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (*--t == '\n')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz x = state->re.head;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz do
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz record_handle r_x = { state, x };
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if ((result = regrexec(&x->re, s, t - s, state->posnum, state->pos, state->options, '\n', (void*)&r_x, record)) < 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz goto done;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (result && result != REG_NOMATCH)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz regfatal(&x->re, 3, result);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz } while (x = x->next);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s = t + 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz done:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error_info.file = file;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error_info.line = line;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->byline && !state->label)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (hits && state->list >= 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state->any = 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!state->query)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!state->list)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->count)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->count & 2)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state->hits += hits;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->prefix)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstdout, "%s:", name);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstdout, "%I*u\n", sizeof(hits), hits);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if ((hits != 0) == (state->list > 0))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->list < 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state->any = 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstdout, "%s\n", name);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz x = state->re.head;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz do
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (x->hits && state->list >= 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state->any = 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->query)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!state->query)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!state->list)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->count)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->count & 2)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz x->total += x->hits;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state->hits += x->hits;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->prefix)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstdout, "%s:", name);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->label)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstdout, "%s:", x->string);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstdout, "%I*u\n", sizeof(x->hits), x->hits);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if ((x->hits != 0) == (state->list > 0))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->list < 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state->any = 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state->label)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstdout, "%s:%s\n", name, x->string);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstdout, "%s\n", name);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz x->hits = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz } while (x = x->next);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzint grep_main(int argc, char** argv, void *context)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int c;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char* s;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char* h;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Sfio_t* f;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz State_s state;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz memset(&state, 0, sizeof(state));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz NoP(argc);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.match = 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options = REG_FIRST|REG_NOSUB|REG_NULL;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz h = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (strcmp(astconf("CONFORMANCE", NiL, NiL), "standard"))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options |= REG_LENIENT;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (s = strrchr(argv[0], '/'))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s++;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s = argv[0];
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz switch (*s)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'e':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'E':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s = "egrep";
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options |= REG_EXTENDED;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'f':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'F':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s = "fgrep";
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options |= REG_LITERAL;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'p':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'P':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s = "pgrep";
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options |= REG_EXTENDED|REG_LENIENT;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'x':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'X':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s = "xgrep";
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options |= REG_AUGMENTED;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz default:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s = "grep";
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error_info.id = s;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while (c = optget(argv, usage))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz switch (c)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'E':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options |= REG_EXTENDED;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'F':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options |= REG_LITERAL;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'G':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options &= ~(REG_AUGMENTED|REG_EXTENDED);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'H':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.prefix = opt_info.num;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'L':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.list = -opt_info.num;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'N':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz h = opt_info.arg;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'O':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options |= REG_LENIENT;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'P':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options |= REG_EXTENDED|REG_LENIENT;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'S':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options &= ~REG_LENIENT;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'T':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz s = opt_info.arg;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz switch (*s)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'b':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'm':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz c = *s++;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.buffer.size = strton(s, &s, NiL, 1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (c == 'b' && !(state.buffer.base = newof(0, char, state.buffer.size, 0)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(ERROR_SYSTEM|3, "out of space [test buffer]");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (*s)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(3, "%s: invalid characters after test", s);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'f':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options |= REG_FIRST;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'l':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options |= REG_LEFT;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'n':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.buffer.noshare = 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'r':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options |= REG_RIGHT;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz default:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(3, "%s: unknown test", s);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'X':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options |= REG_AUGMENTED;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'a':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'b':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options &= ~(REG_FIRST|REG_NOSUB);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'c':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.count |= 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'e':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz addstring(&state, &state.pattern, opt_info.arg);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'f':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz addstring(&state, &state.file, opt_info.arg);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'h':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.prefix = 2;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'i':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options |= REG_ICASE;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'l':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.list = opt_info.num;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'm':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.label = 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'n':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.number = 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'q':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.query = 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 's':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.suppress = opt_info.num;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 't':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.count |= 2;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'v':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state.match = !opt_info.num)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options &= ~REG_INVERT;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options |= REG_INVERT;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'w':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.words = 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case 'x':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options |= REG_LEFT|REG_RIGHT;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case '?':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(ERROR_USAGE|4, "%s", opt_info.arg);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz case ':':
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(2, "%s", opt_info.arg);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz default:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(3, "%s: not implemented", opt_info.name);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz argv += opt_info.index;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if ((state.options & REG_LITERAL) && (state.options & (REG_AUGMENTED|REG_EXTENDED)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(3, "-F and -A or -P or -X are incompatible");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if ((state.options & REG_LITERAL) && state.words)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(ERROR_SYSTEM|3, "-F and -w are incompatible");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!state.file.head && !state.pattern.head)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!argv[0])
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(3, "no pattern");
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz addstring(&state, &state.pattern, *argv++);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!(state.options & (REG_FIRST|REG_NOSUB)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state.count || state.list || state.query || (state.options & REG_INVERT))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.options |= REG_FIRST|REG_NOSUB;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.pos = state.posvec;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.posnum = elementsof(state.posvec);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz compile(&state);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!argv[0])
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.prefix = h ? 1 : 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz execute(&state, sfstdin, h);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state.prefix > 1)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.prefix = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if (argv[1])
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.prefix = 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while (s = *argv++)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (f = sfopen(NiL, s, "r"))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz execute(&state, f, s);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfclose(f);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state.query && state.any)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz break;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz state.notfound = 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (!state.suppress)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz error(ERROR_SYSTEM|2, "%s: cannot open", s);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if ((state.count & 2) && !state.query && !state.list)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (state.label)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Item_t* x;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz x = state.re.head;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz do
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstdout, "%s:%I*u\n", x->string, sizeof(x->total), x->total);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz } while (x = x->next);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(sfstdout, "%I*u\n", sizeof(state.hits), state.hits);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return (state.notfound && !state.query) ? 2 : !state.any;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzint b_egrep(int argc, char** argv, void *context)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return grep_main(argc, argv, context);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzint b_grep(int argc, char** argv, void *context)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return grep_main(argc, argv, context);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzint b_fgrep(int argc, char** argv, void *context)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return grep_main(argc, argv, context);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzint b_pgrep(int argc, char** argv, void *context)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return grep_main(argc, argv, context);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzint b_xgrep(int argc, char** argv, void *context)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return grep_main(argc, argv, context);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}