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