aboutsummaryrefslogtreecommitdiff
path: root/sys/cmd/rc/code.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cmd/rc/code.c')
-rw-r--r--sys/cmd/rc/code.c490
1 files changed, 0 insertions, 490 deletions
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);
-}