xref: /original-bsd/old/sh/name.c (revision 7a4e9f34)
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 }
323