1*35187Smarc /*
2*35187Smarc 
3*35187Smarc  *      Copyright (c) 1984, 1985, 1986 AT&T
4*35187Smarc  *      All Rights Reserved
5*35187Smarc 
6*35187Smarc  *      THIS IS UNPUBLISHED PROPRIETARY SOURCE
7*35187Smarc  *      CODE OF AT&T.
8*35187Smarc  *      The copyright notice above does not
9*35187Smarc  *      evidence any actual or intended
10*35187Smarc  *      publication of such source code.
11*35187Smarc 
12*35187Smarc  */
13*35187Smarc /* @(#)findnod.c	1.1 */
14*35187Smarc 
15*35187Smarc /*
16*35187Smarc  *   FINDNOD.C
17*35187Smarc  *
18*35187Smarc  *   Programmer:  D. G. Korn
19*35187Smarc  *
20*35187Smarc  *        Owner:  D. A. Lambeth
21*35187Smarc  *
22*35187Smarc  *         Date:  April 17, 1980
23*35187Smarc  *
24*35187Smarc  *
25*35187Smarc  *
26*35187Smarc  *   FINDNOD (NAME, ROOT, TYPE)
27*35187Smarc  *
28*35187Smarc  *        Return a pointer to the Namnod in the tree given by
29*35187Smarc  *        ROOT whose namid is NAME.  If TYPE has non-zero last bit, create
30*35187Smarc  *        a new node with namid NAME, if one does not exist, and
31*35187Smarc  *        insert it into ROOT.
32*35187Smarc  *
33*35187Smarc  *   _NAMP (NAME, ROOT, TYPE)
34*35187Smarc  *
35*35187Smarc  *        Return a pointer to the Namnod in the linked list
36*35187Smarc  *        of Namnods given by ROOT whose namid is NAME.  If
37*35187Smarc  *        TYPE is non-zero, create a new node with namid
38*35187Smarc  *        NAME, if one does not exist, and link it into the list.
39*35187Smarc  *
40*35187Smarc  *   MAK_NOD (NAME)
41*35187Smarc  *
42*35187Smarc  *        Allocate a Namnod, setting its namid to NAME and its
43*35187Smarc  *        value to VALUE to NULL.
44*35187Smarc  *
45*35187Smarc  *   COPY_NOD(NODE, TYPE)
46*35187Smarc  *
47*35187Smarc  *	  Return a pointer to a Namnod in the last Shell tree
48*35187Smarc  *	  whose name is the same as that in NODE.
49*35187Smarc  *	  If TYPE is non-zero the attributes of NODE
50*35187Smarc  *	  are also copied.
51*35187Smarc  *
52*35187Smarc  *
53*35187Smarc  *   See Also:  lookup(III), linknod(III), chkid(III)
54*35187Smarc  */
55*35187Smarc 
56*35187Smarc #include	"name.h"
57*35187Smarc #include        "flags.h"
58*35187Smarc 
59*35187Smarc #define round(a,b)	(a+b-1)&~(b-1)
60*35187Smarc 
61*35187Smarc struct Namnod *mak_nod();
62*35187Smarc char	*bracket_match();
63*35187Smarc struct Namnod *findnod();
64*35187Smarc 
65*35187Smarc extern char	*malloc(), *valup();
66*35187Smarc extern char	*strcpy();
67*35187Smarc extern unsigned	chkid();
68*35187Smarc extern void	failed();
69*35187Smarc extern void	assign();
70*35187Smarc extern void	free();
71*35187Smarc extern struct Namaray *growaray();
72*35187Smarc extern long	aeval();
73*35187Smarc #ifdef NAME_SCOPE
74*35187Smarc extern	char	*index();
75*35187Smarc struct Namnod *copy_nod();
76*35187Smarc #endif
77*35187Smarc static struct Namnod *_namp();
78*35187Smarc 
79*35187Smarc static int save_i;
80*35187Smarc 
81*35187Smarc /*
82*35187Smarc  *   FINDNOD (NAME, ROOT, TYPE)
83*35187Smarc  *
84*35187Smarc  *        char *NAME;
85*35187Smarc  *
86*35187Smarc  *        struct Amemory *ROOT;
87*35187Smarc  *
88*35187Smarc  *        int TYPE;
89*35187Smarc  *
90*35187Smarc  *   Return a pointer to the Namnod in tree ROOT whose namid is
91*35187Smarc  *   NAME.  If TYPE is non-zero, a Namnod of the given id will
92*35187Smarc  *   be created, if necessary.  If the RE_USE bit is set then
93*35187Smarc  *   the hash code will not be recomputed.  This is set in
94*35187Smarc  *   lookup(III) when looking up the name in several trees.
95*35187Smarc  *
96*35187Smarc  *   If TYPE is zero, and NAME is not found, NULL is returned.
97*35187Smarc  *
98*35187Smarc  *   NAME should be of a form acceptable to chkid(III).
99*35187Smarc  *
100*35187Smarc  *   Algorithm:  Memory (ROOT) is an array of linked lists of
101*35187Smarc  *               Namnods.  Hashing on NAME selects one list; a
102*35187Smarc  *               scan of this locates the node of interest.
103*35187Smarc  */
104*35187Smarc 
findnod(name,root,type)105*35187Smarc struct Namnod *findnod(name,root,type)
106*35187Smarc char *name;
107*35187Smarc struct Amemory *root;
108*35187Smarc {
109*35187Smarc 	register char *cp = name;
110*35187Smarc 	register int c;
111*35187Smarc 	struct Namnod *np = NULL;
112*35187Smarc 	{
113*35187Smarc 		register int i;
114*35187Smarc 		while((c = *((unsigned char*)cp++)) && c!= '[');
115*35187Smarc 		if(c)
116*35187Smarc 			*--cp = 0;
117*35187Smarc 		if((type&RE_USE)==0)
118*35187Smarc 			save_i = chkid(name);
119*35187Smarc 		if((i=save_i)==0)
120*35187Smarc 		{
121*35187Smarc 			if(type&CHK_FOR)
122*35187Smarc 				goto skip;
123*35187Smarc 	        	failed (name, notid);
124*35187Smarc 		}
125*35187Smarc 		i &= root->memsize-1;
126*35187Smarc 		np = _namp(name,&root->memhead[i],type&ADD_NOD);
127*35187Smarc 	skip:
128*35187Smarc 		if(c)
129*35187Smarc 			*cp = c;
130*35187Smarc 		if(np == NULL)
131*35187Smarc 			return(np);
132*35187Smarc 		if ((c == 0) && !(attest (np, ARRAY)))
133*35187Smarc 			return(np);
134*35187Smarc 		if(c == 0)
135*35187Smarc 		{
136*35187Smarc 	        	setdot (np, 0);
137*35187Smarc 			return(np);
138*35187Smarc 		}
139*35187Smarc 	}
140*35187Smarc 	{
141*35187Smarc 		register struct Namaray *ap;
142*35187Smarc 		register int dot;
143*35187Smarc 		char *sp;
144*35187Smarc 		struct Namnod *nq;
145*35187Smarc 		if (attest (np, ARRAY))
146*35187Smarc 			ap = arayp (np);
147*35187Smarc 		else
148*35187Smarc 		{
149*35187Smarc #ifdef NAME_SCOPE
150*35187Smarc 			if(attest(np, C_WRITE))
151*35187Smarc 			{
152*35187Smarc 				np = copy_nod(np,2);
153*35187Smarc 			}
154*35187Smarc #endif
155*35187Smarc 			ap = growaray((struct Namaray *)NULL,0);
156*35187Smarc 		}
157*35187Smarc 		cp = bracket_match(sp=cp);
158*35187Smarc 		c = *cp;
159*35187Smarc 		*cp = 0;
160*35187Smarc 		dot = (int)aeval((char*)sp+1);
161*35187Smarc 		*cp = c;
162*35187Smarc 		if ((dot >= ARRMAX) || (dot < 0))
163*35187Smarc 			failed(name,subscript);
164*35187Smarc 		else
165*35187Smarc 	        	ap->adot = dot;
166*35187Smarc 		if (!attest (np, ARRAY))
167*35187Smarc 			if (dot == 0)
168*35187Smarc 			{
169*35187Smarc 				free((char *)ap);
170*35187Smarc 				return(np);
171*35187Smarc 			}
172*35187Smarc 			else if ((cp = valup (np)) != NULL)
173*35187Smarc 	        	{
174*35187Smarc 		        	nq = mak_nod (np->namid);
175*35187Smarc 				nq->value.namflg = np->value.namflg;
176*35187Smarc 		        	assign (nq, cp);
177*35187Smarc 		        	ap->val[0] = &nq->value;
178*35187Smarc 		        }
179*35187Smarc 		if (dot > ap->maxi)
180*35187Smarc 			ap = growaray (ap, dot);
181*35187Smarc 		np->value.namval.aray = ap;
182*35187Smarc 		np->value.namflg |= ARRAY;
183*35187Smarc 		setdot (np, dot);
184*35187Smarc 		return(np);
185*35187Smarc 	}
186*35187Smarc }
187*35187Smarc 
188*35187Smarc 
189*35187Smarc /*
190*35187Smarc  * skip to a matching ']' and return pointer to matched character
191*35187Smarc  * routine assumes that you are sitting on the '['
192*35187Smarc  */
193*35187Smarc 
bracket_match(string)194*35187Smarc char *bracket_match(string)
195*35187Smarc register char *string;
196*35187Smarc {
197*35187Smarc 	register int count = 1;
198*35187Smarc 	register int c;
199*35187Smarc 	while(count>0 && (c= *++string))
200*35187Smarc 	{
201*35187Smarc 		if(c=='[')
202*35187Smarc 			count++;
203*35187Smarc 		else if(c==']')
204*35187Smarc 			count--;
205*35187Smarc 	}
206*35187Smarc 	return(string);
207*35187Smarc }
208*35187Smarc 
209*35187Smarc /*
210*35187Smarc  *   _NAMP (NAME, ROOT, TYPE)
211*35187Smarc  *
212*35187Smarc  *        char *NAME;
213*35187Smarc  *
214*35187Smarc  *        struct Amemory *ROOT;
215*35187Smarc  *
216*35187Smarc  *        int TYPE;
217*35187Smarc  *
218*35187Smarc  *   Return a pointer to the Namnod in a linked list of
219*35187Smarc  *   Namnods (given by ROOT) whose namid is NAME.  If TYPE
220*35187Smarc  *   is non-zero, a new Namnod with the given NAME will
221*35187Smarc  *   be inserted, if none is found.
222*35187Smarc  *
223*35187Smarc  *   NAME should be of a form acceptable to chkid(III).
224*35187Smarc  */
225*35187Smarc 
_namp(name,root,type)226*35187Smarc static struct Namnod *_namp(name,root,type)
227*35187Smarc char *name;
228*35187Smarc struct Namnod **root;
229*35187Smarc {
230*35187Smarc 	register char *cp,*sp;
231*35187Smarc 	register struct Namnod *np;
232*35187Smarc 	register struct Namnod *nq = NULL;
233*35187Smarc 	struct Namnod *rp = *root;
234*35187Smarc 
235*35187Smarc 	for(np=rp;np;nq=np,np=np->namnxt)
236*35187Smarc 	{
237*35187Smarc 		if((np->value.namflg&N_AVAIL)==0)
238*35187Smarc 		{
239*35187Smarc 			/* match even if np->name has an = in it */
240*35187Smarc 			cp = np->namid;
241*35187Smarc 			sp = name;
242*35187Smarc 			do
243*35187Smarc 			{
244*35187Smarc 				if(*sp==0)
245*35187Smarc 				{
246*35187Smarc 					if(*cp && *cp != '=')
247*35187Smarc 						break;
248*35187Smarc 					if(nq==NULL)
249*35187Smarc 						return(np);
250*35187Smarc 					nq->namnxt = np->namnxt;
251*35187Smarc 					np->namnxt = rp;
252*35187Smarc 					return(*root=np);
253*35187Smarc 				}
254*35187Smarc 			}
255*35187Smarc 			while(*sp++ == *cp++);
256*35187Smarc 		}
257*35187Smarc 	}
258*35187Smarc 	if(type==0)
259*35187Smarc 		return((struct Namnod*)NULL);
260*35187Smarc 	np = mak_nod(name);
261*35187Smarc 	np->namnxt = rp;
262*35187Smarc 	return(*root=np);
263*35187Smarc }
264*35187Smarc 
265*35187Smarc /*
266*35187Smarc  *   MAKNOD (NAME)
267*35187Smarc  *
268*35187Smarc  *        char *NAME;
269*35187Smarc  *
270*35187Smarc  *   Allocate a Namnod, setting its namid to NAME and its value
271*35187Smarc  *   to VALUE to NULL.  A pointer to the allocated node is returned.
272*35187Smarc  *   NULL is returned if there is no space to be allocated
273*35187Smarc  *   for the Namnod.
274*35187Smarc  *
275*35187Smarc  *   NAME should be of a form acceptable to chkid(III).
276*35187Smarc  */
277*35187Smarc 
mak_nod(name)278*35187Smarc struct Namnod *mak_nod(name)
279*35187Smarc char *name;
280*35187Smarc {
281*35187Smarc 	register struct Namnod *np;
282*35187Smarc 	if((np=(struct Namnod *)malloc((unsigned)sizeof(struct Namnod)+strlen(name)+1)) == (struct Namnod*)NULL)
283*35187Smarc 		return(np);
284*35187Smarc 	np->namid = (char *)(np+1);
285*35187Smarc 	strcpy (np->namid, name);
286*35187Smarc 	np->value.namflg = N_DEFAULT;
287*35187Smarc 	np->value.namval.cp = NULL;
288*35187Smarc 	np->namnxt = NULL;
289*35187Smarc 	np->namsz = 0;
290*35187Smarc 	return(np);
291*35187Smarc }
292*35187Smarc 
293*35187Smarc #ifdef NAME_SCOPE
copy_nod(node,type)294*35187Smarc struct Namnod *copy_nod(node, type)
295*35187Smarc struct Namnod *node;
296*35187Smarc int type;
297*35187Smarc {
298*35187Smarc 	register struct Namnod *oldnp = node;
299*35187Smarc 	register struct Namnod *newnp;
300*35187Smarc 	register struct Amemory *rootp=namep;
301*35187Smarc 	char *cp;
302*35187Smarc 	while(rootp->nexttree)
303*35187Smarc 		rootp = rootp->nexttree;	/* skip to last tree */
304*35187Smarc 	if(cp = index(node->namid,'='))
305*35187Smarc 		*cp = 0;
306*35187Smarc 	newnp = findnod(oldnp->namid,rootp,1);
307*35187Smarc 	if(cp)
308*35187Smarc 		*cp = '=';
309*35187Smarc 	if(type==0)
310*35187Smarc 		return(newnp);
311*35187Smarc 	oldnp->value.namflg &= ~C_WRITE;
312*35187Smarc 	newnp->value.namflg = oldnp->value.namflg&~(IN_DIR|N_FREE|N_ALLOC);
313*35187Smarc 	newnp->namid = oldnp->namid;
314*35187Smarc 	oldnp->value.namflg |= N_AVAIL;
315*35187Smarc 	if(attest(oldnp, ARRAY))
316*35187Smarc 	{
317*35187Smarc 		register struct Namaray *ap1,*ap2;
318*35187Smarc 		int dot;
319*35187Smarc 		char *val;
320*35187Smarc 		ap1 = arayp(oldnp);
321*35187Smarc 		dot = ap1->adot;
322*35187Smarc 		ap2 = growaray((struct Namaray*)0,ap1->maxi);
323*35187Smarc 		newnp->value.namval.aray = ap2;
324*35187Smarc 		for(ap1->adot=0;ap1->adot <= ap1->maxi;ap1->adot++)
325*35187Smarc 			if(val=valup(oldnp))
326*35187Smarc 			{
327*35187Smarc 				ap2->adot = ap1->adot;
328*35187Smarc 				assign(newnp,val);
329*35187Smarc 			}
330*35187Smarc 		ap2->adot = dot;
331*35187Smarc 	}
332*35187Smarc 	else if(type==2 )
333*35187Smarc 		assign(newnp,valup(oldnp));
334*35187Smarc 	return(newnp);
335*35187Smarc }
336*35187Smarc #endif	/* NAME_SCOPE */
337