xref: /original-bsd/old/sh/name.c (revision 6386612b)
1 #ifndef lint
2 static char sccsid[] = "@(#)name.c	4.3 03/19/85";
3 #endif
4 
5 #
6 /*
7  * UNIX shell
8  *
9  * S. R. Bourne
10  * Bell Telephone Laboratories
11  *
12  */
13 
14 #include	"defs.h"
15 
16 PROC BOOL	chkid();
17 
18 
19 NAMNOD	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 
27 NAMPTR		namep = &mailnod;
28 
29 
30 /* ========	variable and string handling	======== */
31 
32 syslook(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 
52 setlist(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 
67 VOID	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 
91 replace(a, v)
92 	REG STRING	*a;
93 	STRING		v;
94 {
95 	free(*a); *a=make(v);
96 }
97 
98 dfault(n,v)
99 	NAMPTR		n;
100 	STRING		v;
101 {
102 	IF n->namval==0
103 	THEN	assign(n,v)
104 	FI
105 }
106 
107 assign(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 
117 INT	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 
157 assnum(p, i)
158 	STRING		*p;
159 	INT		i;
160 {
161 	itos(i); replace(p,numbuf);
162 }
163 
164 STRING	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 
177 NAMPTR		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 
205 LOCAL 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 
221 LOCAL VOID (*namfn)();
222 namscan(fn)
223 	VOID		(*fn)();
224 {
225 	namfn=fn;
226 	namwalk(namep);
227 }
228 
229 LOCAL 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 
239 VOID	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 
252 LOCAL 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 
263 VOID	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 
274 VOID	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 
288 VOID	setupenv()
289 {
290 	REG STRING	*e=environ;
291 
292 	WHILE *e
293 	DO setname(*e++, N_ENVNAM) OD
294 }
295 
296 LOCAL INT	namec;
297 
298 VOID	countnam(n)
299 	NAMPTR		n;
300 {
301 	namec++;
302 }
303 
304 LOCAL STRING 	*argnam;
305 
306 VOID	pushnam(n)
307 	NAMPTR		n;
308 {
309 	IF n->namval
310 	THEN	*argnam++ = staknam(n);
311 	FI
312 }
313 
314 STRING	*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 }
325