/* @(#)func.c 1.2 */ /* * UNIX shell * * Bell Telephone Laboratories * */ #include "defs.h" #define prfc(c) pushstak(c) freefunc(val) char *val; { freetree((struct trenod *)val); } freetree(t) register struct trenod *t; { if (t) { register int type; if (t->tretyp & CNTMSK) { t->tretyp--; return; } type = t->tretyp & COMMSK; switch (type) { case TFND: shfree(fndptr(t)->fndnam); freetree(fndptr(t)->fndval); break; case TCOM: freeio(comptr(t)->comio); free_arg(comptr(t)->comarg); free_arg(comptr(t)->comset); break; case TFORK: freeio(forkptr(t)->forkio); freetree(forkptr(t)->forktre); break; case TPAR: freetree(parptr(t)->partre); break; case TFIL: case TLST: case TAND: case TORF: freetree(lstptr(t)->lstlef); freetree(lstptr(t)->lstrit); break; case TFOR: { struct fornod *f = (struct fornod *)t; shfree(f->fornam); freetree(f->fortre); if (f->forlst) { freeio(f->forlst->comio); free_arg(f->forlst->comarg); free_arg(f->forlst->comset); shfree(f->forlst); } } break; case TWH: case TUN: freetree(whptr(t)->whtre); freetree(whptr(t)->dotre); break; case TIF: freetree(ifptr(t)->iftre); freetree(ifptr(t)->thtre); freetree(ifptr(t)->eltre); break; case TSW: shfree(swptr(t)->swarg); freereg(swptr(t)->swlst); break; } shfree(t); } } free_arg(argp) register struct argnod *argp; { register struct argnod *sav; while (argp) { sav = argp->argnxt; shfree(argp); argp = sav; } } freeio(iop) register struct ionod *iop; { register struct ionod *sav; while (iop) { if ((iop->iofile & IODOC) && fiotemp != 0) { #ifdef DEBUG prs("unlinking "); prs(iop->ioname); newline(); #endif unlink(iop->ioname); if (fiotemp == iop) fiotemp = iop->iolst; else { struct ionod *fiop = fiotemp; while (fiop->iolst != iop) fiop = fiop->iolst; fiop->iolst = iop->iolst; } } shfree(iop->ioname); shfree(iop->iolink); sav = iop->ionxt; shfree(iop); iop = sav; } } freereg(regp) register struct regnod *regp; { register struct regnod *sav; while (regp) { free_arg(regp->regptr); freetree(regp->regcom); sav = regp->regnxt; shfree(regp); regp = sav; } } /* * Leaves string on top of stack */ char * strf(n) register struct namnod *n; { char *s = locstak(); prfstr(n->namid); prfstr("(){\n"); prf(n->namval.val); prfstr("\n}"); prfc('\0'); return staktop=s; } prfstr(s) register char *s; { while(*s) prfc(*s++); } prf(t) register struct trenod *t; { sigchk(); if (t) { register int type; type = t->tretyp & COMMSK; switch(type) { case TFND: { register struct fndnod *f = (struct fndnod *)t; prfstr(f->fndnam); prfstr("(){\n"); prf(f->fndval); prfstr("\n}"); break; } case TCOM: { prarg(comptr(t)->comset); prarg(comptr(t)->comarg); prio(comptr(t)->comio); break; } case TFORK: prf(forkptr(t)->forktre); prio(forkptr(t)->forkio); if (forkptr(t)->forktyp & FAMP) prfstr(" &"); break; case TPAR: prfstr("("); prf(parptr(t)->partre); prfstr(")"); break; case TFIL: prf(lstptr(t)->lstlef); prfstr(" | "); prf(lstptr(t)->lstrit); break; case TLST: prf(lstptr(t)->lstlef); prfc(NL); prf(lstptr(t)->lstrit); break; case TAND: prf(lstptr(t)->lstlef); prfstr(" && "); prf(lstptr(t)->lstrit); break; case TORF: prf(lstptr(t)->lstlef); prfstr(" || "); prf(lstptr(t)->lstrit); break; case TFOR: { register struct argnod *arg; register struct fornod *f = (struct fornod *)t; prfstr("for "); prfstr(f->fornam); if (f->forlst) { arg = f->forlst->comarg; prfstr(" in"); while(arg != ENDARGS) { prfc(SP); prfqstr(arg->argval); arg = arg->argnxt; } } prfstr("\ndo\n"); prf(f->fortre); prfstr("\ndone"); } break; case TWH: case TUN: if (type == TWH) prfstr("while "); else prfstr("until "); prf(whptr(t)->whtre); prfstr("\ndo\n"); prf(whptr(t)->dotre); prfstr("\ndone"); break; case TIF: { struct ifnod *f = (struct ifnod *)t; prfstr("if "); prf(f->iftre); prfstr("\nthen\n"); prf(f->thtre); if (f->eltre) { prfstr("\nelse\n"); prf(f->eltre); } prfstr("\nfi"); break; } case TSW: { register struct regnod *swl; prfstr("case "); prfqstr(swptr(t)->swarg); prfstr(" in\n"); swl = swptr(t)->swlst; while(swl) { struct argnod *arg = swl->regptr; if (arg) { prfqstr(arg->argval); arg = arg->argnxt; } while(arg) { prfc('|'); prfqstr(arg->argval); arg = arg->argnxt; } prfstr(") "); prf(swl->regcom); prfstr(";;\n"); swl = swl->regnxt; } prfstr("esac"); } break; } } sigchk(); } prarg(argp) register struct argnod *argp; { while (argp) { prfqstr(argp->argval); prfc(SP); argp=argp->argnxt; } } prio(iop) register struct ionod *iop; { register int iof; register char *ion; while (iop) { iof = iop->iofile; ion = iop->ioname; if (*ion) { itos(iof & IOUFD); prfstr(numbuf); if (iof & IODOC) prfstr("<"); else if (iof & IOMOV) { if (iof & IOPUT) prfstr(">&"); else prfstr("<&"); } else if ((iof & IOPUT) == 0) prfc('<'); else if (iof & IOAPP) prfstr(">>"); else prfc('>'); prfstr(ion); prfc(SP); } iop = iop->ionxt; } } prfqstr(p) register char *p; { int quote, equote; int allquotes; more: quote = equote = allquotes = 0; if(*p == '"'){ register char *t = p; quote = equote = '"'; allquotes = 1; while(*++t!='"') if(!(*t"E)){ allquotes=0; break; } if(allquotes) quote='\''; prfc(quote); p++; } while(*p != equote){ if(*p=='"') goto more; if(!allquotes && (*p"E)) prfc('\\'); prfc(*p++&~QUOTE); } if(quote){ prfc(quote); if(*++p != 0) goto more; } }