X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=array.c;h=aff66caf87daa6467746cf0a7067e37e392888ff;hb=39c3038ca76b338006c640ae6da52b407dd9e654;hp=156b78378feb61314304f050e7c8041fc3d9307e;hpb=8d063cd8450e59ea1c611a2f4f5a21059a2804f1;p=p5sagit%2Fp5-mst-13.2.git diff --git a/array.c b/array.c index 156b783..aff66ca 100644 --- a/array.c +++ b/array.c @@ -1,25 +1,56 @@ -/* $Header: array.c,v 1.0 87/12/18 13:04:42 root Exp $ +/* $Header: array.c,v 3.0.1.3 90/10/15 14:56:17 lwall Locked $ + * + * Copyright (c) 1989, Larry Wall + * + * You may distribute under the terms of the GNU General Public License + * as specified in the README file that comes with the perl 3.0 kit. * * $Log: array.c,v $ - * Revision 1.0 87/12/18 13:04:42 root - * Initial revision + * Revision 3.0.1.3 90/10/15 14:56:17 lwall + * patch29: non-existent array values no longer cause core dumps + * + * Revision 3.0.1.2 90/08/13 21:52:20 lwall + * patch28: defined(@array) and defined(%array) didn't work right + * + * Revision 3.0.1.1 89/11/17 15:02:52 lwall + * patch5: nested foreach on same array didn't work + * + * Revision 3.0 89/10/18 15:08:33 lwall + * 3.0 baseline * */ -#include #include "EXTERN.h" -#include "handy.h" -#include "util.h" -#include "search.h" #include "perl.h" STR * -afetch(ar,key) +afetch(ar,key,lval) register ARRAY *ar; int key; +int lval; { - if (key < 0 || key > ar->ary_max) - return Nullstr; + STR *str; + + if (key < 0 || key > ar->ary_fill) { + if (lval && key >= 0) { + if (ar->ary_flags & ARF_REAL) + str = Str_new(5,0); + else + str = str_static(&str_undef); + (void)astore(ar,key,str); + return str; + } + else + return &str_undef; + } + if (!ar->ary_array[key]) { + if (lval) { + str = Str_new(6,0); + (void)astore(ar,key,str); + return str; + } + return &str_undef; + } return ar->ary_array[key]; } @@ -29,56 +60,108 @@ register ARRAY *ar; int key; STR *val; { - bool retval; + int retval; if (key < 0) return FALSE; if (key > ar->ary_max) { - int newmax = key + ar->ary_max / 5; + int newmax; - ar->ary_array = (STR**)saferealloc((char*)ar->ary_array, - (newmax+1) * sizeof(STR*)); - bzero((char*)&ar->ary_array[ar->ary_max+1], - (newmax - ar->ary_max) * sizeof(STR*)); - ar->ary_max = newmax; + if (ar->ary_alloc != ar->ary_array) { + retval = ar->ary_array - ar->ary_alloc; + Copy(ar->ary_array, ar->ary_alloc, ar->ary_max+1, STR*); + Zero(ar->ary_alloc+ar->ary_max+1, retval, STR*); + ar->ary_max += retval; + ar->ary_array -= retval; + if (key > ar->ary_max - 10) { + newmax = key + ar->ary_max; + goto resize; + } + } + else { + if (ar->ary_alloc) { + newmax = key + ar->ary_max / 5; + resize: + Renew(ar->ary_alloc,newmax+1, STR*); + Zero(&ar->ary_alloc[ar->ary_max+1], newmax - ar->ary_max, STR*); + } + else { + newmax = key < 4 ? 4 : key; + Newz(2,ar->ary_alloc, newmax+1, STR*); + } + ar->ary_array = ar->ary_alloc; + ar->ary_max = newmax; + } + } + if ((ar->ary_flags & ARF_REAL) && ar->ary_fill < key) { + while (++ar->ary_fill < key) { + if (ar->ary_array[ar->ary_fill] != Nullstr) { + str_free(ar->ary_array[ar->ary_fill]); + ar->ary_array[ar->ary_fill] = Nullstr; + } + } } - if (key > ar->ary_fill) - ar->ary_fill = key; retval = (ar->ary_array[key] != Nullstr); - if (retval) + if (retval && (ar->ary_flags & ARF_REAL)) str_free(ar->ary_array[key]); ar->ary_array[key] = val; return retval; } -bool -adelete(ar,key) -register ARRAY *ar; -int key; +ARRAY * +anew(stab) +STAB *stab; { - if (key < 0 || key > ar->ary_max) - return FALSE; - if (ar->ary_array[key]) { - str_free(ar->ary_array[key]); - ar->ary_array[key] = Nullstr; - return TRUE; - } - return FALSE; + register ARRAY *ar; + + New(1,ar,1,ARRAY); + ar->ary_magic = Str_new(7,0); + ar->ary_alloc = ar->ary_array = 0; + str_magic(ar->ary_magic, stab, '#', Nullch, 0); + ar->ary_max = ar->ary_fill = -1; + ar->ary_flags = ARF_REAL; + return ar; } ARRAY * -anew() +afake(stab,size,strp) +STAB *stab; +int size; +STR **strp; { - register ARRAY *ar = (ARRAY*)safemalloc(sizeof(ARRAY)); + register ARRAY *ar; - ar->ary_array = (STR**) safemalloc(5 * sizeof(STR*)); - ar->ary_fill = -1; - ar->ary_max = 4; - bzero((char*)ar->ary_array, 5 * sizeof(STR*)); + New(3,ar,1,ARRAY); + New(4,ar->ary_alloc,size+1,STR*); + Copy(strp,ar->ary_alloc,size,STR*); + ar->ary_array = ar->ary_alloc; + ar->ary_magic = Str_new(8,0); + str_magic(ar->ary_magic, stab, '#', Nullch, 0); + ar->ary_fill = size - 1; + ar->ary_max = size - 1; + ar->ary_flags = 0; return ar; } void +aclear(ar) +register ARRAY *ar; +{ + register int key; + + if (!ar || !(ar->ary_flags & ARF_REAL) || ar->ary_max < 0) + return; + if (key = ar->ary_array - ar->ary_alloc) { + ar->ary_max += key; + ar->ary_array -= key; + } + for (key = 0; key <= ar->ary_max; key++) + str_free(ar->ary_array[key]); + ar->ary_fill = -1; + Zero(ar->ary_array, ar->ary_max+1, STR*); +} + +void afree(ar) register ARRAY *ar; { @@ -86,10 +169,17 @@ register ARRAY *ar; if (!ar) return; - for (key = 0; key <= ar->ary_fill; key++) - str_free(ar->ary_array[key]); - safefree((char*)ar->ary_array); - safefree((char*)ar); + if (key = ar->ary_array - ar->ary_alloc) { + ar->ary_max += key; + ar->ary_array -= key; + } + if (ar->ary_flags & ARF_REAL) { + for (key = 0; key <= ar->ary_max; key++) + str_free(ar->ary_array[key]); + } + str_free(ar->ary_magic); + Safefree(ar->ary_alloc); + Safefree(ar); } bool @@ -122,13 +212,21 @@ register int num; if (num <= 0) return; - astore(ar,ar->ary_fill+num,(STR*)0); /* maybe extend array */ - sstr = ar->ary_array + ar->ary_fill; - dstr = sstr + num; - for (i = ar->ary_fill; i >= 0; i--) { - *dstr-- = *sstr--; + if (ar->ary_array - ar->ary_alloc >= num) { + ar->ary_max += num; + ar->ary_fill += num; + while (num--) + *--ar->ary_array = Nullstr; + } + else { + (void)astore(ar,ar->ary_fill+num,(STR*)0); /* maybe extend array */ + dstr = ar->ary_array + ar->ary_fill; + sstr = dstr - num; + for (i = ar->ary_fill; i >= 0; i--) { + *dstr-- = *sstr--; + } + Zero(ar->ary_array, num, STR*); } - bzero((char*)(ar->ary_array), num * sizeof(STR*)); } STR * @@ -139,44 +237,28 @@ register ARRAY *ar; if (ar->ary_fill < 0) return Nullstr; - retval = ar->ary_array[0]; - bcopy((char*)(ar->ary_array+1),(char*)ar->ary_array, - ar->ary_fill * sizeof(STR*)); - ar->ary_array[ar->ary_fill--] = Nullstr; + retval = *ar->ary_array; + *(ar->ary_array++) = Nullstr; + ar->ary_max--; + ar->ary_fill--; return retval; } -long +int alen(ar) register ARRAY *ar; { - return (long)ar->ary_fill; + return ar->ary_fill; } -void -ajoin(ar,delim,str) +afill(ar, fill) register ARRAY *ar; -char *delim; -register STR *str; +int fill; { - register int i; - register int len; - register int dlen; - - if (ar->ary_fill < 0) { - str_set(str,""); - STABSET(str); - return; - } - dlen = strlen(delim); - len = ar->ary_fill * dlen; /* account for delimiters */ - for (i = ar->ary_fill; i >= 0; i--) - len += str_len(ar->ary_array[i]); - str_grow(str,len); /* preallocate for efficiency */ - str_sset(str,ar->ary_array[0]); - for (i = 1; i <= ar->ary_fill; i++) { - str_ncat(str,delim,dlen); - str_scat(str,ar->ary_array[i]); - } - STABSET(str); + if (fill < 0) + fill = -1; + if (fill <= ar->ary_max) + ar->ary_fill = fill; + else + (void)astore(ar,fill,Nullstr); }