This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perl 3.0 patch #4 Patch #2 continued
[perl5.git] / array.c
CommitLineData
a687059c
LW
1/* $Header: array.c,v 3.0 89/10/18 15:08:33 lwall Locked $
2 *
3 * Copyright (c) 1989, Larry Wall
4 *
5 * You may distribute under the terms of the GNU General Public License
6 * as specified in the README file that comes with the perl 3.0 kit.
8d063cd8
LW
7 *
8 * $Log: array.c,v $
a687059c
LW
9 * Revision 3.0 89/10/18 15:08:33 lwall
10 * 3.0 baseline
8d063cd8
LW
11 *
12 */
13
8d063cd8 14#include "EXTERN.h"
8d063cd8
LW
15#include "perl.h"
16
17STR *
a687059c 18afetch(ar,key,lval)
8d063cd8
LW
19register ARRAY *ar;
20int key;
a687059c 21int lval;
8d063cd8 22{
a687059c
LW
23 STR *str;
24
25 if (key < 0 || key > ar->ary_fill) {
26 if (lval && key >= 0) {
27 if (ar->ary_flags & ARF_REAL)
28 str = Str_new(5,0);
29 else
30 str = str_static(&str_undef);
31 (void)astore(ar,key,str);
32 return str;
33 }
34 else
35 return Nullstr;
36 }
37 if (lval && !ar->ary_array[key]) {
38 str = Str_new(6,0);
39 (void)astore(ar,key,str);
40 return str;
41 }
8d063cd8
LW
42 return ar->ary_array[key];
43}
44
45bool
46astore(ar,key,val)
47register ARRAY *ar;
48int key;
49STR *val;
50{
a687059c 51 int retval;
8d063cd8
LW
52
53 if (key < 0)
54 return FALSE;
55 if (key > ar->ary_max) {
a687059c
LW
56 int newmax;
57
58 if (ar->ary_alloc != ar->ary_array) {
59 retval = ar->ary_array - ar->ary_alloc;
60 Copy(ar->ary_array, ar->ary_alloc, ar->ary_max+1, STR*);
61 Zero(ar->ary_alloc+ar->ary_max+1, retval, STR*);
62 ar->ary_max += retval;
63 ar->ary_array -= retval;
64 if (key > ar->ary_max - 10) {
65 newmax = key + ar->ary_max;
66 goto resize;
67 }
68 }
69 else {
70 newmax = key + ar->ary_max / 5;
71 resize:
72 Renew(ar->ary_alloc,newmax+1, STR*);
73 Zero(&ar->ary_alloc[ar->ary_max+1], newmax - ar->ary_max, STR*);
74 ar->ary_array = ar->ary_alloc;
75 ar->ary_max = newmax;
76 }
8d063cd8 77 }
a687059c
LW
78 if ((ar->ary_flags & ARF_REAL) && ar->ary_fill < key) {
79 while (++ar->ary_fill < key) {
80 if (ar->ary_array[ar->ary_fill] != Nullstr) {
81 str_free(ar->ary_array[ar->ary_fill]);
82 ar->ary_array[ar->ary_fill] = Nullstr;
83 }
378cc40b
LW
84 }
85 }
8d063cd8 86 retval = (ar->ary_array[key] != Nullstr);
a687059c 87 if (retval && (ar->ary_flags & ARF_REAL))
8d063cd8
LW
88 str_free(ar->ary_array[key]);
89 ar->ary_array[key] = val;
90 return retval;
91}
92
8d063cd8 93ARRAY *
378cc40b
LW
94anew(stab)
95STAB *stab;
8d063cd8 96{
a687059c 97 register ARRAY *ar;
8d063cd8 98
a687059c
LW
99 New(1,ar,1,ARRAY);
100 Newz(2,ar->ary_alloc,5,STR*);
101 ar->ary_array = ar->ary_alloc;
102 ar->ary_magic = Str_new(7,0);
103 str_magic(ar->ary_magic, stab, '#', Nullch, 0);
8d063cd8 104 ar->ary_fill = -1;
378cc40b 105 ar->ary_index = -1;
8d063cd8 106 ar->ary_max = 4;
a687059c
LW
107 ar->ary_flags = ARF_REAL;
108 return ar;
109}
110
111ARRAY *
112afake(stab,size,strp)
113STAB *stab;
114int size;
115STR **strp;
116{
117 register ARRAY *ar;
118
119 New(3,ar,1,ARRAY);
120 New(4,ar->ary_alloc,size+1,STR*);
121 Copy(strp,ar->ary_alloc,size,STR*);
122 ar->ary_array = ar->ary_alloc;
123 ar->ary_magic = Str_new(8,0);
124 str_magic(ar->ary_magic, stab, '#', Nullch, 0);
125 ar->ary_fill = size - 1;
126 ar->ary_index = -1;
127 ar->ary_max = size - 1;
128 ar->ary_flags = 0;
8d063cd8
LW
129 return ar;
130}
131
132void
378cc40b
LW
133aclear(ar)
134register ARRAY *ar;
135{
136 register int key;
137
a687059c 138 if (!ar || !(ar->ary_flags & ARF_REAL))
378cc40b 139 return;
a687059c
LW
140 if (key = ar->ary_array - ar->ary_alloc) {
141 ar->ary_max += key;
142 ar->ary_array -= key;
143 }
378cc40b
LW
144 for (key = 0; key <= ar->ary_max; key++)
145 str_free(ar->ary_array[key]);
146 ar->ary_fill = -1;
a687059c 147 Zero(ar->ary_array, ar->ary_max+1, STR*);
378cc40b
LW
148}
149
150void
8d063cd8
LW
151afree(ar)
152register ARRAY *ar;
153{
154 register int key;
155
156 if (!ar)
157 return;
a687059c
LW
158 if (key = ar->ary_array - ar->ary_alloc) {
159 ar->ary_max += key;
160 ar->ary_array -= key;
161 }
162 if (ar->ary_flags & ARF_REAL) {
163 for (key = 0; key <= ar->ary_max; key++)
164 str_free(ar->ary_array[key]);
165 }
378cc40b 166 str_free(ar->ary_magic);
a687059c
LW
167 Safefree(ar->ary_alloc);
168 Safefree(ar);
8d063cd8
LW
169}
170
171bool
172apush(ar,val)
173register ARRAY *ar;
174STR *val;
175{
176 return astore(ar,++(ar->ary_fill),val);
177}
178
179STR *
180apop(ar)
181register ARRAY *ar;
182{
183 STR *retval;
184
185 if (ar->ary_fill < 0)
186 return Nullstr;
187 retval = ar->ary_array[ar->ary_fill];
188 ar->ary_array[ar->ary_fill--] = Nullstr;
189 return retval;
190}
191
192aunshift(ar,num)
193register ARRAY *ar;
194register int num;
195{
196 register int i;
197 register STR **sstr,**dstr;
198
199 if (num <= 0)
200 return;
a687059c
LW
201 if (ar->ary_array - ar->ary_alloc >= num) {
202 ar->ary_max += num;
203 ar->ary_fill += num;
204 while (num--)
205 *--ar->ary_array = Nullstr;
206 }
207 else {
208 (void)astore(ar,ar->ary_fill+num,(STR*)0); /* maybe extend array */
209 dstr = ar->ary_array + ar->ary_fill;
210 sstr = dstr - num;
211 for (i = ar->ary_fill; i >= 0; i--) {
212 *dstr-- = *sstr--;
213 }
214 Zero(ar->ary_array, num, STR*);
8d063cd8 215 }
8d063cd8
LW
216}
217
218STR *
219ashift(ar)
220register ARRAY *ar;
221{
222 STR *retval;
223
224 if (ar->ary_fill < 0)
225 return Nullstr;
a687059c
LW
226 retval = *ar->ary_array;
227 *(ar->ary_array++) = Nullstr;
228 ar->ary_max--;
229 ar->ary_fill--;
8d063cd8
LW
230 return retval;
231}
232
378cc40b 233int
8d063cd8
LW
234alen(ar)
235register ARRAY *ar;
236{
378cc40b
LW
237 return ar->ary_fill;
238}
239
240afill(ar, fill)
241register ARRAY *ar;
242int fill;
243{
244 if (fill < 0)
245 fill = -1;
246 if (fill <= ar->ary_max)
247 ar->ary_fill = fill;
248 else
a687059c 249 (void)astore(ar,fill,Nullstr);
8d063cd8 250}