perl 5.0 alpha 5
[p5sagit/p5-mst-13.2.git] / av.c
CommitLineData
79072805 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 31av_fetch(av,key,lval)
32register AV *av;
79072805 33I32 key;
34I32 lval;
35{
36 SV *sv;
37
463ee0b2 38 if (SvMAGICAL(av)) {
39 if (mg_find((SV*)av,'P')) {
40 if (key < 0)
41 return 0;
42 sv = sv_2mortal(NEWSV(61,0));
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 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 63 sv = NEWSV(5,0);
64 else
65 sv = sv_mortalcopy(&sv_undef);
463ee0b2 66 return av_store(av,key,sv);
79072805 67 }
79072805 68 }
463ee0b2 69 if (!AvARRAY(av)[key]) {
79072805 70 if (lval) {
71 sv = NEWSV(6,0);
463ee0b2 72 return av_store(av,key,sv);
79072805 73 }
74 return 0;
75 }
463ee0b2 76 return &AvARRAY(av)[key];
79072805 77}
78
79SV**
463ee0b2 80av_store(av,key,val)
81register AV *av;
79072805 82I32 key;
83SV *val;
84{
85 I32 tmp;
86 SV** ary;
87
ed6116ce 88 if (key < 0) {
89 key += AvFILL(av) + 1;
90 if (key < 0)
91 return 0;
92 }
463ee0b2 93
94 if (SvMAGICAL(av)) {
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 102 I32 newmax;
103
463ee0b2 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 112 goto resize;
113 }
114 }
115 else {
463ee0b2 116 if (AvALLOC(av)) {
117 newmax = key + AvMAX(av) / 5;
79072805 118 resize:
463ee0b2 119 Renew(AvALLOC(av),newmax+1, SV*);
120 Zero(&AvALLOC(av)[AvMAX(av)+1], newmax - AvMAX(av), SV*);
79072805 121 }
122 else {
123 newmax = key < 4 ? 4 : key;
463ee0b2 124 Newz(2,AvALLOC(av), newmax+1, SV*);
79072805 125 }
463ee0b2 126 SvPVX(av) = (char*)AvALLOC(av);
127 AvMAX(av) = newmax;
79072805 128 }
129 }
463ee0b2 130 ary = AvARRAY(av);
131 if (AvREAL(av)) {
132 if (AvFILL(av) < key) {
133 while (++AvFILL(av) < key) {
134 if (ary[AvFILL(av)] != Nullsv) {
135 sv_free(ary[AvFILL(av)]);
136 ary[AvFILL(av)] = Nullsv;
79072805 137 }
138 }
139 }
140 if (ary[key])
141 sv_free(ary[key]);
142 }
143 ary[key] = val;
463ee0b2 144 if (SvMAGICAL(av)) {
145 MAGIC* mg = SvMAGIC(av);
146 sv_magic(val, (SV*)av, tolower(mg->mg_type), 0, key);
147 mg_set((SV*)av);
148 }
79072805 149 return &ary[key];
150}
151
152AV *
153newAV()
154{
463ee0b2 155 register AV *av;
79072805 156
463ee0b2 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 165}
166
167AV *
168av_make(size,strp)
169register I32 size;
170register SV **strp;
171{
463ee0b2 172 register AV *av;
79072805 173 register I32 i;
174 register SV** ary;
175
463ee0b2 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 181 AvREAL_on(av);
182 SvPVX(av) = (char*)ary;
183 AvFILL(av) = size - 1;
184 AvMAX(av) = size - 1;
79072805 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 194}
195
196AV *
197av_fake(size,strp)
198register I32 size;
199register SV **strp;
200{
463ee0b2 201 register AV *av;
79072805 202 register SV** ary;
203
463ee0b2 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 210 AvREAL_off(av);
211 SvPVX(av) = (char*)ary;
212 AvFILL(av) = size - 1;
213 AvMAX(av) = size - 1;
79072805 214 while (size--) {
215 if (*strp)
216 SvTEMP_off(*strp);
217 strp++;
218 }
ed6116ce 219 SvOK_on(av);
463ee0b2 220 return av;
79072805 221}
222
223void
463ee0b2 224av_clear(av)
225register AV *av;
79072805 226{
227 register I32 key;
228
463ee0b2 229 if (!av || !AvREAL(av) || AvMAX(av) < 0)
79072805 230 return;
231 /*SUPPRESS 560*/
463ee0b2 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++)
237 sv_free(AvARRAY(av)[key]);
238 AvFILL(av) = -1;
239 Zero(AvARRAY(av), AvMAX(av)+1, SV*);
79072805 240}
241
242void
463ee0b2 243av_undef(av)
244register AV *av;
79072805 245{
246 register I32 key;
247
463ee0b2 248 if (!av)
79072805 249 return;
250 /*SUPPRESS 560*/
463ee0b2 251 if (key = AvARRAY(av) - AvALLOC(av)) {
252 AvMAX(av) += key;
253 SvPVX(av) = (char*)(AvARRAY(av) - key);
79072805 254 }
463ee0b2 255 if (AvREAL(av)) {
256 for (key = 0; key <= AvMAX(av); key++)
257 sv_free(AvARRAY(av)[key]);
79072805 258 }
463ee0b2 259 Safefree(AvALLOC(av));
260 AvALLOC(av) = 0;
261 SvPVX(av) = 0;
262 AvMAX(av) = AvFILL(av) = -1;
79072805 263}
264
265void
463ee0b2 266av_free(av)
267AV *av;
79072805 268{
463ee0b2 269 av_undef(av);
270 Safefree(av);
79072805 271}
272
273bool
463ee0b2 274av_push(av,val)
275register AV *av;
79072805 276SV *val;
277{
463ee0b2 278 return av_store(av,++(AvFILL(av)),val) != 0;
79072805 279}
280
281SV *
463ee0b2 282av_pop(av)
283register AV *av;
79072805 284{
285 SV *retval;
286
463ee0b2 287 if (AvFILL(av) < 0)
79072805 288 return Nullsv;
463ee0b2 289 retval = AvARRAY(av)[AvFILL(av)];
290 AvARRAY(av)[AvFILL(av)--] = Nullsv;
291 if (SvMAGICAL(av))
292 mg_set((SV*)av);
79072805 293 return retval;
294}
295
296void
463ee0b2 297av_popnulls(av)
298register AV *av;
79072805 299{
463ee0b2 300 register I32 fill = AvFILL(av);
79072805 301
463ee0b2 302 while (fill >= 0 && !AvARRAY(av)[fill])
79072805 303 fill--;
463ee0b2 304 AvFILL(av) = fill;
79072805 305}
306
307void
463ee0b2 308av_unshift(av,num)
309register AV *av;
79072805 310register I32 num;
311{
312 register I32 i;
313 register SV **sstr,**dstr;
314
315 if (num <= 0)
316 return;
463ee0b2 317 if (AvARRAY(av) - AvALLOC(av) >= num) {
318 AvMAX(av) += num;
319 AvFILL(av) += num;
320 while (num--) {
321 SvPVX(av) = (char*)(AvARRAY(av) - 1);
322 *AvARRAY(av) = Nullsv;
323 }
79072805 324 }
325 else {
463ee0b2 326 (void)av_store(av,AvFILL(av)+num,(SV*)0); /* maybe extend array */
327 dstr = AvARRAY(av) + AvFILL(av);
79072805 328 sstr = dstr - num;
329#ifdef BUGGY_MSC5
330 # pragma loop_opt(off) /* don't loop-optimize the following code */
331#endif /* BUGGY_MSC5 */
463ee0b2 332 for (i = AvFILL(av) - num; i >= 0; i--) {
79072805 333 *dstr-- = *sstr--;
334#ifdef BUGGY_MSC5
335 # pragma loop_opt() /* loop-optimization back to command-line setting */
336#endif /* BUGGY_MSC5 */
337 }
463ee0b2 338 Zero(AvARRAY(av), num, SV*);
79072805 339 }
340}
341
342SV *
463ee0b2 343av_shift(av)
344register AV *av;
79072805 345{
346 SV *retval;
347
463ee0b2 348 if (AvFILL(av) < 0)
79072805 349 return Nullsv;
463ee0b2 350 retval = *AvARRAY(av);
351 *AvARRAY(av) = Nullsv;
352 SvPVX(av) = (char*)(AvARRAY(av) + 1);
353 AvMAX(av)--;
354 AvFILL(av)--;
355 if (SvMAGICAL(av))
356 mg_set((SV*)av);
79072805 357 return retval;
358}
359
360I32
463ee0b2 361av_len(av)
362register AV *av;
79072805 363{
463ee0b2 364 return AvFILL(av);
79072805 365}
366
367void
463ee0b2 368av_fill(av, fill)
369register AV *av;
79072805 370I32 fill;
371{
372 if (fill < 0)
373 fill = -1;
463ee0b2 374 if (fill <= AvMAX(av)) {
375 AvFILL(av) = fill;
376 if (SvMAGICAL(av))
377 mg_set((SV*)av);
378 }
79072805 379 else {
463ee0b2 380 AvFILL(av) = fill - 1; /* don't clobber in-between values */
381 (void)av_store(av,fill,Nullsv);
79072805 382 }
383}