aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2021-10-13 16:46:20 -0700
committerNicholas Noll <nbnoll@eml.cc>2021-10-13 16:46:20 -0700
commit566d54fe549286895fdef8aa9f385686405dd290 (patch)
tree184607f21a2e59f8896a0505fa5597a6976c76ab
parentf2efbb46ef89c7c1693400f7209113c50c959f02 (diff)
RM(rc): old code. too many assumptions baked in
-rw-r--r--sys/cmd/rc/Makefile56
-rw-r--r--sys/cmd/rc/code.c490
-rw-r--r--sys/cmd/rc/exec.c1013
-rw-r--r--sys/cmd/rc/exec.h88
-rw-r--r--sys/cmd/rc/fns.h68
-rw-r--r--sys/cmd/rc/getflags.c244
-rw-r--r--sys/cmd/rc/getflags.h7
-rw-r--r--sys/cmd/rc/glob.c268
-rw-r--r--sys/cmd/rc/havefork.c300
-rw-r--r--sys/cmd/rc/here.c153
-rw-r--r--sys/cmd/rc/history.c4
-rw-r--r--sys/cmd/rc/io.c263
-rw-r--r--sys/cmd/rc/io.h31
-rw-r--r--sys/cmd/rc/lex.c372
-rw-r--r--sys/cmd/rc/linenoise.c1236
-rw-r--r--sys/cmd/rc/linenoise.h77
-rw-r--r--sys/cmd/rc/pcmd.c147
-rw-r--r--sys/cmd/rc/pfnc.c71
-rw-r--r--sys/cmd/rc/prompt.c101
-rw-r--r--sys/cmd/rc/rc.h149
-rw-r--r--sys/cmd/rc/rcmain.unix35
-rw-r--r--sys/cmd/rc/rules.mk40
-rw-r--r--sys/cmd/rc/simple.c507
-rw-r--r--sys/cmd/rc/subr.c77
-rw-r--r--sys/cmd/rc/syn.y91
-rw-r--r--sys/cmd/rc/trap.c37
-rw-r--r--sys/cmd/rc/tree.c146
-rw-r--r--sys/cmd/rc/unix.c627
-rw-r--r--sys/cmd/rc/unix.h54
-rw-r--r--sys/cmd/rc/var.c176
-rw-r--r--sys/cmd/rc/x.tab.h114
-rw-r--r--sys/cmd/rc/y.tab.c1736
-rw-r--r--sys/cmd/rc/y.tab.h139
33 files changed, 0 insertions, 8917 deletions
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(n<NSTATUS){
- v[n]='|';
- strncpy(v+n+1, t, NSTATUS-n-1);
- }
- v[NSTATUS]='\0';
- return v;
-}
-
-void
-Xpipewait(void)
-{
- char status[NSTATUS+1];
- if(runq->pid==-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[] = {"<flag>"};
-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-i<count){
- reason = FEWARGS;
- badflag = c;
- return -1;
- }
- reverse(argv+i, argv+argc);
- reverse(argv+i, argv+argc-count);
- reverse(argv+argc-count+1, argv+argc);
- argc-=count;
- flag[c] = argv+argc+1;
- flag[c][0] = s;
- s="";
- }
- }
- }
- return argc;
-}
-
-static void
-reverse(char **p, char **q)
-{
- char *t;
- for(;p<q;p++,--q){ t=*p; *p=*q; *q = t; }
-}
-
-static int
-scanflag(int c, char *f)
-{
- int fc, count;
- if(0<=c && c<NFLAG)
- while(*f){
- if(*f==' '){
- f++;
- continue;
- }
- fc=*f++;
- if(*f==':'){
- f++;
- if(*f<'0' || '9'<*f){ reason = FLAGSYN; return -1; }
- count = 0;
- while('0'<=*f && *f<='9') count = count*10+*f++-'0';
- }
- else
- count = 0;
- if(*f=='['){
- do{
- f++;
- if(*f=='\0'){ reason = FLAGSYN; return -1; }
- }while(*f!=']');
- f++;
- }
- if(c==fc)
- return count;
- }
- reason = BADFLAG;
- badflag = c;
- return -1;
-}
-
-void
-usage(char *tail)
-{
- char *s, *t, c;
- int count, nflag = 0;
- switch(reason){
- case RESET:
- errs("Flag -");
- errc(badflag);
- errs(": set twice\n");
- break;
- case FEWARGS:
- errs("Flag -");
- errc(badflag);
- errs(": too few arguments\n");
- break;
- case FLAGSYN:
- errs("Bad argument to getflags!\n");
- break;
- case BADFLAG:
- errs("Illegal flag -");
- errc(badflag);
- errc('\n');
- break;
- }
- errs("Usage: ");
- errs(cmdname);
- for(s = flagarg;*s;){
- c=*s;
- if(*s++==' ')
- continue;
- if(*s==':'){
- s++;
- count = 0;
- while('0'<=*s && *s<='9') count = count*10+*s++-'0';
- }
- else count = 0;
- if(count==0){
- if(nflag==0)
- errs(" [-");
- nflag++;
- errc(c);
- }
- if(*s=='['){
- s++;
- while(*s!=']' && *s!='\0') s++;
- if(*s==']')
- s++;
- }
- }
- if(nflag)
- errs("]");
- for(s = flagarg;*s;){
- c=*s;
- if(*s++==' ')
- continue;
- if(*s==':'){
- s++;
- count = 0;
- while('0'<=*s && *s<='9') count = count*10+*s++-'0';
- }
- else count = 0;
- if(count!=0){
- errs(" [-");
- errc(c);
- if(*s=='['){
- s++;
- t = s;
- while(*s!=']' && *s!='\0') s++;
- errs(" ");
- errn(t, s-t);
- if(*s==']')
- s++;
- }
- else
- while(count--) errs(" arg");
- errs("]");
- }
- else if(*s=='['){
- s++;
- while(*s!=']' && *s!='\0') s++;
- if(*s==']')
- s++;
- }
- }
- if(tail){
- errs(" ");
- errs(tail);
- }
- errs("\n");
- Exit("bad flags");
-}
-
-static void
-errn(char *s, int count)
-{
- while(count){ errc(*s++); --count; }
-}
-
-static void
-errs(char *s)
-{
- while(*s) errc(*s++);
-}
-#define NBUF 80
-static char buf[NBUF], *bufp = buf;
-
-static void
-errc(int c)
-{
- *bufp++=c;
- if(bufp==&buf[NBUF] || c=='\n'){
- Write(2, buf, bufp-buf);
- bufp = buf;
- }
-}
diff --git a/sys/cmd/rc/getflags.h b/sys/cmd/rc/getflags.h
deleted file mode 100644
index 9afb32e..0000000
--- a/sys/cmd/rc/getflags.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#define NFLAG 128
-#define NCMDLINE 512
-extern char **flag[NFLAG];
-extern char cmdline[NCMDLINE+1];
-extern char *cmdname;
-extern char *flagset[];
-int getflags(int, char*[], char*, int);
diff --git a/sys/cmd/rc/glob.c b/sys/cmd/rc/glob.c
deleted file mode 100644
index f59be4d..0000000
--- a/sys/cmd/rc/glob.c
+++ /dev/null
@@ -1,268 +0,0 @@
-#include "rc.h"
-#include "exec.h"
-#include "fns.h"
-
-struct Word *globv;
-char *globname;
-/*
- * delete all the GLOB marks from s, in place
- */
-
-void
-deglob(char *s)
-{
- char *t = s;
- do{
- if(*t==GLOB)
- t++;
- *s++=*t;
- }while(*t++);
-}
-
-int
-globcmp(const void *s, const void *t)
-{
- return strcmp(*(char**)s, *(char**)t);
-}
-
-void
-globsort(Word *left, Word *right)
-{
- char **list;
- Word *a;
- int n = 0;
- for(a = left;a!=right;a = a->next) 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(hi<lo){ t = lo; lo = hi; hi = t; }
- }
- if(lo<=c && c<=hi)
- hit = 1;
- }
- if(compl)
- hit=!hit;
- if(!hit)
- return 0;
- break;
- }
- }
- return *s=='\0';
-}
-
-void
-globlist1(Word *gl)
-{
- if(gl){
- globlist1(gl->next);
- 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 <u.h>
-#endif
-#include <signal.h>
-#if defined(PLAN9PORT) && defined(__sun__)
-# define BSD_COMP /* sigh. for TIOCNOTTY */
-#endif
-#include <sys/ioctl.h>
-#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 <stdio.h>
-#include <readline/history.h>
-
-
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 <limits.h>
-#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'<c){
- RedirErr:
- *w = 0;
- yyerror(t->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 <antirez at gmail dot com>
- * Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * 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+<char> 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 <termios.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-
-#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 <tab> 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 <tab>. 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("<newline>");
- 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 <antirez at gmail dot com>
- * Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
- *
- * 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 <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <sys/stat.h>
-
-#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 <param.h> */
-
-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<tree> line paren brace body cmdsa cmdsan assign epilog redir
-%type<tree> cmd simple first word comword keyword words
-%type<tree> NOT FOR IN WHILE IF TWIDDLE BANG SUBSHELL SWITCH FN
-%type<tree> 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 <errno.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <dirent.h>
-#include <assert.h>
-#include <limits.h>
-
-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<nwaitpids; r++)
- if(waitpids[r] != pid)
- waitpids[w++] = waitpids[r];
- nwaitpids = w;
-}
-
-void
-clearwaitpids(void)
-{
- nwaitpids = 0;
-}
-
-int
-havewaitpid(int pid)
-{
- int i;
-
- for(i=0; i<nwaitpids; i++)
- if(waitpids[i] == pid)
- return 1;
- return 0;
-}
-
-int
-chartorune(wchar_t *rune, const char *str)
-{
- int r = mbtowc(rune, str, strlen(str));
- if(r < 0){
- *rune = 0xFFFD;
- return 1;
- }
- return r;
-}
-
diff --git a/sys/cmd/rc/unix.h b/sys/cmd/rc/unix.h
deleted file mode 100644
index 885c638..0000000
--- a/sys/cmd/rc/unix.h
+++ /dev/null
@@ -1,54 +0,0 @@
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <inttypes.h>
-#include <string.h>
-
-#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 <https://www.gnu.org/licenses/>. */
-
-/* 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<Type> (Val)
-# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type> (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
- <limits.h> and (if available) <stdint.h> are included
- so that the code can choose integer types of a good width. */
-
-#ifndef __PTRDIFF_MAX__
-# include <limits.h> /* INFRINGES ON USER NAME SPACE */
-# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__
-# include <stdint.h> /* 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
- <https://h20195.www2.hpe.com/V2/getpdf.aspx/4AA4-7673ENW.pdf>. */
-#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 <stddef.h> /* 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 <stddef.h> /* 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 <libintl.h> /* 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 <alloca.h> /* INFRINGES ON USER NAME SPACE */
-# elif defined _AIX
-# define YYSTACK_ALLOC __alloca
-# elif defined _MSC_VER
-# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
-# define alloca _alloca
-# else
-# define YYSTACK_ALLOC alloca
-# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
-# include <stdlib.h> /* 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 <stdlib.h> /* 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 <stdio.h> /* 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 <https://www.gnu.org/licenses/>. */
-
-/* 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 */