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