home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / perl / Perl / av.c < prev    next >
C/C++ Source or Header  |  1994-12-29  |  8KB  |  441 lines

  1. /*    av.c
  2.  *
  3.  *    Copyright (c) 1991-1994, 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.  */
  9.  
  10. /*
  11.  * "...for the Entwives desired order, and plenty, and peace (by which they
  12.  * meant that things should remain where they had set them)." --Treebeard
  13.  */
  14.  
  15. #include "EXTERN.h"
  16. #include "perl.h"
  17.  
  18. static void    av_reify _((AV* av));
  19.  
  20. static void
  21. av_reify(av)
  22. AV* av;
  23. {
  24.     I32 key;
  25.     SV* sv;
  26.     
  27.     key = AvMAX(av) + 1;
  28.     while (key > AvFILL(av) + 1)
  29.     AvARRAY(av)[--key] = &sv_undef;
  30.     while (key) {
  31.     sv = AvARRAY(av)[--key];
  32.     assert(sv);
  33.     if (sv != &sv_undef)
  34.         (void)SvREFCNT_inc(sv);
  35.     }
  36.     AvREAL_on(av);
  37. }
  38.  
  39. void
  40. av_extend(av,key)
  41. AV *av;
  42. I32 key;
  43. {
  44.     if (key > AvMAX(av)) {
  45.     SV** ary;
  46.     I32 tmp;
  47.     I32 newmax;
  48.  
  49.     if (AvALLOC(av) != AvARRAY(av)) {
  50.         ary = AvALLOC(av) + AvFILL(av) + 1;
  51.         tmp = AvARRAY(av) - AvALLOC(av);
  52.         Move(AvARRAY(av), AvALLOC(av), AvFILL(av)+1, SV*);
  53.         AvMAX(av) += tmp;
  54.         SvPVX(av) = (char*)AvALLOC(av);
  55.         if (AvREAL(av)) {
  56.         while (tmp)
  57.             ary[--tmp] = &sv_undef;
  58.         }
  59.         
  60.         if (key > AvMAX(av) - 10) {
  61.         newmax = key + AvMAX(av);
  62.         goto resize;
  63.         }
  64.     }
  65.     else {
  66.         if (AvALLOC(av)) {
  67.         newmax = key + AvMAX(av) / 5;
  68.           resize:
  69.         Renew(AvALLOC(av),newmax+1, SV*);
  70.         ary = AvALLOC(av) + AvMAX(av) + 1;
  71.         tmp = newmax - AvMAX(av);
  72.         if (av == stack) {    /* Oops, grew stack (via av_store()?) */
  73.             stack_sp = AvALLOC(av) + (stack_sp - stack_base);
  74.             stack_base = AvALLOC(av);
  75.             stack_max = stack_base + newmax;
  76.         }
  77.         }
  78.         else {
  79.         newmax = key < 4 ? 4 : key;
  80.         New(2,AvALLOC(av), newmax+1, SV*);
  81.         ary = AvALLOC(av) + 1;
  82.         tmp = newmax;
  83.         AvALLOC(av)[0] = &sv_undef;    /* For the stacks */
  84.         }
  85.         if (AvREAL(av)) {
  86.         while (tmp)
  87.             ary[--tmp] = &sv_undef;
  88.         }
  89.         
  90.         SvPVX(av) = (char*)AvALLOC(av);
  91.         AvMAX(av) = newmax;
  92.     }
  93.     }
  94. }
  95.  
  96. SV**
  97. av_fetch(av,key,lval)
  98. register AV *av;
  99. I32 key;
  100. I32 lval;
  101. {
  102.     SV *sv;
  103.  
  104.     if (!av)
  105.     return 0;
  106.  
  107.     if (SvRMAGICAL(av)) {
  108.     if (mg_find((SV*)av,'P')) {
  109.         sv = sv_newmortal();
  110.         mg_copy((SV*)av, sv, 0, key);
  111.         Sv = sv;
  112.         return &Sv;
  113.     }
  114.     }
  115.  
  116.     if (key < 0) {
  117.     key += AvFILL(av) + 1;
  118.     if (key < 0)
  119.         return 0;
  120.     }
  121.     else if (key > AvFILL(av)) {
  122.     if (!lval)
  123.         return 0;
  124.     if (AvREALISH(av))
  125.         sv = NEWSV(5,0);
  126.     else
  127.         sv = sv_newmortal();
  128.     return av_store(av,key,sv);
  129.     }
  130.     if (AvARRAY(av)[key] == &sv_undef) {
  131.     if (lval) {
  132.         sv = NEWSV(6,0);
  133.         return av_store(av,key,sv);
  134.     }
  135.     return 0;
  136.     }
  137.     return &AvARRAY(av)[key];
  138. }
  139.  
  140. SV**
  141. av_store(av,key,val)
  142. register AV *av;
  143. I32 key;
  144. SV *val;
  145. {
  146.     SV** ary;
  147.  
  148.     if (!av)
  149.     return 0;
  150.  
  151.     if (SvRMAGICAL(av)) {
  152.     if (mg_find((SV*)av,'P')) {
  153.         mg_copy((SV*)av, val, 0, key);
  154.         return 0;
  155.     }
  156.     }
  157.  
  158.     if (key < 0) {
  159.     key += AvFILL(av) + 1;
  160.     if (key < 0)
  161.         return 0;
  162.     }
  163.     if (!val)
  164.     val = &sv_undef;
  165.  
  166.     if (key > AvMAX(av))
  167.     av_extend(av,key);
  168.     if (AvREIFY(av))
  169.     av_reify(av);
  170.  
  171.     ary = AvARRAY(av);
  172.     if (AvFILL(av) < key) {
  173.     if (!AvREAL(av)) {
  174.         if (av == stack && key > stack_sp - stack_base)
  175.         stack_sp = stack_base + key;    /* XPUSH in disguise */
  176.         do
  177.         ary[++AvFILL(av)] = &sv_undef;
  178.         while (AvFILL(av) < key);
  179.     }
  180.     AvFILL(av) = key;
  181.     }
  182.     else if (AvREAL(av))
  183.     SvREFCNT_dec(ary[key]);
  184.     ary[key] = val;
  185.     if (SvSMAGICAL(av)) {
  186.     if (val != &sv_undef) {
  187.         MAGIC* mg = SvMAGIC(av);
  188.         sv_magic(val, (SV*)av, toLOWER(mg->mg_type), 0, key);
  189.     }
  190.     mg_set((SV*)av);
  191.     }
  192.     return &ary[key];
  193. }
  194.  
  195. AV *
  196. newAV()
  197. {
  198.     register AV *av;
  199.  
  200.     av = (AV*)NEWSV(3,0);
  201.     sv_upgrade((SV *)av, SVt_PVAV);
  202.     AvREAL_on(av);
  203.     AvALLOC(av) = 0;
  204.     SvPVX(av) = 0;
  205.     AvMAX(av) = AvFILL(av) = -1;
  206.     return av;
  207. }
  208.  
  209. AV *
  210. av_make(size,strp)
  211. register I32 size;
  212. register SV **strp;
  213. {
  214.     register AV *av;
  215.     register I32 i;
  216.     register SV** ary;
  217.  
  218.     av = (AV*)NEWSV(8,0);
  219.     sv_upgrade((SV *) av,SVt_PVAV);
  220.     New(4,ary,size+1,SV*);
  221.     AvALLOC(av) = ary;
  222.     AvFLAGS(av) = AVf_REAL;
  223.     SvPVX(av) = (char*)ary;
  224.     AvFILL(av) = size - 1;
  225.     AvMAX(av) = size - 1;
  226.     for (i = 0; i < size; i++) {
  227.     assert (*strp);
  228.     ary[i] = NEWSV(7,0);
  229.     sv_setsv(ary[i], *strp);
  230.     strp++;
  231.     }
  232.     return av;
  233. }
  234.  
  235. AV *
  236. av_fake(size,strp)
  237. register I32 size;
  238. register SV **strp;
  239. {
  240.     register AV *av;
  241.     register SV** ary;
  242.  
  243.     av = (AV*)NEWSV(9,0);
  244.     sv_upgrade((SV *)av, SVt_PVAV);
  245.     New(4,ary,size+1,SV*);
  246.     AvALLOC(av) = ary;
  247.     Copy(strp,ary,size,SV*);
  248.     AvFLAGS(av) = AVf_REIFY;
  249.     SvPVX(av) = (char*)ary;
  250.     AvFILL(av) = size - 1;
  251.     AvMAX(av) = size - 1;
  252.     while (size--) {
  253.     assert (*strp);
  254.     SvTEMP_off(*strp);
  255.     strp++;
  256.     }
  257.     return av;
  258. }
  259.  
  260. void
  261. av_clear(av)
  262. register AV *av;
  263. {
  264.     register I32 key;
  265.     SV** ary;
  266.  
  267.     if (!av || AvMAX(av) < 0)
  268.     return;
  269.     /*SUPPRESS 560*/
  270.  
  271.     if (AvREAL(av)) {
  272.     ary = AvARRAY(av);
  273.     key = AvFILL(av) + 1;
  274.     while (key) {
  275.         SvREFCNT_dec(ary[--key]);
  276.         ary[key] = &sv_undef;
  277.     }
  278.     }
  279.     if (key = AvARRAY(av) - AvALLOC(av)) {
  280.     AvMAX(av) += key;
  281.     SvPVX(av) = (char*)AvALLOC(av);
  282.     }
  283.     AvFILL(av) = -1;
  284. }
  285.  
  286. void
  287. av_undef(av)
  288. register AV *av;
  289. {
  290.     register I32 key;
  291.  
  292.     if (!av)
  293.     return;
  294.     /*SUPPRESS 560*/
  295.     if (AvREAL(av)) {
  296.     key = AvFILL(av) + 1;
  297.     while (key)
  298.         SvREFCNT_dec(AvARRAY(av)[--key]);
  299.     }
  300.     if (key = AvARRAY(av) - AvALLOC(av)) {
  301.     AvMAX(av) += key;
  302.     SvPVX(av) = (char*)AvALLOC(av);
  303.     }
  304.     Safefree(AvALLOC(av));
  305.     AvALLOC(av) = 0;
  306.     SvPVX(av) = 0;
  307.     AvMAX(av) = AvFILL(av) = -1;
  308.     if (AvARYLEN(av)) {
  309.     SvREFCNT_dec(AvARYLEN(av));
  310.     AvARYLEN(av) = 0;
  311.     }
  312. }
  313.  
  314. void
  315. av_push(av,val)
  316. register AV *av;
  317. SV *val;
  318. {
  319.     if (!av)
  320.     return;
  321.     av_store(av,AvFILL(av)+1,val);
  322. }
  323.  
  324. SV *
  325. av_pop(av)
  326. register AV *av;
  327. {
  328.     SV *retval;
  329.  
  330.     if (!av || AvFILL(av) < 0)
  331.     return &sv_undef;
  332.     retval = AvARRAY(av)[AvFILL(av)];
  333.     AvARRAY(av)[AvFILL(av)--] = &sv_undef;
  334.     if (SvSMAGICAL(av))
  335.     mg_set((SV*)av);
  336.     return retval;
  337. }
  338.  
  339. void
  340. av_unshift(av,num)
  341. register AV *av;
  342. register I32 num;
  343. {
  344.     register I32 i;
  345.     register SV **sstr,**dstr;
  346.  
  347.     if (!av || num <= 0)
  348.     return;
  349.     if (!AvREAL(av)) {
  350.     if (AvREIFY(av))
  351.         av_reify(av);
  352.     else
  353.         croak("Can't unshift");
  354.     }
  355.     i = AvARRAY(av) - AvALLOC(av);
  356.     if (i) {
  357.     if (i > num)
  358.         i = num;
  359.     num -= i;
  360.     
  361.     AvMAX(av) += i;
  362.     AvFILL(av) += i;
  363.     SvPVX(av) = (char*)(AvARRAY(av) - i);
  364.     }
  365.     if (num) {
  366.     av_extend(av,AvFILL(av)+num);
  367.     AvFILL(av) += num;
  368.     dstr = AvARRAY(av) + AvFILL(av);
  369.     sstr = dstr - num;
  370. #ifdef BUGGY_MSC5
  371.  # pragma loop_opt(off)    /* don't loop-optimize the following code */
  372. #endif /* BUGGY_MSC5 */
  373.     for (i = AvFILL(av) - num; i >= 0; --i) {
  374.         *dstr-- = *sstr--;
  375. #ifdef BUGGY_MSC5
  376.  # pragma loop_opt()    /* loop-optimization back to command-line setting */
  377. #endif /* BUGGY_MSC5 */
  378.     }
  379.     while (num)
  380.         AvARRAY(av)[--num] = &sv_undef;
  381.     }
  382. }
  383.  
  384. SV *
  385. av_shift(av)
  386. register AV *av;
  387. {
  388.     SV *retval;
  389.  
  390.     if (!av || AvFILL(av) < 0)
  391.     return &sv_undef;
  392.     retval = *AvARRAY(av);
  393.     if (AvREAL(av))
  394.     *AvARRAY(av) = &sv_undef;
  395.     SvPVX(av) = (char*)(AvARRAY(av) + 1);
  396.     AvMAX(av)--;
  397.     AvFILL(av)--;
  398.     if (SvSMAGICAL(av))
  399.     mg_set((SV*)av);
  400.     return retval;
  401. }
  402.  
  403. I32
  404. av_len(av)
  405. register AV *av;
  406. {
  407.     return AvFILL(av);
  408. }
  409.  
  410. void
  411. av_fill(av, fill)
  412. register AV *av;
  413. I32 fill;
  414. {
  415.     if (!av)
  416.     croak("panic: null array");
  417.     if (fill < 0)
  418.     fill = -1;
  419.     if (fill <= AvMAX(av)) {
  420.     I32 key = AvFILL(av);
  421.     SV** ary = AvARRAY(av);
  422.  
  423.     if (AvREAL(av)) {
  424.         while (key > fill) {
  425.         SvREFCNT_dec(ary[key]);
  426.         ary[key--] = &sv_undef;
  427.         }
  428.     }
  429.     else {
  430.         while (key < fill)
  431.         ary[++key] = &sv_undef;
  432.     }
  433.         
  434.     AvFILL(av) = fill;
  435.     if (SvSMAGICAL(av))
  436.         mg_set((SV*)av);
  437.     }
  438.     else
  439.     (void)av_store(av,fill,&sv_undef);
  440. }
  441.