diff options
author | rsc <devnull@localhost> | 2007-03-26 12:02:41 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2007-03-26 12:02:41 +0000 |
commit | c8f538425f4e92e1e438b9bd25cb08e250a93d5b (patch) | |
tree | d701abbcd4973d5b6909d104eefe521de70a4e1c /src/cmd/rc/code.c | |
parent | 79049567a0fac8707ea3f2927403445bdb2394fa (diff) | |
download | plan9port-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.c | 223 |
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++; |