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