1 /*
2 
3  *      Copyright (c) 1984, 1985, 1986 AT&T
4  *      All Rights Reserved
5 
6  *      THIS IS UNPUBLISHED PROPRIETARY SOURCE
7  *      CODE OF AT&T.
8  *      The copyright notice above does not
9  *      evidence any actual or intended
10  *      publication of such source code.
11 
12  */
13 /* @(#)growaray.c	1.1 */
14 
15 /*
16  *   GROWARAY.C
17  *
18  *   Programmer:  D. G. Korn
19  *
20  *        Owner:  D. A. Lambeth
21  *
22  *         Date:  April 17, 1980
23  *
24  *
25  *
26  *   GROWARAY (ARP, MAXI)
27  *
28  *        Create or expand the size of an array of Namnods, ARP,
29  *        such that MAXI is a legal index into ARP.
30  *
31  *   SETDOT (NODE, INDEX)
32  *
33  *        Set the current index of the array NODE to be INDEX.
34  *        (library only)
35  *
36  *
37  *
38  *   See Also:  linknod(III)
39  */
40 
41 #include	"name.h"
42 #include        "flags.h"
43 
44 struct Namaray *growaray();
45 int	arsize ();
46 #ifndef KSHELL
47 void	setdot ();
48 #endif	/* KSHELL */
49 
50 #define round(a,b)	((a+b-1)&~(b-1))
51 extern char	*malloc();
52 extern char	*itos();
53 extern void	failed();
54 extern void	free();
55 
56 /*
57  *   GROWARAY (ARP, MAXI)
58  *
59  *        struct Namaray *ARP;
60  *
61  *        int MAXI;
62  *
63  *        Increase the size of the array of Namnods given by ARP
64  *        so that MAXI is a legal index.  If ARP is NULL, an array
65  *        of the required size is allocated.  A pointer to the
66  *        allocated Namaray structure is returned.
67  *
68  *        MAXI becomes the current index of the array.
69  */
70 
71 struct Namaray *growaray(arp,maxi)
72 struct Namaray *arp;
73 {
74 	register struct Namaray *ap,*aq;
75 	register int cursize, i;
76 	register int newsize = arsize (maxi);
77 	cursize = ((arp == NULL) ? 0 : arsize ((int)arp->maxi));
78 	if (maxi >= ARRMAX)
79 		failed (itos(maxi), subscript);
80 	if (((aq = ap = arp) == NULL) || (newsize > cursize))
81 	{
82 		ap = (struct Namaray *)malloc((unsigned)(sizeof(struct Namaray)
83 				+ (newsize-1)*sizeof(struct Nodval*)));
84 		ap->maxi = maxi;
85 		for(i=0;i < newsize;i++)
86 			ap->val[i] = NULL;
87 		if(aq)
88 		{
89 			for(i=0;i <= aq->maxi;i++)
90 				ap->val[i] = aq->val[i];
91 			free((char *)aq);
92 		}
93 	}
94 	else
95         	if (maxi > ap->maxi)
96 			ap->maxi = maxi;
97 	ap->adot = maxi;
98 	return(ap);
99 }
100 
101 #ifndef KSHELL
102 
103 /*
104  *   SETDOT (NODE, INDEX)
105  *
106  *        struct Namnod *NODE;
107  *
108  *        int INDEX;
109  *
110  *   Given an array of Namnods NODE, set the current index of NODE
111  *   to INDEX.  Trap if INDEX is out of bounds.  Otherwise allocate
112  *   a Nodval for the INDEXth element of NODE, if necessary.
113  */
114 
115 void	setdot (node, index)
116 struct Namnod *node;
117 int index;
118 {
119 	register struct Nodval *nv;
120 	register struct Namaray *ap = arayp (node);
121 
122 	if ((index > ap->maxi) || (index < 0))
123 		failed (node->namid, subscript);
124 	else
125 		ap->adot = index;
126 	if (ap->val[index] == NULL)
127 	{
128 		nv = (struct Nodval*)malloc (sizeof (struct Nodval));
129 		nv->namflg = node->value.namflg & ~ARRAY;
130 		nv->namval.cp = NULL;
131 		ap->val[index] = nv;
132 	}
133 	return;
134 }
135 #endif	/* KSHELL */
136 
137 /*
138  *   ARSIZE (MAXI)
139  *
140  *        int MAXI;
141  *
142  *   Calculate the amount of space to be allocated to hold
143  *   an array into which MAXI is a legal index.  The number of
144  *   elements that will actually fit into the array (> MAXI
145  *   but <= ARRMAX) is returned.
146  *
147  *   ALGORITHM:  The size of an array can be incremented in
148  *               lots of ARRINCR elements.  Internal size is thus
149  *               the least multiple of ARRINCR that is greater than
150  *               MAXI.  (Note that 0-origin indexing is used.)
151  */
152 
153 int	arsize (maxi)
154 register int maxi;
155 {
156 	register int i = round(maxi+1,ARRINCR);
157 	return (i>ARRMAX?ARRMAX:i);
158 }
159