home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / program / language / perl / Source / C / Array < prev    next >
Encoding:
Text File  |  1990-11-06  |  5.2 KB  |  267 lines

  1. /* $Header: array.c,v 3.0.1.3 90/10/15 14:56:17 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.
  7.  *
  8.  * $Log:    array.c,v $
  9.  * Revision 3.0.1.3  90/10/15  14:56:17  lwall
  10.  * patch29: non-existent array values no longer cause core dumps
  11.  * 
  12.  * Revision 3.0.1.2  90/08/13  21:52:20  lwall
  13.  * patch28: defined(@array) and defined(%array) didn't work right
  14.  * 
  15.  * Revision 3.0.1.1  89/11/17  15:02:52  lwall
  16.  * patch5: nested foreach on same array didn't work
  17.  * 
  18.  * Revision 3.0  89/10/18  15:08:33  lwall
  19.  * 3.0 baseline
  20.  * 
  21.  */
  22.  
  23. #include "EXTERN.h"
  24. #include "perl.h"
  25.  
  26. STR *
  27. afetch(ar,key,lval)
  28. register ARRAY *ar;
  29. int key;
  30. int lval;
  31. {
  32.     STR *str;
  33.  
  34.     if (key < 0 || key > ar->ary_fill) {
  35.     if (lval && key >= 0) {
  36.         if (ar->ary_flags & ARF_REAL)
  37.         str = Str_new(5,0);
  38.         else
  39.         str = str_static(&str_undef);
  40.         (void)astore(ar,key,str);
  41.         return str;
  42.     }
  43.     else
  44.         return &str_undef;
  45.     }
  46.     if (!ar->ary_array[key]) {
  47.     if (lval) {
  48.         str = Str_new(6,0);
  49.         (void)astore(ar,key,str);
  50.         return str;
  51.     }
  52.     return &str_undef;
  53.     }
  54.     return ar->ary_array[key];
  55. }
  56.  
  57. bool
  58. astore(ar,key,val)
  59. register ARRAY *ar;
  60. int key;
  61. STR *val;
  62. {
  63.     int retval;
  64.  
  65.     if (key < 0)
  66.     return FALSE;
  67.     if (key > ar->ary_max) {
  68.     int newmax;
  69.  
  70.     if (ar->ary_alloc != ar->ary_array) {
  71.         retval = ar->ary_array - ar->ary_alloc;
  72.         Copy(ar->ary_array, ar->ary_alloc, ar->ary_max+1, STR*);
  73.         Zero(ar->ary_alloc+ar->ary_max+1, retval, STR*);
  74.         ar->ary_max += retval;
  75.         ar->ary_array -= retval;
  76.         if (key > ar->ary_max - 10) {
  77.         newmax = key + ar->ary_max;
  78.         goto resize;
  79.         }
  80.     }
  81.     else {
  82.         if (ar->ary_alloc) {
  83.         newmax = key + ar->ary_max / 5;
  84.           resize:
  85.         Renew(ar->ary_alloc,newmax+1, STR*);
  86.         Zero(&ar->ary_alloc[ar->ary_max+1], newmax - ar->ary_max, STR*);
  87.         }
  88.         else {
  89.         newmax = key < 4 ? 4 : key;
  90.         Newz(2,ar->ary_alloc, newmax+1, STR*);
  91.         }
  92.         ar->ary_array = ar->ary_alloc;
  93.         ar->ary_max = newmax;
  94.     }
  95.     }
  96.     if ((ar->ary_flags & ARF_REAL) && ar->ary_fill < key) {
  97.     while (++ar->ary_fill < key) {
  98.         if (ar->ary_array[ar->ary_fill] != Nullstr) {
  99.         str_free(ar->ary_array[ar->ary_fill]);
  100.         ar->ary_array[ar->ary_fill] = Nullstr;
  101.         }
  102.     }
  103.     }
  104.     retval = (ar->ary_array[key] != Nullstr);
  105.     if (retval && (ar->ary_flags & ARF_REAL))
  106.     str_free(ar->ary_array[key]);
  107.     ar->ary_array[key] = val;
  108.     return retval;
  109. }
  110.  
  111. ARRAY *
  112. anew(stab)
  113. STAB *stab;
  114. {
  115.     register ARRAY *ar;
  116.  
  117.     New(1,ar,1,ARRAY);
  118.     ar->ary_magic = Str_new(7,0);
  119.     ar->ary_alloc = ar->ary_array = 0;
  120.     str_magic(ar->ary_magic, stab, '#', Nullch, 0);
  121.     ar->ary_max = ar->ary_fill = -1;
  122.     ar->ary_flags = ARF_REAL;
  123.     return ar;
  124. }
  125.  
  126. ARRAY *
  127. afake(stab,size,strp)
  128. STAB *stab;
  129. int size;
  130. STR **strp;
  131. {
  132.     register ARRAY *ar;
  133.  
  134.     New(3,ar,1,ARRAY);
  135.     New(4,ar->ary_alloc,size+1,STR*);
  136.     Copy(strp,ar->ary_alloc,size,STR*);
  137.     ar->ary_array = ar->ary_alloc;
  138.     ar->ary_magic = Str_new(8,0);
  139.     str_magic(ar->ary_magic, stab, '#', Nullch, 0);
  140.     ar->ary_fill = size - 1;
  141.     ar->ary_max = size - 1;
  142.     ar->ary_flags = 0;
  143.     return ar;
  144. }
  145.  
  146. void
  147. aclear(ar)
  148. register ARRAY *ar;
  149. {
  150.     register int key;
  151.  
  152.     if (!ar || !(ar->ary_flags & ARF_REAL) || ar->ary_max < 0)
  153.     return;
  154.     if ((key = ar->ary_array - ar->ary_alloc) != 0) {
  155.     ar->ary_max += key;
  156.     ar->ary_array -= key;
  157.     }
  158.     for (key = 0; key <= ar->ary_max; key++)
  159.     str_free(ar->ary_array[key]);
  160.     ar->ary_fill = -1;
  161.     Zero(ar->ary_array, ar->ary_max+1, STR*);
  162. }
  163.  
  164. void
  165. afree(ar)
  166. register ARRAY *ar;
  167. {
  168.     register int key;
  169.  
  170.     if (!ar)
  171.     return;
  172.     if ((key = ar->ary_array - ar->ary_alloc) != 0) {
  173.     ar->ary_max += key;
  174.     ar->ary_array -= key;
  175.     }
  176.     if (ar->ary_flags & ARF_REAL) {
  177.     for (key = 0; key <= ar->ary_max; key++)
  178.         str_free(ar->ary_array[key]);
  179.     }
  180.     str_free(ar->ary_magic);
  181.     Safefree(ar->ary_alloc);
  182.     Safefree(ar);
  183. }
  184.  
  185. bool
  186. apush(ar,val)
  187. register ARRAY *ar;
  188. STR *val;
  189. {
  190.     return astore(ar,++(ar->ary_fill),val);
  191. }
  192.  
  193. STR *
  194. apop(ar)
  195. register ARRAY *ar;
  196. {
  197.     STR *retval;
  198.  
  199.     if (ar->ary_fill < 0)
  200.     return Nullstr;
  201.     retval = ar->ary_array[ar->ary_fill];
  202.     ar->ary_array[ar->ary_fill--] = Nullstr;
  203.     return retval;
  204. }
  205.  
  206. void
  207. aunshift(ar,num)
  208. register ARRAY *ar;
  209. register int num;
  210. {
  211.     register int i;
  212.     register STR **sstr,**dstr;
  213.  
  214.     if (num <= 0)
  215.     return;
  216.     if (ar->ary_array - ar->ary_alloc >= num) {
  217.     ar->ary_max += num;
  218.     ar->ary_fill += num;
  219.     while (num--)
  220.         *--ar->ary_array = Nullstr;
  221.     }
  222.     else {
  223.     (void)astore(ar,ar->ary_fill+num,(STR*)0);    /* maybe extend array */
  224.     dstr = ar->ary_array + ar->ary_fill;
  225.     sstr = dstr - num;
  226.     for (i = ar->ary_fill; i >= 0; i--) {
  227.         *dstr-- = *sstr--;
  228.     }
  229.     Zero(ar->ary_array, num, STR*);
  230.     }
  231. }
  232.  
  233. STR *
  234. ashift(ar)
  235. register ARRAY *ar;
  236. {
  237.     STR *retval;
  238.  
  239.     if (ar->ary_fill < 0)
  240.     return Nullstr;
  241.     retval = *ar->ary_array;
  242.     *(ar->ary_array++) = Nullstr;
  243.     ar->ary_max--;
  244.     ar->ary_fill--;
  245.     return retval;
  246. }
  247.  
  248. int
  249. alen(ar)
  250. register ARRAY *ar;
  251. {
  252.     return ar->ary_fill;
  253. }
  254.  
  255. void
  256. afill(ar, fill)
  257. register ARRAY *ar;
  258. int fill;
  259. {
  260.     if (fill < 0)
  261.     fill = -1;
  262.     if (fill <= ar->ary_max)
  263.     ar->ary_fill = fill;
  264.     else
  265.     (void)astore(ar,fill,Nullstr);
  266. }
  267.