Today's changes.
More changes.
This commit is contained in:
parent
cb27443abf
commit
8ad517944e
73 changed files with 2865 additions and 1293 deletions
260
src/cmd/grep/main.c
Normal file
260
src/cmd/grep/main.c
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
#define EXTERN
|
||||
#include "grep.h"
|
||||
|
||||
char *validflags = "bchiLlnsv";
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprint(2, "usage: grep [-%s] [-f file] [-e expr] [file ...]\n", validflags);
|
||||
exits("usage");
|
||||
}
|
||||
|
||||
void
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int i, status;
|
||||
|
||||
ARGBEGIN {
|
||||
default:
|
||||
if(utfrune(validflags, ARGC()) == nil)
|
||||
usage();
|
||||
flags[ARGC()]++;
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
flags['e']++;
|
||||
lineno = 0;
|
||||
str2top(ARGF());
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
flags['f']++;
|
||||
filename = ARGF();
|
||||
rein = Bopen(filename, OREAD);
|
||||
if(rein == 0) {
|
||||
fprint(2, "grep: can't open %s: %r\n", filename);
|
||||
exits("open");
|
||||
}
|
||||
lineno = 1;
|
||||
str2top(filename);
|
||||
break;
|
||||
} ARGEND
|
||||
|
||||
if(flags['f'] == 0 && flags['e'] == 0) {
|
||||
if(argc <= 0)
|
||||
usage();
|
||||
str2top(argv[0]);
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
|
||||
follow = mal(maxfollow*sizeof(*follow));
|
||||
state0 = initstate(topre.beg);
|
||||
|
||||
Binit(&bout, 1, OWRITE);
|
||||
switch(argc) {
|
||||
case 0:
|
||||
status = search(0, 0);
|
||||
break;
|
||||
case 1:
|
||||
status = search(argv[0], 0);
|
||||
break;
|
||||
default:
|
||||
status = 0;
|
||||
for(i=0; i<argc; i++)
|
||||
status |= search(argv[i], Hflag);
|
||||
break;
|
||||
}
|
||||
if(status)
|
||||
exits(0);
|
||||
exits("no matches");
|
||||
}
|
||||
|
||||
int
|
||||
search(char *file, int flag)
|
||||
{
|
||||
State *s, *ns;
|
||||
int c, fid, eof, nl, empty;
|
||||
long count, lineno, n;
|
||||
uchar *elp, *lp, *bol;
|
||||
|
||||
if(file == 0) {
|
||||
file = "stdin";
|
||||
fid = 0;
|
||||
flag |= Bflag;
|
||||
} else
|
||||
fid = open(file, OREAD);
|
||||
|
||||
if(fid < 0) {
|
||||
fprint(2, "grep: can't open %s: %r\n", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(flags['b'])
|
||||
flag ^= Bflag; /* dont buffer output */
|
||||
if(flags['c'])
|
||||
flag |= Cflag; /* count */
|
||||
if(flags['h'])
|
||||
flag &= ~Hflag; /* do not print file name in output */
|
||||
if(flags['i'])
|
||||
flag |= Iflag; /* fold upper-lower */
|
||||
if(flags['l'])
|
||||
flag |= Llflag; /* print only name of file if any match */
|
||||
if(flags['L'])
|
||||
flag |= LLflag; /* print only name of file if any non match */
|
||||
if(flags['n'])
|
||||
flag |= Nflag; /* count only */
|
||||
if(flags['s'])
|
||||
flag |= Sflag; /* status only */
|
||||
if(flags['v'])
|
||||
flag |= Vflag; /* inverse match */
|
||||
|
||||
s = state0;
|
||||
lineno = 0;
|
||||
count = 0;
|
||||
eof = 0;
|
||||
empty = 1;
|
||||
nl = 0;
|
||||
lp = u.buf;
|
||||
bol = lp;
|
||||
|
||||
loop0:
|
||||
n = lp-bol;
|
||||
if(n > sizeof(u.pre))
|
||||
n = sizeof(u.pre);
|
||||
memmove(u.buf-n, bol, n);
|
||||
bol = u.buf-n;
|
||||
n = read(fid, u.buf, sizeof(u.buf));
|
||||
/* if file has no final newline, simulate one to emit matches to last line */
|
||||
if(n > 0) {
|
||||
empty = 0;
|
||||
nl = u.buf[n-1]=='\n';
|
||||
} else {
|
||||
if(n < 0){
|
||||
fprint(2, "grep: read error on %s: %r\n", file);
|
||||
return count != 0;
|
||||
}
|
||||
if(!eof && !nl && !empty) {
|
||||
u.buf[0] = '\n';
|
||||
n = 1;
|
||||
eof = 1;
|
||||
}
|
||||
}
|
||||
if(n <= 0) {
|
||||
close(fid);
|
||||
if(flag & Cflag) {
|
||||
if(flag & Hflag)
|
||||
Bprint(&bout, "%s:", file);
|
||||
Bprint(&bout, "%ld\n", count);
|
||||
}
|
||||
if(((flag&Llflag) && count != 0) || ((flag&LLflag) && count == 0))
|
||||
Bprint(&bout, "%s\n", file);
|
||||
Bflush(&bout);
|
||||
return count != 0;
|
||||
}
|
||||
lp = u.buf;
|
||||
elp = lp+n;
|
||||
if(flag & Iflag)
|
||||
goto loopi;
|
||||
|
||||
/*
|
||||
* normal character loop
|
||||
*/
|
||||
loop:
|
||||
c = *lp;
|
||||
ns = s->next[c];
|
||||
if(ns == 0) {
|
||||
increment(s, c);
|
||||
goto loop;
|
||||
}
|
||||
// if(flags['2'])
|
||||
// if(s->match)
|
||||
// print("%d: %.2x**\n", s, c);
|
||||
// else
|
||||
// print("%d: %.2x\n", s, c);
|
||||
lp++;
|
||||
s = ns;
|
||||
if(c == '\n') {
|
||||
lineno++;
|
||||
if(!!s->match == !(flag&Vflag)) {
|
||||
count++;
|
||||
if(flag & (Cflag|Sflag|Llflag|LLflag))
|
||||
goto cont;
|
||||
if(flag & Hflag)
|
||||
Bprint(&bout, "%s:", file);
|
||||
if(flag & Nflag)
|
||||
Bprint(&bout, "%ld: ", lineno);
|
||||
/* suppress extra newline at EOF unless we are labeling matches with file name */
|
||||
Bwrite(&bout, bol, lp-bol-(eof && !(flag&Hflag)));
|
||||
if(flag & Bflag)
|
||||
Bflush(&bout);
|
||||
}
|
||||
if((lineno & Flshcnt) == 0)
|
||||
Bflush(&bout);
|
||||
cont:
|
||||
bol = lp;
|
||||
}
|
||||
if(lp != elp)
|
||||
goto loop;
|
||||
goto loop0;
|
||||
|
||||
/*
|
||||
* character loop for -i flag
|
||||
* for speed
|
||||
*/
|
||||
loopi:
|
||||
c = *lp;
|
||||
if(c >= 'A' && c <= 'Z')
|
||||
c += 'a'-'A';
|
||||
ns = s->next[c];
|
||||
if(ns == 0) {
|
||||
increment(s, c);
|
||||
goto loopi;
|
||||
}
|
||||
lp++;
|
||||
s = ns;
|
||||
if(c == '\n') {
|
||||
lineno++;
|
||||
if(!!s->match == !(flag&Vflag)) {
|
||||
count++;
|
||||
if(flag & (Cflag|Sflag|Llflag|LLflag))
|
||||
goto conti;
|
||||
if(flag & Hflag)
|
||||
Bprint(&bout, "%s:", file);
|
||||
if(flag & Nflag)
|
||||
Bprint(&bout, "%ld: ", lineno);
|
||||
/* suppress extra newline at EOF unless we are labeling matches with file name */
|
||||
Bwrite(&bout, bol, lp-bol-(eof && !(flag&Hflag)));
|
||||
if(flag & Bflag)
|
||||
Bflush(&bout);
|
||||
}
|
||||
if((lineno & Flshcnt) == 0)
|
||||
Bflush(&bout);
|
||||
conti:
|
||||
bol = lp;
|
||||
}
|
||||
if(lp != elp)
|
||||
goto loopi;
|
||||
goto loop0;
|
||||
}
|
||||
|
||||
State*
|
||||
initstate(Re *r)
|
||||
{
|
||||
State *s;
|
||||
int i;
|
||||
|
||||
addcase(r);
|
||||
if(flags['1'])
|
||||
reprint("r", r);
|
||||
nfollow = 0;
|
||||
gen++;
|
||||
fol1(r, Cbegin);
|
||||
follow[nfollow++] = r;
|
||||
qsort(follow, nfollow, sizeof(*follow), fcmp);
|
||||
|
||||
s = sal(nfollow);
|
||||
for(i=0; i<nfollow; i++)
|
||||
s->re[i] = follow[i];
|
||||
return s;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue