1 /* $RCSfile: cmd.c,v $$Revision: 4.0.1.2 $$Date: 91/06/07 10:26:45 $
3 * Copyright (c) 1991, Larry Wall
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.
9 * Revision 4.0.1.2 91/06/07 10:26:45 lwall
10 * patch4: new copyright notice
11 * patch4: made some allowances for "semi-standard" C
13 * Revision 4.0.1.1 91/04/11 17:36:16 lwall
14 * patch1: you may now use "die" and "caller" in a signal handler
16 * Revision 4.0 91/03/20 01:04:18 lwall
32 /* do longjmps() clobber register variables? */
34 #if defined(cray) || defined(STANDARD_C)
38 /* This is the main command loop. We try to spend as much time in this loop
39 * as possible, so lots of optimizations do their activities in here. This
40 * means things get a little sloppy.
44 cmd_exec(cmdparm,gimme,sp)
45 CMD *VOLATILE cmdparm;
49 register CMD *cmd = cmdparm;
50 SPAT *VOLATILE oldspat;
51 VOLATILE int firstsave = savestack->ary_fill;
53 VOLATILE int aryoptsave;
55 VOLATILE int olddlevel;
56 VOLATILE int entdlevel;
58 register STR *retstr = &str_undef;
60 register int cmdflags;
62 register char *go_to = goto_targ;
63 register int newsp = -2;
64 register STR **st = stack->ary_array;
77 tainted = 0; /* Each statement is presumed innocent */
80 if (gimme == G_ARRAY && newsp > -2)
87 cmdflags = cmd->c_flags; /* hopefully load register */
89 if (cmd->c_label && strEQ(go_to,cmd->c_label))
90 goto_targ = go_to = Nullch; /* here at last */
92 switch (cmd->c_type) {
95 oldsave = savestack->ary_fill;
101 if (cmd->ucmd.ccmd.cc_true) {
104 debname[dlevel] = 't';
105 debdelim[dlevel] = '_';
106 if (++dlevel >= dlmax)
110 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
111 st = stack->ary_array; /* possibly reallocated */
117 if (savestack->ary_fill > oldsave)
118 restorelist(oldsave);
122 cmd = cmd->ucmd.ccmd.cc_alt;
123 goto tail_recursion_entry;
126 oldsave = savestack->ary_fill;
132 if (cmd->ucmd.ccmd.cc_true) {
135 debname[dlevel] = 'e';
136 debdelim[dlevel] = '_';
137 if (++dlevel >= dlmax)
141 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
142 st = stack->ary_array; /* possibly reallocated */
148 if (savestack->ary_fill > oldsave)
149 restorelist(oldsave);
156 if (!(cmdflags & CF_ONCE)) {
158 if (++loop_ptr >= loop_max) {
160 Renew(loop_stack, loop_max, struct loop);
162 loop_stack[loop_ptr].loop_label = cmd->c_label;
163 loop_stack[loop_ptr].loop_sp = sp;
166 deb("(Pushing label #%d %s)\n",
167 loop_ptr, cmd->c_label ? cmd->c_label : "");
174 match = setjmp(loop_stack[loop_ptr].loop_env);
176 st = stack->ary_array; /* possibly reallocated */
179 cmdflags = cmd->c_flags|CF_ONCE;
181 if (savestack->ary_fill > oldsave)
182 restorelist(oldsave);
185 fatal("longjmp returned bad value (%d)",match);
186 case O_LAST: /* not done unless go_to found */
193 newsp = sp + lastsize;
201 case O_NEXT: /* not done unless go_to found */
208 case O_REDO: /* not done unless go_to found */
218 oldsave = savestack->ary_fill;
222 if (cmd->ucmd.ccmd.cc_true) {
225 debname[dlevel] = 't';
226 debdelim[dlevel] = '_';
227 if (++dlevel >= dlmax)
231 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
232 st = stack->ary_array; /* possibly reallocated */
242 if (cmd->ucmd.ccmd.cc_alt) {
245 debname[dlevel] = 'a';
246 debdelim[dlevel] = '_';
247 if (++dlevel >= dlmax)
251 newsp = cmd_exec(cmd->ucmd.ccmd.cc_alt,gimme && (cmdflags & CF_TERM),sp);
252 st = stack->ary_array; /* possibly reallocated */
261 if (cmd && cmd->c_head == cmd)
262 /* reached end of while loop */
263 return sp; /* targ isn't in this block */
264 if (cmdflags & CF_ONCE) {
267 tmps = loop_stack[loop_ptr].loop_label;
268 deb("(Popping label #%d %s)\n",loop_ptr,
274 goto tail_recursion_entry;
280 /* Set line number so run-time errors can be located */
287 deb("%s (%lx) r%lx t%lx a%lx n%lx cs%lx\n",
288 cmdname[cmd->c_type],cmd,cmd->c_expr,
289 cmd->ucmd.ccmd.cc_true,cmd->ucmd.ccmd.cc_alt,cmd->c_next,
292 debname[dlevel] = cmdname[cmd->c_type][0];
293 debdelim[dlevel] = '!';
294 if (++dlevel >= dlmax)
299 /* Here is some common optimization */
301 if (cmdflags & CF_COND) {
302 switch (cmdflags & CF_OPTIMIZE) {
305 retstr = cmd->c_short;
308 if (cmdflags & CF_NESURE)
312 retstr = cmd->c_short;
315 if (cmdflags & CF_EQSURE)
320 retstr = STAB_STR(cmd->c_stab);
322 match = str_true(retstr); /* => retstr = retstr, c2 should fix */
323 if (cmdflags & (match ? CF_EQSURE : CF_NESURE))
327 case CFT_ANCHOR: /* /^pat/ optimization */
329 if (*cmd->c_short->str_ptr && !(cmdflags & CF_EQSURE))
330 goto scanner; /* just unanchor it */
332 break; /* must evaluate */
335 case CFT_STROP: /* string op optimization */
336 retstr = STAB_STR(cmd->c_stab);
339 if (*cmd->c_short->str_ptr == *str_get(retstr) &&
340 bcmp(cmd->c_short->str_ptr, str_get(retstr),
341 cmd->c_slen) == 0 ) {
342 if (cmdflags & CF_EQSURE) {
343 if (sawampersand && (cmdflags & CF_OPTIMIZE) != CFT_STROP) {
346 str_nset(stab_val(leftstab),"",0);
348 str_sset(stab_val(amperstab),cmd->c_short);
350 str_nset(stab_val(rightstab),
351 retstr->str_ptr + cmd->c_slen,
352 retstr->str_cur - cmd->c_slen);
355 lastspat = cmd->c_spat;
356 match = !(cmdflags & CF_FIRSTNEG);
361 else if (cmdflags & CF_NESURE) {
362 match = cmdflags & CF_FIRSTNEG;
368 char *zap1, *zap2, zap1c, zap2c;
371 zap1 = cmd->c_short->str_ptr;
372 zap2 = str_get(retstr);
375 zaplen = cmd->c_slen;
376 if ((zap1c == zap2c) && (bcmp(zap1, zap2, zaplen) == 0)) {
377 if (cmdflags & CF_EQSURE) {
379 (cmdflags & CF_OPTIMIZE) != CFT_STROP) {
382 str_nset(stab_val(leftstab),"",0);
384 str_sset(stab_val(amperstab),cmd->c_short);
386 str_nset(stab_val(rightstab),
387 retstr->str_ptr + cmd->c_slen,
388 retstr->str_cur - cmd->c_slen);
391 lastspat = cmd->c_spat;
392 match = !(cmdflags & CF_FIRSTNEG);
397 else if (cmdflags & CF_NESURE) {
398 match = cmdflags & CF_FIRSTNEG;
404 break; /* must evaluate */
406 case CFT_SCAN: /* non-anchored search */
408 retstr = STAB_STR(cmd->c_stab);
410 if (retstr->str_pok & SP_STUDIED)
411 if (screamfirst[cmd->c_short->str_rare] >= 0)
412 tmps = screaminstr(retstr, cmd->c_short);
416 tmps = str_get(retstr); /* make sure it's pok */
418 tmps = fbminstr((unsigned char*)tmps,
419 (unsigned char*)tmps + retstr->str_cur, cmd->c_short);
423 if (cmdflags & CF_EQSURE) {
424 ++cmd->c_short->str_u.str_useful;
428 str_nset(stab_val(leftstab),retstr->str_ptr,
429 tmps - retstr->str_ptr);
431 str_nset(stab_val(amperstab),
432 tmps, cmd->c_short->str_cur);
434 str_nset(stab_val(rightstab),
435 tmps + cmd->c_short->str_cur,
436 retstr->str_cur - (tmps - retstr->str_ptr) -
437 cmd->c_short->str_cur);
439 lastspat = cmd->c_spat;
440 match = !(cmdflags & CF_FIRSTNEG);
448 if (cmdflags & CF_NESURE) {
449 ++cmd->c_short->str_u.str_useful;
450 match = cmdflags & CF_FIRSTNEG;
455 if (--cmd->c_short->str_u.str_useful < 0) {
456 cmdflags &= ~CF_OPTIMIZE;
457 cmdflags |= CFT_EVAL; /* never try this optimization again */
458 cmd->c_flags = (cmdflags & ~CF_ONCE);
460 break; /* must evaluate */
462 case CFT_NUMOP: /* numeric op optimization */
463 retstr = STAB_STR(cmd->c_stab);
465 switch (cmd->c_slen) {
468 if ((!retstr->str_nok && !looks_like_number(retstr)))
469 warn("Possible use of == on string value");
471 match = (str_gnum(retstr) == cmd->c_short->str_u.str_nval);
474 match = (str_gnum(retstr) != cmd->c_short->str_u.str_nval);
477 match = (str_gnum(retstr) < cmd->c_short->str_u.str_nval);
480 match = (str_gnum(retstr) <= cmd->c_short->str_u.str_nval);
483 match = (str_gnum(retstr) > cmd->c_short->str_u.str_nval);
486 match = (str_gnum(retstr) >= cmd->c_short->str_u.str_nval);
490 if (cmdflags & CF_EQSURE) {
495 else if (cmdflags & CF_NESURE) {
499 break; /* must evaluate */
501 case CFT_INDGETS: /* while (<$foo>) */
502 last_in_stab = stabent(str_get(STAB_STR(cmd->c_stab)),TRUE);
503 if (!stab_io(last_in_stab))
504 stab_io(last_in_stab) = stio_new();
506 case CFT_GETS: /* really a while (<file>) */
507 last_in_stab = cmd->c_stab;
509 fp = stab_io(last_in_stab)->ifp;
510 retstr = stab_val(defstab);
513 if (fp && str_gets(retstr, fp, 0)) {
514 if (*retstr->str_ptr == '0' && retstr->str_cur == 1)
518 stab_io(last_in_stab)->lines++;
520 else if (stab_io(last_in_stab)->flags & IOF_ARGV) {
522 goto doeval; /* first time through */
523 fp = nextargv(last_in_stab);
526 (void)do_close(last_in_stab,FALSE);
527 stab_io(last_in_stab)->flags |= IOF_START;
539 while (tmps_max > tmps_base) { /* clean up after last eval */
540 str_free(tmps_list[tmps_max]);
541 tmps_list[tmps_max--] = Nullstr;
543 newsp = eval(cmd->c_expr,gimme && (cmdflags & CF_TERM),sp);
544 st = stack->ary_array; /* possibly reallocated */
546 match = str_true(retstr);
547 if (cmd->c_expr->arg_type == O_FLIP) /* undid itself? */
548 cmdflags = copyopt(cmd,cmd->c_expr[3].arg_ptr.arg_cmd);
551 retstr = stab_val(cmd->c_stab);
553 match = (retstr->str_cur != 0);
554 tmps = str_get(retstr);
555 tmps += retstr->str_cur - match;
556 str_nset(&str_chop,tmps,match);
559 retstr->str_cur = tmps - retstr->str_ptr;
564 match = cmd->c_short->str_u.str_useful; /* just to get register */
566 if (match < 0) { /* first time through here? */
567 ar = stab_array(cmd->c_expr[1].arg_ptr.arg_stab);
568 aryoptsave = savestack->ary_fill;
569 savesptr(&stab_val(cmd->c_stab));
570 savelong(&cmd->c_short->str_u.str_useful);
573 ar = stab_xarray(cmd->c_expr[1].arg_ptr.arg_stab);
574 if (cmd->c_type != C_WHILE && savestack->ary_fill > firstsave)
575 restorelist(firstsave);
578 if (match >= ar->ary_fill) { /* we're in LAST, probably */
580 cmd->c_short->str_u.str_useful = -1; /* actually redundant */
585 if (!(retstr = ar->ary_array[match]))
586 retstr = afetch(ar,match,TRUE);
587 stab_val(cmd->c_stab) = retstr;
588 cmd->c_short->str_u.str_useful = match;
596 if (DBsingle->str_u.str_nval != 0)
598 if (DBsignal->str_u.str_nval != 0)
600 if (DBtrace->str_u.str_nval != 0)
605 /* we have tried to make this normal case as abnormal as possible */
608 if (gimme == G_ARRAY) {
609 lastretstr = Nullstr;
611 lastsize = newsp - sp;
617 while (tmps_max > tmps_base) { /* clean up after last eval */
618 str_free(tmps_list[tmps_max]);
619 tmps_list[tmps_max--] = Nullstr;
621 newsp = eval(cmd->c_expr,
622 gimme && (cmdflags & CF_TERM) && cmd->c_type == C_EXPR &&
623 !cmd->ucmd.acmd.ac_expr,
625 st = stack->ary_array; /* possibly reallocated */
627 if (newsp > sp && retstr)
628 match = str_true(retstr);
633 /* if flipflop was true, flop it */
636 if (match && cmdflags & CF_FLIP) {
637 while (tmps_max > tmps_base) { /* clean up after last eval */
638 str_free(tmps_list[tmps_max]);
639 tmps_list[tmps_max--] = Nullstr;
641 if (cmd->c_expr->arg_type == O_FLOP) { /* currently toggled? */
642 newsp = eval(cmd->c_expr,G_SCALAR,sp);/*let eval undo it*/
643 cmdflags = copyopt(cmd,cmd->c_expr[3].arg_ptr.arg_cmd);
646 newsp = eval(cmd->c_expr,G_SCALAR,sp);/* let eval do it */
647 if (cmd->c_expr->arg_type == O_FLOP) /* still toggled? */
648 cmdflags = copyopt(cmd,cmd->c_expr[4].arg_ptr.arg_cmd);
651 else if (cmdflags & CF_FLIP) {
652 if (cmd->c_expr->arg_type == O_FLOP) { /* currently toggled? */
653 match = TRUE; /* force on */
657 /* at this point, match says whether our expression was true */
660 if (cmdflags & CF_INVERT)
666 tainted = 0; /* modifier doesn't affect regular expression */
669 /* now to do the actual command, if any */
671 switch (cmd->c_type) {
673 fatal("panic: cmd_exec");
674 case C_EXPR: /* evaluated for side effects */
675 if (cmd->ucmd.acmd.ac_expr) { /* more to do? */
676 if (gimme == G_ARRAY) {
677 lastretstr = Nullstr;
679 lastsize = newsp - sp;
685 while (tmps_max > tmps_base) { /* clean up after last eval */
686 str_free(tmps_list[tmps_max]);
687 tmps_list[tmps_max--] = Nullstr;
689 newsp = eval(cmd->ucmd.acmd.ac_expr,gimme && (cmdflags&CF_TERM),sp);
690 st = stack->ary_array; /* possibly reallocated */
696 double value = str_gnum(STAB_STR(cmd->c_stab));
700 if (((double)match) > value)
701 --match; /* was fractional--truncate other way */
706 match = *(str_get(STAB_STR(cmd->c_stab))) & 255;
708 match -= cmd->ucmd.scmd.sc_offset;
711 else if (match > cmd->ucmd.scmd.sc_max)
712 match = cmd->ucmd.scmd.sc_max;
713 cmd = cmd->ucmd.scmd.sc_next[match];
714 goto tail_recursion_entry;
716 cmd = cmd->ucmd.ccmd.cc_alt;
717 goto tail_recursion_entry;
719 fatal("panic: ELSIF");
722 oldsave = savestack->ary_fill;
728 if (cmd->ucmd.ccmd.cc_true) {
731 debname[dlevel] = 't';
732 debdelim[dlevel] = '_';
733 if (++dlevel >= dlmax)
737 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
738 st = stack->ary_array; /* possibly reallocated */
742 if (savestack->ary_fill > oldsave)
743 restorelist(oldsave);
747 cmd = cmd->ucmd.ccmd.cc_alt;
748 goto tail_recursion_entry;
751 oldsave = savestack->ary_fill;
757 if (cmd->ucmd.ccmd.cc_true) {
760 debname[dlevel] = 'e';
761 debdelim[dlevel] = '_';
762 if (++dlevel >= dlmax)
766 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
767 st = stack->ary_array; /* possibly reallocated */
771 if (savestack->ary_fill > oldsave)
772 restorelist(oldsave);
779 if (!(cmdflags & CF_ONCE)) { /* first time through here? */
781 if (++loop_ptr >= loop_max) {
783 Renew(loop_stack, loop_max, struct loop);
785 loop_stack[loop_ptr].loop_label = cmd->c_label;
786 loop_stack[loop_ptr].loop_sp = sp;
789 deb("(Pushing label #%d %s)\n",
790 loop_ptr, cmd->c_label ? cmd->c_label : "");
797 match = setjmp(loop_stack[loop_ptr].loop_env);
799 st = stack->ary_array; /* possibly reallocated */
802 cmdflags = cmd->c_flags|CF_ONCE;
805 if (savestack->ary_fill > oldsave)
806 restorelist(oldsave);
809 fatal("longjmp returned bad value (%d)",match);
816 newsp = sp + lastsize;
839 oldsave = savestack->ary_fill;
844 if (cmd->ucmd.ccmd.cc_true) {
847 debname[dlevel] = 't';
848 debdelim[dlevel] = '_';
849 if (++dlevel >= dlmax)
853 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
854 st = stack->ary_array; /* possibly reallocated */
857 /* actually, this spot is rarely reached anymore since the above
858 * cmd_exec() returns through longjmp(). Hooray for structure.
864 if (cmd->ucmd.ccmd.cc_alt) {
867 debname[dlevel] = 'a';
868 debdelim[dlevel] = '_';
869 if (++dlevel >= dlmax)
873 newsp = cmd_exec(cmd->ucmd.ccmd.cc_alt,gimme && (cmdflags & CF_TERM),sp);
874 st = stack->ary_array; /* possibly reallocated */
879 if (savestack->ary_fill > oldsave) {
880 if (cmdflags & CF_TERM) {
881 for (match = sp + 1; match <= newsp; match++)
882 st[match] = str_mortal(st[match]);
885 restorelist(oldsave);
888 dlevel = olddlevel - 1;
890 if (cmd->c_type != C_BLOCK)
891 goto until_loop; /* go back and evaluate conditional again */
893 if (cmdflags & CF_LOOP) {
894 cmdflags |= CF_COND; /* now test the condition */
901 if (cmdflags & CF_ONCE) {
904 tmps = loop_stack[loop_ptr].loop_label;
905 deb("(Popping label #%d %s)\n",loop_ptr, tmps ? tmps : "");
909 if ((cmdflags & CF_OPTIMIZE) == CFT_ARRAY &&
910 savestack->ary_fill > aryoptsave)
911 restorelist(aryoptsave);
914 goto tail_recursion_entry;
920 deb(pat,a1,a2,a3,a4,a5,a6,a7,a8)
925 fprintf(stderr,"%-4ld",(long)curcmd->c_line);
926 for (i=0; i<dlevel; i++)
927 fprintf(stderr,"%c%c ",debname[i],debdelim[i]);
928 fprintf(stderr,pat,a1,a2,a3,a4,a5,a6,a7,a8);
940 fprintf(stderr,"%-4ld",(long)curcmd->c_line);
941 for (i=0; i<dlevel; i++)
942 fprintf(stderr,"%c%c ",debname[i],debdelim[i]);
944 pat = va_arg(args, char *);
945 (void) vfprintf(stderr,pat,args);
955 cmd->c_flags &= CF_ONCE|CF_COND|CF_LOOP;
956 cmd->c_flags |= which->c_flags;
957 cmd->c_short = which->c_short;
958 cmd->c_slen = which->c_slen;
959 cmd->c_stab = which->c_stab;
970 str->str_state = SS_SARY;
971 str->str_u.str_stab = stab;
973 Safefree(str->str_ptr);
974 str->str_ptr = Nullch;
977 str->str_ptr = (char*)stab_array(stab);
978 (void)apush(savestack,str); /* save array ptr */
979 stab_xarray(stab) = Null(ARRAY*);
980 return stab_xarray(aadd(stab));
990 str->str_state = SS_SHASH;
991 str->str_u.str_stab = stab;
993 Safefree(str->str_ptr);
994 str->str_ptr = Nullch;
997 str->str_ptr = (char*)stab_hash(stab);
998 (void)apush(savestack,str); /* save hash ptr */
999 stab_xhash(stab) = Null(HASH*);
1000 return stab_xhash(hadd(stab));
1009 (void)apush(savestack,item); /* remember the pointer */
1010 str = Str_new(12,0);
1012 (void)apush(savestack,str); /* remember the value */
1021 str = Str_new(13,0);
1022 str->str_state = SS_SINT;
1023 str->str_u.str_useful = (long)*intp; /* remember value */
1025 Safefree(str->str_ptr);
1028 str->str_ptr = (char*)intp; /* remember pointer */
1029 (void)apush(savestack,str);
1038 str = Str_new(14,0);
1039 str->str_state = SS_SLONG;
1040 str->str_u.str_useful = *longp; /* remember value */
1042 Safefree(str->str_ptr);
1045 str->str_ptr = (char*)longp; /* remember pointer */
1046 (void)apush(savestack,str);
1055 str = Str_new(15,0);
1056 str->str_state = SS_SSTRP;
1057 str->str_magic = *sptr; /* remember value */
1059 Safefree(str->str_ptr);
1062 str->str_ptr = (char*)sptr; /* remember pointer */
1063 (void)apush(savestack,str);
1072 str = Str_new(16,0);
1073 str->str_state = SS_SNSTAB;
1074 str->str_magic = (STR*)stab; /* remember which stab to free */
1075 (void)apush(savestack,str);
1084 str = Str_new(17,0);
1085 str->str_state = SS_SHPTR;
1086 str->str_u.str_hash = *hptr; /* remember value */
1088 Safefree(str->str_ptr);
1091 str->str_ptr = (char*)hptr; /* remember pointer */
1092 (void)apush(savestack,str);
1101 str = Str_new(17,0);
1102 str->str_state = SS_SAPTR;
1103 str->str_u.str_array = *aptr; /* remember value */
1105 Safefree(str->str_ptr);
1108 str->str_ptr = (char*)aptr; /* remember pointer */
1109 (void)apush(savestack,str);
1113 savelist(sarg,maxsarg)
1114 register STR **sarg;
1120 for (i = 1; i <= maxsarg; i++) {
1121 (void)apush(savestack,sarg[i]); /* remember the pointer */
1122 str = Str_new(18,0);
1123 str_sset(str,sarg[i]);
1124 (void)apush(savestack,str); /* remember the value */
1125 sarg[i]->str_u.str_useful = -1;
1134 register STR *value;
1135 register STAB *stab;
1138 fatal("panic: corrupt saved stack index");
1139 while (savestack->ary_fill > base) {
1140 value = apop(savestack);
1141 switch (value->str_state) {
1142 case SS_NORM: /* normal string */
1144 str = apop(savestack);
1145 str_replace(str,value);
1148 case SS_SARY: /* array reference */
1149 stab = value->str_u.str_stab;
1150 afree(stab_xarray(stab));
1151 stab_xarray(stab) = (ARRAY*)value->str_ptr;
1152 value->str_ptr = Nullch;
1155 case SS_SHASH: /* hash reference */
1156 stab = value->str_u.str_stab;
1157 (void)hfree(stab_xhash(stab), FALSE);
1158 stab_xhash(stab) = (HASH*)value->str_ptr;
1159 value->str_ptr = Nullch;
1162 case SS_SINT: /* int reference */
1163 *((int*)value->str_ptr) = (int)value->str_u.str_useful;
1164 value->str_ptr = Nullch;
1167 case SS_SLONG: /* long reference */
1168 *((long*)value->str_ptr) = value->str_u.str_useful;
1169 value->str_ptr = Nullch;
1172 case SS_SSTRP: /* STR* reference */
1173 *((STR**)value->str_ptr) = value->str_magic;
1174 value->str_magic = Nullstr;
1175 value->str_ptr = Nullch;
1178 case SS_SHPTR: /* HASH* reference */
1179 *((HASH**)value->str_ptr) = value->str_u.str_hash;
1180 value->str_ptr = Nullch;
1183 case SS_SAPTR: /* ARRAY* reference */
1184 *((ARRAY**)value->str_ptr) = value->str_u.str_array;
1185 value->str_ptr = Nullch;
1189 stab = (STAB*)value->str_magic;
1190 value->str_magic = Nullstr;
1191 (void)stab_clear(stab);
1194 case SS_SCSV: /* callsave structure */
1196 CSV *csv = (CSV*) value->str_ptr;
1198 curcmd = csv->curcmd;
1199 curcsv = csv->curcsv;
1200 csv->sub->depth = csv->depth;
1201 if (csv->hasargs) { /* put back old @_ */
1202 afree(csv->argarray);
1203 stab_xarray(defstab) = csv->savearray;
1209 fatal("panic: restorelist inconsistency");
1219 Renew(debname, dlmax, char);
1220 Renew(debdelim, dlmax, char);