Bell 32V development
[unix-history] / usr / src / cmd / sh / name.c
CommitLineData
862515b8
TL
1#
2/*
3 * UNIX shell
4 *
5 * S. R. Bourne
6 * Bell Telephone Laboratories
7 *
8 */
9
10#include "defs.h"
11
12PROC BOOL chkid();
13
14
15NAMNOD 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
23NAMPTR namep = &mailnod;
24
25
26/* ======== variable and string handling ======== */
27
28syslook(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
48setlist(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
63VOID 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
87replace(a, v)
88 REG STRING *a;
89 STRING v;
90{
91 free(*a); *a=make(v);
92}
93
94dfault(n,v)
95 NAMPTR n;
96 STRING v;
97{
98 IF n->namval==0
99 THEN assign(n,v)
100 FI
101}
102
103assign(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
113INT 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
153assnum(p, i)
154 STRING *p;
155 INT i;
156{
157 itos(i); replace(p,numbuf);
158}
159
160STRING 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
173NAMPTR 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
201LOCAL 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
217LOCAL VOID (*namfn)();
218namscan(fn)
219 VOID (*fn)();
220{
221 namfn=fn;
222 namwalk(namep);
223}
224
225LOCAL 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
235VOID 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
248LOCAL 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
259VOID 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
270VOID 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
284VOID getenv()
285{
286 REG STRING *e=environ;
287
288 WHILE *e
289 DO setname(*e++, N_ENVNAM) OD
290}
291
292LOCAL INT namec;
293
294VOID countnam(n)
295 NAMPTR n;
296{
297 namec++;
298}
299
300LOCAL STRING *argnam;
301
302VOID pushnam(n)
303 NAMPTR n;
304{
305 IF n->namval
306 THEN *argnam++ = staknam(n);
307 FI
308}
309
310STRING *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}