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