source: trunk/third/perl/array.c @ 9009

Revision 9009, 5.6 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r9008, which included commits to RCS files with non-trunk default branches.
Line 
1/* $RCSfile: array.c,v $$Revision: 1.1.1.1 $$Date: 1996-10-02 06:39:58 $
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: not supported by cvs2svn $
9 * Revision 4.0.1.3  92/06/08  11:45:05  lwall
10 * patch20: Perl now distinguishes overlapped copies from non-overlapped
11 *
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 *
16 * Revision 4.0.1.1  91/06/07  10:19:08  lwall
17 * patch4: new copyright notice
18 *
19 * Revision 4.0  91/03/20  01:03:32  lwall
20 * 4.0 baseline.
21 *
22 */
23
24#include "EXTERN.h"
25#include "perl.h"
26
27STR *
28afetch(ar,key,lval)
29register ARRAY *ar;
30int key;
31int lval;
32{
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
40                str = str_mortal(&str_undef);
41            (void)astore(ar,key,str);
42            return str;
43        }
44        else
45            return &str_undef;
46    }
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;
54    }
55    return ar->ary_array[key];
56}
57
58bool
59astore(ar,key,val)
60register ARRAY *ar;
61int key;
62STR *val;
63{
64    int retval;
65
66    if (key < 0)
67        return FALSE;
68    if (key > ar->ary_max) {
69        int newmax;
70
71        if (ar->ary_alloc != ar->ary_array) {
72            retval = ar->ary_array - ar->ary_alloc;
73            Move(ar->ary_array, ar->ary_alloc, ar->ary_max+1, STR*);
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 {
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            }
93            ar->ary_array = ar->ary_alloc;
94            ar->ary_max = newmax;
95        }
96    }
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                }
104            }
105        }
106        retval = (ar->ary_array[key] != Nullstr);
107        if (retval)
108            str_free(ar->ary_array[key]);
109    }
110    else
111        retval = 0;
112    ar->ary_array[key] = val;
113    return retval;
114}
115
116ARRAY *
117anew(stab)
118STAB *stab;
119{
120    register ARRAY *ar;
121
122    New(1,ar,1,ARRAY);
123    ar->ary_magic = Str_new(7,0);
124    ar->ary_alloc = ar->ary_array = 0;
125    str_magic(ar->ary_magic, stab, '#', Nullch, 0);
126    ar->ary_max = ar->ary_fill = -1;
127    ar->ary_flags = ARF_REAL;
128    return ar;
129}
130
131ARRAY *
132afake(stab,size,strp)
133STAB *stab;
134register int size;
135register STR **strp;
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;
146    ar->ary_max = size - 1;
147    ar->ary_flags = 0;
148    while (size--) {
149        if (*strp)
150            (*strp)->str_pok &= ~SP_TEMP;
151        strp++;
152    }
153    return ar;
154}
155
156void
157aclear(ar)
158register ARRAY *ar;
159{
160    register int key;
161
162    if (!ar || !(ar->ary_flags & ARF_REAL) || ar->ary_max < 0)
163        return;
164    /*SUPPRESS 560*/
165    if (key = ar->ary_array - ar->ary_alloc) {
166        ar->ary_max += key;
167        ar->ary_array -= key;
168    }
169    for (key = 0; key <= ar->ary_max; key++)
170        str_free(ar->ary_array[key]);
171    ar->ary_fill = -1;
172    Zero(ar->ary_array, ar->ary_max+1, STR*);
173}
174
175void
176afree(ar)
177register ARRAY *ar;
178{
179    register int key;
180
181    if (!ar)
182        return;
183    /*SUPPRESS 560*/
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    }
192    str_free(ar->ary_magic);
193    Safefree(ar->ary_alloc);
194    Safefree(ar);
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
218void
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;
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;
238#ifdef BUGGY_MSC5
239 # pragma loop_opt(off) /* don't loop-optimize the following code */
240#endif /* BUGGY_MSC5 */
241        for (i = ar->ary_fill - num; i >= 0; i--) {
242            *dstr-- = *sstr--;
243#ifdef BUGGY_MSC5
244 # pragma loop_opt()    /* loop-optimization back to command-line setting */
245#endif /* BUGGY_MSC5 */
246        }
247        Zero(ar->ary_array, num, STR*);
248    }
249}
250
251STR *
252ashift(ar)
253register ARRAY *ar;
254{
255    STR *retval;
256
257    if (ar->ary_fill < 0)
258        return Nullstr;
259    retval = *ar->ary_array;
260    *(ar->ary_array++) = Nullstr;
261    ar->ary_max--;
262    ar->ary_fill--;
263    return retval;
264}
265
266int
267alen(ar)
268register ARRAY *ar;
269{
270    return ar->ary_fill;
271}
272
273void
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
283        (void)astore(ar,fill,Nullstr);
284}
Note: See TracBrowser for help on using the repository browser.