home *** CD-ROM | disk | FTP | other *** search
/ ftp.muug.mb.ca / 2014.06.ftp.muug.mb.ca.tar / ftp.muug.mb.ca / pub / src / perl / array.c < prev    next >
C/C++ Source or Header  |  1992-04-11  |  6KB  |  280 lines

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