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