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