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