6875d28af55e6ea7eea0cbe6a81c7083cb443140
[p5sagit/p5-mst-13.2.git] / array.c
1 /* $Header: array.c,v 3.0 89/10/18 15:08:33 lwall Locked $
2  *
3  *    Copyright (c) 1989, Larry Wall
4  *
5  *    You may distribute under the terms of the GNU General Public License
6  *    as specified in the README file that comes with the perl 3.0 kit.
7  *
8  * $Log:        array.c,v $
9  * Revision 3.0  89/10/18  15:08:33  lwall
10  * 3.0 baseline
11  * 
12  */
13
14 #include "EXTERN.h"
15 #include "perl.h"
16
17 STR *
18 afetch(ar,key,lval)
19 register ARRAY *ar;
20 int key;
21 int lval;
22 {
23     STR *str;
24
25     if (key < 0 || key > ar->ary_fill) {
26         if (lval && key >= 0) {
27             if (ar->ary_flags & ARF_REAL)
28                 str = Str_new(5,0);
29             else
30                 str = str_static(&str_undef);
31             (void)astore(ar,key,str);
32             return str;
33         }
34         else
35             return Nullstr;
36     }
37     if (lval && !ar->ary_array[key]) {
38         str = Str_new(6,0);
39         (void)astore(ar,key,str);
40         return str;
41     }
42     return ar->ary_array[key];
43 }
44
45 bool
46 astore(ar,key,val)
47 register ARRAY *ar;
48 int key;
49 STR *val;
50 {
51     int retval;
52
53     if (key < 0)
54         return FALSE;
55     if (key > ar->ary_max) {
56         int newmax;
57
58         if (ar->ary_alloc != ar->ary_array) {
59             retval = ar->ary_array - ar->ary_alloc;
60             Copy(ar->ary_array, ar->ary_alloc, ar->ary_max+1, STR*);
61             Zero(ar->ary_alloc+ar->ary_max+1, retval, STR*);
62             ar->ary_max += retval;
63             ar->ary_array -= retval;
64             if (key > ar->ary_max - 10) {
65                 newmax = key + ar->ary_max;
66                 goto resize;
67             }
68         }
69         else {
70             newmax = key + ar->ary_max / 5;
71           resize:
72             Renew(ar->ary_alloc,newmax+1, STR*);
73             Zero(&ar->ary_alloc[ar->ary_max+1], newmax - ar->ary_max, STR*);
74             ar->ary_array = ar->ary_alloc;
75             ar->ary_max = newmax;
76         }
77     }
78     if ((ar->ary_flags & ARF_REAL) && ar->ary_fill < key) {
79         while (++ar->ary_fill < key) {
80             if (ar->ary_array[ar->ary_fill] != Nullstr) {
81                 str_free(ar->ary_array[ar->ary_fill]);
82                 ar->ary_array[ar->ary_fill] = Nullstr;
83             }
84         }
85     }
86     retval = (ar->ary_array[key] != Nullstr);
87     if (retval && (ar->ary_flags & ARF_REAL))
88         str_free(ar->ary_array[key]);
89     ar->ary_array[key] = val;
90     return retval;
91 }
92
93 ARRAY *
94 anew(stab)
95 STAB *stab;
96 {
97     register ARRAY *ar;
98
99     New(1,ar,1,ARRAY);
100     Newz(2,ar->ary_alloc,5,STR*);
101     ar->ary_array = ar->ary_alloc;
102     ar->ary_magic = Str_new(7,0);
103     str_magic(ar->ary_magic, stab, '#', Nullch, 0);
104     ar->ary_fill = -1;
105     ar->ary_index = -1;
106     ar->ary_max = 4;
107     ar->ary_flags = ARF_REAL;
108     return ar;
109 }
110
111 ARRAY *
112 afake(stab,size,strp)
113 STAB *stab;
114 int size;
115 STR **strp;
116 {
117     register ARRAY *ar;
118
119     New(3,ar,1,ARRAY);
120     New(4,ar->ary_alloc,size+1,STR*);
121     Copy(strp,ar->ary_alloc,size,STR*);
122     ar->ary_array = ar->ary_alloc;
123     ar->ary_magic = Str_new(8,0);
124     str_magic(ar->ary_magic, stab, '#', Nullch, 0);
125     ar->ary_fill = size - 1;
126     ar->ary_index = -1;
127     ar->ary_max = size - 1;
128     ar->ary_flags = 0;
129     return ar;
130 }
131
132 void
133 aclear(ar)
134 register ARRAY *ar;
135 {
136     register int key;
137
138     if (!ar || !(ar->ary_flags & ARF_REAL))
139         return;
140     if (key = ar->ary_array - ar->ary_alloc) {
141         ar->ary_max += key;
142         ar->ary_array -= key;
143     }
144     for (key = 0; key <= ar->ary_max; key++)
145         str_free(ar->ary_array[key]);
146     ar->ary_fill = -1;
147     Zero(ar->ary_array, ar->ary_max+1, STR*);
148 }
149
150 void
151 afree(ar)
152 register ARRAY *ar;
153 {
154     register int key;
155
156     if (!ar)
157         return;
158     if (key = ar->ary_array - ar->ary_alloc) {
159         ar->ary_max += key;
160         ar->ary_array -= key;
161     }
162     if (ar->ary_flags & ARF_REAL) {
163         for (key = 0; key <= ar->ary_max; key++)
164             str_free(ar->ary_array[key]);
165     }
166     str_free(ar->ary_magic);
167     Safefree(ar->ary_alloc);
168     Safefree(ar);
169 }
170
171 bool
172 apush(ar,val)
173 register ARRAY *ar;
174 STR *val;
175 {
176     return astore(ar,++(ar->ary_fill),val);
177 }
178
179 STR *
180 apop(ar)
181 register ARRAY *ar;
182 {
183     STR *retval;
184
185     if (ar->ary_fill < 0)
186         return Nullstr;
187     retval = ar->ary_array[ar->ary_fill];
188     ar->ary_array[ar->ary_fill--] = Nullstr;
189     return retval;
190 }
191
192 aunshift(ar,num)
193 register ARRAY *ar;
194 register int num;
195 {
196     register int i;
197     register STR **sstr,**dstr;
198
199     if (num <= 0)
200         return;
201     if (ar->ary_array - ar->ary_alloc >= num) {
202         ar->ary_max += num;
203         ar->ary_fill += num;
204         while (num--)
205             *--ar->ary_array = Nullstr;
206     }
207     else {
208         (void)astore(ar,ar->ary_fill+num,(STR*)0);      /* maybe extend array */
209         dstr = ar->ary_array + ar->ary_fill;
210         sstr = dstr - num;
211         for (i = ar->ary_fill; i >= 0; i--) {
212             *dstr-- = *sstr--;
213         }
214         Zero(ar->ary_array, num, STR*);
215     }
216 }
217
218 STR *
219 ashift(ar)
220 register ARRAY *ar;
221 {
222     STR *retval;
223
224     if (ar->ary_fill < 0)
225         return Nullstr;
226     retval = *ar->ary_array;
227     *(ar->ary_array++) = Nullstr;
228     ar->ary_max--;
229     ar->ary_fill--;
230     return retval;
231 }
232
233 int
234 alen(ar)
235 register ARRAY *ar;
236 {
237     return ar->ary_fill;
238 }
239
240 afill(ar, fill)
241 register ARRAY *ar;
242 int fill;
243 {
244     if (fill < 0)
245         fill = -1;
246     if (fill <= ar->ary_max)
247         ar->ary_fill = fill;
248     else
249         (void)astore(ar,fill,Nullstr);
250 }