Commit | Line | Data |
---|---|---|
862515b8 TL |
1 | # |
2 | /* | |
3 | * UNIX shell | |
4 | * | |
5 | * S. R. Bourne | |
6 | * Bell Telephone Laboratories | |
7 | * | |
8 | */ | |
9 | ||
10 | #include "defs.h" | |
11 | ||
12 | PROC BOOL chkid(); | |
13 | ||
14 | ||
15 | NAMNOD ps2nod = { NIL, NIL, ps2name}, | |
16 | fngnod = { NIL, NIL, fngname}, | |
17 | pathnod = { NIL, NIL, pathname}, | |
18 | ifsnod = { NIL, NIL, ifsname}, | |
19 | ps1nod = { &pathnod, &ps2nod, ps1name}, | |
20 | homenod = { &fngnod, &ifsnod, homename}, | |
21 | mailnod = { &homenod, &ps1nod, mailname}; | |
22 | ||
23 | NAMPTR namep = &mailnod; | |
24 | ||
25 | ||
26 | /* ======== variable and string handling ======== */ | |
27 | ||
28 | syslook(w,syswds) | |
29 | STRING w; | |
30 | SYSTAB syswds; | |
31 | { | |
32 | REG CHAR first; | |
33 | REG STRING s; | |
34 | REG SYSPTR syscan; | |
35 | ||
36 | syscan=syswds; first = *w; | |
37 | ||
38 | WHILE s=syscan->sysnam | |
39 | DO IF first == *s | |
40 | ANDF eq(w,s) | |
41 | THEN return(syscan->sysval); | |
42 | FI | |
43 | syscan++; | |
44 | OD | |
45 | return(0); | |
46 | } | |
47 | ||
48 | setlist(arg,xp) | |
49 | REG ARGPTR arg; | |
50 | INT xp; | |
51 | { | |
52 | WHILE arg | |
53 | DO REG STRING s=mactrim(arg->argval); | |
54 | setname(s, xp); | |
55 | arg=arg->argnxt; | |
56 | IF flags&execpr | |
57 | THEN prs(s); | |
58 | IF arg THEN blank(); ELSE newline(); FI | |
59 | FI | |
60 | OD | |
61 | } | |
62 | ||
63 | VOID setname(argi, xp) | |
64 | STRING argi; | |
65 | INT xp; | |
66 | { | |
67 | REG STRING argscan=argi; | |
68 | REG NAMPTR n; | |
69 | ||
70 | IF letter(*argscan) | |
71 | THEN WHILE alphanum(*argscan) DO argscan++ OD | |
72 | IF *argscan=='=' | |
73 | THEN *argscan = 0; | |
74 | n=lookup(argi); | |
75 | *argscan++ = '='; | |
76 | attrib(n, xp); | |
77 | IF xp&N_ENVNAM | |
78 | THEN n->namenv = n->namval = argscan; | |
79 | ELSE assign(n, argscan); | |
80 | FI | |
81 | return; | |
82 | FI | |
83 | FI | |
84 | failed(argi,notid); | |
85 | } | |
86 | ||
87 | replace(a, v) | |
88 | REG STRING *a; | |
89 | STRING v; | |
90 | { | |
91 | free(*a); *a=make(v); | |
92 | } | |
93 | ||
94 | dfault(n,v) | |
95 | NAMPTR n; | |
96 | STRING v; | |
97 | { | |
98 | IF n->namval==0 | |
99 | THEN assign(n,v) | |
100 | FI | |
101 | } | |
102 | ||
103 | assign(n,v) | |
104 | NAMPTR n; | |
105 | STRING v; | |
106 | { | |
107 | IF n->namflg&N_RDONLY | |
108 | THEN failed(n->namid,wtfailed); | |
109 | ELSE replace(&n->namval,v); | |
110 | FI | |
111 | } | |
112 | ||
113 | INT readvar(names) | |
114 | STRING *names; | |
115 | { | |
116 | FILEBLK fb; | |
117 | REG FILE f = &fb; | |
118 | REG CHAR c; | |
119 | REG INT rc=0; | |
120 | NAMPTR n=lookup(*names++); /* done now to avoid storage mess */ | |
121 | STKPTR rel=relstak(); | |
122 | ||
123 | push(f); initf(dup(0)); | |
124 | IF lseek(0,0L,1)==-1 | |
125 | THEN f->fsiz=1; | |
126 | FI | |
127 | ||
128 | LOOP c=nextc(0); | |
129 | IF (*names ANDF any(c, ifsnod.namval)) ORF eolchar(c) | |
130 | THEN zerostak(); | |
131 | assign(n,absstak(rel)); setstak(rel); | |
132 | IF *names | |
133 | THEN n=lookup(*names++); | |
134 | ELSE n=0; | |
135 | FI | |
136 | IF eolchar(c) | |
137 | THEN break; | |
138 | FI | |
139 | ELSE pushstak(c); | |
140 | FI | |
141 | POOL | |
142 | WHILE n | |
143 | DO assign(n, nullstr); | |
144 | IF *names THEN n=lookup(*names++); ELSE n=0; FI | |
145 | OD | |
146 | ||
147 | IF eof THEN rc=1 FI | |
148 | lseek(0, (long)(f->fnxt-f->fend), 1); | |
149 | pop(); | |
150 | return(rc); | |
151 | } | |
152 | ||
153 | assnum(p, i) | |
154 | STRING *p; | |
155 | INT i; | |
156 | { | |
157 | itos(i); replace(p,numbuf); | |
158 | } | |
159 | ||
160 | STRING make(v) | |
161 | STRING v; | |
162 | { | |
163 | REG STRING p; | |
164 | ||
165 | IF v | |
166 | THEN movstr(v,p=alloc(length(v))); | |
167 | return(p); | |
168 | ELSE return(0); | |
169 | FI | |
170 | } | |
171 | ||
172 | ||
173 | NAMPTR lookup(nam) | |
174 | REG STRING nam; | |
175 | { | |
176 | REG NAMPTR nscan=namep; | |
177 | REG NAMPTR *prev; | |
178 | INT LR; | |
179 | ||
180 | IF !chkid(nam) | |
181 | THEN failed(nam,notid); | |
182 | FI | |
183 | WHILE nscan | |
184 | DO IF (LR=cf(nam,nscan->namid))==0 | |
185 | THEN return(nscan); | |
186 | ELIF LR<0 | |
187 | THEN prev = &(nscan->namlft); | |
188 | ELSE prev = &(nscan->namrgt); | |
189 | FI | |
190 | nscan = *prev; | |
191 | OD | |
192 | ||
193 | /* add name node */ | |
194 | nscan=alloc(sizeof *nscan); | |
195 | nscan->namlft=nscan->namrgt=NIL; | |
196 | nscan->namid=make(nam); | |
197 | nscan->namval=0; nscan->namflg=N_DEFAULT; nscan->namenv=0; | |
198 | return(*prev = nscan); | |
199 | } | |
200 | ||
201 | LOCAL BOOL chkid(nam) | |
202 | STRING nam; | |
203 | { | |
204 | REG CHAR * cp=nam; | |
205 | ||
206 | IF !letter(*cp) | |
207 | THEN return(FALSE); | |
208 | ELSE WHILE *++cp | |
209 | DO IF !alphanum(*cp) | |
210 | THEN return(FALSE); | |
211 | FI | |
212 | OD | |
213 | FI | |
214 | return(TRUE); | |
215 | } | |
216 | ||
217 | LOCAL VOID (*namfn)(); | |
218 | namscan(fn) | |
219 | VOID (*fn)(); | |
220 | { | |
221 | namfn=fn; | |
222 | namwalk(namep); | |
223 | } | |
224 | ||
225 | LOCAL VOID namwalk(np) | |
226 | REG NAMPTR np; | |
227 | { | |
228 | IF np | |
229 | THEN namwalk(np->namlft); | |
230 | (*namfn)(np); | |
231 | namwalk(np->namrgt); | |
232 | FI | |
233 | } | |
234 | ||
235 | VOID printnam(n) | |
236 | NAMPTR n; | |
237 | { | |
238 | REG STRING s; | |
239 | ||
240 | sigchk(); | |
241 | IF s=n->namval | |
242 | THEN prs(n->namid); | |
243 | prc('='); prs(s); | |
244 | newline(); | |
245 | FI | |
246 | } | |
247 | ||
248 | LOCAL STRING staknam(n) | |
249 | REG NAMPTR n; | |
250 | { | |
251 | REG STRING p; | |
252 | ||
253 | p=movstr(n->namid,staktop); | |
254 | p=movstr("=",p); | |
255 | p=movstr(n->namval,p); | |
256 | return(getstak(p+1-ADR(stakbot))); | |
257 | } | |
258 | ||
259 | VOID exname(n) | |
260 | REG NAMPTR n; | |
261 | { | |
262 | IF n->namflg&N_EXPORT | |
263 | THEN free(n->namenv); | |
264 | n->namenv = make(n->namval); | |
265 | ELSE free(n->namval); | |
266 | n->namval = make(n->namenv); | |
267 | FI | |
268 | } | |
269 | ||
270 | VOID printflg(n) | |
271 | REG NAMPTR n; | |
272 | { | |
273 | IF n->namflg&N_EXPORT | |
274 | THEN prs(export); blank(); | |
275 | FI | |
276 | IF n->namflg&N_RDONLY | |
277 | THEN prs(readonly); blank(); | |
278 | FI | |
279 | IF n->namflg&(N_EXPORT|N_RDONLY) | |
280 | THEN prs(n->namid); newline(); | |
281 | FI | |
282 | } | |
283 | ||
284 | VOID getenv() | |
285 | { | |
286 | REG STRING *e=environ; | |
287 | ||
288 | WHILE *e | |
289 | DO setname(*e++, N_ENVNAM) OD | |
290 | } | |
291 | ||
292 | LOCAL INT namec; | |
293 | ||
294 | VOID countnam(n) | |
295 | NAMPTR n; | |
296 | { | |
297 | namec++; | |
298 | } | |
299 | ||
300 | LOCAL STRING *argnam; | |
301 | ||
302 | VOID pushnam(n) | |
303 | NAMPTR n; | |
304 | { | |
305 | IF n->namval | |
306 | THEN *argnam++ = staknam(n); | |
307 | FI | |
308 | } | |
309 | ||
310 | STRING *setenv() | |
311 | { | |
312 | REG STRING *er; | |
313 | ||
314 | namec=0; | |
315 | namscan(countnam); | |
316 | argnam = er = getstak(namec*BYTESPERWORD+BYTESPERWORD); | |
317 | namscan(pushnam); | |
318 | *argnam++ = 0; | |
319 | return(er); | |
320 | } |