Add original unix v6
This commit is contained in:
@@ -0,0 +1,342 @@
|
||||
#
|
||||
/*
|
||||
* grep -- print lines matching (or not matching) a pattern
|
||||
*
|
||||
*/
|
||||
|
||||
#define CCHR 2
|
||||
#define CDOT 4
|
||||
#define CCL 6
|
||||
#define NCCL 8
|
||||
#define CDOL 10
|
||||
#define CEOF 11
|
||||
|
||||
#define STAR 01
|
||||
|
||||
#define LBSIZE 256
|
||||
#define ESIZE 256
|
||||
|
||||
char ibuf[512];
|
||||
char expbuf[ESIZE];
|
||||
int lnum[2];
|
||||
char linebuf[LBSIZE+1];
|
||||
int bflag;
|
||||
int nflag;
|
||||
int cflag;
|
||||
int vflag;
|
||||
int nfile;
|
||||
int circf;
|
||||
int blkno;
|
||||
int tln[2];
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
extern fout;
|
||||
|
||||
fout = dup(1);
|
||||
flush();
|
||||
while (--argc > 0 && (++argv)[0][0]=='-')
|
||||
switch (argv[0][1]) {
|
||||
|
||||
case 'v':
|
||||
vflag++;
|
||||
continue;
|
||||
|
||||
case 'b':
|
||||
bflag++;
|
||||
continue;
|
||||
|
||||
case 'c':
|
||||
cflag++;
|
||||
continue;
|
||||
|
||||
case 'n':
|
||||
nflag++;
|
||||
continue;
|
||||
|
||||
default:
|
||||
printf2("Unknown flag\n");
|
||||
continue;
|
||||
}
|
||||
if (argc<=0)
|
||||
exit(2);
|
||||
compile(*argv);
|
||||
nfile = --argc;
|
||||
if (argc<=0)
|
||||
execute(0);
|
||||
else while (--argc >= 0) {
|
||||
argv++;
|
||||
execute(*argv);
|
||||
}
|
||||
flush();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
compile(astr)
|
||||
char *astr;
|
||||
{
|
||||
register c;
|
||||
register char *ep, *sp;
|
||||
char *lastep;
|
||||
int cclcnt;
|
||||
|
||||
ep = expbuf;
|
||||
sp = astr;
|
||||
if (*sp == '^') {
|
||||
circf++;
|
||||
sp++;
|
||||
}
|
||||
for (;;) {
|
||||
if (ep >= &expbuf[ESIZE])
|
||||
goto cerror;
|
||||
if ((c = *sp++) != '*')
|
||||
lastep = ep;
|
||||
switch (c) {
|
||||
|
||||
case '\0':
|
||||
*ep++ = CEOF;
|
||||
return;
|
||||
|
||||
case '.':
|
||||
*ep++ = CDOT;
|
||||
continue;
|
||||
|
||||
case '*':
|
||||
if (lastep==0)
|
||||
goto defchar;
|
||||
*lastep =| STAR;
|
||||
continue;
|
||||
|
||||
case '$':
|
||||
if (*sp != '\0')
|
||||
goto defchar;
|
||||
*ep++ = CDOL;
|
||||
continue;
|
||||
|
||||
case '[':
|
||||
*ep++ = CCL;
|
||||
*ep++ = 0;
|
||||
cclcnt = 1;
|
||||
if ((c = *sp++) == '^') {
|
||||
c = *sp++;
|
||||
ep[-2] = NCCL;
|
||||
}
|
||||
do {
|
||||
*ep++ = c;
|
||||
cclcnt++;
|
||||
if (c=='\0' || ep >= &expbuf[ESIZE])
|
||||
goto cerror;
|
||||
} while ((c = *sp++) != ']');
|
||||
lastep[1] = cclcnt;
|
||||
continue;
|
||||
|
||||
case '\\':
|
||||
if ((c = *sp++) == '\0')
|
||||
goto cerror;
|
||||
defchar:
|
||||
default:
|
||||
*ep++ = CCHR;
|
||||
*ep++ = c;
|
||||
}
|
||||
}
|
||||
cerror:
|
||||
printf2("RE error\n");
|
||||
}
|
||||
|
||||
execute(file)
|
||||
{
|
||||
register char *p1, *p2;
|
||||
register c;
|
||||
int f;
|
||||
char *ebp, *cbp;
|
||||
|
||||
if (file) {
|
||||
if ((f = open(file, 0)) < 0) {
|
||||
printf2("Can't open %s\n", file);
|
||||
}
|
||||
} else
|
||||
f = 0;
|
||||
ebp = ibuf;
|
||||
cbp = ibuf;
|
||||
lnum[0] = 0;
|
||||
lnum[1] = 0;
|
||||
tln[0] = 0;
|
||||
tln[1] = 0;
|
||||
blkno = -1;
|
||||
for (;;) {
|
||||
if ((++lnum[1])==0)
|
||||
lnum[1]++;
|
||||
if((lnum[1]&0377) == 0)
|
||||
flush();
|
||||
p1 = linebuf;
|
||||
p2 = cbp;
|
||||
for (;;) {
|
||||
if (p2 >= ebp) {
|
||||
if ((c = read(f, ibuf, 512)) <= 0) {
|
||||
close(f);
|
||||
if (cflag) {
|
||||
if (nfile > 1)
|
||||
printf("%s:", file);
|
||||
p1 = locv(tln[0],tln[1]);
|
||||
printf("%s\n", p1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
blkno++;
|
||||
p2 = ibuf;
|
||||
ebp = ibuf+c;
|
||||
}
|
||||
if ((c = *p2++) == '\n')
|
||||
break;
|
||||
if(c)
|
||||
if (p1 < &linebuf[LBSIZE-1])
|
||||
*p1++ = c;
|
||||
}
|
||||
*p1++ = 0;
|
||||
cbp = p2;
|
||||
p1 = linebuf;
|
||||
p2 = expbuf;
|
||||
if (circf) {
|
||||
if (advance(p1, p2))
|
||||
goto found;
|
||||
goto nfound;
|
||||
}
|
||||
/* fast check for first character */
|
||||
if (*p2==CCHR) {
|
||||
c = p2[1];
|
||||
do {
|
||||
if (*p1!=c)
|
||||
continue;
|
||||
if (advance(p1, p2))
|
||||
goto found;
|
||||
} while (*p1++);
|
||||
goto nfound;
|
||||
}
|
||||
/* regular algorithm */
|
||||
do {
|
||||
if (advance(p1, p2))
|
||||
goto found;
|
||||
} while (*p1++);
|
||||
nfound:
|
||||
if (vflag)
|
||||
succeed(file);
|
||||
continue;
|
||||
found:
|
||||
if (vflag==0)
|
||||
succeed(file);
|
||||
}
|
||||
}
|
||||
|
||||
advance(alp, aep)
|
||||
{
|
||||
register char *lp, *ep, *curlp;
|
||||
char *nextep;
|
||||
|
||||
lp = alp;
|
||||
ep = aep;
|
||||
for (;;) switch (*ep++) {
|
||||
|
||||
case CCHR:
|
||||
if (*ep++ == *lp++)
|
||||
continue;
|
||||
return(0);
|
||||
|
||||
case CDOT:
|
||||
if (*lp++)
|
||||
continue;
|
||||
return(0);
|
||||
|
||||
case CDOL:
|
||||
if (*lp==0)
|
||||
continue;
|
||||
return(0);
|
||||
|
||||
case CEOF:
|
||||
return(1);
|
||||
|
||||
case CCL:
|
||||
if (cclass(ep, *lp++, 1)) {
|
||||
ep =+ *ep;
|
||||
continue;
|
||||
}
|
||||
return(0);
|
||||
|
||||
case NCCL:
|
||||
if (cclass(ep, *lp++, 0)) {
|
||||
ep =+ *ep;
|
||||
continue;
|
||||
}
|
||||
return(0);
|
||||
|
||||
case CDOT|STAR:
|
||||
curlp = lp;
|
||||
while (*lp++);
|
||||
goto star;
|
||||
|
||||
case CCHR|STAR:
|
||||
curlp = lp;
|
||||
while (*lp++ == *ep);
|
||||
ep++;
|
||||
goto star;
|
||||
|
||||
case CCL|STAR:
|
||||
case NCCL|STAR:
|
||||
curlp = lp;
|
||||
while (cclass(ep, *lp++, ep[-1]==(CCL|STAR)));
|
||||
ep =+ *ep;
|
||||
goto star;
|
||||
|
||||
star:
|
||||
do {
|
||||
lp--;
|
||||
if (advance(lp, ep))
|
||||
return(1);
|
||||
} while (lp > curlp);
|
||||
return(0);
|
||||
|
||||
default:
|
||||
printf2("RE botch\n");
|
||||
}
|
||||
}
|
||||
|
||||
cclass(aset, ac, af)
|
||||
{
|
||||
register char *set, c;
|
||||
register n;
|
||||
|
||||
set = aset;
|
||||
if ((c = ac) == 0)
|
||||
return(0);
|
||||
n = *set++;
|
||||
while (--n)
|
||||
if (*set++ == c)
|
||||
return(af);
|
||||
return(!af);
|
||||
}
|
||||
|
||||
printf2(s, a)
|
||||
{
|
||||
extern fout;
|
||||
flush();
|
||||
fout = 2;
|
||||
printf(s, a);
|
||||
flush();
|
||||
exit(2);
|
||||
}
|
||||
|
||||
succeed(f)
|
||||
{
|
||||
if (cflag) {
|
||||
if (++tln[1]==0)
|
||||
tln[0]++;
|
||||
return;
|
||||
}
|
||||
if (nfile > 1)
|
||||
printf("%s:", f);
|
||||
if (bflag)
|
||||
printf("%l:", blkno);
|
||||
if (nflag)
|
||||
printf("%s:", locv(lnum[0], lnum[1]));
|
||||
printf("%s\n", linebuf);
|
||||
}
|
||||
Reference in New Issue
Block a user