This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perl 5.0 alpha 2
[perl5.git] / av.c
CommitLineData
79072805
LW
1/* $RCSfile: array.c,v $$Revision: 4.1 $$Date: 92/08/07 17:18:22 $
2 *
3 * Copyright (c) 1991, Larry Wall
4 *
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
7 *
8 * $Log: array.c,v $
9 * Revision 4.1 92/08/07 17:18:22 lwall
10 * Stage 6 Snapshot
11 *
12 * Revision 4.0.1.3 92/06/08 11:45:05 lwall
13 * patch20: Perl now distinguishes overlapped copies from non-overlapped
14 *
15 * Revision 4.0.1.2 91/11/05 16:00:14 lwall
16 * patch11: random cleanup
17 * patch11: passing non-existend array elements to subrouting caused core dump
18 *
19 * Revision 4.0.1.1 91/06/07 10:19:08 lwall
20 * patch4: new copyright notice
21 *
22 * Revision 4.0 91/03/20 01:03:32 lwall
23 * 4.0 baseline.
24 *
25 */
26
27#include "EXTERN.h"
28#include "perl.h"
29
30SV**
31av_fetch(ar,key,lval)
32register AV *ar;
33I32 key;
34I32 lval;
35{
36 SV *sv;
37
38 if (key < 0 || key > AvFILL(ar)) {
39 if (lval && key >= 0) {
40 if (AvREAL(ar))
41 sv = NEWSV(5,0);
42 else
43 sv = sv_mortalcopy(&sv_undef);
44 return av_store(ar,key,sv);
45 }
46 else
47 return 0;
48 }
49 if (!AvARRAY(ar)[key]) {
50 if (lval) {
51 sv = NEWSV(6,0);
52 return av_store(ar,key,sv);
53 }
54 return 0;
55 }
56 return &AvARRAY(ar)[key];
57}
58
59SV**
60av_store(ar,key,val)
61register AV *ar;
62I32 key;
63SV *val;
64{
65 I32 tmp;
66 SV** ary;
67
68 if (key < 0)
69 return 0;
70 if (key > AvMAX(ar)) {
71 I32 newmax;
72
73 if (AvALLOC(ar) != AvARRAY(ar)) {
74 tmp = AvARRAY(ar) - AvALLOC(ar);
75 Move(AvARRAY(ar), AvALLOC(ar), AvMAX(ar)+1, SV*);
76 Zero(AvALLOC(ar)+AvMAX(ar)+1, tmp, SV*);
77 AvMAX(ar) += tmp;
78 AvARRAY(ar) -= tmp;
79 if (key > AvMAX(ar) - 10) {
80 newmax = key + AvMAX(ar);
81 goto resize;
82 }
83 }
84 else {
85 if (AvALLOC(ar)) {
86 newmax = key + AvMAX(ar) / 5;
87 resize:
88 Renew(AvALLOC(ar),newmax+1, SV*);
89 Zero(&AvALLOC(ar)[AvMAX(ar)+1], newmax - AvMAX(ar), SV*);
90 }
91 else {
92 newmax = key < 4 ? 4 : key;
93 Newz(2,AvALLOC(ar), newmax+1, SV*);
94 }
95 AvARRAY(ar) = AvALLOC(ar);
96 AvMAX(ar) = newmax;
97 }
98 }
99 ary = AvARRAY(ar);
100 if (AvREAL(ar)) {
101 if (AvFILL(ar) < key) {
102 while (++AvFILL(ar) < key) {
103 if (ary[AvFILL(ar)] != Nullsv) {
104 sv_free(ary[AvFILL(ar)]);
105 ary[AvFILL(ar)] = Nullsv;
106 }
107 }
108 }
109 if (ary[key])
110 sv_free(ary[key]);
111 }
112 ary[key] = val;
113 return &ary[key];
114}
115
116AV *
117newAV()
118{
119 register AV *ar;
120
121 Newz(1,ar,1,AV);
122 SvREFCNT(ar) = 1;
123 sv_upgrade(ar,SVt_PVAV);
124 AvREAL_on(ar);
125 AvALLOC(ar) = AvARRAY(ar) = 0;
126 AvMAX(ar) = AvFILL(ar) = -1;
127 return ar;
128}
129
130AV *
131av_make(size,strp)
132register I32 size;
133register SV **strp;
134{
135 register AV *ar;
136 register I32 i;
137 register SV** ary;
138
139 Newz(3,ar,1,AV);
140 sv_upgrade(ar,SVt_PVAV);
141 New(4,ary,size+1,SV*);
142 AvALLOC(ar) = ary;
143 Zero(ary,size,SV*);
144 AvREAL_on(ar);
145 AvARRAY(ar) = ary;
146 AvFILL(ar) = size - 1;
147 AvMAX(ar) = size - 1;
148 for (i = 0; i < size; i++) {
149 if (*strp) {
150 ary[i] = NEWSV(7,0);
151 sv_setsv(ary[i], *strp);
152 }
153 strp++;
154 }
155 return ar;
156}
157
158AV *
159av_fake(size,strp)
160register I32 size;
161register SV **strp;
162{
163 register AV *ar;
164 register SV** ary;
165
166 Newz(3,ar,1,AV);
167 SvREFCNT(ar) = 1;
168 sv_upgrade(ar,SVt_PVAV);
169 New(4,ary,size+1,SV*);
170 AvALLOC(ar) = ary;
171 Copy(strp,ary,size,SV*);
172 AvREAL_off(ar);
173 AvARRAY(ar) = ary;
174 AvFILL(ar) = size - 1;
175 AvMAX(ar) = size - 1;
176 while (size--) {
177 if (*strp)
178 SvTEMP_off(*strp);
179 strp++;
180 }
181 return ar;
182}
183
184void
185av_clear(ar)
186register AV *ar;
187{
188 register I32 key;
189
190 if (!ar || !AvREAL(ar) || AvMAX(ar) < 0)
191 return;
192 /*SUPPRESS 560*/
193 if (key = AvARRAY(ar) - AvALLOC(ar)) {
194 AvMAX(ar) += key;
195 AvARRAY(ar) -= key;
196 }
197 for (key = 0; key <= AvMAX(ar); key++)
198 sv_free(AvARRAY(ar)[key]);
199 AvFILL(ar) = -1;
200 Zero(AvARRAY(ar), AvMAX(ar)+1, SV*);
201}
202
203void
204av_undef(ar)
205register AV *ar;
206{
207 register I32 key;
208
209 if (!ar)
210 return;
211 /*SUPPRESS 560*/
212 if (key = AvARRAY(ar) - AvALLOC(ar)) {
213 AvMAX(ar) += key;
214 AvARRAY(ar) -= key;
215 }
216 if (AvREAL(ar)) {
217 for (key = 0; key <= AvMAX(ar); key++)
218 sv_free(AvARRAY(ar)[key]);
219 }
220 Safefree(AvALLOC(ar));
221 AvALLOC(ar) = AvARRAY(ar) = 0;
222 AvMAX(ar) = AvFILL(ar) = -1;
223}
224
225void
226av_free(ar)
227AV *ar;
228{
229 av_undef(ar);
230 Safefree(ar);
231}
232
233bool
234av_push(ar,val)
235register AV *ar;
236SV *val;
237{
238 return av_store(ar,++(AvFILL(ar)),val) != 0;
239}
240
241SV *
242av_pop(ar)
243register AV *ar;
244{
245 SV *retval;
246
247 if (AvFILL(ar) < 0)
248 return Nullsv;
249 retval = AvARRAY(ar)[AvFILL(ar)];
250 AvARRAY(ar)[AvFILL(ar)--] = Nullsv;
251 return retval;
252}
253
254void
255av_popnulls(ar)
256register AV *ar;
257{
258 register I32 fill = AvFILL(ar);
259
260 while (fill >= 0 && !AvARRAY(ar)[fill])
261 fill--;
262 AvFILL(ar) = fill;
263}
264
265void
266av_unshift(ar,num)
267register AV *ar;
268register I32 num;
269{
270 register I32 i;
271 register SV **sstr,**dstr;
272
273 if (num <= 0)
274 return;
275 if (AvARRAY(ar) - AvALLOC(ar) >= num) {
276 AvMAX(ar) += num;
277 AvFILL(ar) += num;
278 while (num--)
279 *--AvARRAY(ar) = Nullsv;
280 }
281 else {
282 (void)av_store(ar,AvFILL(ar)+num,(SV*)0); /* maybe extend array */
283 dstr = AvARRAY(ar) + AvFILL(ar);
284 sstr = dstr - num;
285#ifdef BUGGY_MSC5
286 # pragma loop_opt(off) /* don't loop-optimize the following code */
287#endif /* BUGGY_MSC5 */
288 for (i = AvFILL(ar) - num; i >= 0; i--) {
289 *dstr-- = *sstr--;
290#ifdef BUGGY_MSC5
291 # pragma loop_opt() /* loop-optimization back to command-line setting */
292#endif /* BUGGY_MSC5 */
293 }
294 Zero(AvARRAY(ar), num, SV*);
295 }
296}
297
298SV *
299av_shift(ar)
300register AV *ar;
301{
302 SV *retval;
303
304 if (AvFILL(ar) < 0)
305 return Nullsv;
306 retval = *AvARRAY(ar);
307 *(AvARRAY(ar)++) = Nullsv;
308 AvMAX(ar)--;
309 AvFILL(ar)--;
310 return retval;
311}
312
313I32
314av_len(ar)
315register AV *ar;
316{
317 return AvFILL(ar);
318}
319
320void
321av_fill(ar, fill)
322register AV *ar;
323I32 fill;
324{
325 if (fill < 0)
326 fill = -1;
327 if (fill <= AvMAX(ar))
328 AvFILL(ar) = fill;
329 else {
330 AvFILL(ar) = fill - 1; /* don't clobber in-between values */
331 (void)av_store(ar,fill,Nullsv);
332 }
333}