static REGPTR syncase(register int esym) { skipnl(); if (wdval == esym) { return (0); } else { register REGPTR r = (REGPTR) getstak(REGTYPE); r->regptr = 0; for (;;) { wdarg->argnxt = r->regptr; r->regptr = wdarg; if (wdval || (word() != ')' && wdval != '|')) { synbad(); } if (wdval == '|') { word(); } else { break; } } r->regcom = cmd(0, NLFLG | MTFLG); if (wdval == ECSYM) { r->regnxt = syncase(esym); } else { chksym(esym); r->regnxt = 0; } return (r); } }
int main(int argc, char *argv[]) { int status; ac = argc; av = argv; ap = 1; if (EQ(argv[0], "[")) { if (!EQ(argv[--ac], "]")) synbad("] missing", ""); } argv[ac] = 0; if (ac <= 1) exit(1); status = (exp() ? 0 : 1); if (nxtarg(1) != 0) synbad("too many arguments", ""); return (status); }
static char * nxtarg(int mt) { if (ap >= ac) { if (mt) { ap++; return (0); } synbad("argument expected", ""); } return (av[ap++]); }
TREPTR cmd(register int sym, int flg) { register TREPTR i, e; i = list(flg); if (wdval == NL) { if (flg & NLFLG) { wdval = ';'; chkpr(NL); } } else if (i == 0 && (flg & MTFLG) == 0) { synbad(); } switch (wdval) { case '&': if (i) i = makefork(FINT | FPRS | FAMP, i); else synbad(); case ';': if (e = cmd(sym, flg | MTFLG)) i = makelist(TLST, i, e); break; case EOFSYM: if (sym == NL) break; default: if (sym) chksym(sym); } return i; }
static TREPTR makelist(int type, TREPTR i, TREPTR r) { register LSTPTR t; if (i == 0 || r == 0) synbad(); else { t = (LSTPTR) getstak(LSTTYPE); t->lsttyp = type; t->lstlef = i; t->lstrit = r; } return (TREPTR) (t); }
static int exp(void) { int p1; char *p2; p1 = e1(); p2 = nxtarg(1); if (p2 != 0) { if (EQ(p2, "-o")) return (p1 | exp()); if (EQ(p2, "]")) synbad("syntax error", ""); } ap--; return (p1); }
static void chksym(int sym) { register int x = sym & wdval; if (((x & SYMFLG) ? x : sym) != wdval) synbad(); }
static void chkword(void) { if (word()) synbad(); }
static TREPTR item(BOOL flag) { register TREPTR t; register IOPTR io; if (flag) io = inout((IOPTR) 0); else io = 0; switch (wdval) { case CASYM: { t = (TREPTR) getstak(SWTYPE); chkword(); ((SWPTR) t)->swarg = wdarg->argval; skipnl(); chksym(INSYM | BRSYM); ((SWPTR) t)->swlst = syncase(wdval == INSYM ? ESSYM : KTSYM); ((SWPTR) t)->swtyp = TSW; break; } case IFSYM: { register int w; t = (TREPTR) getstak(IFTYPE); ((IFPTR) t)->iftyp = TIF; ((IFPTR) t)->iftre = cmd(THSYM, NLFLG); ((IFPTR) t)->thtre = cmd(ELSYM | FISYM | EFSYM, NLFLG); ((IFPTR) t)->eltre = ((w = wdval) == ELSYM ? cmd(FISYM, NLFLG) : (w == EFSYM ? (wdval = IFSYM, item(0)) : 0)); if (w == EFSYM) return (t); break; } case FORSYM: { t = (TREPTR) getstak(FORTYPE); ((FORPTR) t)->fortyp = TFOR; ((FORPTR) t)->forlst = 0; chkword(); ((FORPTR) t)->fornam = wdarg->argval; if (skipnl() == INSYM) { chkword(); ((FORPTR) t)->forlst = (COMPTR) item(0); if (wdval != NL && wdval != ';') synbad(); chkpr(wdval); skipnl(); } chksym(DOSYM | BRSYM); ((FORPTR) t)->fortre = cmd(wdval == DOSYM ? ODSYM : KTSYM, NLFLG); break; } case WHSYM: case UNSYM: { t = (TREPTR) getstak(WHTYPE); ((WHPTR) t)->whtyp = (wdval == WHSYM ? TWH : TUN); ((WHPTR) t)->whtre = cmd(DOSYM, NLFLG); ((WHPTR) t)->dotre = cmd(ODSYM, NLFLG); break; } case BRSYM: t = cmd(KTSYM, NLFLG); break; case '(': { register PARPTR p; p = (PARPTR) getstak(PARTYPE); p->partre = cmd(')', NLFLG); p->partyp = TPAR; t = makefork(0, /*FIXME*/(void *)p); break; } default: if (io == 0) return (0); case 0: { register ARGPTR argp; register ARGPTR *argtail; register ARGPTR *argset = 0; int keywd = 1; t = (TREPTR) getstak(COMTYPE); ((COMPTR) t)->comio = io; /*initial io chain */ argtail = &(((COMPTR) t)->comarg); while (wdval == 0) { argp = wdarg; if (wdset && keywd) { argp->argnxt = (ARGPTR) argset; argset = (ARGPTR *) argp; } else { *argtail = argp; argtail = &(argp->argnxt); keywd = flags & keyflg; } word(); if (flag) ((COMPTR) t)->comio = inout(((COMPTR) t)->comio); } ((COMPTR) t)->comtyp = TCOM; ((COMPTR) t)->comset = (ARGPTR) argset; *argtail = 0; return (t); } } reserv++; word(); if (io = inout(io)) { t = makefork(0, t); t->treio = io; } return t; }
static int e3(void) { int p1; char *a; char *p2; int int1, int2; a = nxtarg(0); if (EQ(a, "(")) { p1 = exp(); if (!EQ(nxtarg(0), ")")) synbad(") expected", ""); return (p1); } p2 = nxtarg(1); ap--; if ((p2 == 0) || (!EQ(p2, "=") && !EQ(p2, "!="))) { if (EQ(a, "-r")) return (tio(nxtarg(0), 4)); if (EQ(a, "-w")) return (tio(nxtarg(0), 2)); if (EQ(a, "-x")) return (tio(nxtarg(0), 1)); if (EQ(a, "-d")) return (filtyp(nxtarg(0), S_IFDIR)); if (EQ(a, "-c")) return (filtyp(nxtarg(0), S_IFCHR)); if (EQ(a, "-b")) return (filtyp(nxtarg(0), S_IFBLK)); if (EQ(a, "-f")) { struct stat statb; return (stat(nxtarg(0), &statb) >= 0 && (statb.st_mode & S_IFMT) != S_IFDIR); } if (EQ(a, "-h")) return (filtyp(nxtarg(0), S_IFLNK)); if (EQ(a, "-u")) return (ftype(nxtarg(0), S_ISUID)); if (EQ(a, "-g")) return (ftype(nxtarg(0), S_ISGID)); if (EQ(a, "-k")) return (ftype(nxtarg(0), S_ISVTX)); if (EQ(a, "-p")) #ifdef S_IFIFO return (filtyp(nxtarg(0), S_IFIFO)); #else return (nxtarg(0), 0); #endif if (EQ(a, "-s")) return (fsizep(nxtarg(0))); if (EQ(a, "-t")) if (ap >= ac) return (isatty(1)); else if (EQ((a = nxtarg(0)), "-a") || EQ(a, "-o")) { ap--; return (isatty(1)); } else return (isatty(atoi(a))); if (EQ(a, "-n")) return (!EQ(nxtarg(0), "")); if (EQ(a, "-z")) return (EQ(nxtarg(0), "")); } p2 = nxtarg(1); if (p2 == 0) return (!EQ(a, "")); if (EQ(p2, "-a") || EQ(p2, "-o")) { ap--; return (!EQ(a, "")); } if (EQ(p2, "=")) return (EQ(nxtarg(0), a)); if (EQ(p2, "!=")) return (!EQ(nxtarg(0), a)); int1 = atoi(a); int2 = atoi(nxtarg(0)); if (EQ(p2, "-eq")) return (int1 == int2); if (EQ(p2, "-ne")) return (int1 != int2); if (EQ(p2, "-gt")) return (int1 > int2); if (EQ(p2, "-lt")) return (int1 < int2); if (EQ(p2, "-ge")) return (int1 >= int2); if (EQ(p2, "-le")) return (int1 <= int2); synbad("unknown operator ", p2); /* NOTREACHED */ return (0); }