From 566d54fe549286895fdef8aa9f385686405dd290 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Wed, 13 Oct 2021 16:46:20 -0700 Subject: RM(rc): old code. too many assumptions baked in --- sys/cmd/rc/Makefile | 56 -- sys/cmd/rc/code.c | 490 -------------- sys/cmd/rc/exec.c | 1013 ---------------------------- sys/cmd/rc/exec.h | 88 --- sys/cmd/rc/fns.h | 68 -- sys/cmd/rc/getflags.c | 244 ------- sys/cmd/rc/getflags.h | 7 - sys/cmd/rc/glob.c | 268 -------- sys/cmd/rc/havefork.c | 300 --------- sys/cmd/rc/here.c | 153 ----- sys/cmd/rc/history.c | 4 - sys/cmd/rc/io.c | 263 -------- sys/cmd/rc/io.h | 31 - sys/cmd/rc/lex.c | 372 ----------- sys/cmd/rc/linenoise.c | 1236 ---------------------------------- sys/cmd/rc/linenoise.h | 77 --- sys/cmd/rc/pcmd.c | 147 ---- sys/cmd/rc/pfnc.c | 71 -- sys/cmd/rc/prompt.c | 101 --- sys/cmd/rc/rc.h | 149 ----- sys/cmd/rc/rcmain.unix | 35 - sys/cmd/rc/rules.mk | 40 -- sys/cmd/rc/simple.c | 507 -------------- sys/cmd/rc/subr.c | 77 --- sys/cmd/rc/syn.y | 91 --- sys/cmd/rc/trap.c | 37 -- sys/cmd/rc/tree.c | 146 ---- sys/cmd/rc/unix.c | 627 ----------------- sys/cmd/rc/unix.h | 54 -- sys/cmd/rc/var.c | 176 ----- sys/cmd/rc/x.tab.h | 114 ---- sys/cmd/rc/y.tab.c | 1736 ------------------------------------------------ sys/cmd/rc/y.tab.h | 139 ---- 33 files changed, 8917 deletions(-) delete mode 100644 sys/cmd/rc/Makefile delete mode 100644 sys/cmd/rc/code.c delete mode 100644 sys/cmd/rc/exec.c delete mode 100644 sys/cmd/rc/exec.h delete mode 100644 sys/cmd/rc/fns.h delete mode 100644 sys/cmd/rc/getflags.c delete mode 100644 sys/cmd/rc/getflags.h delete mode 100644 sys/cmd/rc/glob.c delete mode 100644 sys/cmd/rc/havefork.c delete mode 100644 sys/cmd/rc/here.c delete mode 100644 sys/cmd/rc/history.c delete mode 100644 sys/cmd/rc/io.c delete mode 100644 sys/cmd/rc/io.h delete mode 100644 sys/cmd/rc/lex.c delete mode 100644 sys/cmd/rc/linenoise.c delete mode 100644 sys/cmd/rc/linenoise.h delete mode 100644 sys/cmd/rc/pcmd.c delete mode 100644 sys/cmd/rc/pfnc.c delete mode 100644 sys/cmd/rc/prompt.c delete mode 100644 sys/cmd/rc/rc.h delete mode 100644 sys/cmd/rc/rcmain.unix delete mode 100644 sys/cmd/rc/rules.mk delete mode 100644 sys/cmd/rc/simple.c delete mode 100644 sys/cmd/rc/subr.c delete mode 100644 sys/cmd/rc/syn.y delete mode 100644 sys/cmd/rc/trap.c delete mode 100644 sys/cmd/rc/tree.c delete mode 100644 sys/cmd/rc/unix.c delete mode 100644 sys/cmd/rc/unix.h delete mode 100644 sys/cmd/rc/var.c delete mode 100644 sys/cmd/rc/x.tab.h delete mode 100644 sys/cmd/rc/y.tab.c delete mode 100644 sys/cmd/rc/y.tab.h diff --git a/sys/cmd/rc/Makefile b/sys/cmd/rc/Makefile deleted file mode 100644 index d4b9864..0000000 --- a/sys/cmd/rc/Makefile +++ /dev/null @@ -1,56 +0,0 @@ -YACC=yacc -d -PREFIX=/usr/local -WARNINGS=-Wall -Wextra -Wno-parentheses -Wno-missing-braces -Wno-missing-field-initializers -Wno-comment -Wno-sign-compare -Wno-unused-parameter -Wno-implicit-fallthrough #-Werror -CFLAGS=-g $(WARNINGS) -DPREFIX=\"$(PREFIX)\" -D_XOPEN_SOURCE=500 -LFLAGS=/home/nolln/root/lib/libreadline.a /home/nolln/root/lib/libhistory.a /home/nolln/root/lib/libncursesw.a - -TARG=rc - -OFILES=\ - code.o\ - exec.o\ - getflags.o\ - glob.o\ - here.o\ - io.o\ - lex.o\ - pcmd.o\ - pfnc.o\ - simple.o\ - subr.o\ - trap.o\ - tree.o\ - var.o\ - y.tab.o\ - unix.o\ - havefork.o\ - prompt.o\ - -HFILES=\ - rc.h\ - x.tab.h\ - io.h\ - exec.h\ - fns.h\ - -YFILES=syn.y - -all: $(TARG) - -$(TARG): $(OFILES) - $(CC) $(ARCHS) -o $(TARG) $(OFILES) $(LFLAGS) - -%.o: %.c $(HFILES) - $(CC) $(ARCHS) $(CFLAGS) -c $*.c - -y.tab.h y.tab.c: $(YFILES) - $(YACC) $(YFLAGS) $(YFILES) - -x.tab.h: y.tab.h - cmp -s x.tab.h y.tab.h || cp y.tab.h x.tab.h - -%: %.c $(HFILES) - $(CC) $(ARCHS) -o $@ $< $(LFLAGS) - -clean: - rm -f $(TARG) *.o $(CLEANFILES) diff --git a/sys/cmd/rc/code.c b/sys/cmd/rc/code.c deleted file mode 100644 index 0b280ac..0000000 --- a/sys/cmd/rc/code.c +++ /dev/null @@ -1,490 +0,0 @@ -#include "rc.h" -#include "io.h" -#include "exec.h" -#include "fns.h" -#include "getflags.h" - -#define c0 t->child[0] -#define c1 t->child[1] -#define c2 t->child[2] - -int codep, ncode; - -#define emitf(x) ((void)(codep!=ncode || morecode()), codebuf[codep].f = (x), codep++) -#define emiti(x) ((void)(codep!=ncode || morecode()), codebuf[codep].i = (x), codep++) -#define emits(x) ((void)(codep!=ncode || morecode()), codebuf[codep].s = (x), codep++) - -void stuffdot(int); -char *fnstr(Tree*); -void outcode(Tree*, int); -void codeswitch(Tree*, int); -int iscase(Tree*); -Code *codecopy(Code*); -void codefree(Code*); - -int -morecode(void) -{ - ncode+=100; - codebuf = (Code *)realloc((char *)codebuf, ncode*sizeof codebuf[0]); - if(codebuf==0) - panic("Can't realloc %d bytes in morecode!", - ncode*sizeof codebuf[0]); - memset(codebuf+ncode-100, 0, 100*sizeof codebuf[0]); - return 0; -} - -void -stuffdot(int a) -{ - if(a<0 || codep<=a) - panic("Bad address %d in stuffdot", a); - codebuf[a].i = codep; -} - -int -compile(Tree *t) -{ - ncode = 100; - codebuf = (Code *)emalloc(ncode*sizeof codebuf[0]); - codep = 0; - emiti(0); /* reference count */ - outcode(t, flag['e']?1:0); - if(nerror){ - efree((char *)codebuf); - return 0; - } - readhere(); - emitf(Xreturn); - emitf(0); - return 1; -} - -void -cleanhere(char *f) -{ - emitf(Xdelhere); - emits(strdup(f)); -} - -char* -fnstr(Tree *t) -{ - Io *f = openstr(); - char *v; - extern char nl; - char svnl = nl; - nl=';'; - pfmt(f, "%t", t); - nl = svnl; - v = f->strp; - f->strp = 0; - closeio(f); - return v; -} - -void -outcode(Tree *t, int eflag) -{ - int p, q; - Tree *tt; - if(t==0) - return; - if(t->type!=NOT && t->type!=';') - runq->iflast = 0; - switch(t->type){ - default: - pfmt(err, "bad type %d in outcode\n", t->type); - break; - case '$': - emitf(Xmark); - outcode(c0, eflag); - emitf(Xdol); - break; - case '"': - emitf(Xmark); - outcode(c0, eflag); - emitf(Xqdol); - break; - case SUB: - emitf(Xmark); - outcode(c0, eflag); - emitf(Xmark); - outcode(c1, eflag); - emitf(Xsub); - break; - case '&': - emitf(Xasync); - if(havefork){ - p = emiti(0); - outcode(c0, eflag); - emitf(Xexit); - stuffdot(p); - } else - emits(fnstr(c0)); - break; - case ';': - outcode(c0, eflag); - outcode(c1, eflag); - break; - case '^': - emitf(Xmark); - outcode(c1, eflag); - emitf(Xmark); - outcode(c0, eflag); - emitf(Xconc); - break; - case '`': - emitf(Xbackq); - if(havefork){ - p = emiti(0); - outcode(c0, 0); - emitf(Xexit); - stuffdot(p); - } else - emits(fnstr(c0)); - break; - case ANDAND: - outcode(c0, 0); - emitf(Xtrue); - p = emiti(0); - outcode(c1, eflag); - stuffdot(p); - break; - case ARGLIST: - outcode(c1, eflag); - outcode(c0, eflag); - break; - case BANG: - outcode(c0, eflag); - emitf(Xbang); - break; - case PCMD: - case BRACE: - outcode(c0, eflag); - break; - case COUNT: - emitf(Xmark); - outcode(c0, eflag); - emitf(Xcount); - break; - case FN: - emitf(Xmark); - outcode(c0, eflag); - if(c1){ - emitf(Xfn); - p = emiti(0); - emits(fnstr(c1)); - outcode(c1, eflag); - emitf(Xunlocal); /* get rid of $* */ - emitf(Xreturn); - stuffdot(p); - } - else - emitf(Xdelfn); - break; - case IF: - outcode(c0, 0); - emitf(Xif); - p = emiti(0); - outcode(c1, eflag); - emitf(Xwastrue); - stuffdot(p); - break; - case NOT: - if(!runq->iflast) - yyerror("`if not' does not follow `if(...)'"); - emitf(Xifnot); - p = emiti(0); - outcode(c0, eflag); - stuffdot(p); - break; - case OROR: - outcode(c0, 0); - emitf(Xfalse); - p = emiti(0); - outcode(c1, eflag); - stuffdot(p); - break; - case PAREN: - outcode(c0, eflag); - break; - case SIMPLE: - emitf(Xmark); - outcode(c0, eflag); - emitf(Xsimple); - if(eflag) - emitf(Xeflag); - break; - case SUBSHELL: - emitf(Xsubshell); - if(havefork){ - p = emiti(0); - outcode(c0, eflag); - emitf(Xexit); - stuffdot(p); - } else - emits(fnstr(c0)); - if(eflag) - emitf(Xeflag); - break; - case SWITCH: - codeswitch(t, eflag); - break; - case TWIDDLE: - emitf(Xmark); - outcode(c1, eflag); - emitf(Xmark); - outcode(c0, eflag); - emitf(Xmatch); - if(eflag) - emitf(Xeflag); - break; - case WHILE: - q = codep; - outcode(c0, 0); - if(q==codep) - emitf(Xsettrue); /* empty condition == while(true) */ - emitf(Xtrue); - p = emiti(0); - outcode(c1, eflag); - emitf(Xjump); - emiti(q); - stuffdot(p); - break; - case WORDS: - outcode(c1, eflag); - outcode(c0, eflag); - break; - case FOR: - emitf(Xmark); - if(c1){ - outcode(c1, eflag); - emitf(Xglob); - } - else{ - emitf(Xmark); - emitf(Xword); - emits(strdup("*")); - emitf(Xdol); - } - emitf(Xmark); /* dummy value for Xlocal */ - emitf(Xmark); - outcode(c0, eflag); - emitf(Xlocal); - p = emitf(Xfor); - q = emiti(0); - outcode(c2, eflag); - emitf(Xjump); - emiti(p); - stuffdot(q); - emitf(Xunlocal); - break; - case WORD: - emitf(Xword); - emits(strdup(t->str)); - break; - case DUP: - if(t->rtype==DUPFD){ - emitf(Xdup); - emiti(t->fd0); - emiti(t->fd1); - } - else{ - emitf(Xclose); - emiti(t->fd0); - } - outcode(c1, eflag); - emitf(Xpopredir); - break; - case PIPEFD: - emitf(Xpipefd); - emiti(t->rtype); - if(havefork){ - p = emiti(0); - outcode(c0, eflag); - emitf(Xexit); - stuffdot(p); - } else { - emits(fnstr(c0)); - } - break; - case REDIR: - emitf(Xmark); - outcode(c0, eflag); - emitf(Xglob); - switch(t->rtype){ - case APPEND: - emitf(Xappend); - break; - case WRITE: - emitf(Xwrite); - break; - case READ: - case HERE: - emitf(Xread); - break; - case RDWR: - emitf(Xrdwr); - break; - } - emiti(t->fd0); - outcode(c1, eflag); - emitf(Xpopredir); - break; - case '=': - tt = t; - for(;t && t->type=='=';t = c2); - if(t){ - for(t = tt;t->type=='=';t = c2){ - emitf(Xmark); - outcode(c1, eflag); - emitf(Xmark); - outcode(c0, eflag); - emitf(Xlocal); - } - outcode(t, eflag); - for(t = tt; t->type=='='; t = c2) - emitf(Xunlocal); - } - else{ - for(t = tt;t;t = c2){ - emitf(Xmark); - outcode(c1, eflag); - emitf(Xmark); - outcode(c0, eflag); - emitf(Xassign); - } - } - t = tt; /* so tests below will work */ - break; - case PIPE: - emitf(Xpipe); - emiti(t->fd0); - emiti(t->fd1); - if(havefork){ - p = emiti(0); - q = emiti(0); - outcode(c0, eflag); - emitf(Xexit); - stuffdot(p); - } else { - emits(fnstr(c0)); - q = emiti(0); - } - outcode(c1, eflag); - emitf(Xreturn); - stuffdot(q); - emitf(Xpipewait); - break; - } - if(t->type!=NOT && t->type!=';') - runq->iflast = t->type==IF; - else if(c0) runq->iflast = c0->type==IF; -} -/* - * switch code looks like this: - * Xmark - * (get switch value) - * Xjump 1f - * out: Xjump leave - * 1: Xmark - * (get case values) - * Xcase 1f - * (commands) - * Xjump out - * 1: Xmark - * (get case values) - * Xcase 1f - * (commands) - * Xjump out - * 1: - * leave: - * Xpopm - */ - -void -codeswitch(Tree *t, int eflag) -{ - int leave; /* patch jump address to leave switch */ - int out; /* jump here to leave switch */ - int nextcase; /* patch jump address to next case */ - Tree *tt; - if(c1->child[0]==nil - || c1->child[0]->type!=';' - || !iscase(c1->child[0]->child[0])){ - yyerror("case missing in switch"); - return; - } - emitf(Xmark); - outcode(c0, eflag); - emitf(Xjump); - nextcase = emiti(0); - out = emitf(Xjump); - leave = emiti(0); - stuffdot(nextcase); - t = c1->child[0]; - while(t->type==';'){ - tt = c1; - emitf(Xmark); - for(t = c0->child[0];t->type==ARGLIST;t = c0) outcode(c1, eflag); - emitf(Xcase); - nextcase = emiti(0); - t = tt; - for(;;){ - if(t->type==';'){ - if(iscase(c0)) break; - outcode(c0, eflag); - t = c1; - } - else{ - if(!iscase(t)) outcode(t, eflag); - break; - } - } - emitf(Xjump); - emiti(out); - stuffdot(nextcase); - } - stuffdot(leave); - emitf(Xpopm); -} - -int -iscase(Tree *t) -{ - if(t->type!=SIMPLE) - return 0; - do t = c0; while(t->type==ARGLIST); - return t->type==WORD && !t->quoted && strcmp(t->str, "case")==0; -} - -Code* -codecopy(Code *cp) -{ - cp[0].i++; - return cp; -} - -void -codefree(Code *cp) -{ - Code *p; - if(--cp[0].i!=0) - return; - for(p = cp+1;p->f;p++){ - if(p->f==Xappend || p->f==Xclose || p->f==Xread || p->f==Xwrite - || p->f==Xrdwr - || p->f==Xasync || p->f==Xbackq || p->f==Xcase || p->f==Xfalse - || p->f==Xfor || p->f==Xjump - || p->f==Xsubshell || p->f==Xtrue) p++; - else if(p->f==Xdup || p->f==Xpipefd) p+=2; - else if(p->f==Xpipe) p+=4; - else if(p->f==Xword || p->f==Xdelhere) efree((++p)->s); - else if(p->f==Xfn){ - efree(p[2].s); - p+=2; - } - } - efree((char *)cp); -} diff --git a/sys/cmd/rc/exec.c b/sys/cmd/rc/exec.c deleted file mode 100644 index fdb63cf..0000000 --- a/sys/cmd/rc/exec.c +++ /dev/null @@ -1,1013 +0,0 @@ -#include "rc.h" -#include "getflags.h" -#include "exec.h" -#include "io.h" -#include "fns.h" -/* - * Start executing the given code at the given pc with the given redirection - */ -char *argv0="rc"; -int ndot; -int lastc; -int kidpid; -int mypid; - -Thread *runq; -Code *codebuf; /* compiler output */ -int ntrap; /* number of outstanding traps */ -int trap[NSIG]; /* number of outstanding traps per type */ -int eflagok; /* kludge flag so that -e doesn't exit in startup */ - -char **argp; -char **args; -int nerror; /* number of errors encountered during compilation */ - -void -start(Code *c, int pc, Var *local) -{ - struct Thread *p = new(struct Thread); - - p->code = codecopy(c); - p->pc = pc; - p->argv = 0; - p->redir = p->startredir = runq?runq->redir:0; - p->local = local; - p->cmdfile = 0; - p->cmdfd = 0; - p->eof = 0; - p->iflag = 0; - p->lineno = 1; - p->ret = runq; - runq = p; -} - -Word* -newword(char *wd, Word *next) -{ - Word *p = new(Word); - p->word = strdup(wd); - p->next = next; - return p; -} - -void -pushword(char *wd) -{ - if(runq->argv==0) - panic("pushword but no argv!", 0); - runq->argv->words = newword(wd, runq->argv->words); -} - -void -popword(void) -{ - Word *p; - if(runq->argv==0) - panic("popword but no argv!", 0); - p = runq->argv->words; - if(p==0) - panic("popword but no word!", 0); - runq->argv->words = p->next; - efree(p->word); - efree((char *)p); -} - -void -freelist(Word *w) -{ - Word *nw; - while(w){ - nw = w->next; - efree(w->word); - efree((char *)w); - w = nw; - } -} - -void -pushlist(void) -{ - Words *p = new(Words); - p->next = runq->argv; - p->words = 0; - runq->argv = p; -} - -void -poplist(void) -{ - Words *p = runq->argv; - if(p==0) - panic("poplist but no argv", 0); - freelist(p->words); - runq->argv = p->next; - efree((char *)p); -} - -int -count(Word *w) -{ - int n; - for(n = 0;w;n++) w = w->next; - return n; -} - -void -pushredir(int type, int from, int to) -{ - Redir * rp = new(Redir); - rp->type = type; - rp->from = from; - rp->to = to; - rp->next = runq->redir; - runq->redir = rp; -} - -Var* -newvar(char *name, Var *next) -{ - Var *v = new(Var); - v->name = name; - v->val = 0; - v->fn = 0; - v->changed = 0; - v->fnchanged = 0; - v->next = next; - v->changefn = 0; - return v; -} -/* - * get command line flags, initialize keywords & traps. - * get values from environment. - * set $pid, $cflag, $* - * fabricate bootstrap code and start it (*=(argv);. /usr/lib/rcmain $*) - * start interpreting code - */ -int -main(int argc, char *argv[]) -{ - Code bootstrap[32]; - char num[12], *rcmain; - int i; - - argc = getflags(argc, argv, "SsrdiIlxepvVc:1m:1[command]", 1); - if(argc==-1) - usage("[file [arg ...]]"); - if(argv[0][0]=='-') - flag['l'] = flagset; - if(flag['I']) - flag['i'] = 0; - else if(flag['i']==0 && argc==1 && Isatty(0)) flag['i'] = flagset; - rcmain = flag['m'] ? flag['m'][0] : Rcmain; - err = openfd(2); - kinit(); - Trapinit(); - Vinit(); - inttoascii(num, mypid = getpid()); - pathinit(); - setvar("pid", newword(num, (Word *)0)); - setvar("cflag", flag['c']?newword(flag['c'][0], (Word *)0) - :(Word *)0); - setvar("rcname", newword(argv[0], (Word *)0)); - i = 0; - memset(bootstrap, 0, sizeof bootstrap); - bootstrap[i++].i = 1; - bootstrap[i++].f = Xmark; - bootstrap[i++].f = Xword; - bootstrap[i++].s="*"; - bootstrap[i++].f = Xassign; - bootstrap[i++].f = Xmark; - bootstrap[i++].f = Xmark; - bootstrap[i++].f = Xword; - bootstrap[i++].s="*"; - bootstrap[i++].f = Xdol; - bootstrap[i++].f = Xword; - bootstrap[i++].s = rcmain; - bootstrap[i++].f = Xword; - bootstrap[i++].s="."; - bootstrap[i++].f = Xsimple; - bootstrap[i++].f = Xexit; - bootstrap[i].i = 0; - start(bootstrap, 1, (Var *)0); - /* prime bootstrap argv */ - pushlist(); - argv0 = strdup(argv[0]); - for(i = argc-1;i!=0;--i) pushword(argv[i]); - for(;;){ - if(flag['r']) - pfnc(err, runq); - runq->pc++; - (*runq->code[runq->pc-1].f)(); - if(ntrap) - dotrap(); - } - return 0; /* not reached; silence OS X Lion gcc */ -} -/* - * Opcode routines - * Arguments on stack (...) - * Arguments in line [...] - * Code in line with jump around {...} - * - * Xappend(file)[fd] open file to append - * Xassign(name, val) assign val to name - * Xasync{... Xexit} make thread for {}, no wait - * Xbackq{... Xreturn} make thread for {}, push stdout - * Xbang complement condition - * Xcase(pat, value){...} exec code on match, leave (value) on - * stack - * Xclose[i] close file descriptor - * Xconc(left, right) concatenate, push results - * Xcount(name) push var count - * Xdelfn(name) delete function definition - * Xdeltraps(names) delete named traps - * Xdol(name) get variable value - * Xqdol(name) concatenate variable components - * Xdup[i j] dup file descriptor - * Xexit rc exits with status - * Xfalse{...} execute {} if false - * Xfn(name){... Xreturn} define function - * Xfor(var, list){... Xreturn} for loop - * Xjump[addr] goto - * Xlocal(name, val) create local variable, assign value - * Xmark mark stack - * Xmatch(pat, str) match pattern, set status - * Xpipe[i j]{... Xreturn}{... Xreturn} construct a pipe between 2 new threads, - * wait for both - * Xpipefd[type]{... Xreturn} connect {} to pipe (input or output, - * depending on type), push /dev/fd/?? - * Xpopm(value) pop value from stack - * Xrdwr(file)[fd] open file for reading and writing - * Xread(file)[fd] open file to read - * Xsettraps(names){... Xreturn} define trap functions - * Xshowtraps print trap list - * Xsimple(args) run command and wait - * Xreturn kill thread - * Xsubshell{... Xexit} execute {} in a subshell and wait - * Xtrue{...} execute {} if true - * Xunlocal delete local variable - * Xword[string] push string - * Xwrite(file)[fd] open file to write - */ - -void -Xappend(void) -{ - char *file; - int f; - switch(count(runq->argv->words)){ - default: - Xerror1(">> requires singleton"); - return; - case 0: - Xerror1(">> requires file"); - return; - case 1: - break; - } - file = runq->argv->words->word; - if((f = open(file, 1))<0 && (f = Creat(file))<0){ - pfmt(err, "%s: ", file); - Xerror("can't open"); - return; - } - Seek(f, 0L, 2); - pushredir(ROPEN, f, runq->code[runq->pc].i); - runq->pc++; - poplist(); -} - -void -Xsettrue(void) -{ - setstatus(""); -} - -void -Xbang(void) -{ - setstatus(truestatus()?"false":""); -} - -void -Xclose(void) -{ - pushredir(RCLOSE, runq->code[runq->pc].i, 0); - runq->pc++; -} - -void -Xdup(void) -{ - pushredir(RDUP, runq->code[runq->pc].i, runq->code[runq->pc+1].i); - runq->pc+=2; -} - -void -Xeflag(void) -{ - if(eflagok && !truestatus()) Xexit(); -} - -void -Xexit(void) -{ - struct Var *trapreq; - struct Word *starval; - static int beenhere = 0; - if(getpid()==mypid && !beenhere){ - trapreq = vlook("sigexit"); - if(trapreq->fn){ - beenhere = 1; - --runq->pc; - starval = vlook("*")->val; - start(trapreq->fn, trapreq->pc, (struct Var *)0); - runq->local = newvar(strdup("*"), runq->local); - runq->local->val = copywords(starval, (struct Word *)0); - runq->local->changed = 1; - runq->redir = runq->startredir = 0; - return; - } - } - Exit(getstatus()); -} - -void -Xfalse(void) -{ - if(truestatus()) runq->pc = runq->code[runq->pc].i; - else runq->pc++; -} -int ifnot; /* dynamic if not flag */ - -void -Xifnot(void) -{ - if(ifnot) - runq->pc++; - else - runq->pc = runq->code[runq->pc].i; -} - -void -Xjump(void) -{ - runq->pc = runq->code[runq->pc].i; -} - -void -Xmark(void) -{ - pushlist(); -} - -void -Xpopm(void) -{ - poplist(); -} - -void -Xread(void) -{ - char *file; - int f; - switch(count(runq->argv->words)){ - default: - Xerror1("< requires singleton\n"); - return; - case 0: - Xerror1("< requires file\n"); - return; - case 1: - break; - } - file = runq->argv->words->word; - if((f = open(file, 0))<0){ - pfmt(err, "%s: ", file); - Xerror("can't open"); - return; - } - pushredir(ROPEN, f, runq->code[runq->pc].i); - runq->pc++; - poplist(); -} - -void -Xrdwr(void) -{ - char *file; - int f; - - switch(count(runq->argv->words)){ - default: - Xerror1("<> requires singleton\n"); - return; - case 0: - Xerror1("<> requires file\n"); - return; - case 1: - break; - } - file = runq->argv->words->word; - if((f = open(file, ORDWR))<0){ - pfmt(err, "%s: ", file); - Xerror("can't open"); - return; - } - pushredir(ROPEN, f, runq->code[runq->pc].i); - runq->pc++; - poplist(); -} - -void -turfredir(void) -{ - while(runq->redir!=runq->startredir) - Xpopredir(); -} - -void -Xpopredir(void) -{ - struct Redir *rp = runq->redir; - if(rp==0) - panic("turfredir null!", 0); - runq->redir = rp->next; - if(rp->type==ROPEN) - close(rp->from); - efree((char *)rp); -} - -void -Xreturn(void) -{ - struct Thread *p = runq; - turfredir(); - while(p->argv) poplist(); - codefree(p->code); - runq = p->ret; - efree((char *)p); - if(runq==0) - Exit(getstatus()); -} - -void -Xtrue(void) -{ - if(truestatus()) runq->pc++; - else runq->pc = runq->code[runq->pc].i; -} - -void -Xif(void) -{ - ifnot = 1; - if(truestatus()) runq->pc++; - else runq->pc = runq->code[runq->pc].i; -} - -void -Xwastrue(void) -{ - ifnot = 0; -} - -void -Xword(void) -{ - pushword(runq->code[runq->pc++].s); -} - -void -Xwrite(void) -{ - char *file; - int f; - switch(count(runq->argv->words)){ - default: - Xerror1("> requires singleton\n"); - return; - case 0: - Xerror1("> requires file\n"); - return; - case 1: - break; - } - file = runq->argv->words->word; - if((f = Creat(file))<0){ - pfmt(err, "%s: ", file); - Xerror("can't open"); - return; - } - pushredir(ROPEN, f, runq->code[runq->pc].i); - runq->pc++; - poplist(); -} - -char* -list2str(Word *words) -{ - char *value, *s, *t; - int len = 0; - Word *ap; - for(ap = words;ap;ap = ap->next) - len+=1+strlen(ap->word); - value = emalloc(len+1); - s = value; - for(ap = words;ap;ap = ap->next){ - for(t = ap->word;*t;) *s++=*t++; - *s++=' '; - } - if(s==value) - *s='\0'; - else s[-1]='\0'; - return value; -} - -void -Xmatch(void) -{ - Word *p; - char *subject; - subject = list2str(runq->argv->words); - setstatus("no match"); - for(p = runq->argv->next->words;p;p = p->next) - if(match(subject, p->word, '\0')){ - setstatus(""); - break; - } - efree(subject); - poplist(); - poplist(); -} - -void -Xcase(void) -{ - Word *p; - char *s; - int ok = 0; - s = list2str(runq->argv->next->words); - for(p = runq->argv->words;p;p = p->next){ - if(match(s, p->word, '\0')){ - ok = 1; - break; - } - } - efree(s); - if(ok) - runq->pc++; - else - runq->pc = runq->code[runq->pc].i; - poplist(); -} - -Word* -conclist(Word *lp, Word *rp, Word *tail) -{ - char *buf; - Word *v; - if(lp->next || rp->next) - tail = conclist(lp->next==0?lp:lp->next, rp->next==0?rp:rp->next, - tail); - buf = emalloc(strlen(lp->word)+strlen(rp->word)+1); - strcpy(buf, lp->word); - strcat(buf, rp->word); - v = newword(buf, tail); - efree(buf); - return v; -} - -void -Xconc(void) -{ - Word *lp = runq->argv->words; - Word *rp = runq->argv->next->words; - Word *vp = runq->argv->next->next->words; - int lc = count(lp), rc = count(rp); - if(lc!=0 || rc!=0){ - if(lc==0 || rc==0){ - Xerror1("null list in concatenation"); - return; - } - if(lc!=1 && rc!=1 && lc!=rc){ - Xerror1("mismatched list lengths in concatenation"); - return; - } - vp = conclist(lp, rp, vp); - } - poplist(); - poplist(); - runq->argv->words = vp; -} - -void -Xassign(void) -{ - Var *v; - if(count(runq->argv->words)!=1){ - Xerror1("variable name not singleton!"); - return; - } - deglob(runq->argv->words->word); - v = vlook(runq->argv->words->word); - poplist(); - globlist(); - freewords(v->val); - v->val = runq->argv->words; - v->changed = 1; - if(v->changefn) - v->changefn(v); - runq->argv->words = 0; - poplist(); -} -/* - * copy arglist a, adding the copy to the front of tail - */ - -Word* -copywords(Word *a, Word *tail) -{ - Word *v = 0, **end; - for(end=&v;a;a = a->next,end=&(*end)->next) - *end = newword(a->word, 0); - *end = tail; - return v; -} - -void -Xdol(void) -{ - Word *a, *star; - char *s, *t; - int n; - if(count(runq->argv->words)!=1){ - Xerror1("variable name not singleton!"); - return; - } - s = runq->argv->words->word; - deglob(s); - n = 0; - for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0'; - a = runq->argv->next->words; - if(n==0 || *t) - a = copywords(vlook(s)->val, a); - else{ - star = vlook("*")->val; - if(star && 1<=n && n<=count(star)){ - while(--n) star = star->next; - a = newword(star->word, a); - } - } - poplist(); - runq->argv->words = a; -} - -void -Xqdol(void) -{ - Word *a, *p; - char *s; - int n; - if(count(runq->argv->words)!=1){ - Xerror1("variable name not singleton!"); - return; - } - s = runq->argv->words->word; - deglob(s); - a = vlook(s)->val; - poplist(); - n = count(a); - if(n==0){ - pushword(""); - return; - } - for(p = a;p;p = p->next) n+=strlen(p->word); - s = emalloc(n); - if(a){ - strcpy(s, a->word); - for(p = a->next;p;p = p->next){ - strcat(s, " "); - strcat(s, p->word); - } - } - else - s[0]='\0'; - pushword(s); - efree(s); -} - -Word* -copynwords(Word *a, Word *tail, int n) -{ - Word *v, **end; - - v = 0; - end = &v; - while(n-- > 0){ - *end = newword(a->word, 0); - end = &(*end)->next; - a = a->next; - } - *end = tail; - return v; -} - -Word* -subwords(Word *val, int len, Word *sub, Word *a) -{ - int n, m; - char *s; - if(!sub) - return a; - a = subwords(val, len, sub->next, a); - s = sub->word; - deglob(s); - m = 0; - n = 0; - while('0'<=*s && *s<='9') - n = n*10+ *s++ -'0'; - if(*s == '-'){ - if(*++s == 0) - m = len - n; - else{ - while('0'<=*s && *s<='9') - m = m*10+ *s++ -'0'; - m -= n; - } - } - if(n<1 || n>len || m<0) - return a; - if(n+m>len) - m = len-n; - while(--n > 0) - val = val->next; - return copynwords(val, a, m+1); -} - -void -Xsub(void) -{ - Word *a, *v; - char *s; - if(count(runq->argv->next->words)!=1){ - Xerror1("variable name not singleton!"); - return; - } - s = runq->argv->next->words->word; - deglob(s); - a = runq->argv->next->next->words; - v = vlook(s)->val; - a = subwords(v, count(v), runq->argv->words, a); - poplist(); - poplist(); - runq->argv->words = a; -} - -void -Xcount(void) -{ - Word *a; - char *s, *t; - int n; - char num[12]; - if(count(runq->argv->words)!=1){ - Xerror1("variable name not singleton!"); - return; - } - s = runq->argv->words->word; - deglob(s); - n = 0; - for(t = s;'0'<=*t && *t<='9';t++) n = n*10+*t-'0'; - if(n==0 || *t){ - a = vlook(s)->val; - inttoascii(num, count(a)); - } - else{ - a = vlook("*")->val; - inttoascii(num, a && 1<=n && n<=count(a)?1:0); - } - poplist(); - pushword(num); -} - -void -Xlocal(void) -{ - if(count(runq->argv->words)!=1){ - Xerror1("variable name must be singleton\n"); - return; - } - deglob(runq->argv->words->word); - runq->local = newvar(strdup(runq->argv->words->word), runq->local); - runq->local->val = copywords(runq->argv->next->words, (Word *)0); - runq->local->changed = 1; - poplist(); - poplist(); -} - -void -Xunlocal(void) -{ - Var *v = runq->local, *hid; - if(v==0) - panic("Xunlocal: no locals!", 0); - runq->local = v->next; - hid = vlook(v->name); - hid->changed = 1; - efree(v->name); - freewords(v->val); - efree((char *)v); -} - -void -freewords(Word *w) -{ - Word *nw; - while(w){ - efree(w->word); - nw = w->next; - efree((char *)w); - w = nw; - } -} - -void -Xfn(void) -{ - Var *v; - Word *a; - int end; - end = runq->code[runq->pc].i; - for(a = runq->argv->words;a;a = a->next){ - v = gvlook(a->word); - if(v->fn) - codefree(v->fn); - v->fn = codecopy(runq->code); - v->pc = runq->pc+2; - v->fnchanged = 1; - } - runq->pc = end; - poplist(); -} - -void -Xdelfn(void) -{ - Var *v; - Word *a; - for(a = runq->argv->words;a;a = a->next){ - v = gvlook(a->word); - if(v->fn) - codefree(v->fn); - v->fn = 0; - v->fnchanged = 1; - } - poplist(); -} - -char* -concstatus(char *s, char *t) -{ - static char v[NSTATUS+1]; - int n = strlen(s); - strncpy(v, s, NSTATUS); - if(npid==-1) - setstatus(concstatus(runq->status, getstatus())); - else{ - strncpy(status, getstatus(), NSTATUS); - status[NSTATUS]='\0'; - Waitfor(runq->pid, 1); - runq->pid=-1; - setstatus(concstatus(getstatus(), status)); - } -} - -void -Xrdcmds(void) -{ - struct Thread *p = runq; - Word *prompt; - flush(err); - nerror = 0; - if(flag['s'] && !truestatus()) - pfmt(err, "status=%v\n", vlook("status")->val); - if(runq->iflag){ - prompt = vlook("prompt")->val; - if(prompt) - promptstr = prompt->word; - else - promptstr="% "; - } - Noerror(); - if(yyparse()){ - if(!p->iflag || p->eof && !Eintr()){ - if(p->cmdfile) - efree(p->cmdfile); - closeio(p->cmdfd); - Xreturn(); /* should this be omitted? */ - } - else{ - if(Eintr()){ - pchr(err, '\n'); - p->eof = 0; - } - --p->pc; /* go back for next command */ - } - } - else{ - ntrap = 0; /* avoid double-interrupts during blocked writes */ - --p->pc; /* re-execute Xrdcmds after codebuf runs */ - start(codebuf, 1, runq->local); - } - freenodes(); -} - -void -Xerror(char *s) -{ - if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0) - pfmt(err, "rc: %s: %r\n", s); - else - pfmt(err, "rc (%s): %s: %r\n", argv0, s); - flush(err); - setstatus("error"); - while(!runq->iflag) Xreturn(); -} - -void -Xerror1(char *s) -{ - if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0) - pfmt(err, "rc: %s\n", s); - else - pfmt(err, "rc (%s): %s\n", argv0, s); - flush(err); - setstatus("error"); - while(!runq->iflag) Xreturn(); -} - -void -setstatus(char *s) -{ - setvar("status", newword(s, (Word *)0)); -} - -char* -getstatus(void) -{ - Var *status = vlook("status"); - return status->val?status->val->word:""; -} - -int -truestatus(void) -{ - char *s; - for(s = getstatus();*s;s++) - if(*s!='|' && *s!='0') - return 0; - return 1; -} - -void -Xdelhere(void) -{ - Unlink(runq->code[runq->pc++].s); -} - -void -Xfor(void) -{ - if(runq->argv->words==0){ - poplist(); - runq->pc = runq->code[runq->pc].i; - } - else{ - freelist(runq->local->val); - runq->local->val = runq->argv->words; - runq->local->changed = 1; - runq->argv->words = runq->argv->words->next; - runq->local->val->next = 0; - runq->pc++; - } -} - -void -Xglob(void) -{ - globlist(); -} diff --git a/sys/cmd/rc/exec.h b/sys/cmd/rc/exec.h deleted file mode 100644 index faf29a5..0000000 --- a/sys/cmd/rc/exec.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Definitions used in the interpreter - */ -extern void Xappend(void), Xasync(void), Xbackq(void), Xbang(void), Xclose(void); -extern void Xconc(void), Xcount(void), Xdelfn(void), Xdol(void), Xqdol(void), Xdup(void); -extern void Xexit(void), Xfalse(void), Xfn(void), Xfor(void), Xglob(void); -extern void Xjump(void), Xmark(void), Xmatch(void), Xpipe(void), Xread(void); -extern void Xrdwr(void); -extern void Xrdfn(void), Xunredir(void), Xstar(void), Xreturn(void), Xsubshell(void); -extern void Xtrue(void), Xword(void), Xwrite(void), Xpipefd(void), Xcase(void); -extern void Xlocal(void), Xunlocal(void), Xassign(void), Xsimple(void), Xpopm(void); -extern void Xrdcmds(void), Xwastrue(void), Xif(void), Xifnot(void), Xpipewait(void); -extern void Xdelhere(void), Xpopredir(void), Xsub(void), Xeflag(void), Xsettrue(void); -extern void Xerror(char*); -extern void Xerror1(char*); -/* - * word lists are in correct order, - * i.e. word0->word1->word2->word3->0 - */ -struct Word -{ - char *word; - Word *next; -}; - -struct Words { - Word *words; - Words *next; -}; - -Word *newword(char *, Word *), *copywords(Word *, Word *); - -struct Redir -{ - char type; /* what to do */ - short from, to; /* what to do it to */ - struct Redir *next; /* what else to do (reverse order) */ -}; -#define NSTATUS ERRMAX /* length of status (from plan 9) */ -/* - * redir types - */ -#define ROPEN 1 /* dup2(from, to); close(from); */ -#define RDUP 2 /* dup2(from, to); */ -#define RCLOSE 3 /* close(from); */ -struct Thread -{ - union Code *code; /* code for this thread */ - int pc; /* code[pc] is the next instruction */ - struct Words *argv; /* argument stack */ - struct Redir *redir; /* redirection stack */ - struct Redir *startredir; /* redir inheritance point */ - struct Var *local; /* list of local variables */ - char *cmdfile; /* file name in Xrdcmd */ - struct Io *cmdfd; /* file descriptor for Xrdcmd */ - int iflast; /* static `if not' checking */ - int eof; /* is cmdfd at eof? */ - int iflag; /* interactive? */ - int lineno; /* linenumber */ - int pid; /* process for Xpipewait to wait for */ - char status[NSTATUS]; /* status for Xpipewait */ - Tree *treenodes; /* tree nodes created by this process */ - Thread *ret; /* who continues when this finishes */ -}; - -Code *codecopy(Code*); - -extern Thread *runq; -extern Code *codebuf; /* compiler output */ -extern int ntrap; /* number of outstanding traps */ -extern int trap[NSIG]; /* number of outstanding traps per type */ - -struct Builtin -{ - char *name; - void (*fnc)(void); -}; - -extern struct Builtin builtin[]; - -extern int eflagok; /* kludge flag so that -e doesn't exit in startup */ -extern int havefork; - -void execcd(void), execwhatis(void), execeval(void), execexec(void); -int execforkexec(void); -void execexit(void), execshift(void); -void execwait(void), execumask(void), execdot(void), execflag(void); -void execfunc(Var*), execcmds(Io *); diff --git a/sys/cmd/rc/fns.h b/sys/cmd/rc/fns.h deleted file mode 100644 index e9aa292..0000000 --- a/sys/cmd/rc/fns.h +++ /dev/null @@ -1,68 +0,0 @@ -void Abort(void); -void Closedir(int); -int Creat(char*); -int Dup(int, int); -int Dup1(int); -int Eintr(void); -int Executable(char*); -void Execute(Word*, Word*); -void Exit(char*); -int ForkExecute(char*, char**, int, int, int); -int Globsize(char*); -int Isatty(int); -void Memcpy(char*, char*, long); -void Noerror(void); -int Opendir(char*); -long Read(int, char*, long); -int Readdir(int, char*, int); -long Seek(int, long, long); -void Trapinit(void); -void Unlink(char*); -void Updenv(void); -void Vinit(void); -int Waitfor(int, int); -long Write(int, char*, long); -void addwaitpid(int); -int advance(void); -int back(int); -void cleanhere(char*); -void codefree(Code*); -int compile(Tree*); -char *list2str(Word*); -int count(Word*); -void deglob(char*); -void delwaitpid(int); -void dotrap(void); -void freenodes(void); -void freewords(Word*); -void globlist(void); -int havewaitpid(int); -int idchr(int); -void inttoascii(char*, long); -void kinit(void); -int mapfd(int); -int match(char*, char*, int); -int matchfn(char*, char*); -char** mkargv(Word*); -void clearwaitpids(void); -void panic(char*, int); -void pathinit(void); -void poplist(void); -void popword(void); -void pprompt(void); -void pushlist(void); -void pushredir(int, int, int); -void pushword(char*); -void readhere(void); -Word* searchpath(char*); -void setstatus(char*); -void setvar(char*, Word*); -void skipnl(void); -void start(Code*, int, Var*); -int truestatus(void); -void usage(char*); -int wordchr(int); -void yyerror(char*); -int yylex(void); -int yyparse(void); -int octal(char*); diff --git a/sys/cmd/rc/getflags.c b/sys/cmd/rc/getflags.c deleted file mode 100644 index 09f6e3a..0000000 --- a/sys/cmd/rc/getflags.c +++ /dev/null @@ -1,244 +0,0 @@ -/*% cyntax -DTEST % && cc -DTEST -go # % - */ -#include "rc.h" -#include "getflags.h" -#include "fns.h" -char *flagset[] = {""}; -char **flag[NFLAG]; -char cmdline[NCMDLINE+1]; -char *cmdname; -static char *flagarg=""; -static void reverse(char**, char**); -static int scanflag(int, char*); -static void errn(char*, int); -static void errs(char*); -static void errc(int); -static int reason; -#define RESET 1 -#define FEWARGS 2 -#define FLAGSYN 3 -#define BADFLAG 4 -static int badflag; - -int -getflags(int argc, char *argv[], char *flags, int stop) -{ - char *s, *t; - int i, j, c, count; - flagarg = flags; - if(cmdname==0) - cmdname = argv[0]; - s = cmdline; - for(i = 0;i!=argc;i++){ - for(t = argv[i];*t;t++) - if(s!=&cmdline[NCMDLINE]) - *s++=*t; - if(i!=argc-1 && s!=&cmdline[NCMDLINE]) - *s++=' '; - } - *s='\0'; - i = 1; - while(i!=argc){ - if(argv[i][0]!='-' || argv[i][1]=='\0'){ - if(stop) - return argc; - i++; - continue; - } - s = argv[i]+1; - while(*s){ - c=*s++; - count = scanflag(c, flags); - if(count==-1) - return -1; - if(flag[c]){ reason = RESET; badflag = c; return -1; } - if(count==0){ - flag[c] = flagset; - if(*s=='\0'){ - for(j = i+1;j<=argc;j++) - argv[j-1] = argv[j]; - --argc; - } - } - else{ - if(*s=='\0'){ - for(j = i+1;j<=argc;j++) - argv[j-1] = argv[j]; - --argc; - s = argv[i]; - } - if(argc-inext) n++; - list = (char **)emalloc(n*sizeof(char *)); - for(a = left,n = 0;a!=right;a = a->next,n++) list[n] = a->word; - qsort((void *)list, n, sizeof(void *), globcmp); - for(a = left,n = 0;a!=right;a = a->next,n++) a->word = list[n]; - efree((char *)list); -} -/* - * Push names prefixed by globname and suffixed by a match of p onto the astack. - * namep points to the end of the prefix in globname. - */ - -void -globdir(char *p, char *namep) -{ - char *t, *newp; - int f; - /* scan the pattern looking for a component with a metacharacter in it */ - if(*p=='\0'){ - globv = newword(globname, globv); - return; - } - t = namep; - newp = p; - while(*newp){ - if(*newp==GLOB) - break; - *t=*newp++; - if(*t++=='/'){ - namep = t; - p = newp; - } - } - /* If we ran out of pattern, append the name if accessible */ - if(*newp=='\0'){ - *t='\0'; - if(access(globname, 0)==0) - globv = newword(globname, globv); - return; - } - /* read the directory and recur for any entry that matches */ - *namep='\0'; - if((f = Opendir(globname[0]?globname:"."))<0) return; - while(*newp!='/' && *newp!='\0') newp++; - while(Readdir(f, namep, *newp=='/')){ - if(matchfn(namep, p)){ - for(t = namep;*t;t++); - globdir(newp, t); - } - } - Closedir(f); -} -/* - * Push all file names matched by p on the current thread's stack. - * If there are no matches, the list consists of p. - */ - -void -glob(char *p) -{ - Word *svglobv = globv; - int globlen = Globsize(p); - if(!globlen){ - deglob(p); - globv = newword(p, globv); - return; - } - globname = emalloc(globlen); - globname[0]='\0'; - globdir(p, globname); - efree(globname); - if(svglobv==globv){ - deglob(p); - globv = newword(p, globv); - } - else - globsort(globv, svglobv); -} -/* - * Do p and q point at equal utf codes - */ - -int -equtf(char *p, char *q) -{ - if(*p!=*q) - return 0; - if(twobyte(*p)) return p[1]==q[1]; - if(threebyte(*p)){ - if(p[1]!=q[1]) - return 0; - if(p[1]=='\0') - return 1; /* broken code at end of string! */ - return p[2]==q[2]; - } - if(fourbyte(*p)){ - if(p[1]!=q[1]) - return 0; - if(p[1]=='\0') - return 1; - if(p[2]!=q[2]) - return 0; - if(p[2]=='\0') - return 1; - return p[3]==q[3]; - } - return 1; -} -/* - * Return a pointer to the next utf code in the string, - * not jumping past nuls in broken utf codes! - */ - -char* -nextutf(char *p) -{ - if(twobyte(*p)) return p[1]=='\0'?p+1:p+2; - if(threebyte(*p)) return p[1]=='\0'?p+1:p[2]=='\0'?p+2:p+3; - if(fourbyte(*p)) return p[1]=='\0'?p+1:p[2]=='\0'?p+2:p[3]=='\0'?p+3:p+4; - return p+1; -} -/* - * Convert the utf code at *p to a unicode value - */ - -int -unicode(char *p) -{ - int u=*p&0xff; - if(twobyte(u)) return ((u&0x1f)<<6)|(p[1]&0x3f); - if(threebyte(u)) return (u<<12)|((p[1]&0x3f)<<6)|(p[2]&0x3f); - if(fourbyte(u)) return (u<<18)|((p[1]&0x3f)<<12)|((p[2]&0x3f)<<6)|(p[3]&0x3f); - return u; -} -/* - * Does the string s match the pattern p - * . and .. are only matched by patterns starting with . - * * matches any sequence of characters - * ? matches any single character - * [...] matches the enclosed list of characters - */ - -int -matchfn(char *s, char *p) -{ - if(s[0]=='.' && (s[1]=='\0' || s[1]=='.' && s[2]=='\0') && p[0]!='.') - return 0; - return match(s, p, '/'); -} - -int -match(char *s, char *p, int stop) -{ - int compl, hit, lo, hi, t, c; - for(;*p!=stop && *p!='\0';s = nextutf(s),p = nextutf(p)){ - if(*p!=GLOB){ - if(!equtf(p, s)) return 0; - } - else switch(*++p){ - case GLOB: - if(*s!=GLOB) - return 0; - break; - case '*': - for(;;){ - if(match(s, nextutf(p), stop)) return 1; - if(!*s) - break; - s = nextutf(s); - } - return 0; - case '?': - if(*s=='\0') - return 0; - break; - case '[': - if(*s=='\0') - return 0; - c = unicode(s); - p++; - compl=*p=='~'; - if(compl) - p++; - hit = 0; - while(*p!=']'){ - if(*p=='\0') - return 0; /* syntax error */ - lo = unicode(p); - p = nextutf(p); - if(*p!='-') - hi = lo; - else{ - p++; - if(*p=='\0') - return 0; /* syntax error */ - hi = unicode(p); - p = nextutf(p); - if(hinext); - glob(gl->word); - } -} - -void -globlist(void) -{ - Word *a; - globv = 0; - globlist1(runq->argv->words); - poplist(); - pushlist(); - if(globv){ - for(a = globv;a->next;a = a->next); - a->next = runq->argv->words; - runq->argv->words = globv; - } -} diff --git a/sys/cmd/rc/havefork.c b/sys/cmd/rc/havefork.c deleted file mode 100644 index b59e679..0000000 --- a/sys/cmd/rc/havefork.c +++ /dev/null @@ -1,300 +0,0 @@ -#ifdef Plan9 -#include -#endif -#include -#if defined(PLAN9PORT) && defined(__sun__) -# define BSD_COMP /* sigh. for TIOCNOTTY */ -#endif -#include -#include "rc.h" -#include "getflags.h" -#include "exec.h" -#include "io.h" -#include "fns.h" - -int havefork = 1; - -void -Xasync(void) -{ - int null = open("/dev/null", 0); - int tty; - int pid; - char npid[10]; - if(null<0){ - Xerror("Can't open /dev/null\n"); - return; - } - switch(pid = rfork(RFFDG|RFPROC|RFNOTEG)){ - case -1: - close(null); - Xerror("try again"); - break; - case 0: - clearwaitpids(); - /* - * I don't know what the right thing to do here is, - * so this is all experimentally determined. - * If we just dup /dev/null onto 0, then running - * ssh foo & will reopen /dev/tty, try to read a password, - * get a signal, and repeat, in a tight loop, forever. - * Arguably this is a bug in ssh (it behaves the same - * way under bash as under rc) but I'm fixing it here - * anyway. If we dissociate the process from the tty, - * then it won't be able to open /dev/tty ever again. - * The SIG_IGN on SIGTTOU makes writing the tty - * (via fd 1 or 2, for example) succeed even though - * our pgrp is not the terminal's controlling pgrp. - */ - if((tty = open("/dev/tty", OREAD)) >= 0){ - /* - * Should make reads of tty fail, writes succeed. - */ - signal(SIGTTIN, SIG_IGN); - signal(SIGTTOU, SIG_IGN); - ioctl(tty, TIOCNOTTY); - close(tty); - } - if(isatty(0)) - pushredir(ROPEN, null, 0); - else - close(null); - start(runq->code, runq->pc+1, runq->local); - runq->ret = 0; - break; - default: - addwaitpid(pid); - close(null); - runq->pc = runq->code[runq->pc].i; - inttoascii(npid, pid); - setvar("apid", newword(npid, (Word *)0)); - break; - } -} - -void -Xpipe(void) -{ - struct Thread *p = runq; - int pc = p->pc, forkid; - int lfd = p->code[pc++].i; - int rfd = p->code[pc++].i; - int pfd[2]; - if(pipe(pfd)<0){ - Xerror("can't get pipe"); - return; - } - switch(forkid = fork()){ - case -1: - Xerror("try again"); - break; - case 0: - clearwaitpids(); - start(p->code, pc+2, runq->local); - runq->ret = 0; - close(pfd[PRD]); - pushredir(ROPEN, pfd[PWR], lfd); - break; - default: - addwaitpid(forkid); - start(p->code, p->code[pc].i, runq->local); - close(pfd[PWR]); - pushredir(ROPEN, pfd[PRD], rfd); - p->pc = p->code[pc+1].i; - p->pid = forkid; - break; - } -} - -/* - * Who should wait for the exit from the fork? - */ -void -Xbackq(void) -{ - struct Thread *p = runq; - char wd[8193]; - int c, n; - char *s, *ewd=&wd[8192], *stop, *q; - struct Io *f; - Var *ifs = vlook("ifs"); - Word *v, *nextv; - int pfd[2]; - int pid; - Rune r; - stop = ifs->val?ifs->val->word:""; - if(pipe(pfd)<0){ - Xerror("can't make pipe"); - return; - } - switch(pid = fork()){ - case -1: - Xerror("try again"); - close(pfd[PRD]); - close(pfd[PWR]); - return; - case 0: - clearwaitpids(); - close(pfd[PRD]); - start(runq->code, runq->pc+1, runq->local); - pushredir(ROPEN, pfd[PWR], 1); - return; - default: - addwaitpid(pid); - close(pfd[PWR]); - f = openfd(pfd[PRD]); - s = wd; - v = 0; - while((c = rchr(f))!=EOF){ - if(s != ewd) { - *s++ = c; - for(q=stop; *q; q+=n) { - n = chartorune(&r, q); - if(s-wd >= n && memcmp(s-n, q, n) == 0) { - s -= n; - goto stop; - } - } - continue; - } - stop: - if(s != wd) { - *s = '\0'; - v = newword(wd, v); - } - s = wd; - } - if(s!=wd){ - *s='\0'; - v = newword(wd, v); - } - closeio(f); - Waitfor(pid, 0); - /* v points to reversed arglist -- reverse it onto argv */ - while(v){ - nextv = v->next; - v->next = runq->argv->words; - runq->argv->words = v; - v = nextv; - } - p->pc = p->code[p->pc].i; - return; - } -} - -void -Xpipefd(void) -{ - struct Thread *p = runq; - int pc = p->pc, pid; - char name[40]; - int pfd[2]; - struct { int sidefd, mainfd; } fd[2], *r, *w; - - r = &fd[0]; - w = &fd[1]; - switch(p->code[pc].i){ - case READ: - w = nil; - break; - case WRITE: - r = nil; - } - - if(r){ - if(pipe(pfd)<0){ - Xerror("can't get pipe"); - return; - } - r->sidefd = pfd[PWR]; - r->mainfd = pfd[PRD]; - } - if(w){ - if(pipe(pfd)<0){ - Xerror("can't get pipe"); - return; - } - w->sidefd = pfd[PRD]; - w->mainfd = pfd[PWR]; - } - switch(pid = fork()){ - case -1: - Xerror("try again"); - break; - case 0: - clearwaitpids(); - start(p->code, pc+2, runq->local); - if(r){ - close(r->mainfd); - pushredir(ROPEN, r->sidefd, 1); - } - if(w){ - close(w->mainfd); - pushredir(ROPEN, w->sidefd, 0); - } - runq->ret = 0; - break; - default: - addwaitpid(pid); - if(w){ - close(w->sidefd); - pushredir(ROPEN, w->mainfd, w->mainfd); /* so that Xpopredir can close it later */ - strcpy(name, Fdprefix); - inttoascii(name+strlen(name), w->mainfd); - pushword(name); - } - if(r){ - close(r->sidefd); - pushredir(ROPEN, r->mainfd, r->mainfd); - strcpy(name, Fdprefix); - inttoascii(name+strlen(name), r->mainfd); - pushword(name); - } - p->pc = p->code[pc+1].i; - break; - } -} - -void -Xsubshell(void) -{ - int pid; - switch(pid = fork()){ - case -1: - Xerror("try again"); - break; - case 0: - clearwaitpids(); - start(runq->code, runq->pc+1, runq->local); - runq->ret = 0; - break; - default: - addwaitpid(pid); - Waitfor(pid, 1); - runq->pc = runq->code[runq->pc].i; - break; - } -} - -int -execforkexec(void) -{ - int pid; - int n; - char buf[ERRMAX]; - - switch(pid = fork()){ - case -1: - return -1; - case 0: - clearwaitpids(); - pushword("exec"); - execexec(); - strcpy(buf, "can't exec: "); - n = strlen(buf); - errstr(buf+n, ERRMAX-n); - Exit(buf); - } - addwaitpid(pid); - return pid; -} diff --git a/sys/cmd/rc/here.c b/sys/cmd/rc/here.c deleted file mode 100644 index 8175b04..0000000 --- a/sys/cmd/rc/here.c +++ /dev/null @@ -1,153 +0,0 @@ -#include "rc.h" -#include "exec.h" -#include "io.h" -#include "fns.h" - -struct Here *here, **ehere; - -int ser = 0; -char tmp[]="/tmp/here0000.0000"; -char hex[]="0123456789abcdef"; -void psubst(Io*, char*); -void pstrs(Io*, Word*); - -void -hexnum(char *p, int n) -{ - *p++=hex[(n>>12)&0xF]; - *p++=hex[(n>>8)&0xF]; - *p++=hex[(n>>4)&0xF]; - *p = hex[n&0xF]; -} - -Tree* -heredoc(Tree *tag) -{ - struct Here *h = new(struct Here); - - if(tag->type!=WORD) - yyerror("Bad here tag"); - h->next = 0; - if(here) - *ehere = h; - else - here = h; - ehere=&h->next; - h->tag = tag; - hexnum(&tmp[9], getpid()); - hexnum(&tmp[14], ser++); - h->name = strdup(tmp); - return token(tmp, WORD); -} -/* - * bug: lines longer than NLINE get split -- this can cause spurious - * missubstitution, or a misrecognized EOF marker. - */ -#define NLINE 4096 - -void -readhere(void) -{ - struct Here *h, *nexth; - Io *f; - char *s, *tag; - int c, subst; - char line[NLINE+1]; - for(h = here;h;h = nexth){ - subst=!h->tag->quoted; - tag = h->tag->str; - c = Creat(h->name); - if(c<0) - yyerror("can't create here document"); - f = openfd(c); - s = line; - pprompt(); - while((c = rchr(runq->cmdfd))!=EOF){ - if(c=='\n' || s==&line[NLINE]){ - *s='\0'; - if(tag && strcmp(line, tag)==0) break; - if(subst) - psubst(f, line); - else pstr(f, line); - s = line; - if(c=='\n'){ - pprompt(); - pchr(f, c); - } - else *s++=c; - } - else *s++=c; - } - flush(f); - closeio(f); - cleanhere(h->name); - nexth = h->next; - efree((char *)h); - } - here = 0; - doprompt = 1; -} - -void -psubst(Io *f, char *s) -{ - char *t, *u; - int savec, n; - Word *star; - while(*s){ - if(*s!='$'){ - if(0xa0<=(*s&0xff) && (*s&0xff)<=0xf5){ - pchr(f, *s++); - if(*s=='\0') - break; - } - else if(0xf6<=(*s&0xff) && (*s&0xff)<=0xf7){ - pchr(f, *s++); - if(*s=='\0') - break; - pchr(f, *s++); - if(*s=='\0') - break; - } - pchr(f, *s++); - } - else{ - t=++s; - if(*t=='$') - pchr(f, *t++); - else{ - while(*t && idchr(*t)) t++; - savec=*t; - *t='\0'; - n = 0; - for(u = s;*u && '0'<=*u && *u<='9';u++) n = n*10+*u-'0'; - if(n && *u=='\0'){ - star = vlook("*")->val; - if(star && 1<=n && n<=count(star)){ - while(--n) star = star->next; - pstr(f, star->word); - } - } - else - pstrs(f, vlook(s)->val); - *t = savec; - if(savec=='^') - t++; - } - s = t; - } - } -} - -void -pstrs(Io *f, Word *a) -{ - if(a){ - while(a->next && a->next->word){ - pstr(f, a->word); - pchr(f, ' '); - a = a->next; - } - pstr(f, a->word); - } -} diff --git a/sys/cmd/rc/history.c b/sys/cmd/rc/history.c deleted file mode 100644 index 393c183..0000000 --- a/sys/cmd/rc/history.c +++ /dev/null @@ -1,4 +0,0 @@ -#include -#include - - diff --git a/sys/cmd/rc/io.c b/sys/cmd/rc/io.c deleted file mode 100644 index c06137c..0000000 --- a/sys/cmd/rc/io.c +++ /dev/null @@ -1,263 +0,0 @@ -#include -#include "rc.h" -#include "exec.h" -#include "io.h" -#include "fns.h" - -Io *err; -int pfmtnest = 0; - -void -pfmt(Io *f, char *fmt, ...) -{ - va_list ap; - char err[ERRMAX]; - va_start(ap, fmt); - pfmtnest++; - for(;*fmt;fmt++) - if(*fmt!='%') - pchr(f, *fmt); - else switch(*++fmt){ - case '\0': - va_end(ap); - return; - case 'c': - pchr(f, va_arg(ap, int)); - break; - case 'd': - pdec(f, va_arg(ap, int)); - break; - case 'o': - poct(f, va_arg(ap, unsigned)); - break; - case 'p': - pptr(f, va_arg(ap, void*)); - break; - case 'Q': - pquo(f, va_arg(ap, char *)); - break; - case 'q': - pwrd(f, va_arg(ap, char *)); - break; - case 'r': - rerrstr(err, sizeof err); pstr(f, err); - break; - case 's': - pstr(f, va_arg(ap, char *)); - break; - case 't': - pcmd(f, va_arg(ap, struct Tree *)); - break; - case 'v': - pval(f, va_arg(ap, struct Word *)); - break; - default: - pchr(f, *fmt); - break; - } - va_end(ap); - if(--pfmtnest==0) - flush(f); -} - -void -pchr(Io *b, int c) -{ - if(b->bufp==b->ebuf) - fullbuf(b, c); - else *b->bufp++=c; -} - -int -rchr(Io *b) -{ - if(b->bufp==b->ebuf) - return emptybuf(b); - return *b->bufp++ & 0xFF; -} - -void -pquo(Io *f, char *s) -{ - pchr(f, '\''); - for(;*s;s++) - if(*s=='\'') - pfmt(f, "''"); - else pchr(f, *s); - pchr(f, '\''); -} - -void -pwrd(Io *f, char *s) -{ - char *t; - for(t = s;*t;t++) if(!wordchr(*t)) break; - if(t==s || *t) - pquo(f, s); - else pstr(f, s); -} - -void -pptr(Io *f, void *v) -{ - int n; - uintptr p; - - p = (uintptr)v; - if(sizeof(uintptr) == sizeof(uvlong) && p>>32) - for(n = 60;n>=32;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]); - - for(n = 28;n>=0;n-=4) pchr(f, "0123456789ABCDEF"[(p>>n)&0xF]); -} - -void -pstr(Io *f, char *s) -{ - if(s==0) - s="(null)"; - while(*s) pchr(f, *s++); -} - -void -pdec(Io *f, int n) -{ - if(n<0){ - if(n!=INT_MIN){ - pchr(f, '-'); - pdec(f, -n); - return; - } - /* n is two's complement minimum integer */ - n = -(INT_MIN+1); - pchr(f, '-'); - pdec(f, n/10); - pchr(f, n%10+'1'); - return; - } - if(n>9) - pdec(f, n/10); - pchr(f, n%10+'0'); -} - -void -poct(Io *f, unsigned n) -{ - if(n>7) - poct(f, n>>3); - pchr(f, (n&7)+'0'); -} - -void -pval(Io *f, Word *a) -{ - if(a){ - while(a->next && a->next->word){ - pwrd(f, a->word); - pchr(f, ' '); - a = a->next; - } - pwrd(f, a->word); - } -} - -int -fullbuf(Io *f, int c) -{ - flush(f); - return *f->bufp++=c; -} - -void -flush(Io *f) -{ - int n; - char *s; - if(f->strp){ - n = f->ebuf-f->strp; - f->strp = realloc(f->strp, n+101); - if(f->strp==0) - panic("Can't realloc %d bytes in flush!", n+101); - f->bufp = f->strp+n; - f->ebuf = f->bufp+100; - for(s = f->bufp;s<=f->ebuf;s++) *s='\0'; - } - else{ - n = f->bufp-f->buf; - if(n && Write(f->fd, f->buf, n) < 0){ - Write(3, "Write error\n", 12); - if(ntrap) - dotrap(); - } - f->bufp = f->buf; - f->ebuf = f->buf+NBUF; - } -} - -Io* -openfd(int fd) -{ - Io *f = new(struct Io); - f->fd = fd; - f->bufp = f->ebuf = f->buf; - f->strp = 0; - return f; -} - -Io* -openstr(void) -{ - Io *f = new(struct Io); - char *s; - f->fd=-1; - f->bufp = f->strp = emalloc(101); - f->ebuf = f->bufp+100; - for(s = f->bufp;s<=f->ebuf;s++) *s='\0'; - return f; -} -/* - * Open a corebuffer to read. EOF occurs after reading len - * characters from buf. - */ - -Io* -opencore(char *s, int len) -{ - Io *f = new(struct Io); - char *buf = emalloc(len); - f->fd= -1 /*open("/dev/null", 0)*/; - f->bufp = f->strp = buf; - f->ebuf = buf+len; - Memcpy(buf, s, len); - return f; -} - -void -iorewind(Io *io) -{ - if(io->fd==-1) - io->bufp = io->strp; - else{ - io->bufp = io->ebuf = io->buf; - Seek(io->fd, 0L, 0); - } -} - -void -closeio(Io *io) -{ - if(io->fd>=0) - close(io->fd); - if(io->strp) - efree(io->strp); - efree((char *)io); -} - -int -emptybuf(Io *f) -{ - int n; - if(f->fd==-1 || (n = Read(f->fd, f->buf, NBUF))<=0) return EOF; - f->bufp = f->buf; - f->ebuf = f->buf+n; - return *f->bufp++&0xff; -} diff --git a/sys/cmd/rc/io.h b/sys/cmd/rc/io.h deleted file mode 100644 index 5457735..0000000 --- a/sys/cmd/rc/io.h +++ /dev/null @@ -1,31 +0,0 @@ -#define EOF (-1) -#define NBUF 512 - -struct Io -{ - int fd; - char *bufp, *ebuf, *strp, buf[NBUF]; -}; - -extern struct Io *err; - -Io *openfd(int); -Io *openstr(void); -Io *opencore(char *, int); - -int emptybuf(Io*); -void pchr(Io*, int); -int rchr(Io*); -void closeio(Io*); -void flush(Io*); -int fullbuf(Io*, int); -void pdec(Io*, int); -void poct(Io*, unsigned); -void pptr(Io*, void*); -void pquo(Io*, char*); -void pwrd(Io*, char*); -void pstr(Io*, char*); -void pcmd(Io*, Tree*); -void pval(Io*, Word*); -void pfnc(Io*, Thread*); -void pfmt(Io*, char*, ...); diff --git a/sys/cmd/rc/lex.c b/sys/cmd/rc/lex.c deleted file mode 100644 index b840fff..0000000 --- a/sys/cmd/rc/lex.c +++ /dev/null @@ -1,372 +0,0 @@ -#include "rc.h" -#include "exec.h" -#include "io.h" -#include "getflags.h" -#include "fns.h" - -char *promptstr; -int doprompt; -char tok[NTOK]; - -int getnext(void); - -int -wordchr(int c) -{ - return !strchr("\n \t#;&|^$=`'{}()<>", c) && c!=EOF; -} - -int -idchr(int c) -{ - /* - * Formerly: - * return 'a'<=c && c<='z' || 'A'<=c && c<='Z' || '0'<=c && c<='9' - * || c=='_' || c=='*'; - */ - return c>' ' && !strchr("!\"#$%&'()+,-./:;<=>?@[\\]^`{|}~", c); -} -int future = EOF; -int doprompt = 1; -int inquote; -int incomm; -/* - * Look ahead in the input stream - */ - -int -nextc(void) -{ - if(future==EOF) - future = getnext(); - return future; -} -/* - * Consume the lookahead character. - */ - -int -advance(void) -{ - int c = nextc(); - lastc = future; - future = EOF; - return c; -} -/* - * read a character from the input stream - */ - -int -getnext(void) -{ - int c; - static int peekc = EOF; - if(peekc!=EOF){ - c = peekc; - peekc = EOF; - return c; - } - if(runq->eof) - return EOF; - if(doprompt) - pprompt(); - c = rchr(runq->cmdfd); - if(!inquote && c=='\\'){ - c = rchr(runq->cmdfd); - if(c=='\n' && !incomm){ /* don't continue a comment */ - doprompt = 1; - c=' '; - } - else{ - peekc = c; - c='\\'; - } - } - doprompt = doprompt || c=='\n' || c==EOF; - if(c==EOF) - runq->eof++; - else if(flag['V'] || ndot>=2 && flag['v']) pchr(err, c); - return c; -} - -void -skipwhite(void) -{ - int c; - for(;;){ - c = nextc(); - /* Why did this used to be if(!inquote && c=='#') ?? */ - if(c=='#'){ - incomm = 1; - for(;;){ - c = nextc(); - if(c=='\n' || c==EOF) { - incomm = 0; - break; - } - advance(); - } - } - if(c==' ' || c=='\t') - advance(); - else return; - } -} - -void -skipnl(void) -{ - int c; - for(;;){ - skipwhite(); - c = nextc(); - if(c!='\n') - return; - advance(); - } -} - -int -nextis(int c) -{ - if(nextc()==c){ - advance(); - return 1; - } - return 0; -} - -char* -addtok(char *p, int val) -{ - if(p==0) - return 0; - if(p==&tok[NTOK-1]){ - *p = 0; - yyerror("token buffer too short"); - return 0; - } - *p++=val; - return p; -} - -char* -addutf(char *p, int c) -{ - p = addtok(p, c); - if(twobyte(c)) /* 2-byte escape */ - return addtok(p, advance()); - if(threebyte(c)){ /* 3-byte escape */ - p = addtok(p, advance()); - return addtok(p, advance()); - } - if(fourbyte(c)){ /* 4-byte escape */ - p = addtok(p, advance()); - p = addtok(p, advance()); - return addtok(p, advance()); - } - return p; -} -int lastdol; /* was the last token read '$' or '$#' or '"'? */ -int lastword; /* was the last token read a word or compound word terminator? */ - -int -yylex(void) -{ - int c, d = nextc(); - char *w = tok; - struct Tree *t; - - yylval.tree = 0; - /* - * Embarassing sneakiness: if the last token read was a quoted or unquoted - * WORD then we alter the meaning of what follows. If the next character - * is `(', we return SUB (a subscript paren) and consume the `('. Otherwise, - * if the next character is the first character of a simple or compound word, - * we insert a `^' before it. - */ - if(lastword){ - lastword = 0; - if(d=='('){ - advance(); - strcpy(tok, "( [SUB]"); - return SUB; - } - if(wordchr(d) || d=='\'' || d=='`' || d=='$' || d=='"'){ - strcpy(tok, "^"); - return '^'; - } - } - inquote = 0; - skipwhite(); - switch(c = advance()){ - case EOF: - lastdol = 0; - strcpy(tok, "EOF"); - return EOF; - case '$': - lastdol = 1; - if(nextis('#')){ - strcpy(tok, "$#"); - return COUNT; - } - if(nextis('"')){ - strcpy(tok, "$\""); - return '"'; - } - strcpy(tok, "$"); - return '$'; - case '&': - lastdol = 0; - if(nextis('&')){ - skipnl(); - strcpy(tok, "&&"); - return ANDAND; - } - strcpy(tok, "&"); - return '&'; - case '|': - lastdol = 0; - if(nextis(c)){ - skipnl(); - strcpy(tok, "||"); - return OROR; - } - case '<': - case '>': - lastdol = 0; - /* - * funny redirection tokens: - * redir: arrow | arrow '[' fd ']' - * arrow: '<' | '<<' | '>' | '>>' | '|' - * fd: digit | digit '=' | digit '=' digit - * digit: '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9' - * some possibilities are nonsensical and get a message. - */ - *w++=c; - t = newtree(); - switch(c){ - case '|': - t->type = PIPE; - t->fd0 = 1; - t->fd1 = 0; - break; - case '>': - t->type = REDIR; - if(nextis(c)){ - t->rtype = APPEND; - *w++=c; - } - else t->rtype = WRITE; - t->fd0 = 1; - break; - case '<': - t->type = REDIR; - if(nextis(c)){ - t->rtype = HERE; - *w++=c; - } else if (nextis('>')){ - t->rtype = RDWR; - *w++=c; - } else t->rtype = READ; - t->fd0 = 0; - break; - } - if(nextis('[')){ - *w++='['; - c = advance(); - *w++=c; - if(c<'0' || '9'type==PIPE?"pipe syntax" - :"redirection syntax"); - return EOF; - } - t->fd0 = 0; - do{ - t->fd0 = t->fd0*10+c-'0'; - *w++=c; - c = advance(); - }while('0'<=c && c<='9'); - if(c=='='){ - *w++='='; - if(t->type==REDIR) - t->type = DUP; - c = advance(); - if('0'<=c && c<='9'){ - t->rtype = DUPFD; - t->fd1 = t->fd0; - t->fd0 = 0; - do{ - t->fd0 = t->fd0*10+c-'0'; - *w++=c; - c = advance(); - }while('0'<=c && c<='9'); - } - else{ - if(t->type==PIPE) - goto RedirErr; - t->rtype = CLOSE; - } - } - if(c!=']' - || t->type==DUP && (t->rtype==HERE || t->rtype==APPEND)) - goto RedirErr; - *w++=']'; - } - *w='\0'; - yylval.tree = t; - if(t->type==PIPE) - skipnl(); - return t->type; - case '\'': - lastdol = 0; - lastword = 1; - inquote = 1; - for(;;){ - c = advance(); - if(c==EOF) - break; - if(c=='\''){ - if(nextc()!='\'') - break; - advance(); - } - w = addutf(w, c); - } - if(w!=0) - *w='\0'; - t = token(tok, WORD); - t->quoted = 1; - yylval.tree = t; - return t->type; - } - if(!wordchr(c)){ - lastdol = 0; - tok[0] = c; - tok[1]='\0'; - return c; - } - for(;;){ - /* next line should have (char)c==GLOB, but ken's compiler is broken */ - if(c=='*' || c=='[' || c=='?' || c==(unsigned char)GLOB) - w = addtok(w, GLOB); - w = addutf(w, c); - c = nextc(); - if(lastdol?!idchr(c):!wordchr(c)) break; - advance(); - } - - lastword = 1; - lastdol = 0; - if(w!=0) - *w='\0'; - t = klook(tok); - if(t->type!=WORD) - lastword = 0; - t->quoted = 0; - yylval.tree = t; - return t->type; -} diff --git a/sys/cmd/rc/linenoise.c b/sys/cmd/rc/linenoise.c deleted file mode 100644 index 751b4e9..0000000 --- a/sys/cmd/rc/linenoise.c +++ /dev/null @@ -1,1236 +0,0 @@ -/* linenoise.c -- guerrilla line editing library against the idea that a - * line editing lib needs to be 20,000 lines of C code. - * - * You can find the latest source code at: - * - * http://github.com/antirez/linenoise - * - * Does a number of crazy assumptions that happen to be true in 99.9999% of - * the 2010 UNIX computers around. - * - * ------------------------------------------------------------------------ - * - * Copyright (c) 2010-2016, Salvatore Sanfilippo - * Copyright (c) 2010-2013, Pieter Noordhuis - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * ------------------------------------------------------------------------ - * - * References: - * - http://invisible-island.net/xterm/ctlseqs/ctlseqs.html - * - http://www.3waylabs.com/nw/WWW/products/wizcon/vt220.html - * - * Todo list: - * - Filter bogus Ctrl+ combinations. - * - Win32 support - * - * Bloat: - * - History search like Ctrl+r in readline? - * - * List of escape sequences used by this program, we do everything just - * with three sequences. In order to be so cheap we may have some - * flickering effect with some slow terminal, but the lesser sequences - * the more compatible. - * - * EL (Erase Line) - * Sequence: ESC [ n K - * Effect: if n is 0 or missing, clear from cursor to end of line - * Effect: if n is 1, clear from beginning of line to cursor - * Effect: if n is 2, clear entire line - * - * CUF (CUrsor Forward) - * Sequence: ESC [ n C - * Effect: moves cursor forward n chars - * - * CUB (CUrsor Backward) - * Sequence: ESC [ n D - * Effect: moves cursor backward n chars - * - * The following is used to get the terminal width if getting - * the width with the TIOCGWINSZ ioctl fails - * - * DSR (Device Status Report) - * Sequence: ESC [ 6 n - * Effect: reports the current cusor position as ESC [ n ; m R - * where n is the row and m is the column - * - * When multi line mode is enabled, we also use an additional escape - * sequence. However multi line editing is disabled by default. - * - * CUU (Cursor Up) - * Sequence: ESC [ n A - * Effect: moves cursor up of n chars. - * - * CUD (Cursor Down) - * Sequence: ESC [ n B - * Effect: moves cursor down of n chars. - * - * When linenoiseClearScreen() is called, two additional escape sequences - * are used in order to clear the screen and position the cursor at home - * position. - * - * CUP (Cursor position) - * Sequence: ESC [ H - * Effect: moves the cursor to upper left corner - * - * ED (Erase display) - * Sequence: ESC [ 2 J - * Effect: clear the whole screen - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "linenoise.h" - -#define LINENOISE_DEFAULT_HISTORY_MAX_LEN 100 -#define LINENOISE_MAX_LINE 4096 - -static char *unsupported_term[] = {"dumb","cons25","emacs",NULL}; -static linenoiseCompletionCallback *completionCallback = NULL; -static linenoiseHintsCallback *hintsCallback = NULL; -static linenoiseFreeHintsCallback *freeHintsCallback = NULL; - -static struct termios orig_termios; /* In order to restore at exit.*/ -static int maskmode = 0; /* Show "***" instead of input. For passwords. */ -static int rawmode = 0; /* For atexit() function to check if restore is needed*/ -static int mlmode = 0; /* Multi line mode. Default is single line. */ -static int atexit_registered = 0; /* Register atexit just 1 time. */ -static int history_max_len = LINENOISE_DEFAULT_HISTORY_MAX_LEN; -static int history_len = 0; -static char **history = NULL; - -/* The linenoiseState structure represents the state during line editing. - * We pass this state to functions implementing specific editing - * functionalities. */ -struct linenoiseState { - int ifd; /* Terminal stdin file descriptor. */ - int ofd; /* Terminal stdout file descriptor. */ - char *buf; /* Edited line buffer. */ - size_t buflen; /* Edited line buffer size. */ - const char *prompt; /* Prompt to display. */ - size_t plen; /* Prompt length. */ - size_t pos; /* Current cursor position. */ - size_t oldpos; /* Previous refresh cursor position. */ - size_t len; /* Current edited line length. */ - size_t cols; /* Number of columns in terminal. */ - size_t maxrows; /* Maximum num of rows used so far (multiline mode) */ - int history_index; /* The history index we are currently editing. */ -}; - -enum KEY_ACTION{ - KEY_NULL = 0, /* NULL */ - CTRL_A = 1, /* Ctrl+a */ - CTRL_B = 2, /* Ctrl-b */ - CTRL_C = 3, /* Ctrl-c */ - CTRL_D = 4, /* Ctrl-d */ - CTRL_E = 5, /* Ctrl-e */ - CTRL_F = 6, /* Ctrl-f */ - CTRL_H = 8, /* Ctrl-h */ - TAB = 9, /* Tab */ - CTRL_K = 11, /* Ctrl+k */ - CTRL_L = 12, /* Ctrl+l */ - ENTER = 13, /* Enter */ - CTRL_N = 14, /* Ctrl-n */ - CTRL_P = 16, /* Ctrl-p */ - CTRL_T = 20, /* Ctrl-t */ - CTRL_U = 21, /* Ctrl+u */ - CTRL_W = 23, /* Ctrl+w */ - ESC = 27, /* Escape */ - BACKSPACE = 127 /* Backspace */ -}; - -static void linenoiseAtExit(void); -int linenoiseHistoryAdd(const char *line); -static void refreshLine(struct linenoiseState *l); - -/* Debugging macro. */ -#if 0 -FILE *lndebug_fp = NULL; -#define lndebug(...) \ - do { \ - if (lndebug_fp == NULL) { \ - lndebug_fp = fopen("/tmp/lndebug.txt","a"); \ - fprintf(lndebug_fp, \ - "[%d %d %d] p: %d, rows: %d, rpos: %d, max: %d, oldmax: %d\n", \ - (int)l->len,(int)l->pos,(int)l->oldpos,plen,rows,rpos, \ - (int)l->maxrows,old_rows); \ - } \ - fprintf(lndebug_fp, ", " __VA_ARGS__); \ - fflush(lndebug_fp); \ - } while (0) -#else -#define lndebug(fmt, ...) -#endif - -int -strcasecmp(const char *_l, const char *_r) -{ - const unsigned char *l=(void *)_l, *r=(void *)_r; - for (; *l && *r && (*l == *r || tolower(*l) == tolower(*r)); l++, r++); - return tolower(*l) - tolower(*r); -} - - -/* ======================= Low level terminal handling ====================== */ - -/* Enable "mask mode". When it is enabled, instead of the input that - * the user is typing, the terminal will just display a corresponding - * number of asterisks, like "****". This is useful for passwords and other - * secrets that should not be displayed. */ -void linenoiseMaskModeEnable(void) { - maskmode = 1; -} - -/* Disable mask mode. */ -void linenoiseMaskModeDisable(void) { - maskmode = 0; -} - -/* Set if to use or not the multi line mode. */ -void linenoiseSetMultiLine(int ml) { - mlmode = ml; -} - -/* Return true if the terminal name is in the list of terminals we know are - * not able to understand basic escape sequences. */ -static int isUnsupportedTerm(void) { - char *term = getenv("TERM"); - int j; - - if(term == NULL) return 0; - for(j = 0; unsupported_term[j]; j++) - if(!strcasecmp(term,unsupported_term[j])) return 1; - return 0; -} - -/* Raw mode: 1960 magic shit. */ -static int enableRawMode(int fd) { - struct termios raw; - - if (!isatty(STDIN_FILENO)) goto fatal; - if (!atexit_registered) { - atexit(linenoiseAtExit); - atexit_registered = 1; - } - if (tcgetattr(fd,&orig_termios) == -1) goto fatal; - - raw = orig_termios; /* modify the original mode */ - /* input modes: no break, no CR to NL, no parity check, no strip char, - * no start/stop output control. */ - raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); - /* output modes - disable post processing */ - raw.c_oflag &= ~(OPOST); - /* control modes - set 8 bit chars */ - raw.c_cflag |= (CS8); - /* local modes - choing off, canonical off, no extended functions, - * no signal chars (^Z,^C) */ - raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); - /* control chars - set return condition: min number of bytes and timer. - * We want read to return every single byte, without timeout. */ - raw.c_cc[VMIN] = 1; raw.c_cc[VTIME] = 0; /* 1 byte, no timer */ - - /* put terminal in raw mode after flushing */ - if (tcsetattr(fd,TCSAFLUSH,&raw) < 0) goto fatal; - rawmode = 1; - return 0; - -fatal: - errno = ENOTTY; - return -1; -} - -static void disableRawMode(int fd) { - /* Don't even check the return value as it's too late. */ - if (rawmode && tcsetattr(fd,TCSAFLUSH,&orig_termios) != -1) - rawmode = 0; -} - -/* Use the ESC [6n escape sequence to query the horizontal cursor position - * and return it. On error -1 is returned, on success the position of the - * cursor. */ -static int getCursorPosition(int ifd, int ofd) { - char buf[32]; - int cols, rows; - unsigned int i = 0; - - /* Report cursor location */ - if (write(ofd, "\x1b[6n", 4) != 4) return -1; - - /* Read the response: ESC [ rows ; cols R */ - while (i < sizeof(buf)-1) { - if (read(ifd,buf+i,1) != 1) break; - if (buf[i] == 'R') break; - i++; - } - buf[i] = '\0'; - - /* Parse it. */ - if (buf[0] != ESC || buf[1] != '[') return -1; - if (sscanf(buf+2,"%d;%d",&rows,&cols) != 2) return -1; - return cols; -} - -/* Try to get the number of columns in the current terminal, or assume 80 - * if it fails. */ -static int getColumns(int ifd, int ofd) { - struct winsize ws; - - if (ioctl(1, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) { - /* ioctl() failed. Try to query the terminal itself. */ - int start, cols; - - /* Get the initial position so we can restore it later. */ - start = getCursorPosition(ifd,ofd); - if (start == -1) goto failed; - - /* Go to right margin and get position. */ - if (write(ofd,"\x1b[999C",6) != 6) goto failed; - cols = getCursorPosition(ifd,ofd); - if (cols == -1) goto failed; - - /* Restore position. */ - if (cols > start) { - char seq[32]; - snprintf(seq,32,"\x1b[%dD",cols-start); - if (write(ofd,seq,strlen(seq)) == -1) { - /* Can't recover... */ - } - } - return cols; - } else { - return ws.ws_col; - } - -failed: - return 80; -} - -/* Clear the screen. Used to handle ctrl+l */ -void linenoiseClearScreen(void) { - if (write(STDOUT_FILENO,"\x1b[H\x1b[2J",7) <= 0) { - /* nothing to do, just to avoid warning. */ - } -} - -/* Beep, used for completion when there is nothing to complete or when all - * the choices were already shown. */ -static void linenoiseBeep(void) { - fprintf(stderr, "\x7"); - fflush(stderr); -} - -/* ============================== Completion ================================ */ - -/* Free a list of completion option populated by linenoiseAddCompletion(). */ -static void freeCompletions(linenoiseCompletions *lc) { - size_t i; - for (i = 0; i < lc->len; i++) - free(lc->cvec[i]); - if (lc->cvec != NULL) - free(lc->cvec); -} - -/* This is an helper function for linenoiseEdit() and is called when the - * user types the key in order to complete the string currently in the - * input. - * - * The state of the editing is encapsulated into the pointed linenoiseState - * structure as described in the structure definition. */ -static int completeLine(struct linenoiseState *ls) { - linenoiseCompletions lc = { 0, NULL }; - int nread, nwritten; - char c = 0; - - completionCallback(ls->buf,&lc); - if (lc.len == 0) { - linenoiseBeep(); - } else { - size_t stop = 0, i = 0; - - while(!stop) { - /* Show completion or original buffer */ - if (i < lc.len) { - struct linenoiseState saved = *ls; - - ls->len = ls->pos = strlen(lc.cvec[i]); - ls->buf = lc.cvec[i]; - refreshLine(ls); - ls->len = saved.len; - ls->pos = saved.pos; - ls->buf = saved.buf; - } else { - refreshLine(ls); - } - - nread = read(ls->ifd,&c,1); - if (nread <= 0) { - freeCompletions(&lc); - return -1; - } - - switch(c) { - case 9: /* tab */ - i = (i+1) % (lc.len+1); - if (i == lc.len) linenoiseBeep(); - break; - case 27: /* escape */ - /* Re-show original buffer */ - if (i < lc.len) refreshLine(ls); - stop = 1; - break; - default: - /* Update buffer and return */ - if (i < lc.len) { - nwritten = snprintf(ls->buf,ls->buflen,"%s",lc.cvec[i]); - ls->len = ls->pos = nwritten; - } - stop = 1; - break; - } - } - } - - freeCompletions(&lc); - return c; /* Return last read character */ -} - -/* Register a callback function to be called for tab-completion. */ -void linenoiseSetCompletionCallback(linenoiseCompletionCallback *fn) { - completionCallback = fn; -} - -/* Register a hits function to be called to show hits to the user at the - * right of the prompt. */ -void linenoiseSetHintsCallback(linenoiseHintsCallback *fn) { - hintsCallback = fn; -} - -/* Register a function to free the hints returned by the hints callback - * registered with linenoiseSetHintsCallback(). */ -void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *fn) { - freeHintsCallback = fn; -} - -/* This function is used by the callback function registered by the user - * in order to add completion options given the input string when the - * user typed . See the example.c source code for a very easy to - * understand example. */ -void linenoiseAddCompletion(linenoiseCompletions *lc, const char *str) { - size_t len = strlen(str); - char *copy, **cvec; - - copy = malloc(len+1); - if (copy == NULL) return; - memcpy(copy,str,len+1); - cvec = realloc(lc->cvec,sizeof(char*)*(lc->len+1)); - if (cvec == NULL) { - free(copy); - return; - } - lc->cvec = cvec; - lc->cvec[lc->len++] = copy; -} - -/* =========================== Line editing ================================= */ - -/* We define a very simple "append buffer" structure, that is an heap - * allocated string where we can append to. This is useful in order to - * write all the escape sequences in a buffer and flush them to the standard - * output in a single call, to avoid flickering effects. */ -struct abuf { - char *b; - int len; -}; - -static void abInit(struct abuf *ab) { - ab->b = NULL; - ab->len = 0; -} - -static void abAppend(struct abuf *ab, const char *s, int len) { - char *new = realloc(ab->b,ab->len+len); - - if (new == NULL) return; - memcpy(new+ab->len,s,len); - ab->b = new; - ab->len += len; -} - -static void abFree(struct abuf *ab) { - free(ab->b); -} - -/* Helper of refreshSingleLine() and refreshMultiLine() to show hints - * to the right of the prompt. */ -void refreshShowHints(struct abuf *ab, struct linenoiseState *l, int plen) { - char seq[64]; - if (hintsCallback && plen+l->len < l->cols) { - int color = -1, bold = 0; - char *hint = hintsCallback(l->buf,&color,&bold); - if (hint) { - int hintlen = strlen(hint); - int hintmaxlen = l->cols-(plen+l->len); - if (hintlen > hintmaxlen) hintlen = hintmaxlen; - if (bold == 1 && color == -1) color = 37; - if (color != -1 || bold != 0) - snprintf(seq,64,"\033[%d;%d;49m",bold,color); - else - seq[0] = '\0'; - abAppend(ab,seq,strlen(seq)); - abAppend(ab,hint,hintlen); - if (color != -1 || bold != 0) - abAppend(ab,"\033[0m",4); - /* Call the function to free the hint returned. */ - if (freeHintsCallback) freeHintsCallback(hint); - } - } -} - -/* Single line low level line refresh. - * - * Rewrite the currently edited line accordingly to the buffer content, - * cursor position, and number of columns of the terminal. */ -static void refreshSingleLine(struct linenoiseState *l) { - char seq[64]; - size_t plen = strlen(l->prompt); - int fd = l->ofd; - char *buf = l->buf; - size_t len = l->len; - size_t pos = l->pos; - struct abuf ab; - - while((plen+pos) >= l->cols) { - buf++; - len--; - pos--; - } - while (plen+len > l->cols) { - len--; - } - - abInit(&ab); - /* Cursor to left edge */ - snprintf(seq,64,"\r"); - abAppend(&ab,seq,strlen(seq)); - /* Write the prompt and the current buffer content */ - abAppend(&ab,l->prompt,strlen(l->prompt)); - if (maskmode == 1) { - while (len--) abAppend(&ab,"*",1); - } else { - abAppend(&ab,buf,len); - } - /* Show hits if any. */ - refreshShowHints(&ab,l,plen); - /* Erase to right */ - snprintf(seq,64,"\x1b[0K"); - abAppend(&ab,seq,strlen(seq)); - /* Move cursor to original position. */ - snprintf(seq,64,"\r\x1b[%dC", (int)(pos+plen)); - abAppend(&ab,seq,strlen(seq)); - if (write(fd,ab.b,ab.len) == -1) {} /* Can't recover from write error. */ - abFree(&ab); -} - -/* Multi line low level line refresh. - * - * Rewrite the currently edited line accordingly to the buffer content, - * cursor position, and number of columns of the terminal. */ -static void refreshMultiLine(struct linenoiseState *l) { - char seq[64]; - int plen = strlen(l->prompt); - int rows = (plen+l->len+l->cols-1)/l->cols; /* rows used by current buf. */ - int rpos = (plen+l->oldpos+l->cols)/l->cols; /* cursor relative row. */ - int rpos2; /* rpos after refresh. */ - int col; /* colum position, zero-based. */ - int old_rows = l->maxrows; - int fd = l->ofd, j; - struct abuf ab; - - /* Update maxrows if needed. */ - if (rows > (int)l->maxrows) l->maxrows = rows; - - /* First step: clear all the lines used before. To do so start by - * going to the last row. */ - abInit(&ab); - if (old_rows-rpos > 0) { - lndebug("go down %d", old_rows-rpos); - snprintf(seq,64,"\x1b[%dB", old_rows-rpos); - abAppend(&ab,seq,strlen(seq)); - } - - /* Now for every row clear it, go up. */ - for (j = 0; j < old_rows-1; j++) { - lndebug("clear+up"); - snprintf(seq,64,"\r\x1b[0K\x1b[1A"); - abAppend(&ab,seq,strlen(seq)); - } - - /* Clean the top line. */ - lndebug("clear"); - snprintf(seq,64,"\r\x1b[0K"); - abAppend(&ab,seq,strlen(seq)); - - /* Write the prompt and the current buffer content */ - abAppend(&ab,l->prompt,strlen(l->prompt)); - if (maskmode == 1) { - unsigned int i; - for (i = 0; i < l->len; i++) abAppend(&ab,"*",1); - } else { - abAppend(&ab,l->buf,l->len); - } - - /* Show hits if any. */ - refreshShowHints(&ab,l,plen); - - /* If we are at the very end of the screen with our prompt, we need to - * emit a newline and move the prompt to the first column. */ - if (l->pos && - l->pos == l->len && - (l->pos+plen) % l->cols == 0) - { - lndebug(""); - abAppend(&ab,"\n",1); - snprintf(seq,64,"\r"); - abAppend(&ab,seq,strlen(seq)); - rows++; - if (rows > (int)l->maxrows) l->maxrows = rows; - } - - /* Move cursor to right position. */ - rpos2 = (plen+l->pos+l->cols)/l->cols; /* current cursor relative row. */ - lndebug("rpos2 %d", rpos2); - - /* Go up till we reach the expected positon. */ - if (rows-rpos2 > 0) { - lndebug("go-up %d", rows-rpos2); - snprintf(seq,64,"\x1b[%dA", rows-rpos2); - abAppend(&ab,seq,strlen(seq)); - } - - /* Set column. */ - col = (plen+(int)l->pos) % (int)l->cols; - lndebug("set col %d", 1+col); - if (col) - snprintf(seq,64,"\r\x1b[%dC", col); - else - snprintf(seq,64,"\r"); - abAppend(&ab,seq,strlen(seq)); - - lndebug("\n"); - l->oldpos = l->pos; - - if (write(fd,ab.b,ab.len) == -1) {} /* Can't recover from write error. */ - abFree(&ab); -} - -/* Calls the two low level functions refreshSingleLine() or - * refreshMultiLine() according to the selected mode. */ -static void refreshLine(struct linenoiseState *l) { - if (mlmode) - refreshMultiLine(l); - else - refreshSingleLine(l); -} - -/* Insert the character 'c' at cursor current position. - * - * On error writing to the terminal -1 is returned, otherwise 0. */ -int linenoiseEditInsert(struct linenoiseState *l, char c) { - if (l->len < l->buflen) { - if (l->len == l->pos) { - l->buf[l->pos] = c; - l->pos++; - l->len++; - l->buf[l->len] = '\0'; - if ((!mlmode && l->plen+l->len < l->cols && !hintsCallback)) { - /* Avoid a full update of the line in the - * trivial case. */ - char d = (maskmode==1) ? '*' : c; - if (write(l->ofd,&d,1) == -1) return -1; - } else { - refreshLine(l); - } - } else { - memmove(l->buf+l->pos+1,l->buf+l->pos,l->len-l->pos); - l->buf[l->pos] = c; - l->len++; - l->pos++; - l->buf[l->len] = '\0'; - refreshLine(l); - } - } - return 0; -} - -/* Move cursor on the left. */ -void linenoiseEditMoveLeft(struct linenoiseState *l) { - if (l->pos > 0) { - l->pos--; - refreshLine(l); - } -} - -/* Move cursor on the right. */ -void linenoiseEditMoveRight(struct linenoiseState *l) { - if (l->pos != l->len) { - l->pos++; - refreshLine(l); - } -} - -/* Move cursor to the start of the line. */ -void linenoiseEditMoveHome(struct linenoiseState *l) { - if (l->pos != 0) { - l->pos = 0; - refreshLine(l); - } -} - -/* Move cursor to the end of the line. */ -void linenoiseEditMoveEnd(struct linenoiseState *l) { - if (l->pos != l->len) { - l->pos = l->len; - refreshLine(l); - } -} - -/* Substitute the currently edited line with the next or previous history - * entry as specified by 'dir'. */ -#define LINENOISE_HISTORY_NEXT 0 -#define LINENOISE_HISTORY_PREV 1 -void linenoiseEditHistoryNext(struct linenoiseState *l, int dir) { - if (history_len > 1) { - /* Update the current history entry before to - * overwrite it with the next one. */ - free(history[history_len - 1 - l->history_index]); - history[history_len - 1 - l->history_index] = strdup(l->buf); - /* Show the new entry */ - l->history_index += (dir == LINENOISE_HISTORY_PREV) ? 1 : -1; - if (l->history_index < 0) { - l->history_index = 0; - return; - } else if (l->history_index >= history_len) { - l->history_index = history_len-1; - return; - } - strncpy(l->buf,history[history_len - 1 - l->history_index],l->buflen); - l->buf[l->buflen-1] = '\0'; - l->len = l->pos = strlen(l->buf); - refreshLine(l); - } -} - -/* Delete the character at the right of the cursor without altering the cursor - * position. Basically this is what happens with the "Delete" keyboard key. */ -void linenoiseEditDelete(struct linenoiseState *l) { - if (l->len > 0 && l->pos < l->len) { - memmove(l->buf+l->pos,l->buf+l->pos+1,l->len-l->pos-1); - l->len--; - l->buf[l->len] = '\0'; - refreshLine(l); - } -} - -/* Backspace implementation. */ -void linenoiseEditBackspace(struct linenoiseState *l) { - if (l->pos > 0 && l->len > 0) { - memmove(l->buf+l->pos-1,l->buf+l->pos,l->len-l->pos); - l->pos--; - l->len--; - l->buf[l->len] = '\0'; - refreshLine(l); - } -} - -/* Delete the previosu word, maintaining the cursor at the start of the - * current word. */ -void linenoiseEditDeletePrevWord(struct linenoiseState *l) { - size_t old_pos = l->pos; - size_t diff; - - while (l->pos > 0 && l->buf[l->pos-1] == ' ') - l->pos--; - while (l->pos > 0 && l->buf[l->pos-1] != ' ') - l->pos--; - diff = old_pos - l->pos; - memmove(l->buf+l->pos,l->buf+old_pos,l->len-old_pos+1); - l->len -= diff; - refreshLine(l); -} - -/* This function is the core of the line editing capability of linenoise. - * It expects 'fd' to be already in "raw mode" so that every key pressed - * will be returned ASAP to read(). - * - * The resulting string is put into 'buf' when the user type enter, or - * when ctrl+d is typed. - * - * The function returns the length of the current buffer. */ -static int linenoiseEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen, const char *prompt) -{ - struct linenoiseState l; - - /* Populate the linenoise state that we pass to functions implementing - * specific editing functionalities. */ - l.ifd = stdin_fd; - l.ofd = stdout_fd; - l.buf = buf; - l.buflen = buflen; - l.prompt = prompt; - l.plen = strlen(prompt); - l.oldpos = l.pos = 0; - l.len = 0; - l.cols = getColumns(stdin_fd, stdout_fd); - l.maxrows = 0; - l.history_index = 0; - - /* Buffer starts empty. */ - l.buf[0] = '\0'; - l.buflen--; /* Make sure there is always space for the nulterm */ - - /* The latest history entry is always our current buffer, that - * initially is just an empty string. */ - linenoiseHistoryAdd(""); - - if (write(l.ofd,prompt,l.plen) == -1) return -1; - while(1) { - char c; - int nread; - char seq[3]; - - nread = read(l.ifd,&c,1); - if (nread <= 0) return l.len; - - /* Only autocomplete when the callback is set. It returns < 0 when - * there was an error reading from fd. Otherwise it will return the - * character that should be handled next. */ - if (c == 9 && completionCallback != NULL) { - c = completeLine(&l); - /* Return on errors */ - if (c < 0) return l.len; - /* Read next character when 0 */ - if (c == 0) continue; - } - - switch(c) { - case ENTER: /* enter */ - history_len--; - free(history[history_len]); - if (mlmode) linenoiseEditMoveEnd(&l); - if (hintsCallback) { - /* Force a refresh without hints to leave the previous - * line as the user typed it after a newline. */ - linenoiseHintsCallback *hc = hintsCallback; - hintsCallback = NULL; - refreshLine(&l); - hintsCallback = hc; - } - return (int)l.len; - case CTRL_C: /* ctrl-c */ - errno = EAGAIN; - return -1; - case BACKSPACE: /* backspace */ - case 8: /* ctrl-h */ - linenoiseEditBackspace(&l); - break; - case CTRL_D: /* ctrl-d, remove char at right of cursor, or if the - line is empty, act as end-of-file. */ - if (l.len > 0) { - linenoiseEditDelete(&l); - } else { - history_len--; - free(history[history_len]); - return -1; - } - break; - case CTRL_T: /* ctrl-t, swaps current character with previous. */ - if (l.pos > 0 && l.pos < l.len) { - int aux = buf[l.pos-1]; - buf[l.pos-1] = buf[l.pos]; - buf[l.pos] = aux; - if (l.pos != l.len-1) l.pos++; - refreshLine(&l); - } - break; - case CTRL_B: /* ctrl-b */ - linenoiseEditMoveLeft(&l); - break; - case CTRL_F: /* ctrl-f */ - linenoiseEditMoveRight(&l); - break; - case CTRL_P: /* ctrl-p */ - linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_PREV); - break; - case CTRL_N: /* ctrl-n */ - linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_NEXT); - break; - case ESC: /* escape sequence */ - /* Read the next two bytes representing the escape sequence. - * Use two calls to handle slow terminals returning the two - * chars at different times. */ - if (read(l.ifd,seq,1) == -1) break; - if (read(l.ifd,seq+1,1) == -1) break; - - /* ESC [ sequences. */ - if (seq[0] == '[') { - if (seq[1] >= '0' && seq[1] <= '9') { - /* Extended escape, read additional byte. */ - if (read(l.ifd,seq+2,1) == -1) break; - if (seq[2] == '~') { - switch(seq[1]) { - case '3': /* Delete key. */ - linenoiseEditDelete(&l); - break; - } - } - } else { - switch(seq[1]) { - case 'A': /* Up */ - linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_PREV); - break; - case 'B': /* Down */ - linenoiseEditHistoryNext(&l, LINENOISE_HISTORY_NEXT); - break; - case 'C': /* Right */ - linenoiseEditMoveRight(&l); - break; - case 'D': /* Left */ - linenoiseEditMoveLeft(&l); - break; - case 'H': /* Home */ - linenoiseEditMoveHome(&l); - break; - case 'F': /* End*/ - linenoiseEditMoveEnd(&l); - break; - } - } - } - - /* ESC O sequences. */ - else if (seq[0] == 'O') { - switch(seq[1]) { - case 'H': /* Home */ - linenoiseEditMoveHome(&l); - break; - case 'F': /* End*/ - linenoiseEditMoveEnd(&l); - break; - } - } - break; - default: - if (linenoiseEditInsert(&l,c)) return -1; - break; - case CTRL_U: /* Ctrl+u, delete the whole line. */ - buf[0] = '\0'; - l.pos = l.len = 0; - refreshLine(&l); - break; - case CTRL_K: /* Ctrl+k, delete from current to end of line. */ - buf[l.pos] = '\0'; - l.len = l.pos; - refreshLine(&l); - break; - case CTRL_A: /* Ctrl+a, go to the start of the line */ - linenoiseEditMoveHome(&l); - break; - case CTRL_E: /* ctrl+e, go to the end of the line */ - linenoiseEditMoveEnd(&l); - break; - case CTRL_L: /* ctrl+l, clear screen */ - linenoiseClearScreen(); - refreshLine(&l); - break; - case CTRL_W: /* ctrl+w, delete previous word */ - linenoiseEditDeletePrevWord(&l); - break; - } - } - return l.len; -} - -/* This special mode is used by linenoise in order to print scan codes - * on screen for debugging / development purposes. It is implemented - * by the linenoise_example program using the --keycodes option. */ -void linenoisePrintKeyCodes(void) { - char quit[4]; - - printf("Linenoise key codes debugging mode.\n" - "Press keys to see scan codes. Type 'quit' at any time to exit.\n"); - if (enableRawMode(STDIN_FILENO) == -1) return; - memset(quit,' ',4); - while(1) { - char c; - int nread; - - nread = read(STDIN_FILENO,&c,1); - if (nread <= 0) continue; - memmove(quit,quit+1,sizeof(quit)-1); /* shift string to left. */ - quit[sizeof(quit)-1] = c; /* Insert current char on the right. */ - if (memcmp(quit,"quit",sizeof(quit)) == 0) break; - - printf("'%c' %02x (%d) (type quit to exit)\n", - isprint(c) ? c : '?', (int)c, (int)c); - printf("\r"); /* Go left edge manually, we are in raw mode. */ - fflush(stdout); - } - disableRawMode(STDIN_FILENO); -} - -/* This function calls the line editing function linenoiseEdit() using - * the STDIN file descriptor set in raw mode. */ -static int linenoiseRaw(char *buf, size_t buflen, const char *prompt) { - int count; - - if (buflen == 0) { - errno = EINVAL; - return -1; - } - - if (enableRawMode(STDIN_FILENO) == -1) return -1; - count = linenoiseEdit(STDIN_FILENO, STDOUT_FILENO, buf, buflen, prompt); - disableRawMode(STDIN_FILENO); - printf("\n"); - return count; -} - -/* This function is called when linenoise() is called with the standard - * input file descriptor not attached to a TTY. So for example when the - * program using linenoise is called in pipe or with a file redirected - * to its standard input. In this case, we want to be able to return the - * line regardless of its length (by default we are limited to 4k). */ -static char *linenoiseNoTTY(void) { - char *line = NULL; - size_t len = 0, maxlen = 0; - - while(1) { - if (len == maxlen) { - if (maxlen == 0) maxlen = 16; - maxlen *= 2; - char *oldval = line; - line = realloc(line,maxlen); - if (line == NULL) { - if (oldval) free(oldval); - return NULL; - } - } - int c = fgetc(stdin); - if (c == EOF || c == '\n') { - if (c == EOF && len == 0) { - free(line); - return NULL; - } else { - line[len] = '\0'; - return line; - } - } else { - line[len] = c; - len++; - } - } -} - -/* The high level function that is the main API of the linenoise library. - * This function checks if the terminal has basic capabilities, just checking - * for a blacklist of stupid terminals, and later either calls the line - * editing function or uses dummy fgets() so that you will be able to type - * something even in the most desperate of the conditions. */ -char *linenoise(const char *prompt) { - char buf[LINENOISE_MAX_LINE]; - int count; - - if (!isatty(STDIN_FILENO)) { - /* Not a tty: read from file / pipe. In this mode we don't want any - * limit to the line size, so we call a function to handle that. */ - return linenoiseNoTTY(); - } else if (isUnsupportedTerm()) { - size_t len; - - printf("%s",prompt); - fflush(stdout); - if (fgets(buf,LINENOISE_MAX_LINE,stdin) == NULL) return NULL; - len = strlen(buf); - while(len && (buf[len-1] == '\n' || buf[len-1] == '\r')) { - len--; - buf[len] = '\0'; - } - return strdup(buf); - } else { - count = linenoiseRaw(buf,LINENOISE_MAX_LINE,prompt); - if (count == -1) return NULL; - return strdup(buf); - } -} - -/* This is just a wrapper the user may want to call in order to make sure - * the linenoise returned buffer is freed with the same allocator it was - * created with. Useful when the main program is using an alternative - * allocator. */ -void linenoiseFree(void *ptr) { - free(ptr); -} - -/* ================================ History ================================= */ - -/* Free the history, but does not reset it. Only used when we have to - * exit() to avoid memory leaks are reported by valgrind & co. */ -static void freeHistory(void) { - if (history) { - int j; - - for (j = 0; j < history_len; j++) - free(history[j]); - free(history); - } -} - -/* At exit we'll try to fix the terminal to the initial conditions. */ -static void linenoiseAtExit(void) { - disableRawMode(STDIN_FILENO); - freeHistory(); -} - -/* This is the API call to add a new entry in the linenoise history. - * It uses a fixed array of char pointers that are shifted (memmoved) - * when the history max length is reached in order to remove the older - * entry and make room for the new one, so it is not exactly suitable for huge - * histories, but will work well for a few hundred of entries. - * - * Using a circular buffer is smarter, but a bit more complex to handle. */ -int linenoiseHistoryAdd(const char *line) { - char *linecopy; - - if (history_max_len == 0) return 0; - - /* Initialization on first call. */ - if (history == NULL) { - history = malloc(sizeof(char*)*history_max_len); - if (history == NULL) return 0; - memset(history,0,(sizeof(char*)*history_max_len)); - } - - /* Don't add duplicated lines. */ - if (history_len && !strcmp(history[history_len-1], line)) return 0; - - /* Add an heap allocated copy of the line in the history. - * If we reached the max length, remove the older line. */ - linecopy = strdup(line); - if (!linecopy) return 0; - if (history_len == history_max_len) { - free(history[0]); - memmove(history,history+1,sizeof(char*)*(history_max_len-1)); - history_len--; - } - history[history_len] = linecopy; - history_len++; - return 1; -} - -/* Set the maximum length for the history. This function can be called even - * if there is already some history, the function will make sure to retain - * just the latest 'len' elements if the new history length value is smaller - * than the amount of items already inside the history. */ -int linenoiseHistorySetMaxLen(int len) { - char **new; - - if (len < 1) return 0; - if (history) { - int tocopy = history_len; - - new = malloc(sizeof(char*)*len); - if (new == NULL) return 0; - - /* If we can't copy everything, free the elements we'll not use. */ - if (len < tocopy) { - int j; - - for (j = 0; j < tocopy-len; j++) free(history[j]); - tocopy = len; - } - memset(new,0,sizeof(char*)*len); - memcpy(new,history+(history_len-tocopy), sizeof(char*)*tocopy); - free(history); - history = new; - } - history_max_len = len; - if (history_len > history_max_len) - history_len = history_max_len; - return 1; -} - -/* Save the history in the specified file. On success 0 is returned - * otherwise -1 is returned. */ -int linenoiseHistorySave(const char *filename) { - mode_t old_umask = umask(S_IXUSR|S_IRWXG|S_IRWXO); - FILE *fp; - int j; - - fp = fopen(filename,"w"); - umask(old_umask); - if(fp == NULL) return -1; - chmod(filename,S_IRUSR|S_IWUSR); - for (j = 0; j < history_len; j++) - fprintf(fp,"%s\n",history[j]); - fclose(fp); - return 0; -} - -/* Load the history from the specified file. If the file does not exist - * zero is returned and no operation is performed. - * - * If the file exists and the operation succeeded 0 is returned, otherwise - * on error -1 is returned. */ -int linenoiseHistoryLoad(const char *filename) { - FILE *fp = fopen(filename,"r"); - char buf[LINENOISE_MAX_LINE]; - - if (fp == NULL) return -1; - - while (fgets(buf,LINENOISE_MAX_LINE,fp) != NULL) { - char *p; - - p = strchr(buf,'\r'); - if (!p) p = strchr(buf,'\n'); - if (p) *p = '\0'; - linenoiseHistoryAdd(buf); - } - fclose(fp); - return 0; -} diff --git a/sys/cmd/rc/linenoise.h b/sys/cmd/rc/linenoise.h deleted file mode 100644 index 9349f1b..0000000 --- a/sys/cmd/rc/linenoise.h +++ /dev/null @@ -1,77 +0,0 @@ -/* linenoise.h -- VERSION 1.0 - * - * Guerrilla line editing library against the idea that a line editing lib - * needs to be 20,000 lines of C code. - * - * See linenoise.c for more information. - * - * ------------------------------------------------------------------------ - * - * Copyright (c) 2010-2014, Salvatore Sanfilippo - * Copyright (c) 2010-2013, Pieter Noordhuis - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __LINENOISE_H -#define __LINENOISE_H - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct linenoiseCompletions { - size_t len; - char **cvec; -} linenoiseCompletions; - -typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *); -typedef char*(linenoiseHintsCallback)(const char *, int *color, int *bold); -typedef void(linenoiseFreeHintsCallback)(void *); - -void linenoiseSetCompletionCallback(linenoiseCompletionCallback *); -void linenoiseSetHintsCallback(linenoiseHintsCallback *); -void linenoiseSetFreeHintsCallback(linenoiseFreeHintsCallback *); -void linenoiseAddCompletion(linenoiseCompletions *, const char *); - -char *linenoise(const char *prompt); -void linenoiseFree(void *ptr); -int linenoiseHistoryAdd(const char *line); -int linenoiseHistorySetMaxLen(int len); -int linenoiseHistorySave(const char *filename); -int linenoiseHistoryLoad(const char *filename); - -void linenoiseClearScreen(void); -void linenoiseSetMultiLine(int ml); -void linenoisePrintKeyCodes(void); -void linenoiseMaskModeEnable(void); -void linenoiseMaskModeDisable(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __LINENOISE_H */ diff --git a/sys/cmd/rc/pcmd.c b/sys/cmd/rc/pcmd.c deleted file mode 100644 index 44754c1..0000000 --- a/sys/cmd/rc/pcmd.c +++ /dev/null @@ -1,147 +0,0 @@ -#include "rc.h" -#include "io.h" -#include "fns.h" -char nl='\n'; /* change to semicolon for bourne-proofing */ -#define c0 t->child[0] -#define c1 t->child[1] -#define c2 t->child[2] - -void -pdeglob(Io *f, char *s) -{ - while(*s){ - if(*s==GLOB) - s++; - pchr(f, *s++); - } -} - -void -pcmd(Io *f, Tree *t) -{ - if(t==0) - return; - switch(t->type){ - default: pfmt(f, "bad %d %p %p %p", t->type, c0, c1, c2); - break; - case '$': pfmt(f, "$%t", c0); - break; - case '"': pfmt(f, "$\"%t", c0); - break; - case '&': pfmt(f, "%t&", c0); - break; - case '^': pfmt(f, "%t^%t", c0, c1); - break; - case '`': pfmt(f, "`%t", c0); - break; - case ANDAND: pfmt(f, "%t && %t", c0, c1); - break; - case BANG: pfmt(f, "! %t", c0); - break; - case BRACE: pfmt(f, "{%t}", c0); - break; - case COUNT: pfmt(f, "$#%t", c0); - break; - case FN: pfmt(f, "fn %t %t", c0, c1); - break; - case IF: pfmt(f, "if%t%t", c0, c1); - break; - case NOT: pfmt(f, "if not %t", c0); - break; - case OROR: pfmt(f, "%t || %t", c0, c1); - break; - case PCMD: - case PAREN: pfmt(f, "(%t)", c0); - break; - case SUB: pfmt(f, "$%t(%t)", c0, c1); - break; - case SIMPLE: pfmt(f, "%t", c0); - break; - case SUBSHELL: pfmt(f, "@ %t", c0); - break; - case SWITCH: pfmt(f, "switch %t %t", c0, c1); - break; - case TWIDDLE: pfmt(f, "~ %t %t", c0, c1); - break; - case WHILE: pfmt(f, "while %t%t", c0, c1); - break; - case ARGLIST: - if(c0==0) - pfmt(f, "%t", c1); - else if(c1==0) - pfmt(f, "%t", c0); - else - pfmt(f, "%t %t", c0, c1); - break; - case ';': - if(c0){ - if(c1) - pfmt(f, "%t%c%t", c0, nl, c1); - else pfmt(f, "%t", c0); - } - else pfmt(f, "%t", c1); - break; - case WORDS: - if(c0) - pfmt(f, "%t ", c0); - pfmt(f, "%t", c1); - break; - case FOR: - pfmt(f, "for(%t", c0); - if(c1) - pfmt(f, " in %t", c1); - pfmt(f, ")%t", c2); - break; - case WORD: - if(t->quoted) - pfmt(f, "%Q", t->str); - else pdeglob(f, t->str); - break; - case DUP: - if(t->rtype==DUPFD) - pfmt(f, ">[%d=%d]", t->fd1, t->fd0); /* yes, fd1, then fd0; read lex.c */ - else - pfmt(f, ">[%d=]", t->fd0); - pfmt(f, "%t", c1); - break; - case PIPEFD: - case REDIR: - switch(t->rtype){ - case HERE: - pchr(f, '<'); - case READ: - case RDWR: - pchr(f, '<'); - if(t->rtype==RDWR) - pchr(f, '>'); - if(t->fd0!=0) - pfmt(f, "[%d]", t->fd0); - break; - case APPEND: - pchr(f, '>'); - case WRITE: - pchr(f, '>'); - if(t->fd0!=1) - pfmt(f, "[%d]", t->fd0); - break; - } - pfmt(f, "%t", c0); - if(c1) - pfmt(f, " %t", c1); - break; - case '=': - pfmt(f, "%t=%t", c0, c1); - if(c2) - pfmt(f, " %t", c2); - break; - case PIPE: - pfmt(f, "%t|", c0); - if(t->fd1==0){ - if(t->fd0!=1) - pfmt(f, "[%d]", t->fd0); - } - else pfmt(f, "[%d=%d]", t->fd0, t->fd1); - pfmt(f, "%t", c1); - break; - } -} diff --git a/sys/cmd/rc/pfnc.c b/sys/cmd/rc/pfnc.c deleted file mode 100644 index f6f32cd..0000000 --- a/sys/cmd/rc/pfnc.c +++ /dev/null @@ -1,71 +0,0 @@ -#include "rc.h" -#include "exec.h" -#include "io.h" -#include "fns.h" -struct{ - void (*f)(void); - char *name; -}fname[] = { - Xappend, "Xappend", - Xasync, "Xasync", - Xbang, "Xbang", - Xclose, "Xclose", - Xdup, "Xdup", - Xeflag, "Xeflag", - Xexit, "Xexit", - Xfalse, "Xfalse", - Xifnot, "Xifnot", - Xjump, "Xjump", - Xmark, "Xmark", - Xpopm, "Xpopm", - Xrdwr, "Xrdwr", - Xread, "Xread", - Xreturn, "Xreturn", - Xtrue, "Xtrue", - Xif, "Xif", - Xwastrue, "Xwastrue", - Xword, "Xword", - Xwrite, "Xwrite", - Xmatch, "Xmatch", - Xcase, "Xcase", - Xconc, "Xconc", - Xassign, "Xassign", - Xdol, "Xdol", - Xcount, "Xcount", - Xlocal, "Xlocal", - Xunlocal, "Xunlocal", - Xfn, "Xfn", - Xdelfn, "Xdelfn", - Xpipe, "Xpipe", - Xpipewait, "Xpipewait", - Xrdcmds, "Xrdcmds", - (void (*)(void))Xerror, "Xerror", - Xbackq, "Xbackq", - Xpipefd, "Xpipefd", - Xsubshell, "Xsubshell", - Xdelhere, "Xdelhere", - Xfor, "Xfor", - Xglob, "Xglob", - Xrdfn, "Xrdfn", - Xsimple, "Xsimple", - Xrdfn, "Xrdfn", - Xqdol, "Xqdol", -0}; - -void -pfnc(Io *fd, Thread *t) -{ - int i; - void (*fn)(void) = t->code[t->pc].f; - Words *a; - pfmt(fd, "pid %d cycle %p %d ", getpid(), t->code, t->pc); - for(i = 0;fname[i].f;i++) if(fname[i].f==fn){ - pstr(fd, fname[i].name); - break; - } - if(!fname[i].f) - pfmt(fd, "%p", fn); - for(a = t->argv;a;a = a->next) pfmt(fd, " (%v)", a->words); - pchr(fd, '\n'); - flush(fd); -} diff --git a/sys/cmd/rc/prompt.c b/sys/cmd/rc/prompt.c deleted file mode 100644 index e474c14..0000000 --- a/sys/cmd/rc/prompt.c +++ /dev/null @@ -1,101 +0,0 @@ -#include "rc.h" -#include "fns.h" -#include "io.h" -#include "exec.h" -#include "getflags.h" -#include -#include -#include -#include - -#include "linenoise.h" - -#define DEBUG(f, a...) \ - if(0){}else{pfmt(err, "\n%s: "f, __FUNCTION__, ## a);flush(err);} - -#define HISTORY_PATH "~/.local/rc/history" - -#define COMPLETE_FN "complete" -#define COMPLETE_RESULTS "rc_complete_results" - -static -char* -completion_matches(const char *s, int i) -{ - Word *w; - - for(w=vlook(COMPLETE_RESULTS)->val; w; w=w->next, i--) - if(!i) - return strdup(w->word); - return nil; -} - -static -void -completion(const char *text, linenoiseCompletions *lc) -{ - linenoiseAddCompletion(lc, "test"); -} - -static -void -savehist(void) -{ - linenoiseHistorySave(HISTORY_PATH); -} - -static -void -readline(void) -{ - static int first = 1; - Io *f = runq->cmdfd; - char *s; - long n; - - if(first){ - linenoiseSetMultiLine(1); - linenoiseSetCompletionCallback(completion); - - linenoiseHistorySetMaxLen(10000); - - /* history */ - if(linenoiseHistoryLoad(HISTORY_PATH)!=0 && errno!=ENOENT) - pfmt(err, "rc: loadhistory: %s\n", strerror(errno)); - - atexit(savehist); - first = 0; - } - - s = linenoise(promptstr); - if(!s) - return; - - n = strlen(s); - assert(n < NBUF-1); - strcpy(f->buf, s); - f->buf[n++] = '\n'; - f->bufp = f->buf; - f->ebuf = f->buf+n; - - linenoiseHistoryAdd(s); - free(s); -} - -void -pprompt(void) -{ - Var *prompt; - - if(runq->iflag){ - flush(err); - readline(); - prompt = vlook("prompt"); - if(prompt->val && prompt->val->next) - promptstr = prompt->val->next->word; - else - promptstr="\t"; - } - runq->lineno++; - doprompt = 0; -} diff --git a/sys/cmd/rc/rc.h b/sys/cmd/rc/rc.h deleted file mode 100644 index c91bdd4..0000000 --- a/sys/cmd/rc/rc.h +++ /dev/null @@ -1,149 +0,0 @@ -#include "unix.h" - -#define YYMAXDEPTH 500 -#ifndef PAREN -#ifndef YYMAJOR -#include "x.tab.h" -#endif -#endif - -#undef pipe /* so that /dev/fd works */ -#define searchpath rcsearchpath /* avoid new libc function */ - -typedef struct Tree Tree; -typedef struct Word Word; -typedef struct Io Io; -typedef union Code Code; -typedef struct Var Var; -typedef struct Words Words; -typedef struct Redir Redir; -typedef struct Thread Thread; -typedef struct Builtin Builtin; - -struct Tree -{ - int type; - int rtype, fd0, fd1; /* details of REDIR PIPE DUP tokens */ - char *str; - int quoted; - int iskw; - Tree *child[3]; - Tree *next; -}; - -Tree *newtree(void); -void freetree(Tree*); - -Tree *token(char*, int); -Tree *klook(char*); - -Tree *tree1(int, Tree*); -Tree *tree2(int, Tree*, Tree*); -Tree *tree3(int, Tree*, Tree*, Tree*); - -Tree *mung1(Tree*, Tree*); -Tree *mung2(Tree*, Tree*, Tree*); -Tree *mung3(Tree*, Tree*, Tree*, Tree*); -Tree *epimung(Tree*, Tree*); -Tree *simplemung(Tree*); -Tree *heredoc(Tree*); - -extern Tree *cmdtree; - -/* - * The first word of any code vector is a reference count. - * Always create a new reference to a code vector by calling codecopy(.). - * Always call codefree(.) when deleting a reference. - */ -union Code -{ - void (*f)(void); - int i; - char *s; -}; - -extern char *promptstr; -extern int doprompt; - -#define NTOK 8192 -extern char tok[NTOK]; - -#define APPEND 1 -#define WRITE 2 -#define READ 3 -#define HERE 4 -#define DUPFD 5 -#define CLOSE 6 -#define RDWR 7 - -struct Var -{ - char *name; /* ascii name */ - Word *val; /* value */ - int changed; - Code *fn; /* pointer to function's code vector */ - int fnchanged; - int pc; /* pc of start of function */ - Var *next; /* next on hash or local list */ - void (*changefn)(Var*); -}; -Var *vlook(char*), *gvlook(char*), *newvar(char*, Var*); - -#define NVAR 521 -extern Var *gvar[NVAR]; /* hash for globals */ - -#define new(type) ((type *)emalloc(sizeof(type))) -void *emalloc(long); -void *Malloc(ulong); -void efree(void*); -#define NOFILE 128 /* should come from */ - -struct Here -{ - Tree *tag; - char *name; - struct Here *next; -}; -/* - * Glob character escape in strings: - * In a string, GLOB must be followed by *?[ or GLOB. - * GLOB* matches any string - * GLOB? matches any single character - * GLOB[...] matches anything in the brackets - * GLOBGLOB matches GLOB - */ -#define GLOB ((char)0x01) -/* - * onebyte(c), twobyte(c), threebyte(c) - * Is c the first character of a one- two- or three-byte utf sequence? - */ -#define onebyte(c) ((c&0x80)==0x00) -#define twobyte(c) ((c&0xe0)==0xc0) -#define threebyte(c) ((c&0xf0)==0xe0) -#define fourbyte(c) ((c&0xf8)==0xf0) - -extern char **argp; -extern char **args; -extern int nerror; /* number of errors encountered during compilation */ -/* - * Which fds are the reading/writing end of a pipe? - * Unfortunately, this can vary from system to system. - * 9th edition Unix doesn't care, the following defines - * work on plan 9. - */ -#define PRD 0 -#define PWR 1 -extern char *Rcmain, *Fdprefix; -#define register - -char *getstatus(void); - -/* - * How many dot commands have we executed? - * Used to ensure that -v flag doesn't print rcmain. - */ -extern int ndot; -extern int lastc; -extern int lastword; -extern int kidpid; -extern int mypid; diff --git a/sys/cmd/rc/rcmain.unix b/sys/cmd/rc/rcmain.unix deleted file mode 100644 index 42b3be4..0000000 --- a/sys/cmd/rc/rcmain.unix +++ /dev/null @@ -1,35 +0,0 @@ -# rcmain: unix version -if(~ $#home 0) home=$HOME -if(~ $#ifs 0) ifs=' -' -profile=$home/.rcrc -switch($#prompt){ -case 0 - prompt=('% ' ' ') -case 1 - prompt=($prompt ' ') -} -if(~ $rcname ?.out) prompt=('broken! ' ' ') -if(flag p) path=/bin -if not { - finit - if(~ $#path 0) path=(. /bin /usr/bin /usr/local/bin) -} -fn sigexit -if(! ~ $#cflag 0){ - if(flag l && test -r $profile) . $profile - status='' - eval $cflag -} -if not if(flag i){ - if(flag l && test -r $profile) . $profile - status='' - if(! ~ $#* 0) . $* - . -i /dev/fd/0 -} -if not if(~ $#* 0) . /dev/fd/0 -if not{ - status='' - . $* -} -exit $status diff --git a/sys/cmd/rc/rules.mk b/sys/cmd/rc/rules.mk deleted file mode 100644 index 8c34cfd..0000000 --- a/sys/cmd/rc/rules.mk +++ /dev/null @@ -1,40 +0,0 @@ -include share/push.mk -# Iterate through subdirectory tree - -# Local sources -SRCS_$(d) := \ - $(d)/code.c\ - $(d)/exec.c\ - $(d)/getflags.c\ - $(d)/glob.c\ - $(d)/here.c\ - $(d)/io.c\ - $(d)/lex.c\ - $(d)/pcmd.c\ - $(d)/pfnc.c\ - $(d)/simple.c\ - $(d)/subr.c\ - $(d)/trap.c\ - $(d)/tree.c\ - $(d)/var.c\ - $(d)/y.tab.c\ - $(d)/unix.c\ - $(d)/havefork.c\ - $(d)/linenoise.c\ - $(d)/prompt.c - -BINS_$(d) := $(d)/rc - -include share/paths.mk - -# Local rules -$(d)/y.tab.h $(d)/y.tab.c: $(d)/syn.y - yacc --header=sys/cmd/rc/y.tab.h --output=sys/cmd/rc/y.tab.c $^ - -$(BINS_$(d)): TCFLAGS = \ - -D_XOPEN_SOURCE=500 - -$(BINS_$(d)): $(OBJS_$(d)) $(OBJ_DIR)/sys/libn/libn.a - $(COMPLINK) - -include share/pop.mk diff --git a/sys/cmd/rc/simple.c b/sys/cmd/rc/simple.c deleted file mode 100644 index 465fe43..0000000 --- a/sys/cmd/rc/simple.c +++ /dev/null @@ -1,507 +0,0 @@ -/* - * Maybe `simple' is a misnomer. - */ -#include "rc.h" -#include "getflags.h" -#include "exec.h" -#include "io.h" -#include "fns.h" -/* - * Search through the following code to see if we're just going to exit. - */ -int -exitnext(void){ - union Code *c=&runq->code[runq->pc]; - - while(c->f==Xpopredir) - c++; - - return c->f==Xexit; -} - -void -Xsimple(void) -{ - Word *a; - Thread *p = runq; - Var *v; - struct Builtin *bp; - int pid; - globlist(); - a = runq->argv->words; - if(a==0){ - Xerror1("empty argument list"); - return; - } - if(flag['x']) - pfmt(err, "%v\n", p->argv->words); /* wrong, should do redirs */ - v = gvlook(a->word); - if(v->fn) - execfunc(v); - else{ - if(strcmp(a->word, "builtin")==0){ - if(count(a)==1){ - pfmt(err, "builtin: empty argument list\n"); - setstatus("empty arg list"); - poplist(); - return; - } - a = a->next; - popword(); - } - for(bp = builtin;bp->name;bp++) - if(strcmp(a->word, bp->name)==0){ - (*bp->fnc)(); - return; - } - if(exitnext()){ - /* fork and wait is redundant */ - pushword("exec"); - execexec(); - Xexit(); - } - else{ - flush(err); - Updenv(); /* necessary so changes don't go out again */ - if((pid = execforkexec()) < 0){ - Xerror("try again"); - return; - } - - /* interrupts don't get us out */ - poplist(); - while(Waitfor(pid, 1) < 0) - ; - } - } -} -struct Word nullpath = { "", 0}; - -void -doredir(Redir *rp) -{ - if(rp){ - doredir(rp->next); - switch(rp->type){ - case ROPEN: - if(rp->from!=rp->to){ - Dup(rp->from, rp->to); - close(rp->from); - } - break; - case RDUP: - Dup(rp->from, rp->to); - break; - case RCLOSE: - close(rp->from); - break; - } - } -} - -Word* -searchpath(char *w) -{ - Word *path; - if(strncmp(w, "/", 1)==0 -/* || strncmp(w, "#", 1)==0 */ - || strncmp(w, "./", 2)==0 - || strncmp(w, "../", 3)==0 - || (path = vlook("path")->val)==0) - path=&nullpath; - return path; -} - -void -execexec(void) -{ - popword(); /* "exec" */ - if(runq->argv->words==0){ - Xerror1("empty argument list"); - return; - } - doredir(runq->redir); - Execute(runq->argv->words, searchpath(runq->argv->words->word)); - poplist(); -} - -void -execfunc(Var *func) -{ - Word *starval; - popword(); - starval = runq->argv->words; - runq->argv->words = 0; - poplist(); - start(func->fn, func->pc, runq->local); - runq->local = newvar(strdup("*"), runq->local); - runq->local->val = starval; - runq->local->changed = 1; -} - -int -dochdir(char *word) -{ - /* report to /dev/wdir if it exists and we're interactive */ - static int wdirfd = -2; - if(chdir(word)<0) return -1; - if(flag['i']!=0){ - if(wdirfd==-2) /* try only once */ - wdirfd = open("/dev/wdir", OWRITE|OCEXEC); - if(wdirfd>=0) - write(wdirfd, word, strlen(word)); - } - return 1; -} - -void -execcd(void) -{ - Word *a = runq->argv->words; - Word *cdpath; - char dir[512]; - setstatus("can't cd"); - cdpath = vlook("cdpath")->val; - switch(count(a)){ - default: - pfmt(err, "Usage: cd [directory]\n"); - break; - case 2: - if(a->next->word[0]=='/' || cdpath==0) - cdpath=&nullpath; - for(;cdpath;cdpath = cdpath->next){ - strcpy(dir, cdpath->word); - if(dir[0]) - strcat(dir, "/"); - strcat(dir, a->next->word); - if(dochdir(dir)>=0){ - if(strlen(cdpath->word) - && strcmp(cdpath->word, ".")!=0) - pfmt(err, "%s\n", dir); - setstatus(""); - break; - } - } - if(cdpath==0) - pfmt(err, "Can't cd %s: %r\n", a->next->word); - break; - case 1: - a = vlook("home")->val; - if(count(a)>=1){ - if(dochdir(a->word)>=0) - setstatus(""); - else - pfmt(err, "Can't cd %s: %r\n", a->word); - } - else - pfmt(err, "Can't cd -- $home empty\n"); - break; - } - poplist(); -} - -void -execexit(void) -{ - switch(count(runq->argv->words)){ - default: - pfmt(err, "Usage: exit [status]\nExiting anyway\n"); - case 2: - setstatus(runq->argv->words->next->word); - case 1: Xexit(); - } -} - -void -execshift(void) -{ - int n; - Word *a; - Var *star; - switch(count(runq->argv->words)){ - default: - pfmt(err, "Usage: shift [n]\n"); - setstatus("shift usage"); - poplist(); - return; - case 2: - n = atoi(runq->argv->words->next->word); - break; - case 1: - n = 1; - break; - } - star = vlook("*"); - for(;n && star->val;--n){ - a = star->val->next; - efree(star->val->word); - efree((char *)star->val); - star->val = a; - star->changed = 1; - } - setstatus(""); - poplist(); -} - -int -octal(char *s) -{ - int n = 0; - while(*s==' ' || *s=='\t' || *s=='\n') s++; - while('0'<=*s && *s<='7') n = n*8+*s++-'0'; - return n; -} - -int -mapfd(int fd) -{ - Redir *rp; - for(rp = runq->redir;rp;rp = rp->next){ - switch(rp->type){ - case RCLOSE: - if(rp->from==fd) - fd=-1; - break; - case RDUP: - case ROPEN: - if(rp->to==fd) - fd = rp->from; - break; - } - } - return fd; -} -union Code rdcmds[4]; - -void -execcmds(Io *f) -{ - static int first = 1; - if(first){ - rdcmds[0].i = 1; - rdcmds[1].f = Xrdcmds; - rdcmds[2].f = Xreturn; - first = 0; - } - start(rdcmds, 1, runq->local); - runq->cmdfd = f; - runq->iflast = 0; -} - -void -execeval(void) -{ - char *cmdline, *s, *t; - int len = 0; - Word *ap; - if(count(runq->argv->words)<=1){ - Xerror1("Usage: eval cmd ..."); - return; - } - eflagok = 1; - for(ap = runq->argv->words->next;ap;ap = ap->next) - len+=1+strlen(ap->word); - cmdline = emalloc(len); - s = cmdline; - for(ap = runq->argv->words->next;ap;ap = ap->next){ - for(t = ap->word;*t;) *s++=*t++; - *s++=' '; - } - s[-1]='\n'; - poplist(); - execcmds(opencore(cmdline, len)); - efree(cmdline); -} -union Code dotcmds[14]; - -void -execdot(void) -{ - int iflag = 0; - int fd; - Words *av; - Thread *p = runq; - char *zero; - static int first = 1; - char file[512]; - Word *path; - if(first){ - dotcmds[0].i = 1; - dotcmds[1].f = Xmark; - dotcmds[2].f = Xword; - dotcmds[3].s="0"; - dotcmds[4].f = Xlocal; - dotcmds[5].f = Xmark; - dotcmds[6].f = Xword; - dotcmds[7].s="*"; - dotcmds[8].f = Xlocal; - dotcmds[9].f = Xrdcmds; - dotcmds[10].f = Xunlocal; - dotcmds[11].f = Xunlocal; - dotcmds[12].f = Xreturn; - first = 0; - } - else - eflagok = 1; - popword(); - if(p->argv->words && strcmp(p->argv->words->word, "-i")==0){ - iflag = 1; - popword(); - } - /* get input file */ - if(p->argv->words==0){ - Xerror1("Usage: . [-i] file [arg ...]"); - return; - } - zero = strdup(p->argv->words->word); - popword(); - fd=-1; - for(path = searchpath(zero);path;path = path->next){ - strcpy(file, path->word); - if(file[0]) - strcat(file, "/"); - strcat(file, zero); - if((fd = open(file, 0))>=0) break; - if(strcmp(file, "/dev/stdin")==0){ /* for sun & ucb */ - fd = Dup1(0); - if(fd>=0) - break; - } - } - if(fd<0){ - pfmt(err, "%s: ", zero); - setstatus("can't open"); - Xerror(".: can't open"); - return; - } - /* set up for a new command loop */ - start(dotcmds, 1, (struct Var *)0); - pushredir(RCLOSE, fd, 0); - runq->cmdfile = zero; - runq->cmdfd = openfd(fd); - runq->iflag = iflag; - runq->iflast = 0; - /* push $* value */ - pushlist(); - runq->argv->words = p->argv->words; - /* free caller's copy of $* */ - av = p->argv; - p->argv = av->next; - efree((char *)av); - /* push $0 value */ - pushlist(); - pushword(zero); - ndot++; -} - -void -execflag(void) -{ - char *letter, *val; - switch(count(runq->argv->words)){ - case 2: - setstatus(flag[(uchar)runq->argv->words->next->word[0]]?"":"flag not set"); - break; - case 3: - letter = runq->argv->words->next->word; - val = runq->argv->words->next->next->word; - if(strlen(letter)==1){ - if(strcmp(val, "+")==0){ - flag[(uchar)letter[0]] = flagset; - break; - } - if(strcmp(val, "-")==0){ - flag[(uchar)letter[0]] = 0; - break; - } - } - default: - Xerror1("Usage: flag [letter] [+-]"); - return; - } - poplist(); -} - -void -execwhatis(void){ /* mildly wrong -- should fork before writing */ - Word *a, *b, *path; - Var *v; - struct Builtin *bp; - char file[512]; - struct Io out[1]; - int found, sep; - a = runq->argv->words->next; - if(a==0){ - Xerror1("Usage: whatis name ..."); - return; - } - setstatus(""); - out->fd = mapfd(1); - out->bufp = out->buf; - out->ebuf = &out->buf[NBUF]; - out->strp = 0; - for(;a;a = a->next){ - v = vlook(a->word); - if(v->val){ - pfmt(out, "%s=", a->word); - if(v->val->next==0) - pfmt(out, "%q\n", v->val->word); - else{ - sep='('; - for(b = v->val;b && b->word;b = b->next){ - pfmt(out, "%c%q", sep, b->word); - sep=' '; - } - pfmt(out, ")\n"); - } - found = 1; - } - else - found = 0; - v = gvlook(a->word); - if(v->fn) - pfmt(out, "fn %s %s\n", v->name, v->fn[v->pc-1].s); - else{ - for(bp = builtin;bp->name;bp++) - if(strcmp(a->word, bp->name)==0){ - pfmt(out, "builtin %s\n", a->word); - break; - } - if(!bp->name){ - for(path = searchpath(a->word);path;path = path->next){ - strcpy(file, path->word); - if(file[0]) - strcat(file, "/"); - strcat(file, a->word); - if(Executable(file)){ - pfmt(out, "%s\n", file); - break; - } - } - if(!path && !found){ - pfmt(err, "%s: not found\n", a->word); - setstatus("not found"); - } - } - } - } - poplist(); - flush(err); -} - -void -execwait(void) -{ - switch(count(runq->argv->words)){ - default: - Xerror1("Usage: wait [pid]"); - return; - case 2: - Waitfor(atoi(runq->argv->words->next->word), 0); - break; - case 1: - Waitfor(-1, 0); - break; - } - poplist(); -} diff --git a/sys/cmd/rc/subr.c b/sys/cmd/rc/subr.c deleted file mode 100644 index 79a945e..0000000 --- a/sys/cmd/rc/subr.c +++ /dev/null @@ -1,77 +0,0 @@ -#include "rc.h" -#include "exec.h" -#include "io.h" -#include "fns.h" - -void* -emalloc(long n) -{ - char *p = (char *)Malloc(n); - if(p==0) - panic("Can't malloc %d bytes", n); -/* if(err){ pfmt(err, "malloc %d->%p\n", n, p); flush(err); } /**/ - memset(p, 0, n); - return p; -} - -void -efree(void *p) -{ -/* pfmt(err, "free %p\n", p); flush(err); /**/ - if(p) - free(p); - else pfmt(err, "free 0\n"); -} -extern int lastword, lastdol; - -void -yyerror(char *m) -{ - pfmt(err, "rc: "); - if(runq->cmdfile && !runq->iflag) - pfmt(err, "%s:%d: ", runq->cmdfile, runq->lineno); - else if(runq->cmdfile) - pfmt(err, "%s: ", runq->cmdfile); - else if(!runq->iflag) - pfmt(err, "line %d: ", runq->lineno); - if(tok[0] && tok[0]!='\n') - pfmt(err, "token %q: ", tok); - pfmt(err, "%s\n", m); - flush(err); - lastword = 0; - lastdol = 0; - while(lastc!='\n' && lastc!=EOF) advance(); - nerror++; - setvar("status", newword(m, (Word *)0)); -} -char *bp; - -static void -iacvt(int n) -{ - if(n<0){ - *bp++='-'; - n=-n; /* doesn't work for n==-inf */ - } - if(n/10) - iacvt(n/10); - *bp++=n%10+'0'; -} - -void -inttoascii(char *s, long n) -{ - bp = s; - iacvt(n); - *bp='\0'; -} - -void -panic(char *s, int n) -{ - pfmt(err, "rc: "); - pfmt(err, s, n); - pchr(err, '\n'); - flush(err); - Abort(); -} diff --git a/sys/cmd/rc/syn.y b/sys/cmd/rc/syn.y deleted file mode 100644 index 3af3254..0000000 --- a/sys/cmd/rc/syn.y +++ /dev/null @@ -1,91 +0,0 @@ -%term FOR IN WHILE IF NOT TWIDDLE BANG SUBSHELL SWITCH FN -%term WORD REDIR DUP PIPE SUB -%term SIMPLE ARGLIST WORDS BRACE PAREN PCMD PIPEFD /* not used in syntax */ -/* operator priorities -- lowest first */ -%left IF WHILE FOR SWITCH ')' NOT -%left ANDAND OROR -%left BANG SUBSHELL -%left PIPE -%left '^' -%right '$' COUNT '"' -%left SUB -%{ -#include "rc.h" -#include "fns.h" -%} -%union{ - struct Tree *tree; -}; -%type line paren brace body cmdsa cmdsan assign epilog redir -%type cmd simple first word comword keyword words -%type NOT FOR IN WHILE IF TWIDDLE BANG SUBSHELL SWITCH FN -%type WORD REDIR DUP PIPE -%% -rc: { return 1;} -| line '\n' {return !compile($1);} -line: cmd -| cmdsa line {$$=tree2(';', $1, $2);} -body: cmd -| cmdsan body {$$=tree2(';', $1, $2);} -cmdsa: cmd ';' -| cmd '&' {$$=tree1('&', $1);} -cmdsan: cmdsa -| cmd '\n' -brace: '{' body '}' {$$=tree1(BRACE, $2);} -paren: '(' body ')' {$$=tree1(PCMD, $2);} -assign: first '=' word {$$=tree2('=', $1, $3);} -epilog: {$$=0;} -| redir epilog {$$=mung2($1, $1->child[0], $2);} -redir: REDIR word {$$=mung1($1, $1->rtype==HERE?heredoc($2):$2);} -| DUP -cmd: {$$=0;} -| brace epilog {$$=epimung($1, $2);} -| IF paren {skipnl();} cmd - {$$=mung2($1, $2, $4);} -| IF NOT {skipnl();} cmd {$$=mung1($2, $4);} -| FOR '(' word IN words ')' {skipnl();} cmd - /* - * if ``words'' is nil, we need a tree element to distinguish between - * for(i in ) and for(i), the former being a loop over the empty set - * and the latter being the implicit argument loop. so if $5 is nil - * (the empty set), we represent it as "()". don't parenthesize non-nil - * functions, to avoid growing parentheses every time we reread the - * definition. - */ - {$$=mung3($1, $3, $5 ? $5 : tree1(PAREN, $5), $8);} -| FOR '(' word ')' {skipnl();} cmd - {$$=mung3($1, $3, (struct Tree *)0, $6);} -| WHILE paren {skipnl();} cmd - {$$=mung2($1, $2, $4);} -| SWITCH word {skipnl();} brace - {$$=tree2(SWITCH, $2, $4);} -| simple {$$=simplemung($1);} -| TWIDDLE word words {$$=mung2($1, $2, $3);} -| cmd ANDAND cmd {$$=tree2(ANDAND, $1, $3);} -| cmd OROR cmd {$$=tree2(OROR, $1, $3);} -| cmd PIPE cmd {$$=mung2($2, $1, $3);} -| redir cmd %prec BANG {$$=mung2($1, $1->child[0], $2);} -| assign cmd %prec BANG {$$=mung3($1, $1->child[0], $1->child[1], $2);} -| BANG cmd {$$=mung1($1, $2);} -| SUBSHELL cmd {$$=mung1($1, $2);} -| FN words brace {$$=tree2(FN, $2, $3);} -| FN words {$$=tree1(FN, $2);} -simple: first -| simple word {$$=tree2(ARGLIST, $1, $2);} -| simple redir {$$=tree2(ARGLIST, $1, $2);} -first: comword -| first '^' word {$$=tree2('^', $1, $3);} -word: keyword {lastword=1; $1->type=WORD;} -| comword -| word '^' word {$$=tree2('^', $1, $3);} -comword: '$' word {$$=tree1('$', $2);} -| '$' word SUB words ')' {$$=tree2(SUB, $2, $4);} -| '"' word {$$=tree1('"', $2);} -| COUNT word {$$=tree1(COUNT, $2);} -| WORD -| '`' brace {$$=tree1('`', $2);} -| '(' words ')' {$$=tree1(PAREN, $2);} -| REDIR brace {$$=mung1($1, $2); $$->type=PIPEFD;} -keyword: FOR|IN|WHILE|IF|NOT|TWIDDLE|BANG|SUBSHELL|SWITCH|FN -words: {$$=(struct Tree*)0;} -| words word {$$=tree2(WORDS, $1, $2);} diff --git a/sys/cmd/rc/trap.c b/sys/cmd/rc/trap.c deleted file mode 100644 index ef46143..0000000 --- a/sys/cmd/rc/trap.c +++ /dev/null @@ -1,37 +0,0 @@ -#include "rc.h" -#include "exec.h" -#include "fns.h" -#include "io.h" -extern char *Signame[]; - -void -dotrap(void) -{ - int i; - struct Var *trapreq; - struct Word *starval; - starval = vlook("*")->val; - while(ntrap) for(i = 0;i!=NSIG;i++) while(trap[i]){ - --trap[i]; - --ntrap; - if(getpid()!=mypid) Exit(getstatus()); - trapreq = vlook(Signame[i]); - if(trapreq->fn){ - start(trapreq->fn, trapreq->pc, (struct Var *)0); - runq->local = newvar(strdup("*"), runq->local); - runq->local->val = copywords(starval, (struct Word *)0); - runq->local->changed = 1; - runq->redir = runq->startredir = 0; - } - else if(i==SIGINT || i==SIGQUIT){ - /* - * run the stack down until we uncover the - * command reading loop. Xreturn will exit - * if there is none (i.e. if this is not - * an interactive rc.) - */ - while(!runq->iflag) Xreturn(); - } - else Exit(getstatus()); - } -} diff --git a/sys/cmd/rc/tree.c b/sys/cmd/rc/tree.c deleted file mode 100644 index 5ab6c5d..0000000 --- a/sys/cmd/rc/tree.c +++ /dev/null @@ -1,146 +0,0 @@ -#include "rc.h" -#include "exec.h" -#include "io.h" -#include "fns.h" -Tree *treenodes; -/* - * create and clear a new tree node, and add it - * to the node list. - */ - -Tree* -newtree(void) -{ - Tree *t = new(Tree); - t->iskw = 0; - t->str = 0; - t->child[0] = t->child[1] = t->child[2] = 0; - t->next = treenodes; - treenodes = t; - return t; -} - -void -freenodes(void) -{ - Tree *t, *u; - for(t = treenodes;t;t = u){ - u = t->next; - if(t->str) - efree(t->str); - efree((char *)t); - } - treenodes = 0; -} - -Tree* -tree1(int type, Tree *c0) -{ - return tree3(type, c0, (Tree *)0, (Tree *)0); -} - -Tree* -tree2(int type, Tree *c0, Tree *c1) -{ - return tree3(type, c0, c1, (Tree *)0); -} - -Tree* -tree3(int type, Tree *c0, Tree *c1, Tree *c2) -{ - Tree *t; - if(type==';'){ - if(c0==0) - return c1; - if(c1==0) - return c0; - } - t = newtree(); - t->type = type; - t->child[0] = c0; - t->child[1] = c1; - t->child[2] = c2; - return t; -} - -Tree* -mung1(Tree *t, Tree *c0) -{ - t->child[0] = c0; - return t; -} - -Tree* -mung2(Tree *t, Tree *c0, Tree *c1) -{ - t->child[0] = c0; - t->child[1] = c1; - return t; -} - -Tree* -mung3(Tree *t, Tree *c0, Tree *c1, Tree *c2) -{ - t->child[0] = c0; - t->child[1] = c1; - t->child[2] = c2; - return t; -} - -Tree* -epimung(Tree *comp, Tree *epi) -{ - Tree *p; - if(epi==0) - return comp; - for(p = epi;p->child[1];p = p->child[1]); - p->child[1] = comp; - return epi; -} -/* - * Add a SIMPLE node at the root of t and percolate all the redirections - * up to the root. - */ - -Tree* -simplemung(Tree *t) -{ - Tree *u; - struct Io *s; - t = tree1(SIMPLE, t); - s = openstr(); - pfmt(s, "%t", t); - t->str = strdup(s->strp); - closeio(s); - for(u = t->child[0];u->type==ARGLIST;u = u->child[0]){ - if(u->child[1]->type==DUP - || u->child[1]->type==REDIR){ - u->child[1]->child[1] = t; - t = u->child[1]; - u->child[1] = 0; - } - } - return t; -} - -Tree* -token(char *str, int type) -{ - Tree *t = newtree(); - t->type = type; - t->str = strdup(str); - return t; -} - -void -freetree(Tree *p) -{ - if(p==0) - return; - freetree(p->child[0]); - freetree(p->child[1]); - freetree(p->child[2]); - if(p->str) - efree(p->str); - efree((char *)p); -} diff --git a/sys/cmd/rc/unix.c b/sys/cmd/rc/unix.c deleted file mode 100644 index eb96813..0000000 --- a/sys/cmd/rc/unix.c +++ /dev/null @@ -1,627 +0,0 @@ -/* - * Unix versions of system-specific functions - * By convention, exported routines herein have names beginning with an - * upper case letter. - */ -#include "rc.h" -#include "fns.h" -#include "io.h" -#include "exec.h" -#include "getflags.h" -#include -#include -#include -#include -#include -#include -#include - -char *Rcmain = "/home/nolln/root/sys/cmd/rc/rcmain.unix"; -char *Fdprefix = "/dev/fd/"; - -void execfinit(void); - -struct Builtin builtin[] = { - "cd", execcd, - "whatis", execwhatis, - "eval", execeval, - "exec", execexec, /* but with popword first */ - "exit", execexit, - "shift", execshift, - "wait", execwait, - "umask", execumask, - ".", execdot, - "finit", execfinit, - "flag", execflag, - /* "history", exechistory, */ - 0 -}; -#define SEP '\1' -char **environp; - -struct Word* -enval(register char *s) -{ - char *t, c; - struct Word *v; - for(t = s;*t && *t!=SEP;t++); - c=*t; - *t='\0'; - v = newword(s, c=='\0'?(struct Word *)0:enval(t+1)); - *t = c; - return v; -} - -void -Vinit(void) -{ - extern char **environ; - char *s; - char **env = environ; - environp = env; - for(;*env;env++){ - for(s=*env;*s && *s!='(' && *s!='=';s++); - switch(*s){ - case '\0': - pfmt(err, "environment %q?\n", *env); - break; - case '=': - *s='\0'; - setvar(*env, enval(s+1)); - *s='='; - break; - case '(': /* ignore functions for now */ - break; - } - } -} - -char **envp; - -void -Xrdfn(void) -{ - char *s; - int len; - for(;*envp;envp++){ - for(s=*envp;*s && *s!='(' && *s!='=';s++); - switch(*s){ - case '\0': - pfmt(err, "environment %q?\n", *envp); - break; - case '=': /* ignore variables */ - break; - case '(': /* Bourne again */ - s=*envp+3; - envp++; - len = strlen(s); - s[len]='\n'; - execcmds(opencore(s, len+1)); - s[len]='\0'; - return; - } - } - Xreturn(); -} - -union Code rdfns[4]; - -void -execfinit(void) -{ - static int first = 1; - if(first){ - rdfns[0].i = 1; - rdfns[1].f = Xrdfn; - rdfns[2].f = Xjump; - rdfns[3].i = 1; - first = 0; - } - Xpopm(); - envp = environp; - start(rdfns, 1, runq->local); -} - -int -cmpenv(const void *aa, const void *ab) -{ - char **a = (char**)aa, **b = (char**)ab; - - return strcmp(*a, *b); -} - -char ** -mkenv(void) -{ - char **env, **ep, *p, *q; - struct Var **h, *v; - struct Word *a; - int nvar = 0, nchr = 0, sep; - - /* - * Slightly kludgy loops look at locals then globals. - * locals no longer exist - geoff - */ - for(h = gvar-1; h != &gvar[NVAR]; h++) - for(v = h >= gvar? *h: runq->local; v ;v = v->next){ - if((v==vlook(v->name)) && v->val){ - nvar++; - nchr+=strlen(v->name)+1; - for(a = v->val;a;a = a->next) - nchr+=strlen(a->word)+1; - } - if(v->fn){ - nvar++; - nchr+=strlen(v->name)+strlen(v->fn[v->pc-1].s)+8; - } - } - env = (char **)emalloc((nvar+1)*sizeof(char *)+nchr); - ep = env; - p = (char *)&env[nvar+1]; - for(h = gvar-1; h != &gvar[NVAR]; h++) - for(v = h >= gvar? *h: runq->local;v;v = v->next){ - if((v==vlook(v->name)) && v->val){ - *ep++=p; - q = v->name; - while(*q) *p++=*q++; - sep='='; - for(a = v->val;a;a = a->next){ - *p++=sep; - sep = SEP; - q = a->word; - while(*q) *p++=*q++; - } - *p++='\0'; - } - if(v->fn){ - *ep++=p; - *p++='#'; *p++='('; *p++=')'; /* to fool Bourne */ - *p++='f'; *p++='n'; *p++=' '; - q = v->name; - while(*q) *p++=*q++; - *p++=' '; - q = v->fn[v->pc-1].s; - while(*q) *p++=*q++; - *p++='\0'; - } - } - *ep = 0; - qsort((void *)env, nvar, sizeof ep[0], cmpenv); - return env; -} -char *sigmsg[] = { -/* 0 normal */ 0, -/* 1 SIGHUP */ "Hangup", -/* 2 SIGINT */ 0, -/* 3 SIGQUIT */ "Quit", -/* 4 SIGILL */ "Illegal instruction", -/* 5 SIGTRAP */ "Trace/BPT trap", -/* 6 SIGIOT */ "abort", -/* 7 SIGEMT */ "EMT trap", -/* 8 SIGFPE */ "Floating exception", -/* 9 SIGKILL */ "Killed", -/* 10 SIGBUS */ "Bus error", -/* 11 SIGSEGV */ "Memory fault", -/* 12 SIGSYS */ "Bad system call", -/* 13 SIGPIPE */ 0, -/* 14 SIGALRM */ "Alarm call", -/* 15 SIGTERM */ "Terminated", -/* 16 unused */ "signal 16", -/* 17 SIGSTOP */ "Process stopped", -/* 18 unused */ "signal 18", -/* 19 SIGCONT */ "Process continued", -/* 20 SIGCHLD */ "Child death", -}; - -int -Waitfor(int pid, int persist) -{ - int wpid, sig; - struct Thread *p; - int wstat; - char wstatstr[12]; - - for(;;){ - errno = 0; - wpid = wait(&wstat); - if(errno==EINTR && persist) - continue; - if(wpid==-1) - break; - sig = wstat&0177; - if(sig==0177){ - pfmt(err, "trace: "); - sig = (wstat>>8)&0177; - } - if(sig>(sizeof sigmsg/sizeof sigmsg[0]) || sigmsg[sig]){ - if(pid!=wpid) - pfmt(err, "%d: ", wpid); - if(sig<=(sizeof sigmsg/sizeof sigmsg[0])) - pfmt(err, "%s", sigmsg[sig]); - else if(sig==0177) pfmt(err, "stopped by ptrace"); - else pfmt(err, "signal %d", sig); - if(wstat&0200)pfmt(err, " -- core dumped"); - pfmt(err, "\n"); - } - wstat = sig?sig+1000:(wstat>>8)&0xFF; - if(wpid==pid){ - inttoascii(wstatstr, wstat); - setstatus(wstatstr); - break; - } - else{ - for(p = runq->ret;p;p = p->ret) - if(p->pid==wpid){ - p->pid=-1; - inttoascii(p->status, wstat); - break; - } - } - } - return 0; -} - -char ** -mkargv(register struct Word *a) -{ - char **argv = (char **)emalloc((count(a)+2)*sizeof(char *)); - char **argp = argv+1; /* leave one at front for runcoms */ - - for(;a;a = a->next) - *argp++=a->word; - *argp = 0; - return argv; -} - -void -Updenv(void) -{ -} - -void -Execute(struct Word *args, struct Word *path) -{ - char *msg="not found"; - int txtbusy = 0; - char **env = mkenv(); - char **argv = mkargv(args); - char file[512]; - - for(;path;path = path->next){ - strcpy(file, path->word); - if(file[0]) - strcat(file, "/"); - strcat(file, argv[1]); -ReExec: - execve(file, argv+1, env); - switch(errno){ - case ENOEXEC: - pfmt(err, "%s: Bourne again\n", argv[1]); - argv[0]="sh"; - argv[1] = strdup(file); - execve("/bin/sh", argv, env); - goto Bad; - case ETXTBSY: - if(++txtbusy!=5){ - sleep(txtbusy); - goto ReExec; - } - msg="text busy"; goto Bad; - case EACCES: - msg="no access"; - break; - case ENOMEM: - msg="not enough memory"; goto Bad; - case E2BIG: - msg="too big"; goto Bad; - } - } -Bad: - pfmt(err, "%s: %s\n", argv[1], msg); - efree((char *)env); - efree((char *)argv); -} - -#define NDIR NAME_MAX - -int -Globsize(register char *p) -{ - int isglob = 0, globlen = NDIR+1; - for(;*p;p++){ - if(*p==GLOB){ - p++; - if(*p!=GLOB) - isglob++; - globlen+=*p=='*'?NDIR:1; - } - else - globlen++; - } - return isglob?globlen:0; -} - -#define NDIRLIST 50 - -DIR *dirlist[NDIRLIST]; - -int -Opendir(char *name) -{ - DIR **dp; - for(dp = dirlist;dp!=&dirlist[NDIRLIST];dp++) - if(*dp==0){ - *dp = opendir(name); - return *dp?dp-dirlist:-1; - } - return -1; -} - -int -Readdir(int f, char *p, int onlydirs) -{ - struct dirent *dp; - - if(f<0 || f>=NDIRLIST) - return 0; - - dp = readdir(dirlist[f]); - if(dp==0) - return 0; - strcpy(p, dp->d_name); - return 1; -} - -void -Closedir(int f) -{ - if(f<0 || f>=NDIRLIST) - return; - - closedir(dirlist[f]); - dirlist[f] = 0; -} - -char *Signame[] = { - "sigexit", "sighup", "sigint", "sigquit", - "sigill", "sigtrap", "sigiot", "sigemt", - "sigfpe", "sigkill", "sigbus", "sigsegv", - "sigsys", "sigpipe", "sigalrm", "sigterm", - "sig16", "sigstop", "sigtstp", "sigcont", - "sigchld", "sigttin", "sigttou", "sigtint", - "sigxcpu", "sigxfsz", "sig26", "sig27", - "sig28", "sig29", "sig30", "sig31", - 0, -}; - -void -gettrap(int sig) -{ - signal(sig, gettrap); - trap[sig]++; - ntrap++; - if(ntrap>=NSIG){ - pfmt(err, "rc: Too many traps (trap %d), dumping core\n", sig); - signal(SIGABRT, (void (*)())0); - kill(getpid(), SIGABRT); - } -} - -void -Trapinit(void) -{ - int i; - void (*sig)(); - - if(1 || flag['d']){ /* wrong!!! */ - sig = signal(SIGINT, gettrap); - if(sig==SIG_IGN) - signal(SIGINT, SIG_IGN); - } - else{ - for(i = 1;i<=NSIG;i++) if(i!=SIGCHLD){ - sig = signal(i, gettrap); - if(sig==SIG_IGN) - signal(i, SIG_IGN); - } - } -} - -void -Unlink(char *name) -{ - unlink(name); -} - -long -Write(int fd, char *buf, long cnt) -{ - return write(fd, buf, cnt); -} - -long -Read(int fd, char *buf, long cnt) -{ - return read(fd, buf, cnt); -} - -long -Seek(int fd, long cnt, long whence) -{ - return lseek(fd, cnt, whence); -} - -int -Executable(char *file) -{ - return(access(file, 01)==0); -} - -int -Creat(char *file) -{ - return creat(file, 0666); -} - -int -Dup(int a, int b){ - return dup2(a, b); -} - -int -Dup1(int a){ - return dup(a); -} -/* - * Wrong: should go through components of a|b|c and return the maximum. - */ -void -Exit(char *stat) -{ - int n = 0; - - while(*stat){ - if(*stat!='|'){ - if(*stat<'0' || '9'<*stat) - exit(1); - else n = n*10+*stat-'0'; - } - stat++; - } - exit(n); -} - -int -Eintr(void){ - return errno==EINTR; -} - -void -Noerror(void) -{ - errno = 0; -} - -int -Isatty(int fd){ - return isatty(fd); -} - -void -Abort(void) -{ - abort(); -} - -void -execumask(void) /* wrong -- should fork before writing */ -{ - int m; - struct Io out[1]; - switch(count(runq->argv->words)){ - default: - pfmt(err, "Usage: umask [umask]\n"); - setstatus("umask usage"); - poplist(); - return; - case 2: - umask(octal(runq->argv->words->next->word)); - break; - case 1: - umask(m = umask(0)); - out->fd = mapfd(1); - out->bufp = out->buf; - out->ebuf=&out->buf[NBUF]; - out->strp = 0; - pfmt(out, "%o\n", m); - break; - } - setstatus(""); - poplist(); -} - -void -Memcpy(char *a, char *b, long n) -{ - memmove(a, b, n); -} - -void* -Malloc(unsigned long n) -{ - return (void *)malloc(n); -} - -void -errstr(char *buf, int len) -{ - strncpy(buf, strerror(errno), len); -} - -int -needsrcquote(int c) -{ - if(c <= ' ') - return 1; - if(strchr("`^#*[]=|\\?${}()'<>&;", c)) - return 1; - return 0; -} - -int -rfork(int bits) -{ - return fork(); -} - -int *waitpids; -int nwaitpids; - -void -addwaitpid(int pid) -{ - waitpids = realloc(waitpids, (nwaitpids+1)*sizeof waitpids[0]); - if(waitpids == 0) - panic("Can't realloc %d waitpids", nwaitpids+1); - waitpids[nwaitpids++] = pid; -} - -void -delwaitpid(int pid) -{ - int r, w; - - for(r=w=0; r -#include -#include -#include -#include -#include -#include -#include - -#ifndef NSIG -#define NSIG 32 -#endif - -#ifndef ERRMAX -#define ERRMAX 128 -#endif - -/* plan 9 compatibility */ -#define RFPROC 1 -#define RFFDG 1 -#define RFNOTEG 1 - -#define uintptr uintptr_t -#define Rune wchar_t - -#define nil ((void*)0) - -/* in case uchar, etc. are built-in types */ -#define uchar _fmtuchar -#define ushort _fmtushort -#define uint _fmtuint -#define ulong _fmtulong -#define vlong _fmtvlong -#define uvlong _fmtuvlong - -typedef unsigned char uchar; -typedef unsigned short ushort; -typedef unsigned int uint; -typedef unsigned long ulong; -typedef unsigned long long uvlong; - -#define OREAD O_RDONLY -#define OWRITE O_WRONLY -#define ORDWR O_RDWR -#define OCEXEC 0 - -extern char *argv0; -extern int chartorune(wchar_t *, const char *); -extern int rfork(int); -extern void errstr(char *, int); -#define rerrstr errstr - -extern void exechistory(void); - diff --git a/sys/cmd/rc/var.c b/sys/cmd/rc/var.c deleted file mode 100644 index a1c60e0..0000000 --- a/sys/cmd/rc/var.c +++ /dev/null @@ -1,176 +0,0 @@ -#include "rc.h" -#include "exec.h" -#include "fns.h" - -Var *gvar[NVAR] = { 0 }; /* hash for globals */ - -int -hash(char *s, int n) -{ - int h = 0, i = 1; - while(*s) h+=*s++*i++; - h%=n; - return h<0?h+n:h; -} -#define NKW 30 -struct kw{ - char *name; - int type; - struct kw *next; -}*kw[NKW]; - -void -kenter(int type, char *name) -{ - int h = hash(name, NKW); - struct kw *p = new(struct kw); - p->type = type; - p->name = name; - p->next = kw[h]; - kw[h] = p; -} - -void -kinit(void) -{ - kenter(FOR, "for"); - kenter(IN, "in"); - kenter(WHILE, "while"); - kenter(IF, "if"); - kenter(NOT, "not"); - kenter(TWIDDLE, "~"); - kenter(BANG, "!"); - kenter(SUBSHELL, "@"); - kenter(SWITCH, "switch"); - kenter(FN, "fn"); -} - -Tree* -klook(char *name) -{ - struct kw *p; - Tree *t = token(name, WORD); - for(p = kw[hash(name, NKW)];p;p = p->next) - if(strcmp(p->name, name)==0){ - t->type = p->type; - t->iskw = 1; - break; - } - return t; -} - -Var* -gvlook(char *name) -{ - int h = hash(name, NVAR); - Var *v; - for(v = gvar[h];v;v = v->next) if(strcmp(v->name, name)==0) return v; - return gvar[h] = newvar(strdup(name), gvar[h]); -} - -Var* -vlook(char *name) -{ - Var *v; - if(runq) - for(v = runq->local;v;v = v->next) - if(strcmp(v->name, name)==0) return v; - return gvlook(name); -} - -void -_setvar(char *name, Word *val, int callfn) -{ - struct Var *v = vlook(name); - - freewords(v->val); - v->val=val; - v->changed=1; - if(callfn && v->changefn) - v->changefn(v); -} - -void -setvar(char *name, Word *val) -{ - _setvar(name, val, 1); -} - -void -bigpath(Var *v) -{ - /* convert $PATH to $path */ - char *p, *q; - Word **l, *w; - - if(v->val == nil){ - _setvar("path", nil, 0); - return; - } - p = v->val->word; - w = nil; - l = &w; - /* - * Doesn't handle escaped colon nonsense. - */ - if(p[0] == 0) - p = nil; - while(p){ - q = strchr(p, ':'); - if(q) - *q = 0; - *l = newword(p[0] ? p : ".", nil); - l = &(*l)->next; - if(q){ - *q = ':'; - p = q+1; - }else - p = nil; - } - _setvar("path", w, 0); -} - -char* -list2strcolon(Word *words) -{ - char *value, *s, *t; - int len = 0; - Word *ap; - for(ap = words;ap;ap = ap->next) - len+=1+strlen(ap->word); - value = emalloc(len+1); - s = value; - for(ap = words;ap;ap = ap->next){ - for(t = ap->word;*t;) *s++=*t++; - *s++=':'; - } - if(s==value) - *s='\0'; - else s[-1]='\0'; - return value; -} -void -littlepath(Var *v) -{ - /* convert $path to $PATH */ - char *p; - Word *w; - - p = list2strcolon(v->val); - w = new(Word); - w->word = p; - w->next = nil; - _setvar("PATH", w, 1); /* 1: recompute $path to expose colon problems */ -} - -void -pathinit(void) -{ - Var *v; - - v = gvlook("path"); - v->changefn = littlepath; - v = gvlook("PATH"); - v->changefn = bigpath; - bigpath(v); -} diff --git a/sys/cmd/rc/x.tab.h b/sys/cmd/rc/x.tab.h deleted file mode 100644 index 6b2da03..0000000 --- a/sys/cmd/rc/x.tab.h +++ /dev/null @@ -1,114 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.3. */ - -/* Skeleton interface for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - FOR = 258, - IN = 259, - WHILE = 260, - IF = 261, - NOT = 262, - TWIDDLE = 263, - BANG = 264, - SUBSHELL = 265, - SWITCH = 266, - FN = 267, - WORD = 268, - REDIR = 269, - DUP = 270, - PIPE = 271, - SUB = 272, - SIMPLE = 273, - ARGLIST = 274, - WORDS = 275, - BRACE = 276, - PAREN = 277, - PCMD = 278, - PIPEFD = 279, - OROR = 280, - ANDAND = 281, - COUNT = 282 - }; -#endif -/* Tokens. */ -#define FOR 258 -#define IN 259 -#define WHILE 260 -#define IF 261 -#define NOT 262 -#define TWIDDLE 263 -#define BANG 264 -#define SUBSHELL 265 -#define SWITCH 266 -#define FN 267 -#define WORD 268 -#define REDIR 269 -#define DUP 270 -#define PIPE 271 -#define SUB 272 -#define SIMPLE 273 -#define ARGLIST 274 -#define WORDS 275 -#define BRACE 276 -#define PAREN 277 -#define PCMD 278 -#define PIPEFD 279 -#define OROR 280 -#define ANDAND 281 -#define COUNT 282 - - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -#line 16 "syn.y" -{ - struct Tree *tree; -} -/* Line 1529 of yacc.c. */ -#line 107 "y.tab.h" - YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - -extern YYSTYPE yylval; - diff --git a/sys/cmd/rc/y.tab.c b/sys/cmd/rc/y.tab.c deleted file mode 100644 index a62aadc..0000000 --- a/sys/cmd/rc/y.tab.c +++ /dev/null @@ -1,1736 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.8.2. */ - -/* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, - Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, - especially those whose name start with YY_ or yy_. They are - private implementation details that can be changed or removed. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output, and Bison version. */ -#define YYBISON 30802 - -/* Bison version string. */ -#define YYBISON_VERSION "3.8.2" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - - - - -/* First part of user prologue. */ -#line 12 "sys/cmd/rc/syn.y" - -#include "rc.h" -#include "fns.h" - -#line 76 "sys/cmd/rc/y.tab.c" - -# ifndef YY_CAST -# ifdef __cplusplus -# define YY_CAST(Type, Val) static_cast (Val) -# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) -# else -# define YY_CAST(Type, Val) ((Type) (Val)) -# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) -# endif -# endif -# ifndef YY_NULLPTR -# if defined __cplusplus -# if 201103L <= __cplusplus -# define YY_NULLPTR nullptr -# else -# define YY_NULLPTR 0 -# endif -# else -# define YY_NULLPTR ((void*)0) -# endif -# endif - -#include "y.tab.h" -/* Symbol kind. */ -enum yysymbol_kind_t -{ - YYSYMBOL_YYEMPTY = -2, - YYSYMBOL_YYEOF = 0, /* "end of file" */ - YYSYMBOL_YYerror = 1, /* error */ - YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ - YYSYMBOL_FOR = 3, /* FOR */ - YYSYMBOL_IN = 4, /* IN */ - YYSYMBOL_WHILE = 5, /* WHILE */ - YYSYMBOL_IF = 6, /* IF */ - YYSYMBOL_NOT = 7, /* NOT */ - YYSYMBOL_TWIDDLE = 8, /* TWIDDLE */ - YYSYMBOL_BANG = 9, /* BANG */ - YYSYMBOL_SUBSHELL = 10, /* SUBSHELL */ - YYSYMBOL_SWITCH = 11, /* SWITCH */ - YYSYMBOL_FN = 12, /* FN */ - YYSYMBOL_WORD = 13, /* WORD */ - YYSYMBOL_REDIR = 14, /* REDIR */ - YYSYMBOL_DUP = 15, /* DUP */ - YYSYMBOL_PIPE = 16, /* PIPE */ - YYSYMBOL_SUB = 17, /* SUB */ - YYSYMBOL_SIMPLE = 18, /* SIMPLE */ - YYSYMBOL_ARGLIST = 19, /* ARGLIST */ - YYSYMBOL_WORDS = 20, /* WORDS */ - YYSYMBOL_BRACE = 21, /* BRACE */ - YYSYMBOL_PAREN = 22, /* PAREN */ - YYSYMBOL_PCMD = 23, /* PCMD */ - YYSYMBOL_PIPEFD = 24, /* PIPEFD */ - YYSYMBOL_25_ = 25, /* ')' */ - YYSYMBOL_ANDAND = 26, /* ANDAND */ - YYSYMBOL_OROR = 27, /* OROR */ - YYSYMBOL_28_ = 28, /* '^' */ - YYSYMBOL_29_ = 29, /* '$' */ - YYSYMBOL_COUNT = 30, /* COUNT */ - YYSYMBOL_31_ = 31, /* '"' */ - YYSYMBOL_32_n_ = 32, /* '\n' */ - YYSYMBOL_33_ = 33, /* ';' */ - YYSYMBOL_34_ = 34, /* '&' */ - YYSYMBOL_35_ = 35, /* '{' */ - YYSYMBOL_36_ = 36, /* '}' */ - YYSYMBOL_37_ = 37, /* '(' */ - YYSYMBOL_38_ = 38, /* '=' */ - YYSYMBOL_39_ = 39, /* '`' */ - YYSYMBOL_YYACCEPT = 40, /* $accept */ - YYSYMBOL_rc = 41, /* rc */ - YYSYMBOL_line = 42, /* line */ - YYSYMBOL_body = 43, /* body */ - YYSYMBOL_cmdsa = 44, /* cmdsa */ - YYSYMBOL_cmdsan = 45, /* cmdsan */ - YYSYMBOL_brace = 46, /* brace */ - YYSYMBOL_paren = 47, /* paren */ - YYSYMBOL_assign = 48, /* assign */ - YYSYMBOL_epilog = 49, /* epilog */ - YYSYMBOL_redir = 50, /* redir */ - YYSYMBOL_cmd = 51, /* cmd */ - YYSYMBOL_52_1 = 52, /* $@1 */ - YYSYMBOL_53_2 = 53, /* $@2 */ - YYSYMBOL_54_3 = 54, /* $@3 */ - YYSYMBOL_55_4 = 55, /* $@4 */ - YYSYMBOL_56_5 = 56, /* $@5 */ - YYSYMBOL_57_6 = 57, /* $@6 */ - YYSYMBOL_simple = 58, /* simple */ - YYSYMBOL_first = 59, /* first */ - YYSYMBOL_word = 60, /* word */ - YYSYMBOL_comword = 61, /* comword */ - YYSYMBOL_keyword = 62, /* keyword */ - YYSYMBOL_words = 63 /* words */ -}; -typedef enum yysymbol_kind_t yysymbol_kind_t; - - - - -#ifdef short -# undef short -#endif - -/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure - and (if available) are included - so that the code can choose integer types of a good width. */ - -#ifndef __PTRDIFF_MAX__ -# include /* INFRINGES ON USER NAME SPACE */ -# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_STDINT_H -# endif -#endif - -/* Narrow types that promote to a signed type and that can represent a - signed or unsigned integer of at least N bits. In tables they can - save space and decrease cache pressure. Promoting to a signed type - helps avoid bugs in integer arithmetic. */ - -#ifdef __INT_LEAST8_MAX__ -typedef __INT_LEAST8_TYPE__ yytype_int8; -#elif defined YY_STDINT_H -typedef int_least8_t yytype_int8; -#else -typedef signed char yytype_int8; -#endif - -#ifdef __INT_LEAST16_MAX__ -typedef __INT_LEAST16_TYPE__ yytype_int16; -#elif defined YY_STDINT_H -typedef int_least16_t yytype_int16; -#else -typedef short yytype_int16; -#endif - -/* Work around bug in HP-UX 11.23, which defines these macros - incorrectly for preprocessor constants. This workaround can likely - be removed in 2023, as HPE has promised support for HP-UX 11.23 - (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of - . */ -#ifdef __hpux -# undef UINT_LEAST8_MAX -# undef UINT_LEAST16_MAX -# define UINT_LEAST8_MAX 255 -# define UINT_LEAST16_MAX 65535 -#endif - -#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ -typedef __UINT_LEAST8_TYPE__ yytype_uint8; -#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ - && UINT_LEAST8_MAX <= INT_MAX) -typedef uint_least8_t yytype_uint8; -#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX -typedef unsigned char yytype_uint8; -#else -typedef short yytype_uint8; -#endif - -#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ -typedef __UINT_LEAST16_TYPE__ yytype_uint16; -#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ - && UINT_LEAST16_MAX <= INT_MAX) -typedef uint_least16_t yytype_uint16; -#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX -typedef unsigned short yytype_uint16; -#else -typedef int yytype_uint16; -#endif - -#ifndef YYPTRDIFF_T -# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ -# define YYPTRDIFF_T __PTRDIFF_TYPE__ -# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ -# elif defined PTRDIFF_MAX -# ifndef ptrdiff_t -# include /* INFRINGES ON USER NAME SPACE */ -# endif -# define YYPTRDIFF_T ptrdiff_t -# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX -# else -# define YYPTRDIFF_T long -# define YYPTRDIFF_MAXIMUM LONG_MAX -# endif -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned -# endif -#endif - -#define YYSIZE_MAXIMUM \ - YY_CAST (YYPTRDIFF_T, \ - (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ - ? YYPTRDIFF_MAXIMUM \ - : YY_CAST (YYSIZE_T, -1))) - -#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) - - -/* Stored state numbers (used for stacks). */ -typedef yytype_int8 yy_state_t; - -/* State numbers in computations. */ -typedef int yy_state_fast_t; - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -# endif -# endif -# ifndef YY_ -# define YY_(Msgid) Msgid -# endif -#endif - - -#ifndef YY_ATTRIBUTE_PURE -# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) -# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) -# else -# define YY_ATTRIBUTE_PURE -# endif -#endif - -#ifndef YY_ATTRIBUTE_UNUSED -# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) -# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -# else -# define YY_ATTRIBUTE_UNUSED -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YY_USE(E) ((void) (E)) -#else -# define YY_USE(E) /* empty */ -#endif - -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ -# if __GNUC__ * 100 + __GNUC_MINOR__ < 407 -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") -# else -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ - _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# endif -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ - _Pragma ("GCC diagnostic pop") -#else -# define YY_INITIAL_VALUE(Value) Value -#endif -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END -#endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ -#endif - -#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ -# define YY_IGNORE_USELESS_CAST_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") -# define YY_IGNORE_USELESS_CAST_END \ - _Pragma ("GCC diagnostic pop") -#endif -#ifndef YY_IGNORE_USELESS_CAST_BEGIN -# define YY_IGNORE_USELESS_CAST_BEGIN -# define YY_IGNORE_USELESS_CAST_END -#endif - - -#define YY_ASSERT(E) ((void) (0 && (E))) - -#if !defined yyoverflow - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS -# include /* INFRINGES ON USER NAME SPACE */ - /* Use EXIT_SUCCESS as a witness for stdlib.h. */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's 'empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* !defined yyoverflow */ - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yy_state_t yyss_alloc; - YYSTYPE yyvs_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYPTRDIFF_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / YYSIZEOF (*yyptr); \ - } \ - while (0) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) -# else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYPTRDIFF_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ - while (0) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 62 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 346 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 40 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 24 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 71 -/* YYNSTATES -- Number of states. */ -#define YYNSTATES 116 - -/* YYMAXUTOK -- Last valid token kind. */ -#define YYMAXUTOK 282 - - -/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, with out-of-bounds checking. */ -#define YYTRANSLATE(YYX) \ - (0 <= (YYX) && (YYX) <= YYMAXUTOK \ - ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ - : YYSYMBOL_YYUNDEF) - -/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex. */ -static const yytype_int8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 32, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 31, 2, 29, 2, 34, 2, - 37, 25, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, - 2, 38, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 28, 2, 39, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 35, 2, 36, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 26, 27, 30 -}; - -#if YYDEBUG -/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ -static const yytype_int8 yyrline[] = -{ - 0, 24, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 43, 45, 45, 46, 46, 56, 56, 58, - 58, 60, 60, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 90, 91 -}; -#endif - -/** Accessing symbol of state STATE. */ -#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) - -#if YYDEBUG || 0 -/* The user-facing name of the symbol whose (internal) number is - YYSYMBOL. No bounds checking. */ -static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; - -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "\"end of file\"", "error", "\"invalid token\"", "FOR", "IN", "WHILE", - "IF", "NOT", "TWIDDLE", "BANG", "SUBSHELL", "SWITCH", "FN", "WORD", - "REDIR", "DUP", "PIPE", "SUB", "SIMPLE", "ARGLIST", "WORDS", "BRACE", - "PAREN", "PCMD", "PIPEFD", "')'", "ANDAND", "OROR", "'^'", "'$'", - "COUNT", "'\"'", "'\\n'", "';'", "'&'", "'{'", "'}'", "'('", "'='", - "'`'", "$accept", "rc", "line", "body", "cmdsa", "cmdsan", "brace", - "paren", "assign", "epilog", "redir", "cmd", "$@1", "$@2", "$@3", "$@4", - "$@5", "$@6", "simple", "first", "word", "comword", "keyword", "words", YY_NULLPTR -}; - -static const char * -yysymbol_name (yysymbol_kind_t yysymbol) -{ - return yytname[yysymbol]; -} -#endif - -#define YYPACT_NINF (-30) - -#define yypact_value_is_default(Yyn) \ - ((Yyn) == YYPACT_NINF) - -#define YYTABLE_NINF (-3) - -#define yytable_value_is_error(Yyn) \ - 0 - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -static const yytype_int16 yypact[] = -{ - 121, -29, -23, -6, 295, 307, 307, 295, -30, -30, - 134, -30, 295, 295, 295, 307, -30, -20, 12, -15, - 307, -4, 307, 307, 61, 171, -19, -30, 295, 307, - -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, -30, -30, -20, 1, -30, -30, 24, 24, 1, - 134, -30, 1, 29, -30, -30, 11, -30, 307, 34, - 184, -30, -30, -30, -30, 295, -30, -4, 24, 24, - 307, 307, 307, -30, -30, -30, 1, 295, 295, 9, - 23, 307, 307, 307, 295, 295, -20, -30, 1, -30, - -30, -30, -30, -30, -30, -30, 24, 24, -30, 1, - -30, -30, -30, 36, 36, 36, -30, -30, 221, 258, - 307, -30, -30, 36, 307, 36 -}; - -/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE does not specify something else to do. Zero - means the default is an error. */ -static const yytype_int8 yydefact[] = -{ - 19, 0, 0, 0, 0, 19, 19, 0, 70, 56, - 0, 18, 0, 0, 0, 19, 70, 0, 0, 0, - 19, 15, 19, 19, 4, 33, 44, 47, 0, 19, - 29, 23, 21, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 0, 70, 50, 49, 40, 41, 31, - 43, 59, 17, 52, 55, 54, 0, 10, 19, 6, - 0, 57, 1, 3, 5, 0, 20, 15, 39, 38, - 19, 19, 19, 8, 9, 46, 45, 0, 0, 0, - 0, 19, 19, 19, 0, 34, 0, 42, 71, 70, - 12, 7, 11, 58, 16, 37, 35, 36, 48, 14, - 70, 27, 13, 30, 24, 22, 51, 32, 0, 0, - 19, 53, 25, 28, 19, 26 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = -{ - -30, -30, 33, -25, 16, -30, 15, 48, -30, -13, - -18, 0, -30, -30, -30, -30, -30, -30, -30, -30, - 31, 14, -30, -14 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int8 yydefgoto[] = -{ - 0, 18, 19, 56, 57, 58, 21, 30, 22, 66, - 23, 59, 83, 82, 114, 110, 81, 86, 25, 26, - 88, 27, 46, 50 -}; - -/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule whose - number is the opposite. If YYTABLE_NINF, syntax error. */ -static const yytype_int8 yytable[] = -{ - 24, 31, 60, 67, 80, 47, 48, 75, 28, 77, - 65, 11, 62, 100, 29, 15, 20, 63, 45, 78, - 24, 45, 68, 69, 45, 51, 45, 45, 45, 84, - 85, 29, 61, 91, 101, 44, 20, 84, 49, 45, - 70, 52, 45, 53, 54, 55, 89, 90, 102, 67, - 70, 32, 70, 64, 94, 0, 76, 0, 51, 79, - 71, 72, 71, 72, 45, 87, 92, 73, 74, 0, - 95, 96, 97, 0, 45, 108, 0, 70, 0, 45, - 0, 103, 104, 105, 0, 0, 109, 71, 72, 0, - 0, 45, 45, 0, 73, 74, 52, 0, 45, 45, - 0, 107, 0, 0, 0, 0, 0, 0, 98, 99, - 113, 0, 0, 0, 115, 106, 0, 0, 0, 0, - 0, -2, 45, 45, 1, 0, 2, 3, 0, 4, - 5, 6, 7, 8, 9, 10, 11, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 9, 43, 0, - 12, 13, 14, 0, 0, 0, 15, 0, 16, 0, - 17, 0, 0, 12, 13, 14, 0, 0, 0, 15, - 0, 16, 0, 17, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 9, 10, 11, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 9, 43, 0, - 12, 13, 14, 0, 0, 0, 0, 0, 16, 93, - 17, 0, 0, 12, 13, 14, 0, 0, 0, 0, - 0, 16, 0, 17, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 9, 43, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 111, 0, 0, 0, - 12, 13, 14, 0, 0, 0, 0, 0, 16, 0, - 17, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 9, 43, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 112, 0, 0, 0, 12, 13, 14, - 0, 0, 0, 0, 0, 16, 0, 17, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 9, 43, - 1, 0, 2, 3, 0, 4, 5, 6, 7, 8, - 9, 10, 11, 0, 12, 13, 14, 0, 0, 0, - 0, 0, 16, 0, 17, 0, 12, 13, 14, 0, - 0, 0, 15, 0, 16, 0, 17 -}; - -static const yytype_int8 yycheck[] = -{ - 0, 7, 16, 21, 29, 5, 6, 25, 37, 28, - 14, 15, 0, 4, 37, 35, 0, 32, 4, 38, - 20, 7, 22, 23, 10, 10, 12, 13, 14, 28, - 44, 37, 17, 58, 25, 4, 20, 28, 7, 25, - 16, 10, 28, 12, 13, 14, 17, 36, 25, 67, - 16, 3, 16, 20, 67, -1, 25, -1, 43, 28, - 26, 27, 26, 27, 50, 50, 32, 33, 34, -1, - 70, 71, 72, -1, 60, 89, -1, 16, -1, 65, - -1, 81, 82, 83, -1, -1, 100, 26, 27, -1, - -1, 77, 78, -1, 33, 34, 65, -1, 84, 85, - -1, 86, -1, -1, -1, -1, -1, -1, 77, 78, - 110, -1, -1, -1, 114, 84, -1, -1, -1, -1, - -1, 0, 108, 109, 3, -1, 5, 6, -1, 8, - 9, 10, 11, 12, 13, 14, 15, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, - 29, 30, 31, -1, -1, -1, 35, -1, 37, -1, - 39, -1, -1, 29, 30, 31, -1, -1, -1, 35, - -1, 37, -1, 39, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, - 29, 30, 31, -1, -1, -1, -1, -1, 37, 25, - 39, -1, -1, 29, 30, 31, -1, -1, -1, -1, - -1, 37, -1, 39, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 25, -1, -1, -1, - 29, 30, 31, -1, -1, -1, -1, -1, 37, -1, - 39, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 25, -1, -1, -1, 29, 30, 31, - -1, -1, -1, -1, -1, 37, -1, 39, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 3, -1, 5, 6, -1, 8, 9, 10, 11, 12, - 13, 14, 15, -1, 29, 30, 31, -1, -1, -1, - -1, -1, 37, -1, 39, -1, 29, 30, 31, -1, - -1, -1, 35, -1, 37, -1, 39 -}; - -/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of - state STATE-NUM. */ -static const yytype_int8 yystos[] = -{ - 0, 3, 5, 6, 8, 9, 10, 11, 12, 13, - 14, 15, 29, 30, 31, 35, 37, 39, 41, 42, - 44, 46, 48, 50, 51, 58, 59, 61, 37, 37, - 47, 7, 47, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 14, 60, 61, 62, 51, 51, 60, - 63, 46, 60, 60, 60, 60, 43, 44, 45, 51, - 63, 46, 0, 32, 42, 14, 49, 50, 51, 51, - 16, 26, 27, 33, 34, 50, 60, 28, 38, 60, - 43, 56, 53, 52, 28, 63, 57, 46, 60, 17, - 36, 43, 32, 25, 49, 51, 51, 51, 60, 60, - 4, 25, 25, 51, 51, 51, 60, 46, 63, 63, - 55, 25, 25, 51, 54, 51 -}; - -/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ -static const yytype_int8 yyr1[] = -{ - 0, 40, 41, 41, 42, 42, 43, 43, 44, 44, - 45, 45, 46, 47, 48, 49, 49, 50, 50, 51, - 51, 52, 51, 53, 51, 54, 51, 55, 51, 56, - 51, 57, 51, 51, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 58, 58, 58, 59, 59, 60, - 60, 60, 61, 61, 61, 61, 61, 61, 61, 61, - 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 63, 63 -}; - -/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ -static const yytype_int8 yyr2[] = -{ - 0, 2, 0, 2, 1, 2, 1, 2, 2, 2, - 1, 2, 3, 3, 3, 0, 2, 2, 1, 0, - 2, 0, 4, 0, 4, 0, 8, 0, 6, 0, - 4, 0, 4, 1, 3, 3, 3, 3, 2, 2, - 2, 2, 3, 2, 1, 2, 2, 1, 3, 1, - 1, 3, 2, 5, 2, 2, 1, 2, 3, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 2 -}; - - -enum { YYENOMEM = -2 }; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab -#define YYNOMEM goto yyexhaustedlab - - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ - do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ - while (0) - -/* Backward compatibility with an undocumented macro. - Use YYerror or YYUNDEF. */ -#define YYERRCODE YYUNDEF - - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - - - - -# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Kind, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - - -/*-----------------------------------. -| Print this symbol's value on YYO. | -`-----------------------------------*/ - -static void -yy_symbol_value_print (FILE *yyo, - yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) -{ - FILE *yyoutput = yyo; - YY_USE (yyoutput); - if (!yyvaluep) - return; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YY_USE (yykind); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - -/*---------------------------. -| Print this symbol on YYO. | -`---------------------------*/ - -static void -yy_symbol_print (FILE *yyo, - yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep) -{ - YYFPRINTF (yyo, "%s %s (", - yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); - - yy_symbol_value_print (yyo, yykind, yyvaluep); - YYFPRINTF (yyo, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -static void -yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -static void -yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, - int yyrule) -{ - int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, - YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), - &yyvsp[(yyi + 1) - (yynrhs)]); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyssp, yyvsp, Rule); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) ((void) 0) -# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - - - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -static void -yydestruct (const char *yymsg, - yysymbol_kind_t yykind, YYSTYPE *yyvaluep) -{ - YY_USE (yyvaluep); - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YY_USE (yykind); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - -/* Lookahead token kind. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; -/* Number of syntax errors so far. */ -int yynerrs; - - - - -/*----------. -| yyparse. | -`----------*/ - -int -yyparse (void) -{ - yy_state_fast_t yystate = 0; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus = 0; - - /* Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* Their size. */ - YYPTRDIFF_T yystacksize = YYINITDEPTH; - - /* The state stack: array, bottom, top. */ - yy_state_t yyssa[YYINITDEPTH]; - yy_state_t *yyss = yyssa; - yy_state_t *yyssp = yyss; - - /* The semantic value stack: array, bottom, top. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp = yyvs; - - int yyn; - /* The return value of yyparse. */ - int yyresult; - /* Lookahead symbol kind. */ - yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - - - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yychar = YYEMPTY; /* Cause a token to be read. */ - - goto yysetstate; - - -/*------------------------------------------------------------. -| yynewstate -- push a new state, which is found in yystate. | -`------------------------------------------------------------*/ -yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - -/*--------------------------------------------------------------------. -| yysetstate -- set current state (the top of the stack) to yystate. | -`--------------------------------------------------------------------*/ -yysetstate: - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - YY_ASSERT (0 <= yystate && yystate < YYNSTATES); - YY_IGNORE_USELESS_CAST_BEGIN - *yyssp = YY_CAST (yy_state_t, yystate); - YY_IGNORE_USELESS_CAST_END - YY_STACK_PRINT (yyss, yyssp); - - if (yyss + yystacksize - 1 <= yyssp) -#if !defined yyoverflow && !defined YYSTACK_RELOCATE - YYNOMEM; -#else - { - /* Get the current used size of the three stacks, in elements. */ - YYPTRDIFF_T yysize = yyssp - yyss + 1; - -# if defined yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - yy_state_t *yyss1 = yyss; - YYSTYPE *yyvs1 = yyvs; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * YYSIZEOF (*yyssp), - &yyvs1, yysize * YYSIZEOF (*yyvsp), - &yystacksize); - yyss = yyss1; - yyvs = yyvs1; - } -# else /* defined YYSTACK_RELOCATE */ - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - YYNOMEM; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yy_state_t *yyss1 = yyss; - union yyalloc *yyptr = - YY_CAST (union yyalloc *, - YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); - if (! yyptr) - YYNOMEM; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - YY_IGNORE_USELESS_CAST_BEGIN - YYDPRINTF ((stderr, "Stack size increased to %ld\n", - YY_CAST (long, yystacksize))); - YY_IGNORE_USELESS_CAST_END - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } -#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ - - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token\n")); - yychar = yylex (); - } - - if (yychar <= YYEOF) - { - yychar = YYEOF; - yytoken = YYSYMBOL_YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else if (yychar == YYerror) - { - /* The scanner already issued an error message, process directly - to error recovery. But do not keep the error token as - lookahead, it is too special and may lead us to an endless - loop in error recovery. */ - yychar = YYUNDEF; - yytoken = YYSYMBOL_YYerror; - goto yyerrlab1; - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - /* Discard the shifted token. */ - yychar = YYEMPTY; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - '$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: /* rc: %empty */ -#line 24 "sys/cmd/rc/syn.y" - { return 1;} -#line 1247 "sys/cmd/rc/y.tab.c" - break; - - case 3: /* rc: line '\n' */ -#line 25 "sys/cmd/rc/syn.y" - {return !compile((yyvsp[-1].tree));} -#line 1253 "sys/cmd/rc/y.tab.c" - break; - - case 5: /* line: cmdsa line */ -#line 27 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree2(';', (yyvsp[-1].tree), (yyvsp[0].tree));} -#line 1259 "sys/cmd/rc/y.tab.c" - break; - - case 7: /* body: cmdsan body */ -#line 29 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree2(';', (yyvsp[-1].tree), (yyvsp[0].tree));} -#line 1265 "sys/cmd/rc/y.tab.c" - break; - - case 9: /* cmdsa: cmd '&' */ -#line 31 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree1('&', (yyvsp[-1].tree));} -#line 1271 "sys/cmd/rc/y.tab.c" - break; - - case 12: /* brace: '{' body '}' */ -#line 34 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree1(BRACE, (yyvsp[-1].tree));} -#line 1277 "sys/cmd/rc/y.tab.c" - break; - - case 13: /* paren: '(' body ')' */ -#line 35 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree1(PCMD, (yyvsp[-1].tree));} -#line 1283 "sys/cmd/rc/y.tab.c" - break; - - case 14: /* assign: first '=' word */ -#line 36 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree2('=', (yyvsp[-2].tree), (yyvsp[0].tree));} -#line 1289 "sys/cmd/rc/y.tab.c" - break; - - case 15: /* epilog: %empty */ -#line 37 "sys/cmd/rc/syn.y" - {(yyval.tree)=0;} -#line 1295 "sys/cmd/rc/y.tab.c" - break; - - case 16: /* epilog: redir epilog */ -#line 38 "sys/cmd/rc/syn.y" - {(yyval.tree)=mung2((yyvsp[-1].tree), (yyvsp[-1].tree)->child[0], (yyvsp[0].tree));} -#line 1301 "sys/cmd/rc/y.tab.c" - break; - - case 17: /* redir: REDIR word */ -#line 39 "sys/cmd/rc/syn.y" - {(yyval.tree)=mung1((yyvsp[-1].tree), (yyvsp[-1].tree)->rtype==HERE?heredoc((yyvsp[0].tree)):(yyvsp[0].tree));} -#line 1307 "sys/cmd/rc/y.tab.c" - break; - - case 19: /* cmd: %empty */ -#line 41 "sys/cmd/rc/syn.y" - {(yyval.tree)=0;} -#line 1313 "sys/cmd/rc/y.tab.c" - break; - - case 20: /* cmd: brace epilog */ -#line 42 "sys/cmd/rc/syn.y" - {(yyval.tree)=epimung((yyvsp[-1].tree), (yyvsp[0].tree));} -#line 1319 "sys/cmd/rc/y.tab.c" - break; - - case 21: /* $@1: %empty */ -#line 43 "sys/cmd/rc/syn.y" - {skipnl();} -#line 1325 "sys/cmd/rc/y.tab.c" - break; - - case 22: /* cmd: IF paren $@1 cmd */ -#line 44 "sys/cmd/rc/syn.y" - {(yyval.tree)=mung2((yyvsp[-3].tree), (yyvsp[-2].tree), (yyvsp[0].tree));} -#line 1331 "sys/cmd/rc/y.tab.c" - break; - - case 23: /* $@2: %empty */ -#line 45 "sys/cmd/rc/syn.y" - {skipnl();} -#line 1337 "sys/cmd/rc/y.tab.c" - break; - - case 24: /* cmd: IF NOT $@2 cmd */ -#line 45 "sys/cmd/rc/syn.y" - {(yyval.tree)=mung1((yyvsp[-2].tree), (yyvsp[0].tree));} -#line 1343 "sys/cmd/rc/y.tab.c" - break; - - case 25: /* $@3: %empty */ -#line 46 "sys/cmd/rc/syn.y" - {skipnl();} -#line 1349 "sys/cmd/rc/y.tab.c" - break; - - case 26: /* cmd: FOR '(' word IN words ')' $@3 cmd */ -#line 55 "sys/cmd/rc/syn.y" - {(yyval.tree)=mung3((yyvsp[-7].tree), (yyvsp[-5].tree), (yyvsp[-3].tree) ? (yyvsp[-3].tree) : tree1(PAREN, (yyvsp[-3].tree)), (yyvsp[0].tree));} -#line 1355 "sys/cmd/rc/y.tab.c" - break; - - case 27: /* $@4: %empty */ -#line 56 "sys/cmd/rc/syn.y" - {skipnl();} -#line 1361 "sys/cmd/rc/y.tab.c" - break; - - case 28: /* cmd: FOR '(' word ')' $@4 cmd */ -#line 57 "sys/cmd/rc/syn.y" - {(yyval.tree)=mung3((yyvsp[-5].tree), (yyvsp[-3].tree), (struct Tree *)0, (yyvsp[0].tree));} -#line 1367 "sys/cmd/rc/y.tab.c" - break; - - case 29: /* $@5: %empty */ -#line 58 "sys/cmd/rc/syn.y" - {skipnl();} -#line 1373 "sys/cmd/rc/y.tab.c" - break; - - case 30: /* cmd: WHILE paren $@5 cmd */ -#line 59 "sys/cmd/rc/syn.y" - {(yyval.tree)=mung2((yyvsp[-3].tree), (yyvsp[-2].tree), (yyvsp[0].tree));} -#line 1379 "sys/cmd/rc/y.tab.c" - break; - - case 31: /* $@6: %empty */ -#line 60 "sys/cmd/rc/syn.y" - {skipnl();} -#line 1385 "sys/cmd/rc/y.tab.c" - break; - - case 32: /* cmd: SWITCH word $@6 brace */ -#line 61 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree2(SWITCH, (yyvsp[-2].tree), (yyvsp[0].tree));} -#line 1391 "sys/cmd/rc/y.tab.c" - break; - - case 33: /* cmd: simple */ -#line 62 "sys/cmd/rc/syn.y" - {(yyval.tree)=simplemung((yyvsp[0].tree));} -#line 1397 "sys/cmd/rc/y.tab.c" - break; - - case 34: /* cmd: TWIDDLE word words */ -#line 63 "sys/cmd/rc/syn.y" - {(yyval.tree)=mung2((yyvsp[-2].tree), (yyvsp[-1].tree), (yyvsp[0].tree));} -#line 1403 "sys/cmd/rc/y.tab.c" - break; - - case 35: /* cmd: cmd ANDAND cmd */ -#line 64 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree2(ANDAND, (yyvsp[-2].tree), (yyvsp[0].tree));} -#line 1409 "sys/cmd/rc/y.tab.c" - break; - - case 36: /* cmd: cmd OROR cmd */ -#line 65 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree2(OROR, (yyvsp[-2].tree), (yyvsp[0].tree));} -#line 1415 "sys/cmd/rc/y.tab.c" - break; - - case 37: /* cmd: cmd PIPE cmd */ -#line 66 "sys/cmd/rc/syn.y" - {(yyval.tree)=mung2((yyvsp[-1].tree), (yyvsp[-2].tree), (yyvsp[0].tree));} -#line 1421 "sys/cmd/rc/y.tab.c" - break; - - case 38: /* cmd: redir cmd */ -#line 67 "sys/cmd/rc/syn.y" - {(yyval.tree)=mung2((yyvsp[-1].tree), (yyvsp[-1].tree)->child[0], (yyvsp[0].tree));} -#line 1427 "sys/cmd/rc/y.tab.c" - break; - - case 39: /* cmd: assign cmd */ -#line 68 "sys/cmd/rc/syn.y" - {(yyval.tree)=mung3((yyvsp[-1].tree), (yyvsp[-1].tree)->child[0], (yyvsp[-1].tree)->child[1], (yyvsp[0].tree));} -#line 1433 "sys/cmd/rc/y.tab.c" - break; - - case 40: /* cmd: BANG cmd */ -#line 69 "sys/cmd/rc/syn.y" - {(yyval.tree)=mung1((yyvsp[-1].tree), (yyvsp[0].tree));} -#line 1439 "sys/cmd/rc/y.tab.c" - break; - - case 41: /* cmd: SUBSHELL cmd */ -#line 70 "sys/cmd/rc/syn.y" - {(yyval.tree)=mung1((yyvsp[-1].tree), (yyvsp[0].tree));} -#line 1445 "sys/cmd/rc/y.tab.c" - break; - - case 42: /* cmd: FN words brace */ -#line 71 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree2(FN, (yyvsp[-1].tree), (yyvsp[0].tree));} -#line 1451 "sys/cmd/rc/y.tab.c" - break; - - case 43: /* cmd: FN words */ -#line 72 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree1(FN, (yyvsp[0].tree));} -#line 1457 "sys/cmd/rc/y.tab.c" - break; - - case 45: /* simple: simple word */ -#line 74 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree2(ARGLIST, (yyvsp[-1].tree), (yyvsp[0].tree));} -#line 1463 "sys/cmd/rc/y.tab.c" - break; - - case 46: /* simple: simple redir */ -#line 75 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree2(ARGLIST, (yyvsp[-1].tree), (yyvsp[0].tree));} -#line 1469 "sys/cmd/rc/y.tab.c" - break; - - case 48: /* first: first '^' word */ -#line 77 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree2('^', (yyvsp[-2].tree), (yyvsp[0].tree));} -#line 1475 "sys/cmd/rc/y.tab.c" - break; - - case 49: /* word: keyword */ -#line 78 "sys/cmd/rc/syn.y" - {lastword=1; (yyvsp[0].tree)->type=WORD;} -#line 1481 "sys/cmd/rc/y.tab.c" - break; - - case 51: /* word: word '^' word */ -#line 80 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree2('^', (yyvsp[-2].tree), (yyvsp[0].tree));} -#line 1487 "sys/cmd/rc/y.tab.c" - break; - - case 52: /* comword: '$' word */ -#line 81 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree1('$', (yyvsp[0].tree));} -#line 1493 "sys/cmd/rc/y.tab.c" - break; - - case 53: /* comword: '$' word SUB words ')' */ -#line 82 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree2(SUB, (yyvsp[-3].tree), (yyvsp[-1].tree));} -#line 1499 "sys/cmd/rc/y.tab.c" - break; - - case 54: /* comword: '"' word */ -#line 83 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree1('"', (yyvsp[0].tree));} -#line 1505 "sys/cmd/rc/y.tab.c" - break; - - case 55: /* comword: COUNT word */ -#line 84 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree1(COUNT, (yyvsp[0].tree));} -#line 1511 "sys/cmd/rc/y.tab.c" - break; - - case 57: /* comword: '`' brace */ -#line 86 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree1('`', (yyvsp[0].tree));} -#line 1517 "sys/cmd/rc/y.tab.c" - break; - - case 58: /* comword: '(' words ')' */ -#line 87 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree1(PAREN, (yyvsp[-1].tree));} -#line 1523 "sys/cmd/rc/y.tab.c" - break; - - case 59: /* comword: REDIR brace */ -#line 88 "sys/cmd/rc/syn.y" - {(yyval.tree)=mung1((yyvsp[-1].tree), (yyvsp[0].tree)); (yyval.tree)->type=PIPEFD;} -#line 1529 "sys/cmd/rc/y.tab.c" - break; - - case 70: /* words: %empty */ -#line 90 "sys/cmd/rc/syn.y" - {(yyval.tree)=(struct Tree*)0;} -#line 1535 "sys/cmd/rc/y.tab.c" - break; - - case 71: /* words: words word */ -#line 91 "sys/cmd/rc/syn.y" - {(yyval.tree)=tree2(WORDS, (yyvsp[-1].tree), (yyvsp[0].tree));} -#line 1541 "sys/cmd/rc/y.tab.c" - break; - - -#line 1545 "sys/cmd/rc/y.tab.c" - - default: break; - } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - - *++yyvsp = yyval; - - /* Now 'shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - { - const int yylhs = yyr1[yyn] - YYNTOKENS; - const int yyi = yypgoto[yylhs] + *yyssp; - yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp - ? yytable[yyi] - : yydefgoto[yylhs]); - } - - goto yynewstate; - - -/*--------------------------------------. -| yyerrlab -- here on detecting error. | -`--------------------------------------*/ -yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; - yyerror (YY_("syntax error")); - } - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - /* Pacify compilers when the user code never invokes YYERROR and the - label yyerrorlab therefore never appears in user code. */ - if (0) - YYERROR; - ++yynerrs; - - /* Do not reclaim the symbols of the rule whose action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - /* Pop stack until we find a state that shifts the error token. */ - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYSYMBOL_YYerror; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - YY_ACCESSING_SYMBOL (yystate), yyvsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturnlab; - - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturnlab; - - -/*-----------------------------------------------------------. -| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | -`-----------------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - goto yyreturnlab; - - -/*----------------------------------------------------------. -| yyreturnlab -- parsing is finished, clean up and return. | -`----------------------------------------------------------*/ -yyreturnlab: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - } - /* Do not reclaim the symbols of the rule whose action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - YY_ACCESSING_SYMBOL (+*yyssp), yyvsp); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif - - return yyresult; -} - diff --git a/sys/cmd/rc/y.tab.h b/sys/cmd/rc/y.tab.h deleted file mode 100644 index ba05ca2..0000000 --- a/sys/cmd/rc/y.tab.h +++ /dev/null @@ -1,139 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.8.2. */ - -/* Bison interface for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, - Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, - especially those whose name start with YY_ or yy_. They are - private implementation details that can be changed or removed. */ - -#ifndef YY_YY_SYS_CMD_RC_Y_TAB_H_INCLUDED -# define YY_YY_SYS_CMD_RC_Y_TAB_H_INCLUDED -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int yydebug; -#endif - -/* Token kinds. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - YYEMPTY = -2, - YYEOF = 0, /* "end of file" */ - YYerror = 256, /* error */ - YYUNDEF = 257, /* "invalid token" */ - FOR = 258, /* FOR */ - IN = 259, /* IN */ - WHILE = 260, /* WHILE */ - IF = 261, /* IF */ - NOT = 262, /* NOT */ - TWIDDLE = 263, /* TWIDDLE */ - BANG = 264, /* BANG */ - SUBSHELL = 265, /* SUBSHELL */ - SWITCH = 266, /* SWITCH */ - FN = 267, /* FN */ - WORD = 268, /* WORD */ - REDIR = 269, /* REDIR */ - DUP = 270, /* DUP */ - PIPE = 271, /* PIPE */ - SUB = 272, /* SUB */ - SIMPLE = 273, /* SIMPLE */ - ARGLIST = 274, /* ARGLIST */ - WORDS = 275, /* WORDS */ - BRACE = 276, /* BRACE */ - PAREN = 277, /* PAREN */ - PCMD = 278, /* PCMD */ - PIPEFD = 279, /* PIPEFD */ - ANDAND = 280, /* ANDAND */ - OROR = 281, /* OROR */ - COUNT = 282 /* COUNT */ - }; - typedef enum yytokentype yytoken_kind_t; -#endif -/* Token kinds. */ -#define YYEMPTY -2 -#define YYEOF 0 -#define YYerror 256 -#define YYUNDEF 257 -#define FOR 258 -#define IN 259 -#define WHILE 260 -#define IF 261 -#define NOT 262 -#define TWIDDLE 263 -#define BANG 264 -#define SUBSHELL 265 -#define SWITCH 266 -#define FN 267 -#define WORD 268 -#define REDIR 269 -#define DUP 270 -#define PIPE 271 -#define SUB 272 -#define SIMPLE 273 -#define ARGLIST 274 -#define WORDS 275 -#define BRACE 276 -#define PAREN 277 -#define PCMD 278 -#define PIPEFD 279 -#define ANDAND 280 -#define OROR 281 -#define COUNT 282 - -/* Value type. */ -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -union YYSTYPE -{ -#line 16 "sys/cmd/rc/syn.y" - - struct Tree *tree; - -#line 125 "sys/cmd/rc/y.tab.h" - -}; -typedef union YYSTYPE YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define YYSTYPE_IS_DECLARED 1 -#endif - - -extern YYSTYPE yylval; - - -int yyparse (void); - - -#endif /* !YY_YY_SYS_CMD_RC_Y_TAB_H_INCLUDED */ -- cgit v1.2.1