aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2021-04-22 08:55:35 -0700
committerNicholas Noll <nbnoll@eml.cc>2021-04-22 08:55:35 -0700
commit5d3642b8ef920316693031d2ea34b9def0b1abc5 (patch)
tree8100890ed5b2e4ecdbde09615e0820346ccc3f41 /sys/cmd/rc
parente30f8b22069bec1a3fb68f089a9a7198671eb09a (diff)
chore: rm unfinished projects
Diffstat (limited to 'sys/cmd/rc')
-rw-r--r--sys/cmd/rc/code.c335
-rw-r--r--sys/cmd/rc/code.dep166
-rw-r--r--sys/cmd/rc/exec.c139
-rw-r--r--sys/cmd/rc/glob.c199
-rw-r--r--sys/cmd/rc/io.c446
-rw-r--r--sys/cmd/rc/lex.c417
-rw-r--r--sys/cmd/rc/main.c86
-rw-r--r--sys/cmd/rc/parse.c496
-rw-r--r--sys/cmd/rc/rc.h312
-rw-r--r--sys/cmd/rc/rules.mk22
-rw-r--r--sys/cmd/rc/simple.c13
-rw-r--r--sys/cmd/rc/tree.c144
-rw-r--r--sys/cmd/rc/util.c40
-rw-r--r--sys/cmd/rc/var.c129
-rw-r--r--sys/cmd/rc/word.c64
15 files changed, 0 insertions, 3008 deletions
diff --git a/sys/cmd/rc/code.c b/sys/cmd/rc/code.c
deleted file mode 100644
index edf47cf..0000000
--- a/sys/cmd/rc/code.c
+++ /dev/null
@@ -1,335 +0,0 @@
-#include "rc.h"
-
-#define delcode 100
-#define c0 t->child[0]
-#define c1 t->child[1]
-#define c2 t->child[2]
-
-#define emitf(x) ((code.ip!=code.end || morecode()), code.ip++->f = (x), code.ip)
-#define emiti(x) ((code.ip!=code.end || morecode()), code.ip++->i = (x), code.ip)
-#define emits(x) ((code.ip!=code.end || morecode()), code.ip++->s = (x), code.ip)
-
-static struct
-{
- int cap;
- Code *buf, *ip, *end;
-} code;
-
-static
-int
-morecode(void)
-{
- code.cap += delcode;
- code.buf = erealloc(code.buf, code.cap*sizeof(*code.buf));
- code.end = code.ip + delcode;
- memset(code.ip, 0, delcode*sizeof(*code.buf));
-
- return 0;
-}
-
-static
-void
-stuffdot(Code *p)
-{
- int a;
-
- a = p - code.buf;
- if (code.ip <= p || p < code.buf)
- panic("bad address %d in stuffdot", a);
- code.buf[a].i = code.ip-code.buf;
-}
-
-static
-void
-rcc(Tree *t, int eflag)
-{
- Code *p, *q;
- Tree *tt;
-
- if (!t)
- return;
-
- switch(t->type) {
- default:
- pfmt(errio, "bad type %d in rc compiler\n", t->type);
- break;
- case Tdol:
- emitf(Xmark);
- rcc(c0, eflag);
- emitf(Xdol);
- break;
- case Tquote:
- emitf(Xmark);
- rcc(c0, eflag);
- emitf(Xflatten);
- break;
- case Tsub:
- emitf(Xmark);
- rcc(c0, eflag);
- emitf(Xmark);
- rcc(c1, eflag);
- emitf(Xsub);
- break;
- case Tand:
- emitf(Xasync);
- p = emiti(0);
- rcc(c0, eflag);
- emitf(Xexit);
- stuffdot(p);
- break;
- case Tsemi:
- rcc(c0, eflag);
- rcc(c1, eflag);
- break;
- case Tcarot:
- emitf(Xmark);
- rcc(c1, eflag);
- emitf(Xmark);
- rcc(c0, eflag);
- emitf(Xcat);
- break;
- case Ttick:
- emitf(Xcmdsub);
- p = emiti(0);
- rcc(c0, 0);
- emitf(Xexit);
- stuffdot(p);
- break;
- case Tandand:
- rcc(c0, 0);
- emitf(Xtrue);
- p = emiti(0);
- rcc(c1, eflag);
- stuffdot(p);
- break;
- case Targs:
- rcc(c1, eflag);
- rcc(c0, eflag);
- break;
- case Tbang:
- rcc(c0, eflag);
- emitf(Xnegate);
- break;
- case Tparen:
- case Tbrace:
- rcc(c0, eflag);
- break;
- case Tcount:
- emitf(Xmark);
- rcc(c0, eflag);
- emitf(Xcount);
- break;
- case Tfunc:
- emitf(Xmark);
- rcc(c0, eflag);
- if(c1){
- emitf(Xfunc);
- p = emiti(0);
- emits(fnstr(c1));
- rcc(c1, eflag);
- emitf(Xunlocal); /* get rid of $* */
- emitf(Xkill);
- stuffdot(p);
- } else
- emitf(Xunfunc);
- break;
- case Tif:
- rcc(c0, 0);
- emitf(Xif);
- p = emiti(0);
- rcc(c1, eflag);
- // emitf(Xwastrue);
- stuffdot(p);
- break;
- // case Telse:
- // if(!runq->iflast)
- // rcerror("`else' does not follow `if(...)'");
- // emitf(Xelse);
- // p = emiti(0);
- // rcc(c0, eflag);
- // stuffdot(p);
- // break;
- case Toror:
- rcc(c0, 0);
- emitf(Xfalse);
- p = emiti(0);
- rcc(c1, eflag);
- stuffdot(p);
- break;
- case Tpcmd:
- rcc(c0, eflag);
- break;
- case Tsimple:
- emitf(Xmark);
- rcc(c0, eflag);
- emitf(Xsimple);
- if(eflag)
- emitf(Xeflag);
- break;
- case Tsubshell:
- emitf(Xsubshell);
- p = emiti(0);
- rcc(c0, eflag);
- emitf(Xexit);
- stuffdot(p);
- if(eflag)
- emitf(Xeflag);
- break;
- case Tswitch:
- codeswitch(t, eflag);
- break;
- case Ttwiddle:
- emitf(Xmark);
- rcc(c1, eflag);
- emitf(Xmark);
- rcc(c0, eflag);
- emitf(Xmatch);
- if(eflag)
- emitf(Xeflag);
- break;
- case Twhile:
- q = code.ip;
- rcc(c0, 0);
- if(q==code.ip)
- emitf(Xsettrue); /* empty condition == while(true) */
- emitf(Xtrue);
- p = emiti(0);
- rcc(c1, eflag);
- emitf(Xjump);
- emiti(q-code.buf);
- stuffdot(p);
- break;
- case Twords:
- rcc(c1, eflag);
- rcc(c0, eflag);
- break;
- case Tfor:
- emitf(Xmark);
- if(c1){
- rcc(c1, eflag);
- emitf(Xglob);
- } else{
- emitf(Xmark);
- emitf(Xword);
- emits(strdup("*"));
- emitf(Xdol);
- }
- emitf(Xmark); /* dummy value for Xlocal */
- emitf(Xmark);
- rcc(c0, eflag);
- emitf(Xlocal);
- p = emitf(Xfor);
- q = emiti(0);
- rcc(c2, eflag);
- emitf(Xjump);
- emiti(p-code.buf);
- stuffdot(q);
- emitf(Xunlocal);
- break;
- case Tword:
- emitf(Xword);
- emits(strdup(t->str));
- break;
- case Tdup:
- if(t->redir.type == Rdupfd){
- emitf(Xdup);
- emiti(t->redir.fd[0]);
- emiti(t->redir.fd[1]);
- } else{
- emitf(Xclose);
- emiti(t->redir.fd[0]);
- }
- rcc(c1, eflag);
- emitf(Xpopredir);
- break;
- case Tpipefd:
- emitf(Xpipefd);
- emiti(t->redir.type);
- p = emiti(0);
- rcc(c0, eflag);
- emitf(Xexit);
- stuffdot(p);
- break;
- case Tredir:
- emitf(Xmark);
- rcc(c0, eflag);
- emitf(Xglob);
- switch(t->redir.type){
- case Rappend:
- emitf(Xappend);
- break;
- case Rwrite:
- emitf(Xwrite);
- break;
- case Rread:
- case Rhere:
- emitf(Xread);
- break;
- case Rrdwr:
- emitf(Xrdwr);
- break;
- }
- emiti(t->redir.fd[0]);
- rcc(c1, eflag);
- emitf(Xpopredir);
- break;
- case Teq:
- tt = t;
- for(;t && t->type==Teq;t = c2);
- if(t){
- for(t = tt;t->type==Teq;t = c2){
- emitf(Xmark);
- rcc(c1, eflag);
- emitf(Xmark);
- rcc(c0, eflag);
- emitf(Xlocal);
- }
- rcc(t, eflag);
- for(t = tt; t->type==Teq; t = c2)
- emitf(Xunlocal);
- } else{
- for(t = tt;t;t = c2){
- emitf(Xmark);
- rcc(c1, eflag);
- emitf(Xmark);
- rcc(c0, eflag);
- emitf(Xassign);
- }
- }
- t = tt; /* so tests below will work */
- break;
- case Tpipe:
- emitf(Xpipe);
- emiti(t->redir.fd[0]);
- emiti(t->redir.fd[1]);
- p = emiti(0);
- q = emiti(0);
- rcc(c0, eflag);
- emitf(Xexit);
- stuffdot(p);
- rcc(c1, eflag);
- emitf(Xkill);
- stuffdot(q);
- emitf(Xpipewait);
- break;
- }
- if(t->type!=Telse && t->type!=Tsemi)
- shell->iflast = t->type==Tif;
- else if (c0)
- shell->iflast = c0->type==Tif;
-}
-
-Code*
-compile(Tree *t)
-{
- code.cap = delcode;
- code.buf = code.ip = emalloc(code.cap*sizeof *code.buf);
- code.end = code.ip + code.cap;
-
- emiti(0);
- rcc(t, 0);
- emitf(Xkill);
- emitf(nil);
-
- return code.buf;
-}
diff --git a/sys/cmd/rc/code.dep b/sys/cmd/rc/code.dep
deleted file mode 100644
index 7fdd4bc..0000000
--- a/sys/cmd/rc/code.dep
+++ /dev/null
@@ -1,166 +0,0 @@
-#if 0
-// simple example code
-error
-cd(Args args)
-{
- switch (args.len) {
- case 0:
- errorf("reached cd with no arguments!");
- return 1;
- case 1:
- one:
- errorf("sh: expected argument to command 'cd'");
- return 1;
- case 2:
- if (args.a[1] == nil)
- goto one;
- break;
- default:
- errorf("sh: too many arguments to command 'cd'");
- return 1;
- }
- if (chdir(args.a[1]))
- errorf("cd fail: %s", strerror(errno));
-
- return 0;
-}
-
-error
-quit(Args args)
-{
- exit(0);
-}
-
-Builtin builtins[] = {
- { "cd", cd },
- { "exit", quit },
-};
-
-void
-clear(Header *arr)
-{
- arr->len = 0;
-}
-
-int
-readline(Code *code)
-{
- int n, b;
-
- n = code->len;
-getchar:
- if (code->len >= code->cap) {
- code->cap += 100;
- code->s = realloc(code->s, code->cap);
- }
- /* TODO: unicode? */
- switch ((b = getchar())) {
- case EOF:
- n = -1;
- goto null;
- case '\n':
- n = code->len - n;
- null:
- code->s[code->len] = '\0';
- break;
- default:
- code->s[code->len++] = b;
- goto getchar;
- }
-
- return n;
-}
-
-/* TODO: unicode */
-int
-readargs(Code code, Args *args)
-{
- if (args->a)
- clear(&args->hdr);
- else {
- args->cap += 20;
- args->a = realloc(args->a, args->cap);
- }
-
- args->a[args->len++] = code.s;
- while (*code.s) {
- if (!isspace(*code.s++))
- continue;
-
- code.s[-1] = '\0';
- /* consume all remaining space */
- while (isspace(*code.s))
- code.s++;
-
- if (args->len >= args->cap-1) {
- args->cap += 20;
- args->a = realloc(args->a, args->cap);
- }
- args->a[args->len++] = code.s;
- }
- /* nil acts as a sentinel value */
- args->a[args->len] = nil;
-
- return args->len;
-}
-
-error
-execute(Args args)
-{
- int i, status;
- pid_t cid, wid;
-
- for (i = 0; i < arrlen(builtins); i++) {
- if (strcmp(args.a[0], builtins[i].cmd) == 0)
- return builtins[i].func(args);
- }
-
- if ((cid = fork()) == 0) {
- if (execvp(args.a[0], args.a) == -1)
- errorf("exec failed: %s", strerror(errno));
- exit(1);
- } else if (cid > 0)
- do
- wid = waitpid(cid, &status, WUNTRACED);
- while (!WIFEXITED(status) && !WIFSIGNALED(status));
- else
- errorf("fork failed: %s", strerror(errno));
-
- return status;
-}
-
-static
-void
-flush(void)
-{
- io·flush(stdout);
-}
-
-static
-void
-prompt(void)
-{
- printf(";");
- flush();
-}
-
-int
-main(int argc, char *argv[])
-{
- int i, err, n;
- Code code = {0};
- Args args = {0};
-
- ARGBEGIN {
- } ARGEND;
-
- do {
- clear(&code.hdr);
- prompt();
-
- n = readline(&code);
- readargs(code, &args);
- err = execute(args);
- } while (!err && n > 0);
-}
-#endif
diff --git a/sys/cmd/rc/exec.c b/sys/cmd/rc/exec.c
deleted file mode 100644
index d4822a7..0000000
--- a/sys/cmd/rc/exec.c
+++ /dev/null
@@ -1,139 +0,0 @@
-#include "rc.h"
-
-#define W0 shell->stack->words
-// -----------------------------------------------------------------------
-// helper functions
-
-static
-void
-setstatus(char *s)
-{
- setvar("status", newword(s, nil));
-}
-
-static
-void
-pushredir(int type, int from, int to)
-{
- Redir *r;
-
- alloc(r);
- r->type = type;
- r->from = from;
- r->to = to;
- r->link = shell->redir, shell->redir = r;
-}
-
-// -----------------------------------------------------------------------
-// interpreter functions
-
-void
-Xerror(char *s)
-{
- if(!strcmp(argv0, "rc")||!strcmp(argv0, "/bin/rc"))
- pfmt(errio, "rc: %s: %r\n", s);
- else
- pfmt(errio, "rc (%s): %s: %r\n", argv0, s);
- flush(&errio);
-
- setstatus("error");
- while(!shell->interactive)
- Xkill();
-}
-
-void
-Xappend(void)
-{
- int fd;
- char *path;
-
- switch(count(W0)) {
- default:
- Xerror(">> requires a singleton list");
- return;
- case 0:
- Xerror(">> requires one file");
- return;
- case 1:
- ;
- }
-
- path = shell->stack->words->word;
- if ((fd=open(path, 1))< 0 && (fd=creat(path, 0666L))<0) {
- pfmt(errio, "%s: ", path);
- Xerror("can't open");
- return;
- }
- lseek(fd, 0L, 2);
- pushredir(Fopen, fd, shell->ip++->i);
- poplist();
-}
-
-void
-Xassign(void)
-{
- Var *v;
- if(count(W0)!=1) {
- Xerror("variable name not singleton");
- return;
- }
- unglob(W0->word);
- v = vlookup(W0->word);
- poplist();
- globlist();
- freelist(v->val);
-
- v->val = W0;
- if(v->update)
- v->update(v);
- W0 = nil;
- poplist();
-}
-
-void
-Xmark(void)
-{
- pushlist();
-}
-
-void
-Xword(void)
-{
- pushword(shell->ip++->s);
-}
-
-void Xasync(void);
-void Xcat(void);
-void Xclose(void);
-void Xcmdsub(void);
-void Xcount(void);
-void Xdol(void);
-void Xdup(void);
-void Xexit(void);
-void Xfalse(void);
-void Xflatten(void);
-void Xfor(void);
-void Xfunc(void);
-void Xglob(void);
-void Xif(void);
-void Xjump(void);
-void Xkill(void);
-void Xlocal(void);
-void Xmark(void);
-void Xmatch(void);
-void Xnegate(void);
-void Xpipe(void);
-void Xpipefd(void);
-void Xpipewait(void);
-void Xpop(void);
-void Xpopredir(void);
-void Xrdwr(void);
-void Xread(void);
-void Xsub(void);
-void Xsimple(void);
-void Xsubshell(void);
-void Xtrue(void);
-void Xunfunc(void);
-void Xunlocal(void);
-void Xword(void);
-void Xwrite(void);
diff --git a/sys/cmd/rc/glob.c b/sys/cmd/rc/glob.c
deleted file mode 100644
index 95b2ef3..0000000
--- a/sys/cmd/rc/glob.c
+++ /dev/null
@@ -1,199 +0,0 @@
-#include "rc.h"
-#include <dirent.h>
-
-static Word *matches;
-static char buffer[6*1024];
-
-// -----------------------------------------------------------------------
-// main exports
-
-void
-unglob(char *s)
-{
- char *t = s;
- do {
- if(*t==GLOB)
- t++;
- *s++ = *t;
- } while(*t++);
-}
-
-/*
- * inspiration from rsc's blog post
- * modified for utf8 sequences and character classes
- * returns 1 if string matches pattern is found, 0 otherwise
- */
-static
-int
-match(char *s, char *p)
-{
- int c, ns, np;
- rune sr, pr, lo, tr, hi;
- char *sb = s, *ss = s, *pp = p;
- while(*s || *p){
- if(*p){
- ns = utf8·bytetorune(&sr, s);
- np = utf8·bytetorune(&pr, p);
-
- if(pr==GLOB){
- np = utf8·bytetorune(&pr, ++p);
- switch(pr){
- case '?': /* single match */
- if(*s){
- p+=np, s+=ns;
- continue;
- }
- case '[': /* class match */
- np = utf8·bytetorune(&pr, ++p);
- if((c = (pr == '~')))
- np = utf8·bytetorune(&pr, ++p);
-
- lo = pr;
- while(lo != ']' && *p){
- utf8·bytetorune(&tr, p+np); /* peek ahead */
- if(tr != '-')
- hi = lo;
- else {
- p += np + 1, np = utf8·bytetorune(&hi, p);
- if(!hi) /* we hit a syntax error */
- return 0;
- if(hi < lo)
- tr = hi, hi = lo, lo = tr;
- }
- if(c ^ (lo<=sr && sr<= hi))
- goto match;
- p += np, np = utf8·bytetorune(&lo, p);
- }
- return 0;
- match:
- while (*p++ != ']' && *p); /* just iterate byte-wise */
- s += ns;
- continue;
- case '*': /* zero-or-more match */
- pp = p-1, ss = s+ns;
- p++;
- continue;
- case GLOB:
- if (sr != GLOB)
- return 0;
- s++, p++;
- continue;
- default:
- panic("unrecognized glob operation", pr);
- }
- }
-
- if (sr==pr){
- s+=ns, p+=np;
- continue;
- }
- }
- /* hit end of pattern with no match, restart at last star */
- if (ss > sb) {
- if (!*ss) /* hit end of string while matching a star */
- return 1;
-
- s = ss, p = pp;
- continue;
- }
- /* mismatch */
- return 0;
- }
- return 1;
-}
-
-static
-void
-globdir(char *p, char *path, int fd)
-{
- DIR *d = nil;
- char *g; /* pattern offset (base of new GLOB) */
- char *b; /* pointer into path */
- int i, j;
- struct dirent *e;
-
- if(!*p) {
- printf("making path %s\n", path);
- matches = newword(buffer, matches);
- return;
- }
-
- if((fd = openat(fd, path[0]?path:".", O_RDONLY|O_CLOEXEC|O_DIRECTORY)) < 0)
- return;
- d = fdopendir(fd);
-
- for(g = p, b = path; *g; b++) {
- if(*g==GLOB)
- break;
- *b=*g++;
- if(*b == '/') {
- *b = 0;
- /* open new directory (close if we have opened another already */
- if ((fd = openat(fd, path, O_RDONLY|O_CLOEXEC|O_DIRECTORY)) < 0)
- goto cleanup;
- closedir(d);
- d = fdopendir(fd);
- *b = '/';
- path = b, p = g;
- }
- }
-
- /* if we are at the end of the pattern, check if name exists */
- if(!*g) {
- *b = 0;
- if(faccessat(fd, path, F_OK, AT_SYMLINK_NOFOLLOW) == 0)
- matches = newword(buffer, matches);
- goto cleanup;
- }
-
- /* we have a non-trivial pattern to match */
- /* partition on the next directory */
- while(*g && *g!='/')
- g++;
-
- if(*g){
- j = 1;
- *g = 0;
- } else
- j = 0;
-
- while((e = readdir(d))) {
- if (e->d_name[0] == '.')
- if (e->d_name[1] == 0 || /* . */
- (e->d_name[1] == '.' && e->d_name[2] == 0)) /* .. */
- continue;
-
- for(i=0;e->d_name[i];i++)
- b[i]=e->d_name[i];
- b[i]=0;
-
- if(match(path, p))
- globdir(g+j, b, fd);
- }
-
- printf("successful\n");
-cleanup:
- printf("cleaning up\n");
- /* NOTE: a successful closedir also closes the file descriptor */
- closedir(d);
- return;
-}
-
-void
-glob(char *p)
-{
- char *path = buffer;
-
- globdir(p, path, AT_FDCWD);
-}
-
-#if 0
-int
-main()
-{
- errio = openfd(2);
- glob("\x01*");
- pval(errio, matches);
- flush(&errio);
-}
-#endif
diff --git a/sys/cmd/rc/io.c b/sys/cmd/rc/io.c
deleted file mode 100644
index e06bfcc..0000000
--- a/sys/cmd/rc/io.c
+++ /dev/null
@@ -1,446 +0,0 @@
-#include "rc.h"
-
-#define c0 t->child[0]
-#define c1 t->child[1]
-#define c2 t->child[2]
-
-#undef bufsize
-#define bufsize 512
-#define strsize 100
-
-//------------------------------------------------------------------------
-// buffer operations
-
-/* open file */
-Io*
-openfd(int fd)
-{
- Io *f;
-
- f = emalloc(sizeof *f + bufsize);
- f->fd = fd;
- f->b = f->e = f->buf;
- return f;
-}
-
-/* open string */
-Io*
-openstr(void)
-{
- Io *f;
-
- f = emalloc(sizeof *f + strsize + 1);
- f->fd = -1;
- f->b = f->buf;
- f->e = f->buf+strsize;
- memset(f->b, 0, strsize+1);
-
- return f;
-}
-
-/* open core (not nil terminated) */
-Io*
-opencore(int len, char *s)
-{
- Io *f;
-
- f = emalloc(sizeof *f + len);
- f->fd = -1;
- f->b = f->buf;
- f->e = f->buf+len;
- memcpy(f->b, s, len);
-
- return f;
-}
-
-void
-rewindio(Io *f)
-{
- if (f->fd < 0)
- f->b = f->buf;
- else {
- f->b = f->e = f->buf;
- lseek(f->fd, 0, 0);
- }
-}
-
-void
-closeio(Io *f)
-{
- if (f->fd >= 0)
- close(f->fd);
-
- efree(f);
-}
-
-/* has the chance to realloc */
-void
-flush(Io **fp)
-{
- int n;
- char *s;
- Io *f;
-
- f = *fp;
- if (f->fd < 0) {
- n = f->e - f->b;
- f = erealloc(f, sizeof *f + n + strsize + 1);
- if (!f)
- panic("can't realloc %d bytes in flush", n+strsize+1);
- f->b = f->buf+n;
- f->e = f->buf+n+strsize;
- memset(f->b, 0, strsize+1);
- } else {
- n = f->b - f->buf;
- if (n && write(f->fd, f->buf, n) < 0) {
- write(3, "write error\n", 12);
- // if (ntrap)
- // dotrap();
- }
- f->b = f->buf;
- f->e = f->buf + bufsize;
- }
-
- *fp = f;
-}
-
-//------------------------------------------------------------------------
-// read from io
-
-int
-rchr(Io *f)
-{
- int n;
- if (f->b == f->e) {
- if (f->fd < 0 || (n = read(f->fd, f->buf, bufsize)) <= 0)
- return EOF;
-
- f->b = f->buf;
- f->e = f->b + n;
- }
-
- return *f->b++&0xFF;
-}
-
-//------------------------------------------------------------------------
-// printf functionality
-
-/* character literal */
-int
-pchr(Io *f, int c)
-{
- if (f->b == f->e)
- flush(&f);
-
- return *f->b++=c;
-}
-
-/* quote */
-void
-pquo(Io *f, char *s)
-{
- pchr(f, '\'');
- for (; *s; s++)
- if (*s == '\'')
- pfmt(f, "''");
- else
- pchr(f, *s);
- pchr(f, '\'');
-}
-
-/* word */
-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);
-}
-
-/* pointer */
-void
-pptr(Io *f, void *v)
-{
- int n;
- uintptr p;
-
- if (!v) {
- pstr(f, "<nil>");
- return;
- }
-
- 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]);
-}
-
-/* string */
-void
-pstr(Io *f, char *s)
-{
- if(!s || !s[0])
- s = "<null>";
-
- while(*s)
- pchr(f, *s++);
-}
-
-/* decimal */
-void
-pdec(Io *f, int n)
-{
- if (n < 0) {
- n = -n;
- pchr(f, '-');
- if (n >= 0) {
- pdec(f, n);
- return;
- }
- n = 1 - n;
- pdec(f, n/10);
- pchr(f, n%10+'1');
- return;
- }
-
- if (n > 9)
- pdec(f, n/10);
- pchr(f, n%10+'0');
-}
-
-/* octal */
-void
-poct(Io *f, uint n)
-{
- if (n > 7)
- poct(f, n>>3);
- pchr(f, (n&7)+'0');
-}
-
-/* value */
-void
-pval(Io *f, Word *a)
-{
- if(a) {
- while(a->link && a->link->word) {
- pwrd(f, a->word);
- pchr(f, ' ');
- a = a->link;
- }
- pwrd(f, a->word);
- }
-}
-
-/* tree */
-static
-void
-pdeglob(Io *f, char *s)
-{
- while(*s){
- if(*s==GLOB)
- s++;
- pchr(f, *s++);
- }
-}
-
-void
-pcmd(Io *f, Tree *t)
-{
- if(!t)
- return;
-
- switch(t->type){
- default: pfmt(f, "bad<%d> %p %p %p", t->type, c0, c1, c2);
- break;
- case Tdol: pfmt(f, "$%t", c0);
- break;
- case Tquote: pfmt(f, "$\"%t", c0);
- break;
- case Tand: pfmt(f, "%t&", c0);
- break;
- case Tcarot: pfmt(f, "%t^%t", c0, c1);
- break;
- case Ttick: pfmt(f, "`%t", c0);
- break;
- case Tandand: pfmt(f, "%t && %t", c0, c1);
- break;
- case Tbang: pfmt(f, "! %t", c0);
- break;
- case Tbrace: pfmt(f, "{%t}", c0);
- break;
- case Tcount: pfmt(f, "$#%t", c0);
- break;
- case Tfunc: pfmt(f, "func %t %t", c0, c1);
- break;
- case Tif: (c2) ? pfmt(f, "if%t%t else %t", c0, c1, c2): pfmt(f, "if%t%t", c0, c1);
- break;
- case Toror: pfmt(f, "%t || %t", c0, c1);
- break;
- case Tpcmd: /* fallthrough */
- case Tparen: pfmt(f, "(%t)", c0);
- break;
- case Tsub: pfmt(f, "$%t(%t)", c0, c1);
- break;
- case Tsimple: pfmt(f, "%t", c0);
- break;
- case Tsubshell: pfmt(f, "@ %t", c0);
- break;
- case Tswitch: pfmt(f, "switch %t %t", c0, c1);
- break;
- case Tcase: pfmt(f, "case %t:\n%t", c0, c1);
- break;
- case Ttwiddle: pfmt(f, "~ %t %t", c0, c1);
- break;
- case Twhile: pfmt(f, "while %t%t", c0, c1);
- break;
- case Targs:
- if(c0==0)
- pfmt(f, "%t", c1);
- else if(c1==0)
- pfmt(f, "%t", c0);
- else
- pfmt(f, "%t %t", c0, c1);
- break;
- case Tsemi:
- if(c0) {
- if(c1)
- pfmt(f, "%t%c%t", c0, '\n', c1);
- else
- pfmt(f, "%t", c0);
- } else
- pfmt(f, "%t", c1);
- break;
- case Twords:
- if(c0)
- pfmt(f, "%t ", c0);
- pfmt(f, "%t", c1);
- break;
- case Tfor:
- pfmt(f, "for(%t", c0);
- if(c1)
- pfmt(f, " in %t", c1);
- pfmt(f, ")%t", c2);
- break;
- case Tword:
- if(t->quoted)
- pfmt(f, "%Q", t->str);
- else
- pdeglob(f, t->str);
- break;
- case Tdup:
- if(t->redir.type==Rdupfd)
- pfmt(f, ">[%d=%d]", t->redir.fd[1], t->redir.fd[0]); /* yes, fd1, then fd0; read lex.c */
- else
- pfmt(f, ">[%d=]", t->redir.fd[0]);
- pfmt(f, "%t", c1);
- break;
- case Tpipefd:
- case Tredir:
- switch(t->redir.type){
- case Rhere:
- pchr(f, '<');
- case Rread:
- case Rrdwr:
- pchr(f, '<');
- if(t->redir.type==Rrdwr)
- pchr(f, '>');
- if(t->redir.fd[0]!=0)
- pfmt(f, "[%d]", t->redir.fd[0]);
- break;
- case Rappend:
- pchr(f, '>');
- case Rwrite:
- pchr(f, '>');
- if(t->redir.fd[0]!=1)
- pfmt(f, "[%d]", t->redir.fd[0]);
- break;
- }
- pfmt(f, "%t", c0);
- if(c1)
- pfmt(f, " %t", c1);
- break;
- case Teq:
- pfmt(f, "%t=%t", c0, c1);
- if(c2)
- pfmt(f, " %t", c2);
- break;
- case Tpipe:
- pfmt(f, "%t|", c0);
- if(t->redir.fd[1]==0){
- if(t->redir.fd[0]!=1)
- pfmt(f, "[%d]", t->redir.fd[0]);
- }
- else pfmt(f, "[%d=%d]", t->redir.fd[0], t->redir.fd[1]);
- pfmt(f, "%t", c1);
- break;
- }
-}
-
-/* rc specific printf */
-static int pfmtlev;
-
-void
-vpfmt(Io *f, char *fmt, va_list args)
-{
- char err[124];
-
- pfmtlev++;
- for (; *fmt; fmt++)
- if (*fmt!='%')
- pchr(f, *fmt);
- else switch(*++fmt) {
- case '\0':
- break;
- case 'c':
- pchr(f, va_arg(args, int));
- break;
- case 'd':
- pdec(f, va_arg(args, int));
- break;
- case 'o':
- poct(f, va_arg(args, uint));
- break;
- case 'p':
- pptr(f, va_arg(args, void*));
- break;
- case 'Q':
- pquo(f, va_arg(args, char*));
- break;
- case 'q':
- pwrd(f, va_arg(args, char*));
- break;
- case 'r':
- pstr(f, strerror(errno));
- break;
- case 's':
- pstr(f, va_arg(args, char*));
- break;
- case 't':
- pcmd(f, va_arg(args, Tree*));
- break;
- case 'v':
- pval(f, va_arg(args, Word*));
- break;
- }
-
- if (--pfmtlev==0)
- flush(&f);
-}
-
-void
-pfmt(Io *f, char *fmt, ...)
-{
- va_list args;
- char err[124];
-
- va_start(args, fmt);
- vpfmt(f, fmt, args);
- va_end(args);
-}
diff --git a/sys/cmd/rc/lex.c b/sys/cmd/rc/lex.c
deleted file mode 100644
index f6e2b4e..0000000
--- a/sys/cmd/rc/lex.c
+++ /dev/null
@@ -1,417 +0,0 @@
-#include "rc.h"
-
-#define onebyte(c) ((c&0x80)==0x00)
-#define twobyte(c) ((c&0xe0)==0xc0)
-#define threebyte(c) ((c&0xf0)==0xe0)
-#define fourbyte(c) ((c&0xf8)==0xf0)
-
-// -----------------------------------------------------------------------
-// globals
-
-static int lastc, nextc=EOF, lastdol, lastword, doprompt = 1;
-static char buf[8*1024];
-
-// -----------------------------------------------------------------------
-// utilities
-
-static uchar nwordc[256] =
-{
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-int
-wordchr(int c)
-{
- return !nwordc[c] && c!=EOF;
-}
-
-
-static uchar nquotec[256] =
-{
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-int
-quotechr(char c)
-{
- return !nquotec[c] && c!=EOF;
-}
-
-static uchar nvarc[256] =
-{
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
- 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-
-int
-varchr(char c)
-{
- return !nvarc[c] && c!=EOF;
-}
-
-static
-void
-prompt(void)
-{
- shell->cmd.line++;
- doprompt = 0;
-}
-
-/* lookahead one byte */
-static
-int
-lookahead(void)
-{
- int c;
-
- if(nextc != EOF)
- return nextc;
- if(shell->cmd.eof)
- return EOF;
-
- if(doprompt)
- prompt();
-
- c = rchr(shell->cmd.io);
- doprompt = c == '\n' || c == EOF;
-
- if(c == EOF)
- shell->cmd.eof++;
-
- return nextc = c;
-}
-
-/* consumes the lookahead */
-static
-int
-advance(void)
-{
- int c = lookahead();
- lastc = nextc, nextc = EOF;
-
- return c;
-}
-
-/*
- * advance until we no longer hit horizontal space
- * consumes all comments
- */
-static
-void
-skipws(void)
-{
- int c;
- for(;;) {
- c = lookahead();
- if(c=='#'){
- for(;;){
- c = lookahead();
- if(c=='\n' || c==EOF)
- break;
- advance();
- }
- }
- if(c==' ' || c=='\t')
- advance();
- else
- return;
- }
-}
-
-/* advance until we no longer hit any space */
-void
-skipnl(void)
-{
- int c;
- for(;;) {
- skipws();
- if ((c = lookahead()) != '\n')
- return;
- advance();
- }
-}
-
-/* advance if next char is equal to c */
-static
-int
-nextis(int c)
-{
- if(lookahead()==c) {
- advance();
- return 1;
- }
- return 0;
-}
-
-/* functions to append to our write buffer */
-static
-char*
-putbyte(char *s, int c)
-{
- if(!s)
- return s;
- if(s == arrend(buf)){
- *s = 0;
- rcerror("out of buffer space");
- return nil;
- }
- *s++ = c;
- return s;
-}
-
-static
-char*
-putrune(char *s, int c)
-{
- s = putbyte(s, c);
- if (onebyte(c))
- return s;
- if (twobyte(c))
- return putbyte(s, advance());
- if (threebyte(c)) {
- putbyte(s, advance());
- return putbyte(s, advance());
- }
- if (fourbyte(c)) {
- putbyte(s, advance());
- putbyte(s, advance());
- return putbyte(s, advance());
- }
- rcerror("malformed utf8 stream");
- return nil;
-}
-
-// -----------------------------------------------------------------------
-// main exports
-
-void
-rcerror(char *fmt, ...)
-{
- va_list args;
-
- pfmt(errio, "rc:");
- if (shell->cmd.io)
- pfmt(errio, "%s:%d ", shell->cmd.name, shell->cmd.line);
-
- va_start(args, fmt);
- vpfmt(errio, fmt, args);
- va_end(args);
-
- pfmt(errio, "\n");
-
- flush(&errio);
- lastword = lastdol = 0;
- while (lastc != '\n' && lastc != EOF)
- advance();
- /* for debugging only */
- abort();
-}
-
-/* word is only modified in the event of a lexed word */
-int
-lex(Tree **node)
-{
- int c;
- char *w = buf;
- /*
- * NOTE:
- * we inject tokens into the lexer based on context if last token = word:
- * if we see a (, then we interpret that as a subscript
- * otherwise, if the next character is the first char of a word, we return a ^ operator.
- */
- if(lastword){
- lastword=0;
- c = lookahead();
- if(c=='('){
- advance();
- return Tlparen;
- }
- if(quotechr(c))
- return Tcarot;
- }
-
- skipws();
- switch(c=advance()) {
- case EOF:
- lastdol = 0;
- return EOF;
- case '$':
- lastdol = 1;
- if(nextis('#'))
- return Tcount;
- if (nextis('"'))
- return Tquote;
- return Tdol;
- case '&':
- lastdol = 0;
- if(nextis('&'))
- return Tandand;
- return Tand;
-
- case '!':
- return Tbang;
- case '@':
- return Tsubshell;
- case '~':
- return Ttwiddle;
-
- case '|':
- lastdol = 0;
- if(nextis('|')){
- skipnl();
- return Toror;
- }
- (*node) = newtree();
- (*node)->type = Tpipe;
- (*node)->redir.fd[0] = 0;
- (*node)->redir.fd[1] = 1;
- goto redir;
- case '>':
- (*node) = newtree();
- (*node)->type = Tredir;
- if (nextis(c))
- (*node)->redir.type = Rappend;
- else
- (*node)->redir.type = Rwrite;
- (*node)->redir.fd[0] = 1;
- goto redir;
- case '<':
- (*node) = newtree();
- (*node)->type = Tredir;
- if(nextis(c))
- (*node)->redir.type = Rhere;
- else if(nextis('>'))
- (*node)->redir.type = Rrdwr;
- else
- (*node)->redir.type = Rread;
- (*node)->redir.fd[0] = 0;
- /* fallthrough */
- redir:
- if(nextis('[')) {
- c = advance();
- if(c < '0' || '9' < c) {
- redirerr:
- rcerror("incorrect redirection syntax");
- return EOF;
- }
- (*node)->redir.fd[0] = 0;
- do {
- (*node)->redir.fd[0] = 10*(*node)->redir.fd[0]+(c-'0');
- c = advance();
- } while('0'<=c && c<='9');
-
- if(c == '=') {
- if((*node)->type == Tredir)
- (*node)->type = Tdup;
- c = advance();
- if('0'<=c && c<='9') {
- (*node)->redir.type = Rdupfd;
- (*node)->redir.fd[1] = (*node)->redir.fd[0];
- (*node)->redir.fd[0] = 0;
- do {
- (*node)->redir.fd[0] = 10*(*node)->redir.fd[0]+(c-'0');
- c = advance();
- } while('0'<=c && c<='9');
- } else {
- if((*node)->type == Tpipe)
- goto redirerr;
- (*node)->redir.type = Rclose;
- }
- }
- if (c != ']'
- ||(*node)->type==Tdup && ((*node)->redir.type==Rhere || (*node)->redir.type==Rappend))
- goto redirerr;
- }
- if ((c = ((*node)->type)) == Tpipe)
- skipnl();
- return c;
-
- case '\'':
- lastdol = 0;
- lastword = 1;
- for(;;){
- c = advance();
- if(c==EOF)
- break;
- if(c=='\''){
- if(lookahead()!='\'')
- break;
- advance();
- }
- w = putrune(w, c);
- }
- *w = 0;
- *node = wordnode(buf);
- (*node)->quoted = 1;
- return Tword;
- }
- if (!wordchr(c)) {
- lastdol = 0;
- return c;
- }
- for(;;){
- if(c=='*'||c=='['||c=='?'||c==GLOB)
- w = putbyte(w, GLOB);
- w = putrune(w, c);
- c = lookahead();
- if(lastdol?!varchr(c):!wordchr(c))
- break;
- advance();
- }
- *w = 0;
-
- if ((c = kwlookup(buf)) == -1) {
- (*node) = wordnode(buf);
- (*node)->type = c = Tword;
- (*node)->quoted = 0;
- lastword = 1;
- }
-
- lastdol = 0;
- return c;
-}
diff --git a/sys/cmd/rc/main.c b/sys/cmd/rc/main.c
deleted file mode 100644
index b4a355e..0000000
--- a/sys/cmd/rc/main.c
+++ /dev/null
@@ -1,86 +0,0 @@
-#include "rc.h"
-
-/* globals */
-Thread *shell = nil;
-int ntrap = 0;
-Io *errio;
-
-/* main execution */
-
-void
-dotrap(void)
-{
- exit(1);
-}
-
-void
-bootup(Code *c, int off, Var *vars)
-{
- Thread *sh;
-
- alloc(sh);
- sh->code = c, c->i++;
- sh->ip = sh->code + off;
- sh->local = vars;
- sh->stack = nil;
-
- sh->link = shell, shell = sh;
-}
-
-int
-main(int argc, char *argv[])
-{
- int i;
- Code *ip, sh[32];
-
- ARGBEGIN {
- } ARGEND;
-
- errio = openfd(2);
-
- initkw();
-
- ip = sh;
- memset(sh, 0, sizeof(sh));
- /*
- * NOTE: first element of code is a reference count
- * bootup runs:
- * 1. *=argv[1:]
- * 2. . rcmain $*
- */
-#if 0
- ip++->i = 1;
- ip++->f = Xmark;
- ip++->f = Xword;
- ip++->s = "*";
- ip++->f = Xassign;
- ip++->f = Xmark;
- ip++->f = Xmark;
- ip++->s = "*";
- ip++->f = Xdol;
- ip++->s = "rcmain";
- ip++->f = Xword;
- ip++->s = ".";
- ip++->f = Xsimple;
- ip++->f = Xexit;
- ip++->i = 0;
-
- bootup(sh, 1, nil);
- pushlist();
- for (i = argc-1; i != 0; i--)
- pushword(argv[i]);
-
- for (;;) {
- shell->ip++->f();
- if (ntrap)
- dotrap();
- }
-#else
- bootup(sh, 1, nil);
- shell->cmd.io = openfd(0);
- while (parse())
- ;
-
-#endif
- exit(0);
-}
diff --git a/sys/cmd/rc/parse.c b/sys/cmd/rc/parse.c
deleted file mode 100644
index b61ac3c..0000000
--- a/sys/cmd/rc/parse.c
+++ /dev/null
@@ -1,496 +0,0 @@
-#include "rc.h"
-
-/* TODO: better error messages */
-
-// -----------------------------------------------------------------------
-// global data
-
-static int lastt, nextt=EOF;
-static Tree *node; /* if token was lexed as a tree node (redirs and words), its here */
-
-/* anything that is not listed will automatically terminate parsing the given command */
-static uchar prectab[256] = {
- [Tif] = 1, [Tfor] = 1, [Tswitch] = 1, /* NOTE: we give else lower precedence than if [Telse] = 1, */
- [Tandand] = 2, [Toror] = 2,
- [Tbang] = 3, [Tsubshell] = 3,
- [Tpipe] = 4,
- [Tcarot] = 5,
- [Tdol] = 6, [Tcount] = 6, [Tquote] = 6,
- [Tsub] = 7,
-};
-
-// -----------------------------------------------------------------------
-// helpers
-
-static
-int
-lookahead(void)
-{
- int tok;
-
- if (nextt != EOF)
- return nextt;
-
- tok = lex(&node);
- return nextt = tok;
-}
-
-static
-int
-advance(void)
-{
- int tok = lookahead();
- lastt = nextt, nextt = EOF;
- node = nil;
-
- return tok;
-}
-
-static
-int
-nextis(int tok)
-{
- if (lookahead() == tok) {
- advance();
- return 1;
- }
- return 0;
-}
-
-// -----------------------------------------------------------------------
-// subparsers
-
-/* forward declarations */
-static Tree *word(void);
-static Tree *words(void);
-static Tree* body(int c);
-static Tree *comword(void);
-static Tree *cmd(int prec);
-
-/* implementations */
-
-/*
- * TODO:
- * i don't like all this branching.
- * think of a better way
- */
-
-static
-Tree*
-case_or_cmd(int c)
-{
- Tree *t;
- if (!c || !nextis(Tcase))
- return cmd(1);
-
- t = words();
- if (!nextis(';') && !nextis('\n'))
- rcerror("case: missing terminator: recieved %d", nextt);
-
- t = tree2(Tcase, t, body(0));
- pfmt(errio, "%t\n", t);
-
- return t;
-}
-
-static
-Tree*
-body(int c)
-{
- int tok;
- Tree *l, *r;
-
- skipnl();
- l = case_or_cmd(c);
-loop:
- switch((tok=lookahead())){
- case '&':
- l = tree1('&', l);
- /* fallthrough */
- case ';': case '\n':
- advance();
- /* fallthrough */
- case Tcase:
- if ((r = case_or_cmd(c))) {
- l = tree2(';', l, r);
- goto loop;
- }
- /* fallthrough */
- default:
- ;
- }
-
- return l;
-}
-
-static
-Tree*
-brace(int c)
-{
- Tree *t;
-
- if (!nextis('{'))
- rcerror("brace: expected { found: %c", nextt);
- t = tree1(Tbrace, body(c));
- if (!nextis('}'))
- rcerror("brace: expected } found: %c", nextt);
-
- return t;
-}
-
-static
-Tree*
-paren(void)
-{
- Tree *t;
-
- if (!nextis('('))
- rcerror("not a paren");
- t = tree1(Tparen, body(0));
- if (!nextis(')'))
- rcerror("unmatched paren");
-
- return t;
-}
-
-/* TODO: fill in */
-static
-Tree*
-heredoc(Tree* t)
-{
- return t;
-}
-
-static
-Tree*
-redir(void)
-{
- int tok;
- Tree *t;
-
- switch (tok = lookahead()) {
- case Tdup:
- t = node;
- advance();
- break;
- case Tredir:
- t = node;
- advance();
- t = hang1(t, (t->redir.type == Rhere) ? heredoc(word()) : word());
- break;
- default:
- t = nil;
- }
-
- return t;
-}
-
-static
-Tree*
-epilog(void)
-{
- Tree *t, *tt;
-
- t = redir();
- while((tt = redir()))
- t = hang2(t, t->child[0], tt);
-
- return t;
-}
-
-static
-Tree*
-sword(void)
-{
- int tok;
- if (Kstart < (tok=lookahead()) && tok < Kend)
- return node;
-
- return comword();
-}
-
-static
-Tree*
-word(void)
-{
- int tok;
- Tree *t;
-
- t = sword();
- while(nextis('^'))
- t = tree2('^', t, sword());
-
- return t;
-}
-
-
-static
-Tree*
-words(void)
-{
- Tree *t, *tt;
- t = word();
- while((tt=word()))
- t = tree2(Twords, t, tt);
-
- return t;
-}
-
-/*
- * NOTE: we divergence from Duff's yacc grammar here.
- * he has [dol|count|"]->word, we have [dol|count]->sword
- * calling sword ensures we don't cat strings
- * this was done in Tom's version by setting precedence
- */
-static
-Tree*
-comword(void)
-{
- int tok;
- Tree *t, *tt;
-
- switch(tok=lookahead()){
- case Tdol:
- advance();
- t = sword();
- if(nextis('(')) {
- t = tree2(Tsub, t, words());
- if (!nextis(')'))
- rcerror("malformed index expression");
- }
- return tree1(Tdol, t);
- case Tquote:
- return tree1(Tquote, sword());
- case Tcount:
- advance();
- return tree1(Tcount, sword());
- case Ttick:
- advance();
- return tree1(Ttick, brace(0));
- case Tlparen:
- return paren();
- case Tredir:
- advance();
- t = hang1(node, brace(0));
- t->type = Tpipefd;
- return t;
- case Tword:
- t = node;
- advance();
- return t;
- }
- return nil;
-}
-
-static
-Tree*
-first(void)
-{
- int tok;
- Tree *t;
-
- t = comword();
- while(nextis('^')) {
- t = tree2('^', t, word());
- }
-
- return t;
-}
-
-/* simple _or_ assignment */
-static
-Tree*
-simple_or_assign(void)
-{
- int tok;
- Tree *t, *tt;
-
- /* can't continue */
- if (!(t = first()))
- return nil;
-
- /* is an assignment */
-assign:
- if(nextis('=')) {
- tt = word();
- return tree3(Teq, t, tt, cmd(prectab[Tbang]));
- }
-
- /* is a 'simple' */
-simple:
- switch ((tok=lookahead())) {
- case Tredir:
- case Tdup:
- t = tree2(Targs, t, redir());
- goto simple;
- default:
- if ((tt = word())) {
- t = tree2(Targs, t, tt);
- goto simple;
- }
- /* fallthrough */
- }
-
- return simplehang(t);
-}
-
-static
-Tree*
-opand(void)
-{
- int tok;
- Tree *t, *tt;
-
- switch(tok=lookahead()) {
- case Tif:
- advance();
- t = paren();
- skipnl();
- tt = cmd(prectab[Tif]);
- if (nextis(Telse)) {
- skipnl();
- t = tree3(Tif, t, tt, cmd(prectab[Tif]));
- } else
- t = tree3(Tif, t, tt, nil);
- return t;
- case Telse:
- rcerror("invalid hanging else");
- break;
-
- case Tswitch:
- advance();
- t = word();
- skipnl();
- tt = brace(1);
- t = tree2(Tswitch, t, tt);
- return t;
-
- case Tfor:
- advance();
-
- if (!nextis('('))
- rcerror("for: missing opening paren");
- t = word();
- if (nextis(Tin)) {
- advance();
- tt = words();
- t = tree3(Tfor, t, tt, nil);
- } else
- t = tree3(Tfor, t, nil, nil);
- if (!nextis(')'))
- rcerror("for: missing closing paren");
-
- skipnl();
- tt = cmd(prectab[Tfor]);
- t->child[2] = tt;
- return t;
-
- case Twhile:
- advance();
- t = paren();
- skipnl();
- tt = cmd(1);
- return tree2(Twhile, t, tt);
-
- case Tfunc:
- advance();
- t = words();
- if ((tok=lookahead()) == '{') {
- tt = brace(0);
- t = tree2(Tfunc, t, tt);
- } else
- t = tree1(Tfunc, t);
- return t;
-
- case Tsubshell:
- advance();
- t = tree1(Tsubshell, cmd(prectab[Tsubshell]));
- return t;
-
- case Tbang:
- advance();
- t = tree1(Tbang, cmd(prectab[Tbang]));
- return t;
-
- case Ttwiddle:
- advance();
- tt = word();
- t = tree2(Ttwiddle, tt, words());
- return t;
-
- case Tlbrace:
- t = brace(0);
- tt = epilog();
- return epihang(t, tt);
-
- case Tredir: /* fallthrough */
- case Tdup:
- t = redir();
- tt = cmd(prectab[Tbang]);
- t = hang2(t, t->child[0], tt);
- return t;
- }
-
- return simple_or_assign();
-}
-
-static
-Tree *
-cmd(int prec)
-{
- int np, tok;
- Tree *l, *r, *p;
-
- if (!(l = opand()))
- return nil;
-
- for(;;) {
- tok = lookahead();
- np = prectab[tok];
- if (np < prec)
- break;
- p = node;
- advance();
- r = cmd(np+1);
- if (tok == Tpipe)
- l = hang2(p, l, r);
- else
- l = tree2(tok, l, r);
- }
-
- return l;
-}
-
-// -----------------------------------------------------------------------
-// main function
-
-int
-parse(void)
-{
- int tok;
- Tree *t, *tt;
-
- t = cmd(1);
-loop:
- switch(tok=lookahead()) {
- case '&':
- t = tree1('&', t);
- /* fallthrough */
- case ';':
- advance();
- tt = cmd(1);
- t = tree2(';', t, tt);
- goto loop;
- case '\n':
- advance();
- case EOF:
- pfmt(errio, "%t\n", t);
- break;
- default:
- if (tok > 0x20)
- rcerror("unrecognized token: %c[%d]", tok, tok);
- else
- rcerror("unrecognized token: %d", tok, tok);
- }
- return tok != EOF;
-}
diff --git a/sys/cmd/rc/rc.h b/sys/cmd/rc/rc.h
deleted file mode 100644
index f32a737..0000000
--- a/sys/cmd/rc/rc.h
+++ /dev/null
@@ -1,312 +0,0 @@
-#pragma once
-
-#include <u.h>
-#include <libn.h>
-
-#include <errno.h>
-#include <sys/wait.h>
-
-#define alloc(ptr) ptr = emalloc(sizeof(*ptr))
-
-// -----------------------------------------------------------------------
-// main enums
-
-#define GLOB 0x01
-
-enum
-{
- /* keywords */
- Kstart = 11,
- Tfor, Tin, Twhile, Tif, Telse,
- Tswitch, Tcase, Tfunc, Ttwiddle,
- Tbang, Tsubshell,
- Kend,
-
- /* tokens */
- Tword='w', Tredir='r', Tdup='d', Tsimple='s',
- Targs='A', Twords='W', Tbrace='b', Tparen='p', Tsub='S',
- Tpcmd='c', Tpipefd='-', Tandand='%', Toror='@', Tcount='#',
-
- Ttick='`', Tpipe = '|', Tdol='$', Tquote='"', Tand='&',
- Tlparen = '(', Trparen = ')', Tlbrace='{', Trbrace='}',
- Tsemi=';', Tcarot='^', Teq='=',
-};
-
-enum
-{
- Rappend = 1,
- Rwrite = 2,
- Rread = 3,
- Rhere = 4,
- Rdupfd = 5,
- Rclose = 6,
- Rrdwr = 7,
-};
-
-enum
-{
- Fopen = 1,
- Fdup = 2,
- Fclose = 3,
-};
-
-// -----------------------------------------------------------------------
-// main types
-
-typedef union Code Code;
-typedef struct Word Word;
-typedef struct List List;
-typedef struct Var Var;
-typedef struct Redir Redir;
-typedef struct Tree Tree;
-typedef struct Builtin Builtin;
-typedef struct Thread Thread;
-typedef struct Io Io;
-
-union Code
-{
- int i;
- char *s;
- void (*f)(void);
-};
-
-struct Word
-{
- char *word;
- Word *link;
-};
-
-struct List
-{
- Word *words;
- List *link;
-};
-
-struct Redir
-{
- uchar type;
- short from, to;
- Redir *link;
-};
-
-struct Var
-{
- string name;
- Word *val;
- struct {
- Code *func, *ip;
- uint funcnew : 1;
- };
- struct {
- uint new : 1;
- void (*update)(Var*);
- };
- Var *link;
-};
-
-struct Tree
-{
- ushort type;
- uchar quoted : 1;
- union {
- char *str;
- struct {
- ushort type;
- int fd[2];
- } redir;
- };
-
- Tree *child[3], *link;
-};
-
-struct Builtin
-{
- char *cmd;
- void (*func)(void);
-};
-
-struct Thread
-{
- Code *code, *ip;
- List *stack;
- Redir *redir, *root;
- Var *local;
- uchar interactive : 1;
- struct {
- uchar eof : 1;
- int line;
- char *name;
- Io *io;
- } cmd;
-
- int pid;
- Tree *nodes;
- Thread *link; /* continuation */
-};
-
-struct Io
-{
- int fd;
- uchar *b, *e, buf[];
-};
-
-// -----------------------------------------------------------------------
-// global interpreter variables
-
-extern Thread *shell;
-extern int ntrap;
-extern int status;
-
-extern Io *errio;
-
-extern Builtin builtins[];
-extern Var *globals[1021]; /* for now must be prime */
-
-// -----------------------------------------------------------------------
-// interpreter functions (defined in exec.c)
-
-/*
- * notation:
- * (var1, var2, ...) : items from stack
- * [var1, var2, ...] : items from code stream
- * {var1, var2, ...} : jump block from code stream
- * -> moves value (stack) [code stream]
- */
-extern void Xappend(void); /* Xappend(file)[fd]: open file to append */
-extern void Xassign(void); /* Xassign(name, val): assign name to val */
-extern void Xasync(void); /* Xasync(cmd): run command asynchronously */
-extern void Xcat(void); /* Xcat(list1, list2): concatenate strings */
-extern void Xclose(void); /* Xclose[fd]: close file descriptor */
-extern void Xcmdsub(void); /* Xcmdsub(cmd): use output of command as input to other */
-extern void Xcount(void); /* Xcount(name) -> (number): count items in list*/
-extern void Xdol(void); /* Xdol(name): get variable value */
-extern void Xdup(void); /* Xdup[i, j]: duplicate file descriptor */
-extern void Xexit(void); /* Xexit: exit with status */
-extern void Xfalse(void); /* Xfalse{...}: run only if $status=1 */
-extern void Xflatten(void); /* Xflatten(list) -> (string): flatten list */
-extern void Xfor(void); /* Xfor(list): flatten list */
-extern void Xfunc(void); /* Xfunc(name){... Xreturn}: define function */
-extern void Xglob(void); /* Xglob(list): globs value */
-extern void Xif(void); /* Xif: execute if $status */
-extern void Xjump(void); /* Xjump[addr]: jump to address */
-extern void Xkill(void); /* Xkill kill thread */
-extern void Xlocal(void); /* Xlocal(name, val): define local variable */
-extern void Xmark(void); /* Xmark: delimit stack with new list */
-extern void Xmatch(void); /* Xmatch(pat, str): sets status with result */
-extern void Xnegate(void); /* Xnegate: negate condition */
-extern void Xpipe(void); /* Xpipe[i j]{... Xkill}{... Xkill}: construct a pipe between 2 threads*/
-extern void Xpipefd(void); /* Xpipe[type]{... Xkill}: connect {} to a pipe */
-extern void Xpipewait(void); /* Xpipewait: wait on a pipe */
-extern void Xpop(void); /* Xpop(value): pops value from stack */
-extern void Xpopredir(void); /* Xpopredir(value): pops redir from redir stack */
-extern void Xrdwr(void); /* Xrdwr(file)[fd]: open file for reads/writes */
-extern void Xread(void); /* Xread(file)[fd]: open file for reads */
-extern void Xsub(void); /* Xsub(list, index): subscript list */
-extern void Xsimple(void); /* Xsimple(args): run command */
-extern void Xsubshell(void); /* Xsubshell(args): run command in a subshell */
-extern void Xtrue(void); /* Xtrue{...}: run only if $status=0 */
-extern void Xunfunc(void); /* Xunfunc(name) undefine function */
-extern void Xunlocal(void); /* Xunlocal(name) undefine local */
-extern void Xword(void); /* Xword[val] -> (val) */
-extern void Xwrite(void); /* Xwrite(file)[fd]: open file to write */
-
-extern void Xerror(char *s); /* Xerror report an error */
-
-// -----------------------------------------------------------------------
-// shell functions
-
-/*
- * util.c
- */
-void *emalloc(uintptr size);
-void *erealloc(void *ptr, uintptr size);
-void efree(void *);
-void panic(char *msg, int n);
-
-/*
- * io.c
- */
-Io *openfd(int fd);
-Io *openstr(void);
-Io *opencore(int len, char *s);
-void rewindio(Io *f);
-void closeio(Io *f);
-void flush(Io **fp);
-
-/* reads */
-int rchr(Io *f);
-
-/* writes */
-int pchr(Io *f, int c);
-void pquo(Io *f, char *s);
-void pwrd(Io *f, char *s);
-void pptr(Io *f, void *v);
-void pstr(Io *f, char *s);
-void pdec(Io *f, int n);
-void poct(Io *f, uint n);
-void pval(Io *f, Word *a);
-void pcmd(Io *f, Tree *t);
-void pfmt(Io *f, char *fmt, ...);
-void vpfmt(Io *f, char *fmt, va_list args);
-
-/*
- * word.c
- */
-void pushlist(void);
-void freelist(Word *w);
-void poplist(void);
-
-int count(Word *w);
-Word *newword(char *w, Word *link);
-void pushword(char *w);
-
-/*
- * tree.c
- */
-
-Tree *newtree(void);
-void freetree(Tree *t);
-Tree *tree3(int type, Tree *c0, Tree *c1, Tree *c2);
-Tree *tree2(int type, Tree *c0, Tree *c1);
-Tree *tree1(int type, Tree *c0);
-
-Tree *hang1(Tree *p, Tree *c0);
-Tree *hang2(Tree *p, Tree *c0, Tree *c1);
-Tree *hang3(Tree *p, Tree *c0, Tree *c1, Tree *c2);
-Tree *epihang(Tree *c, Tree *epi);
-Tree *simplehang(Tree *t);
-Tree *wordnode(char *w);
-
-/*
- * var.c
- */
-
-Var *newvar(char *name, Var *link);
-Var *gvlookup(char *name);
-Var *vlookup(char *name);
-void setvar(char *name, Word *val);
-
-int kwlookup(char *name);
-void initkw(void);
-
-/*
- * lex.c
- */
-
-void skipnl(void);
-int wordchr(int c);
-
-void rcerror(char *msg, ...);
-int lex(Tree **node);
-
-/*
- * parse.c
- */
-
-int parse(void);
-
-/*
- * main.c
- */
-
-void dotrap(void);
diff --git a/sys/cmd/rc/rules.mk b/sys/cmd/rc/rules.mk
deleted file mode 100644
index 654a44e..0000000
--- a/sys/cmd/rc/rules.mk
+++ /dev/null
@@ -1,22 +0,0 @@
-include share/push.mk
-
-# Local sources
-SRCS_$(d) := \
- $(d)/glob.c \
- $(d)/word.c \
- $(d)/util.c \
- $(d)/io.c \
- $(d)/var.c \
- $(d)/tree.c \
- $(d)/lex.c \
- $(d)/parse.c \
- $(d)/main.c
-BINS_$(d) := $(d)/rc
-
-include share/paths.mk
-
-# Local rules
-$(BINS_$(d)): $(OBJS_$(d)) $(OBJ_DIR)/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 f934aa1..0000000
--- a/sys/cmd/rc/simple.c
+++ /dev/null
@@ -1,13 +0,0 @@
-void
-Xsimple(void)
-{
- Word *a;
- Var *v;
-
- a = shell->stack->words;
- if (!a) {
- Xerror("empty argument list");
- return;
- }
- v = vlookup(a->word);
-}
diff --git a/sys/cmd/rc/tree.c b/sys/cmd/rc/tree.c
deleted file mode 100644
index 14049e5..0000000
--- a/sys/cmd/rc/tree.c
+++ /dev/null
@@ -1,144 +0,0 @@
-#include "rc.h"
-
-// -----------------------------------------------------------------------
-// globals
-
-static Tree *nodes;
-
-// -----------------------------------------------------------------------
-// exported funcs
-
-Tree*
-newtree(void)
-{
- Tree *t;
-
- alloc(t);
- t->str = nil;
- t->child[0] = t->child[1] = t->child[2] = nil;
- t->redir.fd[0] = t->redir.fd[1] = t->redir.type = 0;
-
- t->link = nodes, nodes = t;
- return t;
-}
-
-void
-freetree(Tree *t)
-{
- if (!t)
- return;
-
- freetree(t->child[0]);
- freetree(t->child[1]);
- freetree(t->child[2]);
-
- if (t->str)
- efree(t->str);
- efree(t);
-}
-
-void
-freenodes(void)
-{
- Tree *t, *u;
-
- for (t = nodes;t;t = u) {
- u = t->link;
- if (t->str)
- efree(t->str);
- efree(t);
- }
- nodes = nil;
-}
-
-/* tree creation */
-Tree*
-tree3(int type, Tree *c0, Tree *c1, Tree *c2)
-{
- Tree *t;
-
- t = newtree();
- t->type = type;
- t->child[0] = c0;
- t->child[1] = c1;
- t->child[2] = c2;
-
- return t;
-}
-
-Tree*
-tree2(int type, Tree *c0, Tree *c1)
-{
- return tree3(type, c0, c1, nil);
-}
-
-Tree*
-tree1(int type, Tree *c0)
-{
- return tree3(type, c0, nil, nil);
-}
-
-/* tree hang */
-Tree*
-hang1(Tree *p, Tree *c0)
-{
- p->child[0] = c0;
- return p;
-}
-
-Tree*
-hang2(Tree *p, Tree *c0, Tree *c1)
-{
- p->child[0] = c0;
- p->child[1] = c1;
- return p;
-}
-
-Tree*
-hang3(Tree *p, Tree *c0, Tree *c1, Tree *c2)
-{
- p->child[0] = c0;
- p->child[1] = c1;
- p->child[2] = c2;
- return p;
-}
-
-/* hangs the cmd underneath the epilogue */
-Tree*
-epihang(Tree *c, Tree *epi)
-{
- Tree *p;
- if(!epi)
- return c;
- for(p=epi;p->child[1];p = p->child[1])
- ;
- p->child[1] = c;
- return epi;
-}
-
-/* hangs tree t from a new simple node. percolates redirections to root */
-Tree*
-simplehang(Tree *t)
-{
- Tree *u;
- t = tree1(Tsimple, t);
- for(u = t->child[0];u->type==Targs;u=u->child[0]) {
- if (u->child[1]->type==Tdup
- || u->child[1]->type==Tredir){
- u->child[1]->child[1] = t;
- t = u->child[1];
- u->child[1] = nil;
- }
- }
- return t;
-}
-
-Tree*
-wordnode(char *w)
-{
- Tree *t = newtree();
- t->type = Tword;
- t->str = strdup(w);
-
- return t;
-}
diff --git a/sys/cmd/rc/util.c b/sys/cmd/rc/util.c
deleted file mode 100644
index 02b3611..0000000
--- a/sys/cmd/rc/util.c
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "rc.h"
-
-void *
-emalloc(uintptr n)
-{
- void *p = malloc(n);
- if (!p)
- panic("can't malloc %d bytes", n);
-
- return p;
-}
-
-void *
-erealloc(void *p, uintptr n)
-{
- void *new = realloc(p, n);
- if (!new)
- panic("can't realloc %d bytes", n);
-
- return new;
-}
-
-void
-efree(void *p)
-{
- if (p)
- free(p);
- else
- pfmt(errio, "free <nil>\n");
-}
-
-void
-panic(char *s, int n)
-{
- pfmt(errio, "rc: ");
- pfmt(errio, s, n);
- pchr(errio, '\n');
- flush(&errio);
- abort();
-}
diff --git a/sys/cmd/rc/var.c b/sys/cmd/rc/var.c
deleted file mode 100644
index d442369..0000000
--- a/sys/cmd/rc/var.c
+++ /dev/null
@@ -1,129 +0,0 @@
-#include "rc.h"
-
-Var *globals[1021] = { 0 };
-
-struct Keyword {
- ushort type;
- char *name;
- struct Keyword *link;
-} *keywords[41];
-
-// -----------------------------------------------------------------------
-// utility
-
-static
-int
-hash(char *s, int n)
-{
- int i = 1, h = 0;
- while (*s)
- h += *s++*i++;
- h %= n;
- return (h<0)?h+n:h;
-}
-
-// -----------------------------------------------------------------------
-// keywords
-
-static
-void
-putkw(int type, char *name)
-{
- struct Keyword *kw;
- int h = hash(name, arrlen(keywords));
-
- alloc(kw);
- kw->type = type;
- kw->name = name;
- kw->link = keywords[h];
-
- keywords[h] = kw;
-}
-
-void
-initkw(void)
-{
- putkw(Tfor, "for");
- putkw(Tin, "in");
- putkw(Twhile, "while");
- putkw(Tif, "if");
- putkw(Telse, "else");
- putkw(Tswitch, "switch");
- putkw(Tcase, "case");
- putkw(Tfunc, "func");
-}
-
-int
-kwlookup(char *name)
-{
- int t;
- struct Keyword *it;
- for(t=-1,it = keywords[hash(name, arrlen(keywords))];it;it = it->link)
- if(!strcmp(it->name, name))
- t = it->type;
- return t;
-}
-
-// -----------------------------------------------------------------------
-// variables
-
-Var *
-newvar(char *name, Var *link)
-{
- Var *v;
-
- alloc(v);
- v->name = name;
- v->val = 0;
- v->func = nil;
- v->funcnew = 0;
- v->new = 0;
- v->update = nil;
- v->link = link;
-
- return v;
-}
-
-/* only global lookup */
-
-Var *
-gvlookup(char *name)
-{
- Var *v;
- int h = hash(name, arrlen(globals));
- for (v = globals[h]; v; v = v->link)
- if (!strcmp(v->name, name))
- return v;
-
- return globals[h] = newvar(strdup(name), globals[h]);
-}
-
-/* local + global lookup */
-Var *
-vlookup(char *name)
-{
- Var *v;
- if (shell)
- for (v = shell->local; v; v = v->link)
- if (!strcmp(v->name, name))
- return v;
- return gvlookup(name);
-}
-
-static
-void
-set(char *name, Word *val, int call)
-{
- Var *v = vlookup(name);
- freelist(v->val);
- v->val = val;
- v->new = 1;
- if (call && v->update)
- v->update(v);
-}
-
-void
-setvar(char *name, Word *val)
-{
- set(name, val, 1);
-}
diff --git a/sys/cmd/rc/word.c b/sys/cmd/rc/word.c
deleted file mode 100644
index 84ff40c..0000000
--- a/sys/cmd/rc/word.c
+++ /dev/null
@@ -1,64 +0,0 @@
-#include "rc.h"
-
-void
-pushlist(void)
-{
- List *ls;
-
- alloc(ls);
- ls->words = nil;
- ls->link = shell->stack, shell->stack = ls;
-}
-
-void
-freelist(Word *w)
-{
- Word *it;
- while (w) {
- it = w->link;
- efree(w->word);
- efree(w);
- w = it;
- }
-}
-
-void
-poplist(void)
-{
- List *ls = shell->stack;
- if (!ls)
- panicf("shell stack underflow");
-
- freelist(ls->words);
- shell->stack = ls->link;
- efree(ls);
-}
-
-int
-count(Word *w)
-{
- int n;
- for (n=0; w; n++)
- w = w->link;
- return n;
-}
-
-Word*
-newword(char *w, Word *link)
-{
- Word *wd;
-
- alloc(wd);
- wd->word = strdup(w);
- wd->link = link;
-
- return wd;
-}
-
-void
-pushword(char *w)
-{
- if (shell->stack == nil)
- panicf("no active stack");
- shell->stack->words = newword(w, shell->stack->words);
-}