perl 4.0 patch 31: patch #20, continued
[p5sagit/p5-mst-13.2.git] / array.c
CommitLineData
bf10efe7 1/* $RCSfile: array.c,v $$Revision: 4.0.1.3 $$Date: 92/06/08 11:45:05 $
a687059c 2 *
2b317908 3 * Copyright (c) 1991, Larry Wall
a687059c 4 *
2b317908 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.
8d063cd8 7 *
8 * $Log: array.c,v $
bf10efe7 9 * Revision 4.0.1.3 92/06/08 11:45:05 lwall
10 * patch20: Perl now distinguishes overlapped copies from non-overlapped
11 *
55204971 12 * Revision 4.0.1.2 91/11/05 16:00:14 lwall
13 * patch11: random cleanup
14 * patch11: passing non-existend array elements to subrouting caused core dump
15 *
2b317908 16 * Revision 4.0.1.1 91/06/07 10:19:08 lwall
17 * patch4: new copyright notice
18 *
fe14fcc3 19 * Revision 4.0 91/03/20 01:03:32 lwall
20 * 4.0 baseline.
8d063cd8 21 *
22 */
23
8d063cd8 24#include "EXTERN.h"
8d063cd8 25#include "perl.h"
26
27STR *
a687059c 28afetch(ar,key,lval)
8d063cd8 29register ARRAY *ar;
30int key;
a687059c 31int lval;
8d063cd8 32{
a687059c 33 STR *str;
34
35 if (key < 0 || key > ar->ary_fill) {
36 if (lval && key >= 0) {
37 if (ar->ary_flags & ARF_REAL)
38 str = Str_new(5,0);
39 else
fe14fcc3 40 str = str_mortal(&str_undef);
a687059c 41 (void)astore(ar,key,str);
42 return str;
43 }
44 else
39c3038c 45 return &str_undef;
a687059c 46 }
39c3038c 47 if (!ar->ary_array[key]) {
48 if (lval) {
49 str = Str_new(6,0);
50 (void)astore(ar,key,str);
51 return str;
52 }
53 return &str_undef;
a687059c 54 }
8d063cd8 55 return ar->ary_array[key];
56}
57
58bool
59astore(ar,key,val)
60register ARRAY *ar;
61int key;
62STR *val;
63{
a687059c 64 int retval;
8d063cd8 65
66 if (key < 0)
67 return FALSE;
68 if (key > ar->ary_max) {
a687059c 69 int newmax;
70
71 if (ar->ary_alloc != ar->ary_array) {
72 retval = ar->ary_array - ar->ary_alloc;
bf10efe7 73 Move(ar->ary_array, ar->ary_alloc, ar->ary_max+1, STR*);
a687059c 74 Zero(ar->ary_alloc+ar->ary_max+1, retval, STR*);
75 ar->ary_max += retval;
76 ar->ary_array -= retval;
77 if (key > ar->ary_max - 10) {
78 newmax = key + ar->ary_max;
79 goto resize;
80 }
81 }
82 else {
6eb13c3b 83 if (ar->ary_alloc) {
84 newmax = key + ar->ary_max / 5;
85 resize:
86 Renew(ar->ary_alloc,newmax+1, STR*);
87 Zero(&ar->ary_alloc[ar->ary_max+1], newmax - ar->ary_max, STR*);
88 }
89 else {
90 newmax = key < 4 ? 4 : key;
91 Newz(2,ar->ary_alloc, newmax+1, STR*);
92 }
a687059c 93 ar->ary_array = ar->ary_alloc;
94 ar->ary_max = newmax;
95 }
8d063cd8 96 }
55204971 97 if (ar->ary_flags & ARF_REAL) {
98 if (ar->ary_fill < key) {
99 while (++ar->ary_fill < key) {
100 if (ar->ary_array[ar->ary_fill] != Nullstr) {
101 str_free(ar->ary_array[ar->ary_fill]);
102 ar->ary_array[ar->ary_fill] = Nullstr;
103 }
a687059c 104 }
378cc40b 105 }
55204971 106 retval = (ar->ary_array[key] != Nullstr);
107 if (retval)
108 str_free(ar->ary_array[key]);
378cc40b 109 }
55204971 110 else
111 retval = 0;
8d063cd8 112 ar->ary_array[key] = val;
113 return retval;
114}
115
8d063cd8 116ARRAY *
378cc40b 117anew(stab)
118STAB *stab;
8d063cd8 119{
a687059c 120 register ARRAY *ar;
8d063cd8 121
a687059c 122 New(1,ar,1,ARRAY);
a687059c 123 ar->ary_magic = Str_new(7,0);
6eb13c3b 124 ar->ary_alloc = ar->ary_array = 0;
a687059c 125 str_magic(ar->ary_magic, stab, '#', Nullch, 0);
6eb13c3b 126 ar->ary_max = ar->ary_fill = -1;
a687059c 127 ar->ary_flags = ARF_REAL;
128 return ar;
129}
130
131ARRAY *
132afake(stab,size,strp)
133STAB *stab;
fe14fcc3 134register int size;
135register STR **strp;
a687059c 136{
137 register ARRAY *ar;
138
139 New(3,ar,1,ARRAY);
140 New(4,ar->ary_alloc,size+1,STR*);
141 Copy(strp,ar->ary_alloc,size,STR*);
142 ar->ary_array = ar->ary_alloc;
143 ar->ary_magic = Str_new(8,0);
144 str_magic(ar->ary_magic, stab, '#', Nullch, 0);
145 ar->ary_fill = size - 1;
a687059c 146 ar->ary_max = size - 1;
147 ar->ary_flags = 0;
fe14fcc3 148 while (size--) {
55204971 149 if (*strp)
150 (*strp)->str_pok &= ~SP_TEMP;
151 strp++;
fe14fcc3 152 }
8d063cd8 153 return ar;
154}
155
156void
378cc40b 157aclear(ar)
158register ARRAY *ar;
159{
160 register int key;
161
6eb13c3b 162 if (!ar || !(ar->ary_flags & ARF_REAL) || ar->ary_max < 0)
378cc40b 163 return;
55204971 164 /*SUPPRESS 560*/
a687059c 165 if (key = ar->ary_array - ar->ary_alloc) {
166 ar->ary_max += key;
167 ar->ary_array -= key;
168 }
378cc40b 169 for (key = 0; key <= ar->ary_max; key++)
170 str_free(ar->ary_array[key]);
171 ar->ary_fill = -1;
a687059c 172 Zero(ar->ary_array, ar->ary_max+1, STR*);
378cc40b 173}
174
175void
8d063cd8 176afree(ar)
177register ARRAY *ar;
178{
179 register int key;
180
181 if (!ar)
182 return;
55204971 183 /*SUPPRESS 560*/
a687059c 184 if (key = ar->ary_array - ar->ary_alloc) {
185 ar->ary_max += key;
186 ar->ary_array -= key;
187 }
188 if (ar->ary_flags & ARF_REAL) {
189 for (key = 0; key <= ar->ary_max; key++)
190 str_free(ar->ary_array[key]);
191 }
378cc40b 192 str_free(ar->ary_magic);
a687059c 193 Safefree(ar->ary_alloc);
194 Safefree(ar);
8d063cd8 195}
196
197bool
198apush(ar,val)
199register ARRAY *ar;
200STR *val;
201{
202 return astore(ar,++(ar->ary_fill),val);
203}
204
205STR *
206apop(ar)
207register ARRAY *ar;
208{
209 STR *retval;
210
211 if (ar->ary_fill < 0)
212 return Nullstr;
213 retval = ar->ary_array[ar->ary_fill];
214 ar->ary_array[ar->ary_fill--] = Nullstr;
215 return retval;
216}
217
bf10efe7 218void
8d063cd8 219aunshift(ar,num)
220register ARRAY *ar;
221register int num;
222{
223 register int i;
224 register STR **sstr,**dstr;
225
226 if (num <= 0)
227 return;
a687059c 228 if (ar->ary_array - ar->ary_alloc >= num) {
229 ar->ary_max += num;
230 ar->ary_fill += num;
231 while (num--)
232 *--ar->ary_array = Nullstr;
233 }
234 else {
235 (void)astore(ar,ar->ary_fill+num,(STR*)0); /* maybe extend array */
236 dstr = ar->ary_array + ar->ary_fill;
237 sstr = dstr - num;
fe14fcc3 238#ifdef BUGGY_MSC5
239 # pragma loop_opt(off) /* don't loop-optimize the following code */
240#endif /* BUGGY_MSC5 */
55204971 241 for (i = ar->ary_fill - num; i >= 0; i--) {
a687059c 242 *dstr-- = *sstr--;
fe14fcc3 243#ifdef BUGGY_MSC5
244 # pragma loop_opt() /* loop-optimization back to command-line setting */
245#endif /* BUGGY_MSC5 */
a687059c 246 }
247 Zero(ar->ary_array, num, STR*);
8d063cd8 248 }
8d063cd8 249}
250
251STR *
252ashift(ar)
253register ARRAY *ar;
254{
255 STR *retval;
256
257 if (ar->ary_fill < 0)
258 return Nullstr;
a687059c 259 retval = *ar->ary_array;
260 *(ar->ary_array++) = Nullstr;
261 ar->ary_max--;
262 ar->ary_fill--;
8d063cd8 263 return retval;
264}
265
378cc40b 266int
8d063cd8 267alen(ar)
268register ARRAY *ar;
269{
378cc40b 270 return ar->ary_fill;
271}
272
bf10efe7 273void
378cc40b 274afill(ar, fill)
275register ARRAY *ar;
276int fill;
277{
278 if (fill < 0)
279 fill = -1;
280 if (fill <= ar->ary_max)
281 ar->ary_fill = fill;
282 else
a687059c 283 (void)astore(ar,fill,Nullstr);
8d063cd8 284}