This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perl 5.0 alpha 9
[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**
463ee0b2
LW
31av_fetch(av,key,lval)
32register AV *av;
79072805
LW
33I32 key;
34I32 lval;
35{
36 SV *sv;
37
8990e307 38 if (SvRMAGICAL(av)) {
463ee0b2
LW
39 if (mg_find((SV*)av,'P')) {
40 if (key < 0)
41 return 0;
8990e307 42 sv = sv_newmortal();
463ee0b2
LW
43 mg_copy((SV*)av, sv, 0, key);
44 if (!lval) {
45 mg_get((SV*)sv);
46 sv_unmagic(sv,'p');
47 }
48 Sv = sv;
49 return &Sv;
50 }
51 }
52
53 if (key < 0 || key > AvFILL(av)) {
ed6116ce
LW
54 if (key < 0) {
55 key += AvFILL(av) + 1;
56 if (key < 0)
57 return 0;
58 }
59 else {
60 if (!lval)
61 return 0;
463ee0b2 62 if (AvREAL(av))
79072805
LW
63 sv = NEWSV(5,0);
64 else
8990e307 65 sv = sv_newmortal();
463ee0b2 66 return av_store(av,key,sv);
79072805 67 }
79072805 68 }
463ee0b2 69 if (!AvARRAY(av)[key]) {
79072805
LW
70 if (lval) {
71 sv = NEWSV(6,0);
463ee0b2 72 return av_store(av,key,sv);
79072805
LW
73 }
74 return 0;
75 }
463ee0b2 76 return &AvARRAY(av)[key];
79072805
LW
77}
78
79SV**
463ee0b2
LW
80av_store(av,key,val)
81register AV *av;
79072805
LW
82I32 key;
83SV *val;
84{
85 I32 tmp;
86 SV** ary;
87
ed6116ce
LW
88 if (key < 0) {
89 key += AvFILL(av) + 1;
90 if (key < 0)
91 return 0;
92 }
463ee0b2 93
8990e307 94 if (SvRMAGICAL(av)) {
463ee0b2
LW
95 if (mg_find((SV*)av,'P')) {
96 mg_copy((SV*)av, val, 0, key);
97 return 0;
98 }
99 }
100
101 if (key > AvMAX(av)) {
79072805
LW
102 I32 newmax;
103
463ee0b2
LW
104 if (AvALLOC(av) != AvARRAY(av)) {
105 tmp = AvARRAY(av) - AvALLOC(av);
106 Move(AvARRAY(av), AvALLOC(av), AvMAX(av)+1, SV*);
107 Zero(AvALLOC(av)+AvMAX(av)+1, tmp, SV*);
108 AvMAX(av) += tmp;
109 SvPVX(av) = (char*)(AvARRAY(av) - tmp);
110 if (key > AvMAX(av) - 10) {
111 newmax = key + AvMAX(av);
79072805
LW
112 goto resize;
113 }
114 }
115 else {
463ee0b2
LW
116 if (AvALLOC(av)) {
117 newmax = key + AvMAX(av) / 5;
79072805 118 resize:
463ee0b2
LW
119 Renew(AvALLOC(av),newmax+1, SV*);
120 Zero(&AvALLOC(av)[AvMAX(av)+1], newmax - AvMAX(av), SV*);
79072805
LW
121 }
122 else {
123 newmax = key < 4 ? 4 : key;
463ee0b2 124 Newz(2,AvALLOC(av), newmax+1, SV*);
79072805 125 }
463ee0b2
LW
126 SvPVX(av) = (char*)AvALLOC(av);
127 AvMAX(av) = newmax;
79072805
LW
128 }
129 }
463ee0b2
LW
130 ary = AvARRAY(av);
131 if (AvREAL(av)) {
132 if (AvFILL(av) < key) {
133 while (++AvFILL(av) < key) {
134 if (ary[AvFILL(av)] != Nullsv) {
8990e307 135 SvREFCNT_dec(ary[AvFILL(av)]);
463ee0b2 136 ary[AvFILL(av)] = Nullsv;
79072805
LW
137 }
138 }
139 }
140 if (ary[key])
8990e307 141 SvREFCNT_dec(ary[key]);
79072805
LW
142 }
143 ary[key] = val;
8990e307 144 if (SvSMAGICAL(av)) {
463ee0b2
LW
145 MAGIC* mg = SvMAGIC(av);
146 sv_magic(val, (SV*)av, tolower(mg->mg_type), 0, key);
147 mg_set((SV*)av);
148 }
79072805
LW
149 return &ary[key];
150}
151
152AV *
153newAV()
154{
463ee0b2 155 register AV *av;
79072805 156
463ee0b2
LW
157 Newz(1,av,1,AV);
158 SvREFCNT(av) = 1;
159 sv_upgrade(av,SVt_PVAV);
160 AvREAL_on(av);
161 AvALLOC(av) = 0;
162 SvPVX(av) = 0;
163 AvMAX(av) = AvFILL(av) = -1;
164 return av;
79072805
LW
165}
166
167AV *
168av_make(size,strp)
169register I32 size;
170register SV **strp;
171{
463ee0b2 172 register AV *av;
79072805
LW
173 register I32 i;
174 register SV** ary;
175
463ee0b2
LW
176 Newz(3,av,1,AV);
177 sv_upgrade(av,SVt_PVAV);
79072805 178 New(4,ary,size+1,SV*);
463ee0b2 179 AvALLOC(av) = ary;
79072805 180 Zero(ary,size,SV*);
463ee0b2
LW
181 AvREAL_on(av);
182 SvPVX(av) = (char*)ary;
183 AvFILL(av) = size - 1;
184 AvMAX(av) = size - 1;
79072805
LW
185 for (i = 0; i < size; i++) {
186 if (*strp) {
187 ary[i] = NEWSV(7,0);
188 sv_setsv(ary[i], *strp);
189 }
190 strp++;
191 }
ed6116ce 192 SvOK_on(av);
463ee0b2 193 return av;
79072805
LW
194}
195
196AV *
197av_fake(size,strp)
198register I32 size;
199register SV **strp;
200{
463ee0b2 201 register AV *av;
79072805
LW
202 register SV** ary;
203
463ee0b2
LW
204 Newz(3,av,1,AV);
205 SvREFCNT(av) = 1;
206 sv_upgrade(av,SVt_PVAV);
79072805 207 New(4,ary,size+1,SV*);
463ee0b2 208 AvALLOC(av) = ary;
79072805 209 Copy(strp,ary,size,SV*);
463ee0b2
LW
210 AvREAL_off(av);
211 SvPVX(av) = (char*)ary;
212 AvFILL(av) = size - 1;
213 AvMAX(av) = size - 1;
79072805
LW
214 while (size--) {
215 if (*strp)
216 SvTEMP_off(*strp);
217 strp++;
218 }
ed6116ce 219 SvOK_on(av);
463ee0b2 220 return av;
79072805
LW
221}
222
223void
463ee0b2
LW
224av_clear(av)
225register AV *av;
79072805
LW
226{
227 register I32 key;
228
463ee0b2 229 if (!av || !AvREAL(av) || AvMAX(av) < 0)
79072805
LW
230 return;
231 /*SUPPRESS 560*/
463ee0b2
LW
232 if (key = AvARRAY(av) - AvALLOC(av)) {
233 AvMAX(av) += key;
234 SvPVX(av) = (char*)(AvARRAY(av) - key);
79072805 235 }
463ee0b2 236 for (key = 0; key <= AvMAX(av); key++)
8990e307 237 SvREFCNT_dec(AvARRAY(av)[key]);
463ee0b2
LW
238 AvFILL(av) = -1;
239 Zero(AvARRAY(av), AvMAX(av)+1, SV*);
79072805
LW
240}
241
242void
463ee0b2
LW
243av_undef(av)
244register AV *av;
79072805
LW
245{
246 register I32 key;
247
463ee0b2 248 if (!av)
79072805
LW
249 return;
250 /*SUPPRESS 560*/
463ee0b2
LW
251 if (key = AvARRAY(av) - AvALLOC(av)) {
252 AvMAX(av) += key;
253 SvPVX(av) = (char*)(AvARRAY(av) - key);
79072805 254 }
463ee0b2
LW
255 if (AvREAL(av)) {
256 for (key = 0; key <= AvMAX(av); key++)
8990e307 257 SvREFCNT_dec(AvARRAY(av)[key]);
79072805 258 }
463ee0b2
LW
259 Safefree(AvALLOC(av));
260 AvALLOC(av) = 0;
261 SvPVX(av) = 0;
262 AvMAX(av) = AvFILL(av) = -1;
79072805
LW
263}
264
79072805 265bool
463ee0b2
LW
266av_push(av,val)
267register AV *av;
79072805
LW
268SV *val;
269{
463ee0b2 270 return av_store(av,++(AvFILL(av)),val) != 0;
79072805
LW
271}
272
273SV *
463ee0b2
LW
274av_pop(av)
275register AV *av;
79072805
LW
276{
277 SV *retval;
278
463ee0b2 279 if (AvFILL(av) < 0)
79072805 280 return Nullsv;
463ee0b2
LW
281 retval = AvARRAY(av)[AvFILL(av)];
282 AvARRAY(av)[AvFILL(av)--] = Nullsv;
8990e307 283 if (SvSMAGICAL(av))
463ee0b2 284 mg_set((SV*)av);
79072805
LW
285 return retval;
286}
287
288void
463ee0b2
LW
289av_popnulls(av)
290register AV *av;
79072805 291{
463ee0b2 292 register I32 fill = AvFILL(av);
79072805 293
463ee0b2 294 while (fill >= 0 && !AvARRAY(av)[fill])
79072805 295 fill--;
463ee0b2 296 AvFILL(av) = fill;
79072805
LW
297}
298
299void
463ee0b2
LW
300av_unshift(av,num)
301register AV *av;
79072805
LW
302register I32 num;
303{
304 register I32 i;
305 register SV **sstr,**dstr;
306
307 if (num <= 0)
308 return;
463ee0b2
LW
309 if (AvARRAY(av) - AvALLOC(av) >= num) {
310 AvMAX(av) += num;
311 AvFILL(av) += num;
312 while (num--) {
313 SvPVX(av) = (char*)(AvARRAY(av) - 1);
314 *AvARRAY(av) = Nullsv;
315 }
79072805
LW
316 }
317 else {
463ee0b2
LW
318 (void)av_store(av,AvFILL(av)+num,(SV*)0); /* maybe extend array */
319 dstr = AvARRAY(av) + AvFILL(av);
79072805
LW
320 sstr = dstr - num;
321#ifdef BUGGY_MSC5
322 # pragma loop_opt(off) /* don't loop-optimize the following code */
323#endif /* BUGGY_MSC5 */
463ee0b2 324 for (i = AvFILL(av) - num; i >= 0; i--) {
79072805
LW
325 *dstr-- = *sstr--;
326#ifdef BUGGY_MSC5
327 # pragma loop_opt() /* loop-optimization back to command-line setting */
328#endif /* BUGGY_MSC5 */
329 }
463ee0b2 330 Zero(AvARRAY(av), num, SV*);
79072805
LW
331 }
332}
333
334SV *
463ee0b2
LW
335av_shift(av)
336register AV *av;
79072805
LW
337{
338 SV *retval;
339
463ee0b2 340 if (AvFILL(av) < 0)
79072805 341 return Nullsv;
463ee0b2
LW
342 retval = *AvARRAY(av);
343 *AvARRAY(av) = Nullsv;
344 SvPVX(av) = (char*)(AvARRAY(av) + 1);
345 AvMAX(av)--;
346 AvFILL(av)--;
8990e307 347 if (SvSMAGICAL(av))
463ee0b2 348 mg_set((SV*)av);
79072805
LW
349 return retval;
350}
351
352I32
463ee0b2
LW
353av_len(av)
354register AV *av;
79072805 355{
463ee0b2 356 return AvFILL(av);
79072805
LW
357}
358
359void
463ee0b2
LW
360av_fill(av, fill)
361register AV *av;
79072805
LW
362I32 fill;
363{
364 if (fill < 0)
365 fill = -1;
463ee0b2
LW
366 if (fill <= AvMAX(av)) {
367 AvFILL(av) = fill;
8990e307 368 if (SvSMAGICAL(av))
463ee0b2
LW
369 mg_set((SV*)av);
370 }
79072805 371 else {
463ee0b2
LW
372 AvFILL(av) = fill - 1; /* don't clobber in-between values */
373 (void)av_store(av,fill,Nullsv);
79072805
LW
374 }
375}