1 /* $RCSfile: cmd.c,v $$Revision: 4.0.1.1 $$Date: 91/04/11 17:36:16 $
3 * Copyright (c) 1989, Larry Wall
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.
9 * Revision 4.0.1.1 91/04/11 17:36:16 lwall
10 * patch1: you may now use "die" and "caller" in a signal handler
12 * Revision 4.0 91/03/20 01:04:18 lwall
28 /* do longjmps() clobber register variables? */
30 #if defined(cray) || defined(__STDC__)
34 /* This is the main command loop. We try to spend as much time in this loop
35 * as possible, so lots of optimizations do their activities in here. This
36 * means things get a little sloppy.
40 cmd_exec(cmdparm,gimme,sp)
41 CMD *VOLATILE cmdparm;
45 register CMD *cmd = cmdparm;
46 SPAT *VOLATILE oldspat;
47 VOLATILE int firstsave = savestack->ary_fill;
49 VOLATILE int aryoptsave;
51 VOLATILE int olddlevel;
52 VOLATILE int entdlevel;
54 register STR *retstr = &str_undef;
56 register int cmdflags;
58 register char *go_to = goto_targ;
59 register int newsp = -2;
60 register STR **st = stack->ary_array;
73 tainted = 0; /* Each statement is presumed innocent */
76 if (gimme == G_ARRAY && newsp > -2)
83 cmdflags = cmd->c_flags; /* hopefully load register */
85 if (cmd->c_label && strEQ(go_to,cmd->c_label))
86 goto_targ = go_to = Nullch; /* here at last */
88 switch (cmd->c_type) {
91 oldsave = savestack->ary_fill;
97 if (cmd->ucmd.ccmd.cc_true) {
100 debname[dlevel] = 't';
101 debdelim[dlevel] = '_';
102 if (++dlevel >= dlmax)
106 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
107 st = stack->ary_array; /* possibly reallocated */
113 if (savestack->ary_fill > oldsave)
114 restorelist(oldsave);
118 cmd = cmd->ucmd.ccmd.cc_alt;
119 goto tail_recursion_entry;
122 oldsave = savestack->ary_fill;
128 if (cmd->ucmd.ccmd.cc_true) {
131 debname[dlevel] = 'e';
132 debdelim[dlevel] = '_';
133 if (++dlevel >= dlmax)
137 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
138 st = stack->ary_array; /* possibly reallocated */
144 if (savestack->ary_fill > oldsave)
145 restorelist(oldsave);
152 if (!(cmdflags & CF_ONCE)) {
154 if (++loop_ptr >= loop_max) {
156 Renew(loop_stack, loop_max, struct loop);
158 loop_stack[loop_ptr].loop_label = cmd->c_label;
159 loop_stack[loop_ptr].loop_sp = sp;
162 deb("(Pushing label #%d %s)\n",
163 loop_ptr, cmd->c_label ? cmd->c_label : "");
170 match = setjmp(loop_stack[loop_ptr].loop_env);
172 st = stack->ary_array; /* possibly reallocated */
175 cmdflags = cmd->c_flags|CF_ONCE;
177 if (savestack->ary_fill > oldsave)
178 restorelist(oldsave);
181 fatal("longjmp returned bad value (%d)",match);
182 case O_LAST: /* not done unless go_to found */
189 newsp = sp + lastsize;
197 case O_NEXT: /* not done unless go_to found */
204 case O_REDO: /* not done unless go_to found */
214 oldsave = savestack->ary_fill;
218 if (cmd->ucmd.ccmd.cc_true) {
221 debname[dlevel] = 't';
222 debdelim[dlevel] = '_';
223 if (++dlevel >= dlmax)
227 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
228 st = stack->ary_array; /* possibly reallocated */
238 if (cmd->ucmd.ccmd.cc_alt) {
241 debname[dlevel] = 'a';
242 debdelim[dlevel] = '_';
243 if (++dlevel >= dlmax)
247 newsp = cmd_exec(cmd->ucmd.ccmd.cc_alt,gimme && (cmdflags & CF_TERM),sp);
248 st = stack->ary_array; /* possibly reallocated */
257 if (cmd && cmd->c_head == cmd)
258 /* reached end of while loop */
259 return sp; /* targ isn't in this block */
260 if (cmdflags & CF_ONCE) {
263 tmps = loop_stack[loop_ptr].loop_label;
264 deb("(Popping label #%d %s)\n",loop_ptr,
270 goto tail_recursion_entry;
276 /* Set line number so run-time errors can be located */
283 deb("%s (%lx) r%lx t%lx a%lx n%lx cs%lx\n",
284 cmdname[cmd->c_type],cmd,cmd->c_expr,
285 cmd->ucmd.ccmd.cc_true,cmd->ucmd.ccmd.cc_alt,cmd->c_next,
288 debname[dlevel] = cmdname[cmd->c_type][0];
289 debdelim[dlevel] = '!';
290 if (++dlevel >= dlmax)
295 /* Here is some common optimization */
297 if (cmdflags & CF_COND) {
298 switch (cmdflags & CF_OPTIMIZE) {
301 retstr = cmd->c_short;
304 if (cmdflags & CF_NESURE)
308 retstr = cmd->c_short;
311 if (cmdflags & CF_EQSURE)
316 retstr = STAB_STR(cmd->c_stab);
318 match = str_true(retstr); /* => retstr = retstr, c2 should fix */
319 if (cmdflags & (match ? CF_EQSURE : CF_NESURE))
323 case CFT_ANCHOR: /* /^pat/ optimization */
325 if (*cmd->c_short->str_ptr && !(cmdflags & CF_EQSURE))
326 goto scanner; /* just unanchor it */
328 break; /* must evaluate */
331 case CFT_STROP: /* string op optimization */
332 retstr = STAB_STR(cmd->c_stab);
335 if (*cmd->c_short->str_ptr == *str_get(retstr) &&
336 bcmp(cmd->c_short->str_ptr, str_get(retstr),
337 cmd->c_slen) == 0 ) {
338 if (cmdflags & CF_EQSURE) {
339 if (sawampersand && (cmdflags & CF_OPTIMIZE) != CFT_STROP) {
342 str_nset(stab_val(leftstab),"",0);
344 str_sset(stab_val(amperstab),cmd->c_short);
346 str_nset(stab_val(rightstab),
347 retstr->str_ptr + cmd->c_slen,
348 retstr->str_cur - cmd->c_slen);
351 lastspat = cmd->c_spat;
352 match = !(cmdflags & CF_FIRSTNEG);
357 else if (cmdflags & CF_NESURE) {
358 match = cmdflags & CF_FIRSTNEG;
364 char *zap1, *zap2, zap1c, zap2c;
367 zap1 = cmd->c_short->str_ptr;
368 zap2 = str_get(retstr);
371 zaplen = cmd->c_slen;
372 if ((zap1c == zap2c) && (bcmp(zap1, zap2, zaplen) == 0)) {
373 if (cmdflags & CF_EQSURE) {
375 (cmdflags & CF_OPTIMIZE) != CFT_STROP) {
378 str_nset(stab_val(leftstab),"",0);
380 str_sset(stab_val(amperstab),cmd->c_short);
382 str_nset(stab_val(rightstab),
383 retstr->str_ptr + cmd->c_slen,
384 retstr->str_cur - cmd->c_slen);
387 lastspat = cmd->c_spat;
388 match = !(cmdflags & CF_FIRSTNEG);
393 else if (cmdflags & CF_NESURE) {
394 match = cmdflags & CF_FIRSTNEG;
400 break; /* must evaluate */
402 case CFT_SCAN: /* non-anchored search */
404 retstr = STAB_STR(cmd->c_stab);
406 if (retstr->str_pok & SP_STUDIED)
407 if (screamfirst[cmd->c_short->str_rare] >= 0)
408 tmps = screaminstr(retstr, cmd->c_short);
412 tmps = str_get(retstr); /* make sure it's pok */
414 tmps = fbminstr((unsigned char*)tmps,
415 (unsigned char*)tmps + retstr->str_cur, cmd->c_short);
419 if (cmdflags & CF_EQSURE) {
420 ++cmd->c_short->str_u.str_useful;
424 str_nset(stab_val(leftstab),retstr->str_ptr,
425 tmps - retstr->str_ptr);
427 str_nset(stab_val(amperstab),
428 tmps, cmd->c_short->str_cur);
430 str_nset(stab_val(rightstab),
431 tmps + cmd->c_short->str_cur,
432 retstr->str_cur - (tmps - retstr->str_ptr) -
433 cmd->c_short->str_cur);
435 lastspat = cmd->c_spat;
436 match = !(cmdflags & CF_FIRSTNEG);
444 if (cmdflags & CF_NESURE) {
445 ++cmd->c_short->str_u.str_useful;
446 match = cmdflags & CF_FIRSTNEG;
451 if (--cmd->c_short->str_u.str_useful < 0) {
452 cmdflags &= ~CF_OPTIMIZE;
453 cmdflags |= CFT_EVAL; /* never try this optimization again */
454 cmd->c_flags = (cmdflags & ~CF_ONCE);
456 break; /* must evaluate */
458 case CFT_NUMOP: /* numeric op optimization */
459 retstr = STAB_STR(cmd->c_stab);
461 switch (cmd->c_slen) {
464 if ((!retstr->str_nok && !looks_like_number(retstr)))
465 warn("Possible use of == on string value");
467 match = (str_gnum(retstr) == cmd->c_short->str_u.str_nval);
470 match = (str_gnum(retstr) != cmd->c_short->str_u.str_nval);
473 match = (str_gnum(retstr) < cmd->c_short->str_u.str_nval);
476 match = (str_gnum(retstr) <= cmd->c_short->str_u.str_nval);
479 match = (str_gnum(retstr) > cmd->c_short->str_u.str_nval);
482 match = (str_gnum(retstr) >= cmd->c_short->str_u.str_nval);
486 if (cmdflags & CF_EQSURE) {
491 else if (cmdflags & CF_NESURE) {
495 break; /* must evaluate */
497 case CFT_INDGETS: /* while (<$foo>) */
498 last_in_stab = stabent(str_get(STAB_STR(cmd->c_stab)),TRUE);
499 if (!stab_io(last_in_stab))
500 stab_io(last_in_stab) = stio_new();
502 case CFT_GETS: /* really a while (<file>) */
503 last_in_stab = cmd->c_stab;
505 fp = stab_io(last_in_stab)->ifp;
506 retstr = stab_val(defstab);
509 if (fp && str_gets(retstr, fp, 0)) {
510 if (*retstr->str_ptr == '0' && retstr->str_cur == 1)
514 stab_io(last_in_stab)->lines++;
516 else if (stab_io(last_in_stab)->flags & IOF_ARGV) {
518 goto doeval; /* first time through */
519 fp = nextargv(last_in_stab);
522 (void)do_close(last_in_stab,FALSE);
523 stab_io(last_in_stab)->flags |= IOF_START;
535 while (tmps_max > tmps_base) { /* clean up after last eval */
536 str_free(tmps_list[tmps_max]);
537 tmps_list[tmps_max--] = Nullstr;
539 newsp = eval(cmd->c_expr,gimme && (cmdflags & CF_TERM),sp);
540 st = stack->ary_array; /* possibly reallocated */
542 match = str_true(retstr);
543 if (cmd->c_expr->arg_type == O_FLIP) /* undid itself? */
544 cmdflags = copyopt(cmd,cmd->c_expr[3].arg_ptr.arg_cmd);
547 retstr = stab_val(cmd->c_stab);
549 match = (retstr->str_cur != 0);
550 tmps = str_get(retstr);
551 tmps += retstr->str_cur - match;
552 str_nset(&str_chop,tmps,match);
555 retstr->str_cur = tmps - retstr->str_ptr;
560 match = cmd->c_short->str_u.str_useful; /* just to get register */
562 if (match < 0) { /* first time through here? */
563 ar = stab_array(cmd->c_expr[1].arg_ptr.arg_stab);
564 aryoptsave = savestack->ary_fill;
565 savesptr(&stab_val(cmd->c_stab));
566 savelong(&cmd->c_short->str_u.str_useful);
569 ar = stab_xarray(cmd->c_expr[1].arg_ptr.arg_stab);
570 if (cmd->c_type != C_WHILE && savestack->ary_fill > firstsave)
571 restorelist(firstsave);
574 if (match >= ar->ary_fill) { /* we're in LAST, probably */
576 cmd->c_short->str_u.str_useful = -1; /* actually redundant */
581 if (!(retstr = ar->ary_array[match]))
582 retstr = afetch(ar,match,TRUE);
583 stab_val(cmd->c_stab) = retstr;
584 cmd->c_short->str_u.str_useful = match;
592 if (DBsingle->str_u.str_nval != 0)
594 if (DBsignal->str_u.str_nval != 0)
596 if (DBtrace->str_u.str_nval != 0)
601 /* we have tried to make this normal case as abnormal as possible */
604 if (gimme == G_ARRAY) {
605 lastretstr = Nullstr;
607 lastsize = newsp - sp;
613 while (tmps_max > tmps_base) { /* clean up after last eval */
614 str_free(tmps_list[tmps_max]);
615 tmps_list[tmps_max--] = Nullstr;
617 newsp = eval(cmd->c_expr,
618 gimme && (cmdflags & CF_TERM) && cmd->c_type == C_EXPR &&
619 !cmd->ucmd.acmd.ac_expr,
621 st = stack->ary_array; /* possibly reallocated */
623 if (newsp > sp && retstr)
624 match = str_true(retstr);
629 /* if flipflop was true, flop it */
632 if (match && cmdflags & CF_FLIP) {
633 while (tmps_max > tmps_base) { /* clean up after last eval */
634 str_free(tmps_list[tmps_max]);
635 tmps_list[tmps_max--] = Nullstr;
637 if (cmd->c_expr->arg_type == O_FLOP) { /* currently toggled? */
638 newsp = eval(cmd->c_expr,G_SCALAR,sp);/*let eval undo it*/
639 cmdflags = copyopt(cmd,cmd->c_expr[3].arg_ptr.arg_cmd);
642 newsp = eval(cmd->c_expr,G_SCALAR,sp);/* let eval do it */
643 if (cmd->c_expr->arg_type == O_FLOP) /* still toggled? */
644 cmdflags = copyopt(cmd,cmd->c_expr[4].arg_ptr.arg_cmd);
647 else if (cmdflags & CF_FLIP) {
648 if (cmd->c_expr->arg_type == O_FLOP) { /* currently toggled? */
649 match = TRUE; /* force on */
653 /* at this point, match says whether our expression was true */
656 if (cmdflags & CF_INVERT)
662 tainted = 0; /* modifier doesn't affect regular expression */
665 /* now to do the actual command, if any */
667 switch (cmd->c_type) {
669 fatal("panic: cmd_exec");
670 case C_EXPR: /* evaluated for side effects */
671 if (cmd->ucmd.acmd.ac_expr) { /* more to do? */
672 if (gimme == G_ARRAY) {
673 lastretstr = Nullstr;
675 lastsize = newsp - sp;
681 while (tmps_max > tmps_base) { /* clean up after last eval */
682 str_free(tmps_list[tmps_max]);
683 tmps_list[tmps_max--] = Nullstr;
685 newsp = eval(cmd->ucmd.acmd.ac_expr,gimme && (cmdflags&CF_TERM),sp);
686 st = stack->ary_array; /* possibly reallocated */
692 double value = str_gnum(STAB_STR(cmd->c_stab));
696 if (((double)match) > value)
697 --match; /* was fractional--truncate other way */
702 match = *(str_get(STAB_STR(cmd->c_stab))) & 255;
704 match -= cmd->ucmd.scmd.sc_offset;
707 else if (match > cmd->ucmd.scmd.sc_max)
708 match = cmd->ucmd.scmd.sc_max;
709 cmd = cmd->ucmd.scmd.sc_next[match];
710 goto tail_recursion_entry;
712 cmd = cmd->ucmd.ccmd.cc_alt;
713 goto tail_recursion_entry;
715 fatal("panic: ELSIF");
718 oldsave = savestack->ary_fill;
724 if (cmd->ucmd.ccmd.cc_true) {
727 debname[dlevel] = 't';
728 debdelim[dlevel] = '_';
729 if (++dlevel >= dlmax)
733 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
734 st = stack->ary_array; /* possibly reallocated */
738 if (savestack->ary_fill > oldsave)
739 restorelist(oldsave);
743 cmd = cmd->ucmd.ccmd.cc_alt;
744 goto tail_recursion_entry;
747 oldsave = savestack->ary_fill;
753 if (cmd->ucmd.ccmd.cc_true) {
756 debname[dlevel] = 'e';
757 debdelim[dlevel] = '_';
758 if (++dlevel >= dlmax)
762 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
763 st = stack->ary_array; /* possibly reallocated */
767 if (savestack->ary_fill > oldsave)
768 restorelist(oldsave);
775 if (!(cmdflags & CF_ONCE)) { /* first time through here? */
777 if (++loop_ptr >= loop_max) {
779 Renew(loop_stack, loop_max, struct loop);
781 loop_stack[loop_ptr].loop_label = cmd->c_label;
782 loop_stack[loop_ptr].loop_sp = sp;
785 deb("(Pushing label #%d %s)\n",
786 loop_ptr, cmd->c_label ? cmd->c_label : "");
793 match = setjmp(loop_stack[loop_ptr].loop_env);
795 st = stack->ary_array; /* possibly reallocated */
798 cmdflags = cmd->c_flags|CF_ONCE;
801 if (savestack->ary_fill > oldsave)
802 restorelist(oldsave);
805 fatal("longjmp returned bad value (%d)",match);
812 newsp = sp + lastsize;
835 oldsave = savestack->ary_fill;
840 if (cmd->ucmd.ccmd.cc_true) {
843 debname[dlevel] = 't';
844 debdelim[dlevel] = '_';
845 if (++dlevel >= dlmax)
849 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
850 st = stack->ary_array; /* possibly reallocated */
853 /* actually, this spot is rarely reached anymore since the above
854 * cmd_exec() returns through longjmp(). Hooray for structure.
860 if (cmd->ucmd.ccmd.cc_alt) {
863 debname[dlevel] = 'a';
864 debdelim[dlevel] = '_';
865 if (++dlevel >= dlmax)
869 newsp = cmd_exec(cmd->ucmd.ccmd.cc_alt,gimme && (cmdflags & CF_TERM),sp);
870 st = stack->ary_array; /* possibly reallocated */
875 if (savestack->ary_fill > oldsave) {
876 if (cmdflags & CF_TERM) {
877 for (match = sp + 1; match <= newsp; match++)
878 st[match] = str_mortal(st[match]);
881 restorelist(oldsave);
884 dlevel = olddlevel - 1;
886 if (cmd->c_type != C_BLOCK)
887 goto until_loop; /* go back and evaluate conditional again */
889 if (cmdflags & CF_LOOP) {
890 cmdflags |= CF_COND; /* now test the condition */
897 if (cmdflags & CF_ONCE) {
900 tmps = loop_stack[loop_ptr].loop_label;
901 deb("(Popping label #%d %s)\n",loop_ptr, tmps ? tmps : "");
905 if ((cmdflags & CF_OPTIMIZE) == CFT_ARRAY &&
906 savestack->ary_fill > aryoptsave)
907 restorelist(aryoptsave);
910 goto tail_recursion_entry;
916 deb(pat,a1,a2,a3,a4,a5,a6,a7,a8)
921 fprintf(stderr,"%-4ld",(long)curcmd->c_line);
922 for (i=0; i<dlevel; i++)
923 fprintf(stderr,"%c%c ",debname[i],debdelim[i]);
924 fprintf(stderr,pat,a1,a2,a3,a4,a5,a6,a7,a8);
936 fprintf(stderr,"%-4ld",(long)curcmd->c_line);
937 for (i=0; i<dlevel; i++)
938 fprintf(stderr,"%c%c ",debname[i],debdelim[i]);
940 pat = va_arg(args, char *);
941 (void) vfprintf(stderr,pat,args);
951 cmd->c_flags &= CF_ONCE|CF_COND|CF_LOOP;
952 cmd->c_flags |= which->c_flags;
953 cmd->c_short = which->c_short;
954 cmd->c_slen = which->c_slen;
955 cmd->c_stab = which->c_stab;
966 str->str_state = SS_SARY;
967 str->str_u.str_stab = stab;
969 Safefree(str->str_ptr);
970 str->str_ptr = Nullch;
973 str->str_ptr = (char*)stab_array(stab);
974 (void)apush(savestack,str); /* save array ptr */
975 stab_xarray(stab) = Null(ARRAY*);
976 return stab_xarray(aadd(stab));
986 str->str_state = SS_SHASH;
987 str->str_u.str_stab = stab;
989 Safefree(str->str_ptr);
990 str->str_ptr = Nullch;
993 str->str_ptr = (char*)stab_hash(stab);
994 (void)apush(savestack,str); /* save hash ptr */
995 stab_xhash(stab) = Null(HASH*);
996 return stab_xhash(hadd(stab));
1005 (void)apush(savestack,item); /* remember the pointer */
1006 str = Str_new(12,0);
1008 (void)apush(savestack,str); /* remember the value */
1017 str = Str_new(13,0);
1018 str->str_state = SS_SINT;
1019 str->str_u.str_useful = (long)*intp; /* remember value */
1021 Safefree(str->str_ptr);
1024 str->str_ptr = (char*)intp; /* remember pointer */
1025 (void)apush(savestack,str);
1034 str = Str_new(14,0);
1035 str->str_state = SS_SLONG;
1036 str->str_u.str_useful = *longp; /* remember value */
1038 Safefree(str->str_ptr);
1041 str->str_ptr = (char*)longp; /* remember pointer */
1042 (void)apush(savestack,str);
1051 str = Str_new(15,0);
1052 str->str_state = SS_SSTRP;
1053 str->str_magic = *sptr; /* remember value */
1055 Safefree(str->str_ptr);
1058 str->str_ptr = (char*)sptr; /* remember pointer */
1059 (void)apush(savestack,str);
1068 str = Str_new(16,0);
1069 str->str_state = SS_SNSTAB;
1070 str->str_magic = (STR*)stab; /* remember which stab to free */
1071 (void)apush(savestack,str);
1080 str = Str_new(17,0);
1081 str->str_state = SS_SHPTR;
1082 str->str_u.str_hash = *hptr; /* remember value */
1084 Safefree(str->str_ptr);
1087 str->str_ptr = (char*)hptr; /* remember pointer */
1088 (void)apush(savestack,str);
1097 str = Str_new(17,0);
1098 str->str_state = SS_SAPTR;
1099 str->str_u.str_array = *aptr; /* remember value */
1101 Safefree(str->str_ptr);
1104 str->str_ptr = (char*)aptr; /* remember pointer */
1105 (void)apush(savestack,str);
1109 savelist(sarg,maxsarg)
1110 register STR **sarg;
1116 for (i = 1; i <= maxsarg; i++) {
1117 (void)apush(savestack,sarg[i]); /* remember the pointer */
1118 str = Str_new(18,0);
1119 str_sset(str,sarg[i]);
1120 (void)apush(savestack,str); /* remember the value */
1121 sarg[i]->str_u.str_useful = -1;
1130 register STR *value;
1131 register STAB *stab;
1134 fatal("panic: corrupt saved stack index");
1135 while (savestack->ary_fill > base) {
1136 value = apop(savestack);
1137 switch (value->str_state) {
1138 case SS_NORM: /* normal string */
1140 str = apop(savestack);
1141 str_replace(str,value);
1144 case SS_SARY: /* array reference */
1145 stab = value->str_u.str_stab;
1146 afree(stab_xarray(stab));
1147 stab_xarray(stab) = (ARRAY*)value->str_ptr;
1148 value->str_ptr = Nullch;
1151 case SS_SHASH: /* hash reference */
1152 stab = value->str_u.str_stab;
1153 (void)hfree(stab_xhash(stab), FALSE);
1154 stab_xhash(stab) = (HASH*)value->str_ptr;
1155 value->str_ptr = Nullch;
1158 case SS_SINT: /* int reference */
1159 *((int*)value->str_ptr) = (int)value->str_u.str_useful;
1160 value->str_ptr = Nullch;
1163 case SS_SLONG: /* long reference */
1164 *((long*)value->str_ptr) = value->str_u.str_useful;
1165 value->str_ptr = Nullch;
1168 case SS_SSTRP: /* STR* reference */
1169 *((STR**)value->str_ptr) = value->str_magic;
1170 value->str_magic = Nullstr;
1171 value->str_ptr = Nullch;
1174 case SS_SHPTR: /* HASH* reference */
1175 *((HASH**)value->str_ptr) = value->str_u.str_hash;
1176 value->str_ptr = Nullch;
1179 case SS_SAPTR: /* ARRAY* reference */
1180 *((ARRAY**)value->str_ptr) = value->str_u.str_array;
1181 value->str_ptr = Nullch;
1185 stab = (STAB*)value->str_magic;
1186 value->str_magic = Nullstr;
1187 (void)stab_clear(stab);
1190 case SS_SCSV: /* callsave structure */
1192 CSV *csv = (CSV*) value->str_ptr;
1194 curcmd = csv->curcmd;
1195 curcsv = csv->curcsv;
1196 csv->sub->depth = csv->depth;
1197 if (csv->hasargs) { /* put back old @_ */
1198 afree(csv->argarray);
1199 stab_xarray(defstab) = csv->savearray;
1205 fatal("panic: restorelist inconsistency");
1215 Renew(debname, dlmax, char);
1216 Renew(debdelim, dlmax, char);