perl 4.0 patch 14: patch #11, continued
[p5sagit/p5-mst-13.2.git] / array.c
diff --git a/array.c b/array.c
index f1446a7..e2561d7 100644 (file)
--- a/array.c
+++ b/array.c
@@ -1,8 +1,16 @@
-/* $Header: array.c,v 2.0 88/06/05 00:08:17 root Exp $
+/* $RCSfile: array.c,v $$Revision: 4.0.1.1 $$Date: 91/06/07 10:19:08 $
+ *
+ *    Copyright (c) 1991, Larry Wall
+ *
+ *    You may distribute under the terms of either the GNU General Public
+ *    License or the Artistic License, as specified in the README file.
  *
  * $Log:       array.c,v $
- * Revision 2.0  88/06/05  00:08:17  root
- * Baseline version 2.0.
+ * Revision 4.0.1.1  91/06/07  10:19:08  lwall
+ * patch4: new copyright notice
+ * 
+ * Revision 4.0  91/03/20  01:03:32  lwall
+ * 4.0 baseline.
  * 
  */
 
 #include "perl.h"
 
 STR *
-afetch(ar,key)
+afetch(ar,key,lval)
 register ARRAY *ar;
 int key;
+int lval;
 {
-    if (key < 0 || key > ar->ary_fill)
-       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_mortal(&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];
 }
 
@@ -25,60 +54,89 @@ 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;
+       }
     }
-    while (ar->ary_fill < key) {
-       if (++ar->ary_fill < key && ar->ary_array[ar->ary_fill] != Nullstr) {
-           str_free(ar->ary_array[ar->ary_fill]);
-           ar->ary_array[ar->ary_fill] = Nullstr;
+    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;
+           }
        }
     }
     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(stab)
+afake(stab,size,strp)
 STAB *stab;
+register int size;
+register STR **strp;
 {
-    register ARRAY *ar = (ARRAY*)safemalloc(sizeof(ARRAY));
+    register ARRAY *ar;
 
-    ar->ary_array = (STR**) safemalloc(5 * sizeof(STR*));
-    ar->ary_magic = str_new(0);
-    ar->ary_magic->str_link.str_magic = stab;
-    ar->ary_fill = -1;
-    ar->ary_index = -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;
+    while (size--) {
+       (*strp++)->str_pok &= ~SP_TEMP;
+    }
     return ar;
 }
 
@@ -88,12 +146,16 @@ register ARRAY *ar;
 {
     register int key;
 
-    if (!ar)
+    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;
-    bzero((char*)ar->ary_array, (ar->ary_max+1) * sizeof(STR*));
+    Zero(ar->ary_array, ar->ary_max+1, STR*);
 }
 
 void
@@ -104,11 +166,17 @@ register ARRAY *ar;
 
     if (!ar)
        return;
-    for (key = 0; key <= ar->ary_max; key++)
-       str_free(ar->ary_array[key]);
+    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((char*)ar->ary_array);
-    safefree((char*)ar);
+    Safefree(ar->ary_alloc);
+    Safefree(ar);
 }
 
 bool
@@ -141,13 +209,27 @@ register int num;
 
     if (num <= 0)
        return;
-    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--;
+    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;
+#ifdef BUGGY_MSC5
+ # pragma loop_opt(off)        /* don't loop-optimize the following code */
+#endif /* BUGGY_MSC5 */
+       for (i = ar->ary_fill; i >= 0; i--) {
+           *dstr-- = *sstr--;
+#ifdef BUGGY_MSC5
+ # pragma loop_opt()   /* loop-optimization back to command-line setting */
+#endif /* BUGGY_MSC5 */
+       }
+       Zero(ar->ary_array, num, STR*);
     }
-    bzero((char*)(ar->ary_array), num * sizeof(STR*));
 }
 
 STR *
@@ -158,10 +240,10 @@ 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;
 }
 
@@ -181,33 +263,5 @@ int fill;
     if (fill <= ar->ary_max)
        ar->ary_fill = fill;
     else
-       astore(ar,fill,Nullstr);
-}
-
-void
-ajoin(ar,delim,str)
-register ARRAY *ar;
-char *delim;
-register STR *str;
-{
-    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);
+       (void)astore(ar,fill,Nullstr);
 }