14887Schin /*********************************************************************** 24887Schin * * 34887Schin * This software is part of the ast package * 4*10898Sroland.mainz@nrubsig.org * Copyright (c) 1982-2009 AT&T Intellectual Property * 54887Schin * and is licensed under the * 64887Schin * Common Public License, Version 1.0 * 78462SApril.Chin@Sun.COM * by AT&T Intellectual Property * 84887Schin * * 94887Schin * A copy of the License is available at * 104887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 124887Schin * * 134887Schin * Information and Software Systems Research * 144887Schin * AT&T Research * 154887Schin * Florham Park NJ * 164887Schin * * 174887Schin * David Korn <dgk@research.att.com> * 184887Schin * * 194887Schin ***********************************************************************/ 204887Schin #pragma prototyped 214887Schin /* 224887Schin * David Korn 234887Schin * AT&T Labs 244887Schin * 254887Schin * shell intermediate code reader 264887Schin * 274887Schin */ 284887Schin 294887Schin #include <ccode.h> 304887Schin #include "defs.h" 314887Schin #include "shnodes.h" 324887Schin #include "path.h" 334887Schin #include "io.h" 344887Schin 358462SApril.Chin@Sun.COM static struct dolnod *r_comlist(Shell_t*); 368462SApril.Chin@Sun.COM static struct argnod *r_arg(Shell_t*); 378462SApril.Chin@Sun.COM static struct ionod *r_redirect(Shell_t*); 388462SApril.Chin@Sun.COM static struct regnod *r_switch(Shell_t*); 398462SApril.Chin@Sun.COM static Shnode_t *r_tree(Shell_t*); 408462SApril.Chin@Sun.COM static char *r_string(Stk_t*); 418462SApril.Chin@Sun.COM static void r_comarg(Shell_t*,struct comnod*); 424887Schin 434887Schin static Sfio_t *infile; 444887Schin 458462SApril.Chin@Sun.COM #define getnode(s,type) ((Shnode_t*)stkalloc((s),sizeof(struct type))) 464887Schin 478462SApril.Chin@Sun.COM Shnode_t *sh_trestore(Shell_t *shp,Sfio_t *in) 484887Schin { 494887Schin Shnode_t *t; 504887Schin infile = in; 518462SApril.Chin@Sun.COM t = r_tree(shp); 524887Schin return(t); 534887Schin } 544887Schin /* 554887Schin * read in a shell tree 564887Schin */ 578462SApril.Chin@Sun.COM static Shnode_t *r_tree(Shell_t *shp) 584887Schin { 594887Schin long l = sfgetl(infile); 604887Schin register int type; 614887Schin register Shnode_t *t=0; 624887Schin if(l<0) 634887Schin return(t); 644887Schin type = l; 654887Schin switch(type&COMMSK) 664887Schin { 674887Schin case TTIME: 684887Schin case TPAR: 698462SApril.Chin@Sun.COM t = getnode(shp->stk,parnod); 708462SApril.Chin@Sun.COM t->par.partre = r_tree(shp); 714887Schin break; 724887Schin case TCOM: 738462SApril.Chin@Sun.COM t = getnode(shp->stk,comnod); 744887Schin t->tre.tretyp = type; 758462SApril.Chin@Sun.COM r_comarg(shp,(struct comnod*)t); 764887Schin break; 774887Schin case TSETIO: 784887Schin case TFORK: 798462SApril.Chin@Sun.COM t = getnode(shp->stk,forknod); 804887Schin t->fork.forkline = sfgetu(infile); 818462SApril.Chin@Sun.COM t->fork.forktre = r_tree(shp); 828462SApril.Chin@Sun.COM t->fork.forkio = r_redirect(shp); 834887Schin break; 844887Schin case TIF: 858462SApril.Chin@Sun.COM t = getnode(shp->stk,ifnod); 868462SApril.Chin@Sun.COM t->if_.iftre = r_tree(shp); 878462SApril.Chin@Sun.COM t->if_.thtre = r_tree(shp); 888462SApril.Chin@Sun.COM t->if_.eltre = r_tree(shp); 894887Schin break; 904887Schin case TWH: 918462SApril.Chin@Sun.COM t = getnode(shp->stk,whnod); 928462SApril.Chin@Sun.COM t->wh.whinc = (struct arithnod*)r_tree(shp); 938462SApril.Chin@Sun.COM t->wh.whtre = r_tree(shp); 948462SApril.Chin@Sun.COM t->wh.dotre = r_tree(shp); 954887Schin break; 964887Schin case TLST: 974887Schin case TAND: 984887Schin case TORF: 994887Schin case TFIL: 1008462SApril.Chin@Sun.COM t = getnode(shp->stk,lstnod); 1018462SApril.Chin@Sun.COM t->lst.lstlef = r_tree(shp); 1028462SApril.Chin@Sun.COM t->lst.lstrit = r_tree(shp); 1034887Schin break; 1044887Schin case TARITH: 1058462SApril.Chin@Sun.COM t = getnode(shp->stk,arithnod); 1064887Schin t->ar.arline = sfgetu(infile); 1078462SApril.Chin@Sun.COM t->ar.arexpr = r_arg(shp); 1084887Schin t->ar.arcomp = 0; 1094887Schin if((t->ar.arexpr)->argflag&ARG_RAW) 1104887Schin t->ar.arcomp = sh_arithcomp((t->ar.arexpr)->argval); 1114887Schin break; 1124887Schin case TFOR: 1138462SApril.Chin@Sun.COM t = getnode(shp->stk,fornod); 1144887Schin t->for_.forline = 0; 1154887Schin if(type&FLINENO) 1164887Schin t->for_.forline = sfgetu(infile); 1178462SApril.Chin@Sun.COM t->for_.fortre = r_tree(shp); 1188462SApril.Chin@Sun.COM t->for_.fornam = r_string(shp->stk); 1198462SApril.Chin@Sun.COM t->for_.forlst = (struct comnod*)r_tree(shp); 1204887Schin break; 1214887Schin case TSW: 1228462SApril.Chin@Sun.COM t = getnode(shp->stk,swnod); 1234887Schin t->sw.swline = 0; 1244887Schin if(type&FLINENO) 1254887Schin t->sw.swline = sfgetu(infile); 1268462SApril.Chin@Sun.COM t->sw.swarg = r_arg(shp); 1274887Schin if(type&COMSCAN) 1288462SApril.Chin@Sun.COM t->sw.swio = r_redirect(shp); 1294887Schin else 1304887Schin t->sw.swio = 0; 1318462SApril.Chin@Sun.COM t->sw.swlst = r_switch(shp); 1324887Schin break; 1334887Schin case TFUN: 1344887Schin { 1354887Schin Stak_t *savstak; 1364887Schin struct slnod *slp; 137*10898Sroland.mainz@nrubsig.org struct functnod *fp; 1388462SApril.Chin@Sun.COM t = getnode(shp->stk,functnod); 1394887Schin t->funct.functloc = -1; 1404887Schin t->funct.functline = sfgetu(infile); 1418462SApril.Chin@Sun.COM t->funct.functnam = r_string(shp->stk); 1424887Schin savstak = stakcreate(STAK_SMALL); 1434887Schin savstak = stakinstall(savstak, 0); 144*10898Sroland.mainz@nrubsig.org slp = (struct slnod*)stkalloc(shp->stk,sizeof(struct slnod)+sizeof(struct functnod)); 1454887Schin slp->slchild = 0; 1468462SApril.Chin@Sun.COM slp->slnext = shp->st.staklist; 1478462SApril.Chin@Sun.COM shp->st.staklist = 0; 148*10898Sroland.mainz@nrubsig.org fp = (struct functnod*)(slp+1); 149*10898Sroland.mainz@nrubsig.org memset(fp, 0, sizeof(*fp)); 150*10898Sroland.mainz@nrubsig.org fp->functtyp = TFUN|FAMP; 151*10898Sroland.mainz@nrubsig.org if(shp->st.filename) 152*10898Sroland.mainz@nrubsig.org fp->functnam = stkcopy(shp->stk,shp->st.filename); 1538462SApril.Chin@Sun.COM t->funct.functtre = r_tree(shp); 1544887Schin t->funct.functstak = slp; 1554887Schin slp->slptr = stakinstall(savstak,0); 1568462SApril.Chin@Sun.COM slp->slchild = shp->st.staklist; 1578462SApril.Chin@Sun.COM t->funct.functargs = (struct comnod*)r_tree(shp); 1584887Schin break; 1594887Schin } 1604887Schin case TTST: 1618462SApril.Chin@Sun.COM t = getnode(shp->stk,tstnod); 1624887Schin t->tst.tstline = sfgetu(infile); 1634887Schin if((type&TPAREN)==TPAREN) 1648462SApril.Chin@Sun.COM t->lst.lstlef = r_tree(shp); 1654887Schin else 1664887Schin { 1678462SApril.Chin@Sun.COM t->lst.lstlef = (Shnode_t*)r_arg(shp); 1684887Schin if((type&TBINARY)) 1698462SApril.Chin@Sun.COM t->lst.lstrit = (Shnode_t*)r_arg(shp); 1704887Schin } 1714887Schin } 1724887Schin if(t) 1734887Schin t->tre.tretyp = type; 1744887Schin return(t); 1754887Schin } 1764887Schin 1778462SApril.Chin@Sun.COM static struct argnod *r_arg(Shell_t *shp) 1784887Schin { 1794887Schin register struct argnod *ap=0, *apold, *aptop=0; 1804887Schin register long l; 1818462SApril.Chin@Sun.COM Stk_t *stkp=shp->stk; 1824887Schin while((l=sfgetu(infile))>0) 1834887Schin { 1848462SApril.Chin@Sun.COM ap = (struct argnod*)stkseek(stkp,(unsigned)l+ARGVAL); 1854887Schin if(!aptop) 1864887Schin aptop = ap; 1874887Schin else 1884887Schin apold->argnxt.ap = ap; 1894887Schin if(--l > 0) 1904887Schin { 1914887Schin sfread(infile,ap->argval,(size_t)l); 1924887Schin ccmaps(ap->argval, l, CC_ASCII, CC_NATIVE); 1934887Schin } 1944887Schin ap->argval[l] = 0; 1954887Schin ap->argchn.cp = 0; 1964887Schin ap->argflag = sfgetc(infile); 1978462SApril.Chin@Sun.COM if((ap->argflag&ARG_MESSAGE) && *ap->argval) 1984887Schin { 1994887Schin /* replace international messages */ 2008462SApril.Chin@Sun.COM ap = sh_endword(shp,1); 2014887Schin ap->argflag &= ~ARG_MESSAGE; 2024887Schin if(!(ap->argflag&(ARG_MAC|ARG_EXP))) 2038462SApril.Chin@Sun.COM ap = sh_endword(shp,0); 2044887Schin else 2054887Schin { 2068462SApril.Chin@Sun.COM ap = (struct argnod*)stkfreeze(stkp,0); 2074887Schin if(ap->argflag==0) 2084887Schin ap->argflag = ARG_RAW; 2094887Schin } 2104887Schin } 2114887Schin else 2128462SApril.Chin@Sun.COM ap = (struct argnod*)stkfreeze(stkp,0); 2138462SApril.Chin@Sun.COM if(*ap->argval==0 && (ap->argflag&~(ARG_APPEND|ARG_MESSAGE|ARG_QUOTED))==0) 2144887Schin { 2158462SApril.Chin@Sun.COM struct fornod *fp = (struct fornod*)getnode(shp->stk,fornod); 2164887Schin fp->fortyp = sfgetu(infile); 2178462SApril.Chin@Sun.COM fp->fortre = r_tree(shp); 2184887Schin fp->fornam = ap->argval+1; 2194887Schin ap->argchn.ap = (struct argnod*)fp; 2204887Schin } 2214887Schin apold = ap; 2224887Schin } 2234887Schin if(ap) 2244887Schin ap->argnxt.ap = 0; 2254887Schin return(aptop); 2264887Schin } 2274887Schin 2288462SApril.Chin@Sun.COM static struct ionod *r_redirect(Shell_t* shp) 2294887Schin { 2304887Schin register long l; 2314887Schin register struct ionod *iop=0, *iopold, *ioptop=0; 2324887Schin while((l=sfgetl(infile))>=0) 2334887Schin { 2348462SApril.Chin@Sun.COM iop = (struct ionod*)getnode(shp->stk,ionod); 2354887Schin if(!ioptop) 2364887Schin ioptop = iop; 2374887Schin else 2384887Schin iopold->ionxt = iop; 2394887Schin iop->iofile = l; 2408462SApril.Chin@Sun.COM iop->ioname = r_string(shp->stk); 2418462SApril.Chin@Sun.COM if(iop->iodelim = r_string(shp->stk)) 2424887Schin { 2434887Schin iop->iosize = sfgetl(infile); 2448462SApril.Chin@Sun.COM if(shp->heredocs) 2458462SApril.Chin@Sun.COM iop->iooffset = sfseek(shp->heredocs,(off_t)0,SEEK_END); 2464887Schin else 2474887Schin { 2488462SApril.Chin@Sun.COM shp->heredocs = sftmp(512); 2494887Schin iop->iooffset = 0; 2504887Schin } 2518462SApril.Chin@Sun.COM sfmove(infile,shp->heredocs, iop->iosize, -1); 2524887Schin } 2534887Schin iopold = iop; 2544887Schin if(iop->iofile&IOVNM) 2558462SApril.Chin@Sun.COM iop->iovname = r_string(shp->stk); 2564887Schin else 2574887Schin iop->iovname = 0; 2584887Schin iop->iofile &= ~IOVNM; 2594887Schin } 2604887Schin if(iop) 2614887Schin iop->ionxt = 0; 2624887Schin return(ioptop); 2634887Schin } 2644887Schin 2658462SApril.Chin@Sun.COM static void r_comarg(Shell_t *shp,struct comnod *com) 2664887Schin { 2674887Schin char *cmdname=0; 2688462SApril.Chin@Sun.COM com->comio = r_redirect(shp); 2698462SApril.Chin@Sun.COM com->comset = r_arg(shp); 2704887Schin com->comstate = 0; 2714887Schin if(com->comtyp&COMSCAN) 2724887Schin { 2738462SApril.Chin@Sun.COM com->comarg = r_arg(shp); 2744887Schin if(com->comarg->argflag==ARG_RAW) 2754887Schin cmdname = com->comarg->argval; 2764887Schin } 2778462SApril.Chin@Sun.COM else if(com->comarg = (struct argnod*)r_comlist(shp)) 2784887Schin cmdname = ((struct dolnod*)(com->comarg))->dolval[ARG_SPARE]; 2794887Schin com->comline = sfgetu(infile); 2804887Schin com->comnamq = 0; 2814887Schin if(cmdname) 2824887Schin { 2834887Schin char *cp; 2848462SApril.Chin@Sun.COM com->comnamp = (void*)nv_search(cmdname,shp->fun_tree,0); 2854887Schin if(com->comnamp && (cp =strrchr(cmdname+1,'.'))) 2864887Schin { 2874887Schin *cp = 0; 2888462SApril.Chin@Sun.COM com->comnamp = (void*)nv_open(cmdname,shp->var_tree,NV_VARNAME|NV_NOADD|NV_NOARRAY); 2894887Schin *cp = '.'; 2904887Schin } 2914887Schin } 2924887Schin else 2934887Schin com->comnamp = 0; 2944887Schin } 2954887Schin 2968462SApril.Chin@Sun.COM static struct dolnod *r_comlist(Shell_t *shp) 2974887Schin { 2984887Schin register struct dolnod *dol=0; 2994887Schin register long l; 3004887Schin register char **argv; 3014887Schin if((l=sfgetl(infile))>0) 3024887Schin { 3038462SApril.Chin@Sun.COM dol = (struct dolnod*)stkalloc(shp->stk,sizeof(struct dolnod) + sizeof(char*)*(l+ARG_SPARE)); 3044887Schin dol->dolnum = l; 3054887Schin dol->dolbot = ARG_SPARE; 3064887Schin argv = dol->dolval+ARG_SPARE; 3078462SApril.Chin@Sun.COM while(*argv++ = r_string(shp->stk)); 3084887Schin } 3094887Schin return(dol); 3104887Schin } 3114887Schin 3128462SApril.Chin@Sun.COM static struct regnod *r_switch(Shell_t *shp) 3134887Schin { 3144887Schin register long l; 3154887Schin struct regnod *reg=0,*regold,*regtop=0; 3164887Schin while((l=sfgetl(infile))>=0) 3174887Schin { 3188462SApril.Chin@Sun.COM reg = (struct regnod*)getnode(shp->stk,regnod); 3194887Schin if(!regtop) 3204887Schin regtop = reg; 3214887Schin else 3224887Schin regold->regnxt = reg; 3234887Schin reg->regflag = l; 3248462SApril.Chin@Sun.COM reg->regptr = r_arg(shp); 3258462SApril.Chin@Sun.COM reg->regcom = r_tree(shp); 3264887Schin regold = reg; 3274887Schin } 3284887Schin if(reg) 3294887Schin reg->regnxt = 0; 3304887Schin return(regtop); 3314887Schin } 3324887Schin 3338462SApril.Chin@Sun.COM static char *r_string(Stk_t *stkp) 3344887Schin { 3354887Schin register Sfio_t *in = infile; 3364887Schin register unsigned long l = sfgetu(in); 3374887Schin register char *ptr; 3384887Schin if(l == 0) 3394887Schin return(NIL(char*)); 3408462SApril.Chin@Sun.COM ptr = stkalloc(stkp,(unsigned)l); 3414887Schin if(--l > 0) 3424887Schin { 3434887Schin if(sfread(in,ptr,(size_t)l)!=(size_t)l) 3444887Schin return(NIL(char*)); 3454887Schin ccmaps(ptr, l, CC_ASCII, CC_NATIVE); 3464887Schin } 3474887Schin ptr[l] = 0; 3484887Schin return(ptr); 3494887Schin } 350