1*4887Schin /*********************************************************************** 2*4887Schin * * 3*4887Schin * This software is part of the ast package * 4*4887Schin * Copyright (c) 1982-2007 AT&T Knowledge Ventures * 5*4887Schin * and is licensed under the * 6*4887Schin * Common Public License, Version 1.0 * 7*4887Schin * by AT&T Knowledge Ventures * 8*4887Schin * * 9*4887Schin * A copy of the License is available at * 10*4887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 11*4887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12*4887Schin * * 13*4887Schin * Information and Software Systems Research * 14*4887Schin * AT&T Research * 15*4887Schin * Florham Park NJ * 16*4887Schin * * 17*4887Schin * David Korn <dgk@research.att.com> * 18*4887Schin * * 19*4887Schin ***********************************************************************/ 20*4887Schin #pragma prototyped 21*4887Schin /* 22*4887Schin * David Korn 23*4887Schin * AT&T Labs 24*4887Schin * 25*4887Schin * shell intermediate code reader 26*4887Schin * 27*4887Schin */ 28*4887Schin 29*4887Schin #include <ccode.h> 30*4887Schin #include "defs.h" 31*4887Schin #include "shnodes.h" 32*4887Schin #include "path.h" 33*4887Schin #include "io.h" 34*4887Schin 35*4887Schin static struct dolnod *r_comlist(void); 36*4887Schin static struct argnod *r_arg(void); 37*4887Schin static struct ionod *r_redirect(void); 38*4887Schin static struct regnod *r_switch(void); 39*4887Schin static Shnode_t *r_tree(void); 40*4887Schin static char *r_string(void); 41*4887Schin static void r_comarg(struct comnod*); 42*4887Schin 43*4887Schin static Sfio_t *infile; 44*4887Schin 45*4887Schin #define getnode(type) ((Shnode_t*)stakalloc(sizeof(struct type))) 46*4887Schin 47*4887Schin Shnode_t *sh_trestore(Sfio_t *in) 48*4887Schin { 49*4887Schin Shnode_t *t; 50*4887Schin infile = in; 51*4887Schin t = r_tree(); 52*4887Schin return(t); 53*4887Schin } 54*4887Schin /* 55*4887Schin * read in a shell tree 56*4887Schin */ 57*4887Schin static Shnode_t *r_tree() 58*4887Schin { 59*4887Schin long l = sfgetl(infile); 60*4887Schin register int type; 61*4887Schin register Shnode_t *t=0; 62*4887Schin if(l<0) 63*4887Schin return(t); 64*4887Schin type = l; 65*4887Schin switch(type&COMMSK) 66*4887Schin { 67*4887Schin case TTIME: 68*4887Schin case TPAR: 69*4887Schin t = getnode(parnod); 70*4887Schin t->par.partre = r_tree(); 71*4887Schin break; 72*4887Schin case TCOM: 73*4887Schin t = getnode(comnod); 74*4887Schin t->tre.tretyp = type; 75*4887Schin r_comarg((struct comnod*)t); 76*4887Schin break; 77*4887Schin case TSETIO: 78*4887Schin case TFORK: 79*4887Schin t = getnode(forknod); 80*4887Schin t->fork.forkline = sfgetu(infile); 81*4887Schin t->fork.forktre = r_tree(); 82*4887Schin t->fork.forkio = r_redirect(); 83*4887Schin break; 84*4887Schin case TIF: 85*4887Schin t = getnode(ifnod); 86*4887Schin t->if_.iftre = r_tree(); 87*4887Schin t->if_.thtre = r_tree(); 88*4887Schin t->if_.eltre = r_tree(); 89*4887Schin break; 90*4887Schin case TWH: 91*4887Schin t = getnode(whnod); 92*4887Schin t->wh.whinc = (struct arithnod*)r_tree(); 93*4887Schin t->wh.whtre = r_tree(); 94*4887Schin t->wh.dotre = r_tree(); 95*4887Schin break; 96*4887Schin case TLST: 97*4887Schin case TAND: 98*4887Schin case TORF: 99*4887Schin case TFIL: 100*4887Schin t = getnode(lstnod); 101*4887Schin t->lst.lstlef = r_tree(); 102*4887Schin t->lst.lstrit = r_tree(); 103*4887Schin break; 104*4887Schin case TARITH: 105*4887Schin t = getnode(arithnod); 106*4887Schin t->ar.arline = sfgetu(infile); 107*4887Schin t->ar.arexpr = r_arg(); 108*4887Schin t->ar.arcomp = 0; 109*4887Schin if((t->ar.arexpr)->argflag&ARG_RAW) 110*4887Schin t->ar.arcomp = sh_arithcomp((t->ar.arexpr)->argval); 111*4887Schin break; 112*4887Schin case TFOR: 113*4887Schin t = getnode(fornod); 114*4887Schin t->for_.forline = 0; 115*4887Schin if(type&FLINENO) 116*4887Schin t->for_.forline = sfgetu(infile); 117*4887Schin t->for_.fortre = r_tree(); 118*4887Schin t->for_.fornam = r_string(); 119*4887Schin t->for_.forlst = (struct comnod*)r_tree(); 120*4887Schin break; 121*4887Schin case TSW: 122*4887Schin t = getnode(swnod); 123*4887Schin t->sw.swline = 0; 124*4887Schin if(type&FLINENO) 125*4887Schin t->sw.swline = sfgetu(infile); 126*4887Schin t->sw.swarg = r_arg(); 127*4887Schin if(type&COMSCAN) 128*4887Schin t->sw.swio = r_redirect(); 129*4887Schin else 130*4887Schin t->sw.swio = 0; 131*4887Schin t->sw.swlst = r_switch(); 132*4887Schin break; 133*4887Schin case TFUN: 134*4887Schin { 135*4887Schin Stak_t *savstak; 136*4887Schin struct slnod *slp; 137*4887Schin t = getnode(functnod); 138*4887Schin t->funct.functloc = -1; 139*4887Schin t->funct.functline = sfgetu(infile); 140*4887Schin t->funct.functnam = r_string(); 141*4887Schin savstak = stakcreate(STAK_SMALL); 142*4887Schin savstak = stakinstall(savstak, 0); 143*4887Schin slp = (struct slnod*)stakalloc(sizeof(struct slnod)); 144*4887Schin slp->slchild = 0; 145*4887Schin slp->slnext = sh.st.staklist; 146*4887Schin sh.st.staklist = 0; 147*4887Schin t->funct.functtre = r_tree(); 148*4887Schin t->funct.functstak = slp; 149*4887Schin slp->slptr = stakinstall(savstak,0); 150*4887Schin slp->slchild = sh.st.staklist; 151*4887Schin t->funct.functargs = (struct comnod*)r_tree(); 152*4887Schin break; 153*4887Schin } 154*4887Schin case TTST: 155*4887Schin t = getnode(tstnod); 156*4887Schin t->tst.tstline = sfgetu(infile); 157*4887Schin if((type&TPAREN)==TPAREN) 158*4887Schin t->lst.lstlef = r_tree(); 159*4887Schin else 160*4887Schin { 161*4887Schin t->lst.lstlef = (Shnode_t*)r_arg(); 162*4887Schin if((type&TBINARY)) 163*4887Schin t->lst.lstrit = (Shnode_t*)r_arg(); 164*4887Schin } 165*4887Schin } 166*4887Schin if(t) 167*4887Schin t->tre.tretyp = type; 168*4887Schin return(t); 169*4887Schin } 170*4887Schin 171*4887Schin static struct argnod *r_arg(void) 172*4887Schin { 173*4887Schin register struct argnod *ap=0, *apold, *aptop=0; 174*4887Schin register long l; 175*4887Schin while((l=sfgetu(infile))>0) 176*4887Schin { 177*4887Schin ap = (struct argnod*)stakseek((unsigned)l+ARGVAL); 178*4887Schin if(!aptop) 179*4887Schin aptop = ap; 180*4887Schin else 181*4887Schin apold->argnxt.ap = ap; 182*4887Schin if(--l > 0) 183*4887Schin { 184*4887Schin sfread(infile,ap->argval,(size_t)l); 185*4887Schin ccmaps(ap->argval, l, CC_ASCII, CC_NATIVE); 186*4887Schin } 187*4887Schin ap->argval[l] = 0; 188*4887Schin ap->argchn.cp = 0; 189*4887Schin ap->argflag = sfgetc(infile); 190*4887Schin if(ap->argflag&ARG_MESSAGE) 191*4887Schin { 192*4887Schin /* replace international messages */ 193*4887Schin ap = sh_endword(1); 194*4887Schin ap->argflag &= ~ARG_MESSAGE; 195*4887Schin if(!(ap->argflag&(ARG_MAC|ARG_EXP))) 196*4887Schin ap = sh_endword(0); 197*4887Schin else 198*4887Schin { 199*4887Schin ap = (struct argnod*)stakfreeze(0); 200*4887Schin if(ap->argflag==0) 201*4887Schin ap->argflag = ARG_RAW; 202*4887Schin } 203*4887Schin } 204*4887Schin else 205*4887Schin ap = (struct argnod*)stakfreeze(0); 206*4887Schin if(*ap->argval==0 && (ap->argflag&~ARG_APPEND)==0) 207*4887Schin { 208*4887Schin struct fornod *fp = (struct fornod*)getnode(fornod); 209*4887Schin fp->fortyp = sfgetu(infile); 210*4887Schin fp->fortre = r_tree(); 211*4887Schin fp->fornam = ap->argval+1; 212*4887Schin ap->argchn.ap = (struct argnod*)fp; 213*4887Schin } 214*4887Schin apold = ap; 215*4887Schin } 216*4887Schin if(ap) 217*4887Schin ap->argnxt.ap = 0; 218*4887Schin return(aptop); 219*4887Schin } 220*4887Schin 221*4887Schin static struct ionod *r_redirect(void) 222*4887Schin { 223*4887Schin register long l; 224*4887Schin register struct ionod *iop=0, *iopold, *ioptop=0; 225*4887Schin while((l=sfgetl(infile))>=0) 226*4887Schin { 227*4887Schin iop = (struct ionod*)getnode(ionod); 228*4887Schin if(!ioptop) 229*4887Schin ioptop = iop; 230*4887Schin else 231*4887Schin iopold->ionxt = iop; 232*4887Schin iop->iofile = l; 233*4887Schin iop->ioname = r_string(); 234*4887Schin if(iop->iodelim = r_string()) 235*4887Schin { 236*4887Schin iop->iosize = sfgetl(infile); 237*4887Schin if(sh.heredocs) 238*4887Schin iop->iooffset = sfseek(sh.heredocs,(off_t)0,SEEK_END); 239*4887Schin else 240*4887Schin { 241*4887Schin sh.heredocs = sftmp(512); 242*4887Schin iop->iooffset = 0; 243*4887Schin } 244*4887Schin sfmove(infile,sh.heredocs, iop->iosize, -1); 245*4887Schin } 246*4887Schin iopold = iop; 247*4887Schin if(iop->iofile&IOVNM) 248*4887Schin iop->iovname = r_string(); 249*4887Schin else 250*4887Schin iop->iovname = 0; 251*4887Schin iop->iofile &= ~IOVNM; 252*4887Schin } 253*4887Schin if(iop) 254*4887Schin iop->ionxt = 0; 255*4887Schin return(ioptop); 256*4887Schin } 257*4887Schin 258*4887Schin static void r_comarg(struct comnod *com) 259*4887Schin { 260*4887Schin char *cmdname=0; 261*4887Schin com->comio = r_redirect(); 262*4887Schin com->comset = r_arg(); 263*4887Schin com->comstate = 0; 264*4887Schin if(com->comtyp&COMSCAN) 265*4887Schin { 266*4887Schin com->comarg = r_arg(); 267*4887Schin if(com->comarg->argflag==ARG_RAW) 268*4887Schin cmdname = com->comarg->argval; 269*4887Schin } 270*4887Schin else if(com->comarg = (struct argnod*)r_comlist()) 271*4887Schin cmdname = ((struct dolnod*)(com->comarg))->dolval[ARG_SPARE]; 272*4887Schin com->comline = sfgetu(infile); 273*4887Schin com->comnamq = 0; 274*4887Schin if(cmdname) 275*4887Schin { 276*4887Schin char *cp; 277*4887Schin com->comnamp = (void*)nv_search(cmdname,sh.fun_tree,0); 278*4887Schin if(com->comnamp && (cp =strrchr(cmdname+1,'.'))) 279*4887Schin { 280*4887Schin *cp = 0; 281*4887Schin com->comnamp = (void*)nv_open(cmdname,sh.var_tree,NV_VARNAME|NV_NOADD|NV_NOARRAY); 282*4887Schin *cp = '.'; 283*4887Schin } 284*4887Schin } 285*4887Schin else 286*4887Schin com->comnamp = 0; 287*4887Schin } 288*4887Schin 289*4887Schin static struct dolnod *r_comlist(void) 290*4887Schin { 291*4887Schin register struct dolnod *dol=0; 292*4887Schin register long l; 293*4887Schin register char **argv; 294*4887Schin if((l=sfgetl(infile))>0) 295*4887Schin { 296*4887Schin dol = (struct dolnod*)stakalloc(sizeof(struct dolnod) + sizeof(char*)*(l+ARG_SPARE)); 297*4887Schin dol->dolnum = l; 298*4887Schin dol->dolbot = ARG_SPARE; 299*4887Schin argv = dol->dolval+ARG_SPARE; 300*4887Schin while(*argv++ = r_string()); 301*4887Schin } 302*4887Schin return(dol); 303*4887Schin } 304*4887Schin 305*4887Schin static struct regnod *r_switch(void) 306*4887Schin { 307*4887Schin register long l; 308*4887Schin struct regnod *reg=0,*regold,*regtop=0; 309*4887Schin while((l=sfgetl(infile))>=0) 310*4887Schin { 311*4887Schin reg = (struct regnod*)getnode(regnod); 312*4887Schin if(!regtop) 313*4887Schin regtop = reg; 314*4887Schin else 315*4887Schin regold->regnxt = reg; 316*4887Schin reg->regflag = l; 317*4887Schin reg->regptr = r_arg(); 318*4887Schin reg->regcom = r_tree(); 319*4887Schin regold = reg; 320*4887Schin } 321*4887Schin if(reg) 322*4887Schin reg->regnxt = 0; 323*4887Schin return(regtop); 324*4887Schin } 325*4887Schin 326*4887Schin static char *r_string(void) 327*4887Schin { 328*4887Schin register Sfio_t *in = infile; 329*4887Schin register unsigned long l = sfgetu(in); 330*4887Schin register char *ptr; 331*4887Schin if(l == 0) 332*4887Schin return(NIL(char*)); 333*4887Schin ptr = stakalloc((unsigned)l); 334*4887Schin if(--l > 0) 335*4887Schin { 336*4887Schin if(sfread(in,ptr,(size_t)l)!=(size_t)l) 337*4887Schin return(NIL(char*)); 338*4887Schin ccmaps(ptr, l, CC_ASCII, CC_NATIVE); 339*4887Schin } 340*4887Schin ptr[l] = 0; 341*4887Schin return(ptr); 342*4887Schin } 343