home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / PERL4036.ZIP / array.c < prev    next >
C/C++ Source or Header  |  1993-02-08  |  6KB  |  285 lines

  1. /* $RCSfile: array.c,v $$Revision: 4.0.1.3 $$Date: 92/06/08 11:45:05 $
  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:    array.c,v $
  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.  
  27. STR *
  28. afetch(ar,key,lval)
  29. register ARRAY *ar;
  30. int key;
  31. int 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.  
  58. bool
  59. astore(ar,key,val)
  60. register ARRAY *ar;
  61. int key;
  62. STR *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.  
  116. ARRAY *
  117. anew(stab)
  118. STAB *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.  
  131. ARRAY *
  132. afake(stab,size,strp)
  133. STAB *stab;
  134. register int size;
  135. register 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.  
  156. void
  157. aclear(ar)
  158. register 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.  
  175. void
  176. afree(ar)
  177. register 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.  
  197. bool
  198. apush(ar,val)
  199. register ARRAY *ar;
  200. STR *val;
  201. {
  202.     return astore(ar,++(ar->ary_fill),val);
  203. }
  204.  
  205. STR *
  206. apop(ar)
  207. register 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.  
  218. void
  219. aunshift(ar,num)
  220. register ARRAY *ar;
  221. register 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.  
  251. STR *
  252. ashift(ar)
  253. register 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.  
  266. int
  267. alen(ar)
  268. register ARRAY *ar;
  269. {
  270.     return ar->ary_fill;
  271. }
  272.  
  273. void
  274. afill(ar, fill)
  275. register ARRAY *ar;
  276. int 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. }
  285.