aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/rc/code.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2007-03-26 12:02:41 +0000
committerrsc <devnull@localhost>2007-03-26 12:02:41 +0000
commitc8f538425f4e92e1e438b9bd25cb08e250a93d5b (patch)
treed701abbcd4973d5b6909d104eefe521de70a4e1c /src/cmd/rc/code.c
parent79049567a0fac8707ea3f2927403445bdb2394fa (diff)
downloadplan9port-c8f538425f4e92e1e438b9bd25cb08e250a93d5b.tar.gz
plan9port-c8f538425f4e92e1e438b9bd25cb08e250a93d5b.tar.bz2
plan9port-c8f538425f4e92e1e438b9bd25cb08e250a93d5b.zip
sync with plan 9
Diffstat (limited to 'src/cmd/rc/code.c')
-rw-r--r--src/cmd/rc/code.c223
1 files changed, 139 insertions, 84 deletions
diff --git a/src/cmd/rc/code.c b/src/cmd/rc/code.c
index 748b9f82..0ae90eeb 100644
--- a/src/cmd/rc/code.c
+++ b/src/cmd/rc/code.c
@@ -7,9 +7,9 @@
#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++)
+#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);
@@ -17,22 +17,32 @@ void codeswitch(tree*, int);
int iscase(tree*);
code *codecopy(code*);
void codefree(code*);
-int morecode(void){
+
+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!",
+ codebuf = (code *)realloc((char *)codebuf, ncode*sizeof codebuf[0]);
+ if(codebuf==0)
+ panic("Can't realloc %d bytes in morecode!",
ncode*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;
+
+void
+stuffdot(int a)
+{
+ if(a<0 || codep<=a)
+ panic("Bad address %d in stuffdot", a);
+ codebuf[a].i = codep;
}
-int compile(tree *t)
+
+int
+compile(tree *t)
{
- ncode=100;
- codebuf=(code *)emalloc(ncode*sizeof codebuf[0]);
- codep=0;
+ ncode = 100;
+ codebuf = (code *)emalloc(ncode*sizeof codebuf[0]);
+ codep = 0;
emiti(0); /* reference count */
outcode(t, flag['e']?1:0);
if(nerror){
@@ -44,31 +54,39 @@ int compile(tree *t)
emitf(0);
return 1;
}
-void cleanhere(char *f)
+
+void
+cleanhere(char *f)
{
emitf(Xdelhere);
emits(strdup(f));
}
-char *fnstr(tree *t)
+
+char*
+fnstr(tree *t)
{
- io *f=openstr();
+ io *f = openstr();
char *v;
extern char nl;
- char svnl=nl;
+ char svnl = nl;
nl=';';
pfmt(f, "%t", t);
- nl=svnl;
- v=f->strp;
- f->strp=0;
+ nl = svnl;
+ v = f->strp;
+ f->strp = 0;
closeio(f);
return v;
}
-void outcode(tree *t, int eflag)
+
+void
+outcode(tree *t, int eflag)
{
int p, q;
tree *tt;
- if(t==0) return;
- if(t->type!=NOT && t->type!=';') runq->iflast=0;
+ 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);
@@ -92,10 +110,13 @@ void outcode(tree *t, int eflag)
break;
case '&':
emitf(Xasync);
- p=emiti(0);
- outcode(c0, eflag);
- emitf(Xexit);
- stuffdot(p);
+ if(havefork){
+ p = emiti(0);
+ outcode(c0, eflag);
+ emitf(Xexit);
+ stuffdot(p);
+ } else
+ emits(fnstr(c0));
break;
case ';':
outcode(c0, eflag);
@@ -110,15 +131,18 @@ void outcode(tree *t, int eflag)
break;
case '`':
emitf(Xbackq);
- p=emiti(0);
- outcode(c0, 0);
- emitf(Xexit);
- stuffdot(p);
+ 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);
+ p = emiti(0);
outcode(c1, eflag);
stuffdot(p);
break;
@@ -144,7 +168,7 @@ void outcode(tree *t, int eflag)
outcode(c0, eflag);
if(c1){
emitf(Xfn);
- p=emiti(0);
+ p = emiti(0);
emits(fnstr(c1));
outcode(c1, eflag);
emitf(Xunlocal); /* get rid of $* */
@@ -157,22 +181,23 @@ void outcode(tree *t, int eflag)
case IF:
outcode(c0, 0);
emitf(Xif);
- p=emiti(0);
+ p = emiti(0);
outcode(c1, eflag);
emitf(Xwastrue);
stuffdot(p);
break;
case NOT:
- if(!runq->iflast) yyerror("`if not' does not follow `if(...)'");
+ if(!runq->iflast)
+ yyerror("`if not' does not follow `if(...)'");
emitf(Xifnot);
- p=emiti(0);
+ p = emiti(0);
outcode(c0, eflag);
stuffdot(p);
break;
case OROR:
outcode(c0, 0);
emitf(Xfalse);
- p=emiti(0);
+ p = emiti(0);
outcode(c1, eflag);
stuffdot(p);
break;
@@ -183,15 +208,20 @@ void outcode(tree *t, int eflag)
emitf(Xmark);
outcode(c0, eflag);
emitf(Xsimple);
- if(eflag) emitf(Xeflag);
+ if(eflag)
+ emitf(Xeflag);
break;
case SUBSHELL:
emitf(Xsubshell);
- p=emiti(0);
- outcode(c0, eflag);
- emitf(Xexit);
- stuffdot(p);
- if(eflag) emitf(Xeflag);
+ 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);
@@ -202,14 +232,16 @@ void outcode(tree *t, int eflag)
emitf(Xmark);
outcode(c0, eflag);
emitf(Xmatch);
- if(eflag) emitf(Xeflag);
+ if(eflag)
+ emitf(Xeflag);
break;
case WHILE:
- q=codep;
+ q = codep;
outcode(c0, 0);
- if(q==codep) emitf(Xsettrue); /* empty condition == while(true) */
+ if(q==codep)
+ emitf(Xsettrue); /* empty condition == while(true) */
emitf(Xtrue);
- p=emiti(0);
+ p = emiti(0);
outcode(c1, eflag);
emitf(Xjump);
emiti(q);
@@ -235,8 +267,8 @@ void outcode(tree *t, int eflag)
emitf(Xmark);
outcode(c0, eflag);
emitf(Xlocal);
- p=emitf(Xfor);
- q=emiti(0);
+ p = emitf(Xfor);
+ q = emiti(0);
outcode(c2, eflag);
emitf(Xjump);
emiti(p);
@@ -263,10 +295,14 @@ void outcode(tree *t, int eflag)
case PIPEFD:
emitf(Xpipefd);
emiti(t->rtype);
- p=emiti(0);
- outcode(c0, eflag);
- emitf(Xexit);
- stuffdot(p);
+ if(havefork){
+ p = emiti(0);
+ outcode(c0, eflag);
+ emitf(Xexit);
+ stuffdot(p);
+ } else {
+ emits(fnstr(c0));
+ }
break;
case REDIR:
emitf(Xmark);
@@ -283,28 +319,31 @@ void outcode(tree *t, int eflag)
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);
+ tt = t;
+ for(;t && t->type=='=';t = c2);
if(t){
- for(t=tt;t->type=='=';t=c2){
+ for(t = tt;t->type=='=';t = c2){
emitf(Xmark);
outcode(c1, eflag);
emitf(Xmark);
outcode(c0, eflag);
emitf(Xlocal);
}
- t=tt;
+ t = tt;
outcode(c2, eflag);
- for(;t->type=='=';t=c2) emitf(Xunlocal);
+ for(;t->type=='=';t = c2) emitf(Xunlocal);
}
else{
- for(t=tt;t;t=c2){
+ for(t = tt;t;t = c2){
emitf(Xmark);
outcode(c1, eflag);
emitf(Xmark);
@@ -312,17 +351,22 @@ void outcode(tree *t, int eflag)
emitf(Xassign);
}
}
- t=tt; /* so tests below will work */
+ t = tt; /* so tests below will work */
break;
case PIPE:
emitf(Xpipe);
emiti(t->fd0);
emiti(t->fd1);
- p=emiti(0);
- q=emiti(0);
- outcode(c0, eflag);
- emitf(Xexit);
- stuffdot(p);
+ 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);
@@ -330,8 +374,8 @@ void outcode(tree *t, int eflag)
break;
}
if(t->type!=NOT && t->type!=';')
- runq->iflast=t->type==IF;
- else if(c0) runq->iflast=c0->type==IF;
+ runq->iflast = t->type==IF;
+ else if(c0) runq->iflast = c0->type==IF;
}
/*
* switch code looks like this:
@@ -353,7 +397,9 @@ void outcode(tree *t, int eflag)
* leave:
* Xpopm
*/
-void codeswitch(tree *t, int eflag)
+
+void
+codeswitch(tree *t, int eflag)
{
int leave; /* patch jump address to leave switch */
int out; /* jump here to leave switch */
@@ -368,23 +414,23 @@ void codeswitch(tree *t, int eflag)
emitf(Xmark);
outcode(c0, eflag);
emitf(Xjump);
- nextcase=emiti(0);
- out=emitf(Xjump);
- leave=emiti(0);
+ nextcase = emiti(0);
+ out = emitf(Xjump);
+ leave = emiti(0);
stuffdot(nextcase);
- t=c1->child[0];
+ t = c1->child[0];
while(t->type==';'){
- tt=c1;
+ tt = c1;
emitf(Xmark);
- for(t=c0->child[0];t->type==ARGLIST;t=c0) outcode(c1, eflag);
+ for(t = c0->child[0];t->type==ARGLIST;t = c0) outcode(c1, eflag);
emitf(Xcase);
- nextcase=emiti(0);
- t=tt;
+ nextcase = emiti(0);
+ t = tt;
for(;;){
if(t->type==';'){
if(iscase(c0)) break;
outcode(c0, eflag);
- t=c1;
+ t = c1;
}
else{
if(!iscase(t)) outcode(t, eflag);
@@ -398,23 +444,32 @@ void codeswitch(tree *t, int eflag)
stuffdot(leave);
emitf(Xpopm);
}
-int iscase(tree *t)
+
+int
+iscase(tree *t)
{
- if(t->type!=SIMPLE) return 0;
- do t=c0; while(t->type==ARGLIST);
+ 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)
+
+code*
+codecopy(code *cp)
{
cp[0].i++;
return cp;
}
-void codefree(code *cp)
+
+void
+codefree(code *cp)
{
code *p;
- if(--cp[0].i!=0) return;
- for(p=cp+1;p->f;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++;