1 /* $Header: cmd.c,v 3.0.1.9 90/10/15 15:32:39 lwall Locked $
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 3.0.1.9 90/10/15 15:32:39 lwall
10 * patch29: non-existent array values no longer cause core dumps
11 * patch29: scripts now run at almost full speed under the debugger
12 * patch29: @ENV = () now works
13 * patch29: added caller
15 * Revision 3.0.1.8 90/08/09 02:28:49 lwall
16 * patch19: did preliminary work toward debugging packages and evals
17 * patch19: conditionals now always supply a scalar context to expression
18 * patch19: switch optimizer was confused by negative fractional values
20 * Revision 3.0.1.7 90/03/27 15:32:37 lwall
21 * patch16: non-terminal blocks should never have arrays requested of them
23 * Revision 3.0.1.6 90/03/12 16:21:09 lwall
24 * patch13: fixed some backwards VOLATILE declarations
25 * patch13: while (s/x//) {} still caused some anomolies
26 * patch13: greater-than test of numeric switch structures did less-than action
28 * Revision 3.0.1.5 90/02/28 16:38:31 lwall
29 * patch9: volatilized some more variables for super-optimizing compilers
30 * patch9: nested foreach loops didn't reset inner loop on next to outer loop
31 * patch9: returned values were read from obsolete stack
32 * patch9: added sanity check on longjmp() return value
33 * patch9: substitutions that almost always succeed can corrupt label stack
34 * patch9: subs which return by both mechanisms can clobber local return data
36 * Revision 3.0.1.4 89/12/21 19:17:41 lwall
37 * patch7: arranged for certain registers to be restored after longjmp()
38 * patch7: made nested or recursive foreach work right
40 * Revision 3.0.1.3 89/11/17 15:04:36 lwall
41 * patch5: nested foreach on same array didn't work
43 * Revision 3.0.1.2 89/11/11 04:08:56 lwall
44 * patch2: non-BSD machines required two ^D's for <>
45 * patch2: grow_dlevel() not inside #ifdef DEBUGGING
47 * Revision 3.0.1.1 89/10/26 23:04:21 lwall
48 * patch1: heuristically disabled optimization could cause core dump
50 * Revision 3.0 89/10/18 15:09:02 lwall
66 /* do longjmps() clobber register variables? */
68 #if defined(cray) || defined(__STDC__)
72 /* This is the main command loop. We try to spend as much time in this loop
73 * as possible, so lots of optimizations do their activities in here. This
74 * means things get a little sloppy.
78 cmd_exec(cmdparm,gimme,sp)
79 CMD *VOLATILE cmdparm;
83 register CMD *cmd = cmdparm;
84 SPAT *VOLATILE oldspat;
85 VOLATILE int firstsave = savestack->ary_fill;
87 VOLATILE int aryoptsave;
89 VOLATILE int olddlevel;
90 VOLATILE int entdlevel;
92 register STR *retstr = &str_undef;
94 register int cmdflags;
96 register char *go_to = goto_targ;
97 register int newsp = -2;
98 register STR **st = stack->ary_array;
106 tail_recursion_entry:
111 tainted = 0; /* Each statement is presumed innocent */
113 if (cmd == Nullcmd) {
114 if (gimme == G_ARRAY && newsp > -2)
121 cmdflags = cmd->c_flags; /* hopefully load register */
123 if (cmd->c_label && strEQ(go_to,cmd->c_label))
124 goto_targ = go_to = Nullch; /* here at last */
126 switch (cmd->c_type) {
129 oldsave = savestack->ary_fill;
135 if (cmd->ucmd.ccmd.cc_true) {
138 debname[dlevel] = 't';
139 debdelim[dlevel] = '_';
140 if (++dlevel >= dlmax)
144 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
145 st = stack->ary_array; /* possibly reallocated */
151 if (savestack->ary_fill > oldsave)
152 restorelist(oldsave);
156 cmd = cmd->ucmd.ccmd.cc_alt;
157 goto tail_recursion_entry;
160 oldsave = savestack->ary_fill;
166 if (cmd->ucmd.ccmd.cc_true) {
169 debname[dlevel] = 'e';
170 debdelim[dlevel] = '_';
171 if (++dlevel >= dlmax)
175 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
176 st = stack->ary_array; /* possibly reallocated */
182 if (savestack->ary_fill > oldsave)
183 restorelist(oldsave);
190 if (!(cmdflags & CF_ONCE)) {
192 if (++loop_ptr >= loop_max) {
194 Renew(loop_stack, loop_max, struct loop);
196 loop_stack[loop_ptr].loop_label = cmd->c_label;
197 loop_stack[loop_ptr].loop_sp = sp;
200 deb("(Pushing label #%d %s)\n",
201 loop_ptr, cmd->c_label ? cmd->c_label : "");
208 if (match = setjmp(loop_stack[loop_ptr].loop_env)) {
209 st = stack->ary_array; /* possibly reallocated */
212 cmdflags = cmd->c_flags|CF_ONCE;
214 if (savestack->ary_fill > oldsave)
215 restorelist(oldsave);
218 fatal("longjmp returned bad value (%d)",match);
219 case O_LAST: /* not done unless go_to found */
226 newsp = sp + lastsize;
234 case O_NEXT: /* not done unless go_to found */
241 case O_REDO: /* not done unless go_to found */
251 oldsave = savestack->ary_fill;
255 if (cmd->ucmd.ccmd.cc_true) {
258 debname[dlevel] = 't';
259 debdelim[dlevel] = '_';
260 if (++dlevel >= dlmax)
264 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
265 st = stack->ary_array; /* possibly reallocated */
275 if (cmd->ucmd.ccmd.cc_alt) {
278 debname[dlevel] = 'a';
279 debdelim[dlevel] = '_';
280 if (++dlevel >= dlmax)
284 newsp = cmd_exec(cmd->ucmd.ccmd.cc_alt,gimme && (cmdflags & CF_TERM),sp);
285 st = stack->ary_array; /* possibly reallocated */
294 if (cmd && cmd->c_head == cmd)
295 /* reached end of while loop */
296 return sp; /* targ isn't in this block */
297 if (cmdflags & CF_ONCE) {
300 tmps = loop_stack[loop_ptr].loop_label;
301 deb("(Popping label #%d %s)\n",loop_ptr,
307 goto tail_recursion_entry;
313 /* Set line number so run-time errors can be located */
320 deb("%s (%lx) r%lx t%lx a%lx n%lx cs%lx\n",
321 cmdname[cmd->c_type],cmd,cmd->c_expr,
322 cmd->ucmd.ccmd.cc_true,cmd->ucmd.ccmd.cc_alt,cmd->c_next,
325 debname[dlevel] = cmdname[cmd->c_type][0];
326 debdelim[dlevel] = '!';
327 if (++dlevel >= dlmax)
332 /* Here is some common optimization */
334 if (cmdflags & CF_COND) {
335 switch (cmdflags & CF_OPTIMIZE) {
338 retstr = cmd->c_short;
341 if (cmdflags & CF_NESURE)
345 retstr = cmd->c_short;
348 if (cmdflags & CF_EQSURE)
353 retstr = STAB_STR(cmd->c_stab);
355 match = str_true(retstr); /* => retstr = retstr, c2 should fix */
356 if (cmdflags & (match ? CF_EQSURE : CF_NESURE))
360 case CFT_ANCHOR: /* /^pat/ optimization */
362 if (*cmd->c_short->str_ptr && !(cmdflags & CF_EQSURE))
363 goto scanner; /* just unanchor it */
365 break; /* must evaluate */
368 case CFT_STROP: /* string op optimization */
369 retstr = STAB_STR(cmd->c_stab);
372 if (*cmd->c_short->str_ptr == *str_get(retstr) &&
373 bcmp(cmd->c_short->str_ptr, str_get(retstr),
374 cmd->c_slen) == 0 ) {
375 if (cmdflags & CF_EQSURE) {
376 if (sawampersand && (cmdflags & CF_OPTIMIZE) != CFT_STROP) {
379 str_nset(stab_val(leftstab),"",0);
381 str_sset(stab_val(amperstab),cmd->c_short);
383 str_nset(stab_val(rightstab),
384 retstr->str_ptr + cmd->c_slen,
385 retstr->str_cur - cmd->c_slen);
387 match = !(cmdflags & CF_FIRSTNEG);
392 else if (cmdflags & CF_NESURE) {
393 match = cmdflags & CF_FIRSTNEG;
399 char *zap1, *zap2, zap1c, zap2c;
402 zap1 = cmd->c_short->str_ptr;
403 zap2 = str_get(retstr);
406 zaplen = cmd->c_slen;
407 if ((zap1c == zap2c) && (bcmp(zap1, zap2, zaplen) == 0)) {
408 if (cmdflags & CF_EQSURE) {
410 (cmdflags & CF_OPTIMIZE) != CFT_STROP) {
413 str_nset(stab_val(leftstab),"",0);
415 str_sset(stab_val(amperstab),cmd->c_short);
417 str_nset(stab_val(rightstab),
418 retstr->str_ptr + cmd->c_slen,
419 retstr->str_cur - cmd->c_slen);
421 match = !(cmdflags & CF_FIRSTNEG);
426 else if (cmdflags & CF_NESURE) {
427 match = cmdflags & CF_FIRSTNEG;
433 break; /* must evaluate */
435 case CFT_SCAN: /* non-anchored search */
437 retstr = STAB_STR(cmd->c_stab);
439 if (retstr->str_pok & SP_STUDIED)
440 if (screamfirst[cmd->c_short->str_rare] >= 0)
441 tmps = screaminstr(retstr, cmd->c_short);
445 tmps = str_get(retstr); /* make sure it's pok */
447 tmps = fbminstr((unsigned char*)tmps,
448 (unsigned char*)tmps + retstr->str_cur, cmd->c_short);
452 if (cmdflags & CF_EQSURE) {
453 ++cmd->c_short->str_u.str_useful;
457 str_nset(stab_val(leftstab),retstr->str_ptr,
458 tmps - retstr->str_ptr);
460 str_sset(stab_val(amperstab),cmd->c_short);
462 str_nset(stab_val(rightstab),
463 tmps + cmd->c_short->str_cur,
464 retstr->str_cur - (tmps - retstr->str_ptr) -
465 cmd->c_short->str_cur);
467 match = !(cmdflags & CF_FIRSTNEG);
475 if (cmdflags & CF_NESURE) {
476 ++cmd->c_short->str_u.str_useful;
477 match = cmdflags & CF_FIRSTNEG;
482 if (--cmd->c_short->str_u.str_useful < 0) {
483 cmdflags &= ~CF_OPTIMIZE;
484 cmdflags |= CFT_EVAL; /* never try this optimization again */
485 cmd->c_flags = (cmdflags & ~CF_ONCE);
487 break; /* must evaluate */
489 case CFT_NUMOP: /* numeric op optimization */
490 retstr = STAB_STR(cmd->c_stab);
492 switch (cmd->c_slen) {
495 if ((!retstr->str_nok && !looks_like_number(retstr)))
496 warn("Possible use of == on string value");
498 match = (str_gnum(retstr) == cmd->c_short->str_u.str_nval);
501 match = (str_gnum(retstr) != cmd->c_short->str_u.str_nval);
504 match = (str_gnum(retstr) < cmd->c_short->str_u.str_nval);
507 match = (str_gnum(retstr) <= cmd->c_short->str_u.str_nval);
510 match = (str_gnum(retstr) > cmd->c_short->str_u.str_nval);
513 match = (str_gnum(retstr) >= cmd->c_short->str_u.str_nval);
517 if (cmdflags & CF_EQSURE) {
522 else if (cmdflags & CF_NESURE) {
526 break; /* must evaluate */
528 case CFT_INDGETS: /* while (<$foo>) */
529 last_in_stab = stabent(str_get(STAB_STR(cmd->c_stab)),TRUE);
530 if (!stab_io(last_in_stab))
531 stab_io(last_in_stab) = stio_new();
533 case CFT_GETS: /* really a while (<file>) */
534 last_in_stab = cmd->c_stab;
536 fp = stab_io(last_in_stab)->ifp;
537 retstr = stab_val(defstab);
540 if (fp && str_gets(retstr, fp, 0)) {
541 if (*retstr->str_ptr == '0' && retstr->str_cur == 1)
545 stab_io(last_in_stab)->lines++;
547 else if (stab_io(last_in_stab)->flags & IOF_ARGV) {
549 goto doeval; /* first time through */
550 fp = nextargv(last_in_stab);
553 (void)do_close(last_in_stab,FALSE);
554 stab_io(last_in_stab)->flags |= IOF_START;
566 while (tmps_max > tmps_base) /* clean up after last eval */
567 str_free(tmps_list[tmps_max--]);
568 newsp = eval(cmd->c_expr,gimme && (cmdflags & CF_TERM),sp);
569 st = stack->ary_array; /* possibly reallocated */
571 match = str_true(retstr);
572 if (cmd->c_expr->arg_type == O_FLIP) /* undid itself? */
573 cmdflags = copyopt(cmd,cmd->c_expr[3].arg_ptr.arg_cmd);
576 retstr = stab_val(cmd->c_stab);
578 match = (retstr->str_cur != 0);
579 tmps = str_get(retstr);
580 tmps += retstr->str_cur - match;
581 str_nset(&str_chop,tmps,match);
584 retstr->str_cur = tmps - retstr->str_ptr;
588 match = cmd->c_short->str_u.str_useful; /* just to get register */
590 if (match < 0) { /* first time through here? */
591 ar = stab_array(cmd->c_expr[1].arg_ptr.arg_stab);
592 aryoptsave = savestack->ary_fill;
593 savesptr(&stab_val(cmd->c_stab));
594 savelong(&cmd->c_short->str_u.str_useful);
597 ar = stab_xarray(cmd->c_expr[1].arg_ptr.arg_stab);
598 if (cmd->c_type != C_WHILE && savestack->ary_fill > firstsave)
599 restorelist(firstsave);
602 if (match >= ar->ary_fill) { /* we're in LAST, probably */
604 cmd->c_short->str_u.str_useful = -1; /* actually redundant */
609 if (!(retstr = ar->ary_array[match]))
610 retstr = afetch(ar,match,TRUE);
611 stab_val(cmd->c_stab) = retstr;
612 cmd->c_short->str_u.str_useful = match;
620 if (DBsingle->str_u.str_nval != 0)
622 if (DBsignal->str_u.str_nval != 0)
624 if (DBtrace->str_u.str_nval != 0)
629 /* we have tried to make this normal case as abnormal as possible */
632 if (gimme == G_ARRAY) {
633 lastretstr = Nullstr;
635 lastsize = newsp - sp;
639 while (tmps_max > tmps_base) /* clean up after last eval */
640 str_free(tmps_list[tmps_max--]);
641 newsp = eval(cmd->c_expr,
642 gimme && (cmdflags & CF_TERM) && cmd->c_type == C_EXPR &&
643 !cmd->ucmd.acmd.ac_expr,
645 st = stack->ary_array; /* possibly reallocated */
647 if (newsp > sp && retstr)
648 match = str_true(retstr);
653 /* if flipflop was true, flop it */
656 if (match && cmdflags & CF_FLIP) {
657 while (tmps_max > tmps_base) /* clean up after last eval */
658 str_free(tmps_list[tmps_max--]);
659 if (cmd->c_expr->arg_type == O_FLOP) { /* currently toggled? */
660 newsp = eval(cmd->c_expr,G_SCALAR,sp);/*let eval undo it*/
661 cmdflags = copyopt(cmd,cmd->c_expr[3].arg_ptr.arg_cmd);
664 newsp = eval(cmd->c_expr,G_SCALAR,sp);/* let eval do it */
665 if (cmd->c_expr->arg_type == O_FLOP) /* still toggled? */
666 cmdflags = copyopt(cmd,cmd->c_expr[4].arg_ptr.arg_cmd);
669 else if (cmdflags & CF_FLIP) {
670 if (cmd->c_expr->arg_type == O_FLOP) { /* currently toggled? */
671 match = TRUE; /* force on */
675 /* at this point, match says whether our expression was true */
678 if (cmdflags & CF_INVERT)
684 tainted = 0; /* modifier doesn't affect regular expression */
687 /* now to do the actual command, if any */
689 switch (cmd->c_type) {
691 fatal("panic: cmd_exec");
692 case C_EXPR: /* evaluated for side effects */
693 if (cmd->ucmd.acmd.ac_expr) { /* more to do? */
694 if (gimme == G_ARRAY) {
695 lastretstr = Nullstr;
697 lastsize = newsp - sp;
701 while (tmps_max > tmps_base) /* clean up after last eval */
702 str_free(tmps_list[tmps_max--]);
703 newsp = eval(cmd->ucmd.acmd.ac_expr,gimme && (cmdflags&CF_TERM),sp);
704 st = stack->ary_array; /* possibly reallocated */
710 double value = str_gnum(STAB_STR(cmd->c_stab));
714 if (((double)match) > value)
715 --match; /* was fractional--truncate other way */
720 match = *(str_get(STAB_STR(cmd->c_stab))) & 255;
722 match -= cmd->ucmd.scmd.sc_offset;
725 else if (match > cmd->ucmd.scmd.sc_max)
726 match = cmd->ucmd.scmd.sc_max;
727 cmd = cmd->ucmd.scmd.sc_next[match];
728 goto tail_recursion_entry;
730 cmd = cmd->ucmd.ccmd.cc_alt;
731 goto tail_recursion_entry;
733 fatal("panic: ELSIF");
736 oldsave = savestack->ary_fill;
742 if (cmd->ucmd.ccmd.cc_true) {
745 debname[dlevel] = 't';
746 debdelim[dlevel] = '_';
747 if (++dlevel >= dlmax)
751 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
752 st = stack->ary_array; /* possibly reallocated */
756 if (savestack->ary_fill > oldsave)
757 restorelist(oldsave);
761 cmd = cmd->ucmd.ccmd.cc_alt;
762 goto tail_recursion_entry;
765 oldsave = savestack->ary_fill;
771 if (cmd->ucmd.ccmd.cc_true) {
774 debname[dlevel] = 'e';
775 debdelim[dlevel] = '_';
776 if (++dlevel >= dlmax)
780 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
781 st = stack->ary_array; /* possibly reallocated */
785 if (savestack->ary_fill > oldsave)
786 restorelist(oldsave);
793 if (!(cmdflags & CF_ONCE)) { /* first time through here? */
795 if (++loop_ptr >= loop_max) {
797 Renew(loop_stack, loop_max, struct loop);
799 loop_stack[loop_ptr].loop_label = cmd->c_label;
800 loop_stack[loop_ptr].loop_sp = sp;
803 deb("(Pushing label #%d %s)\n",
804 loop_ptr, cmd->c_label ? cmd->c_label : "");
811 if (match = setjmp(loop_stack[loop_ptr].loop_env)) {
812 st = stack->ary_array; /* possibly reallocated */
815 cmdflags = cmd->c_flags|CF_ONCE;
818 if (savestack->ary_fill > oldsave)
819 restorelist(oldsave);
822 fatal("longjmp returned bad value (%d)",match);
829 newsp = sp + lastsize;
852 oldsave = savestack->ary_fill;
857 if (cmd->ucmd.ccmd.cc_true) {
860 debname[dlevel] = 't';
861 debdelim[dlevel] = '_';
862 if (++dlevel >= dlmax)
866 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
867 st = stack->ary_array; /* possibly reallocated */
870 /* actually, this spot is rarely reached anymore since the above
871 * cmd_exec() returns through longjmp(). Hooray for structure.
877 if (cmd->ucmd.ccmd.cc_alt) {
880 debname[dlevel] = 'a';
881 debdelim[dlevel] = '_';
882 if (++dlevel >= dlmax)
886 newsp = cmd_exec(cmd->ucmd.ccmd.cc_alt,gimme && (cmdflags & CF_TERM),sp);
887 st = stack->ary_array; /* possibly reallocated */
892 if (savestack->ary_fill > oldsave) {
893 if (cmdflags & CF_TERM) {
894 for (match = sp + 1; match <= newsp; match++)
895 st[match] = str_static(st[match]);
898 restorelist(oldsave);
901 dlevel = olddlevel - 1;
903 if (cmd->c_type != C_BLOCK)
904 goto until_loop; /* go back and evaluate conditional again */
906 if (cmdflags & CF_LOOP) {
907 cmdflags |= CF_COND; /* now test the condition */
914 if (cmdflags & CF_ONCE) {
917 tmps = loop_stack[loop_ptr].loop_label;
918 deb("(Popping label #%d %s)\n",loop_ptr, tmps ? tmps : "");
922 if ((cmdflags & CF_OPTIMIZE) == CFT_ARRAY &&
923 savestack->ary_fill > aryoptsave)
924 restorelist(aryoptsave);
927 goto tail_recursion_entry;
933 deb(pat,a1,a2,a3,a4,a5,a6,a7,a8)
938 fprintf(stderr,"%-4ld",(long)curcmd->c_line);
939 for (i=0; i<dlevel; i++)
940 fprintf(stderr,"%c%c ",debname[i],debdelim[i]);
941 fprintf(stderr,pat,a1,a2,a3,a4,a5,a6,a7,a8);
953 fprintf(stderr,"%-4ld",(long)curcmd->c_line);
954 for (i=0; i<dlevel; i++)
955 fprintf(stderr,"%c%c ",debname[i],debdelim[i]);
957 pat = va_arg(args, char *);
958 (void) vfprintf(stderr,pat,args);
968 cmd->c_flags &= CF_ONCE|CF_COND|CF_LOOP;
969 cmd->c_flags |= which->c_flags;
970 cmd->c_short = which->c_short;
971 cmd->c_slen = which->c_slen;
972 cmd->c_stab = which->c_stab;
983 str->str_state = SS_SARY;
984 str->str_u.str_stab = stab;
986 Safefree(str->str_ptr);
989 str->str_ptr = (char*)stab_array(stab);
990 (void)apush(savestack,str); /* save array ptr */
991 stab_xarray(stab) = Null(ARRAY*);
992 return stab_xarray(aadd(stab));
1001 str = Str_new(11,0);
1002 str->str_state = SS_SHASH;
1003 str->str_u.str_stab = stab;
1005 Safefree(str->str_ptr);
1008 str->str_ptr = (char*)stab_hash(stab);
1009 (void)apush(savestack,str); /* save hash ptr */
1010 stab_xhash(stab) = Null(HASH*);
1011 return stab_xhash(hadd(stab));
1020 (void)apush(savestack,item); /* remember the pointer */
1021 str = Str_new(12,0);
1023 (void)apush(savestack,str); /* remember the value */
1032 str = Str_new(13,0);
1033 str->str_state = SS_SINT;
1034 str->str_u.str_useful = (long)*intp; /* remember value */
1036 Safefree(str->str_ptr);
1039 str->str_ptr = (char*)intp; /* remember pointer */
1040 (void)apush(savestack,str);
1049 str = Str_new(14,0);
1050 str->str_state = SS_SLONG;
1051 str->str_u.str_useful = *longp; /* remember value */
1053 Safefree(str->str_ptr);
1056 str->str_ptr = (char*)longp; /* remember pointer */
1057 (void)apush(savestack,str);
1066 str = Str_new(15,0);
1067 str->str_state = SS_SSTRP;
1068 str->str_magic = *sptr; /* remember value */
1070 Safefree(str->str_ptr);
1073 str->str_ptr = (char*)sptr; /* remember pointer */
1074 (void)apush(savestack,str);
1083 str = Str_new(16,0);
1084 str->str_state = SS_SNSTAB;
1085 str->str_magic = (STR*)stab; /* remember which stab to free */
1086 (void)apush(savestack,str);
1095 str = Str_new(17,0);
1096 str->str_state = SS_SHPTR;
1097 str->str_u.str_hash = *hptr; /* remember value */
1099 Safefree(str->str_ptr);
1102 str->str_ptr = (char*)hptr; /* remember pointer */
1103 (void)apush(savestack,str);
1107 savelist(sarg,maxsarg)
1108 register STR **sarg;
1114 for (i = 1; i <= maxsarg; i++) {
1115 (void)apush(savestack,sarg[i]); /* remember the pointer */
1116 str = Str_new(18,0);
1117 str_sset(str,sarg[i]);
1118 (void)apush(savestack,str); /* remember the value */
1119 sarg[i]->str_u.str_useful = -1;
1128 register STR *value;
1129 register STAB *stab;
1132 fatal("panic: corrupt saved stack index");
1133 while (savestack->ary_fill > base) {
1134 value = apop(savestack);
1135 switch (value->str_state) {
1136 case SS_NORM: /* normal string */
1138 str = apop(savestack);
1139 str_replace(str,value);
1142 case SS_SARY: /* array reference */
1143 stab = value->str_u.str_stab;
1144 afree(stab_xarray(stab));
1145 stab_xarray(stab) = (ARRAY*)value->str_ptr;
1146 value->str_ptr = Nullch;
1149 case SS_SHASH: /* hash reference */
1150 stab = value->str_u.str_stab;
1151 (void)hfree(stab_xhash(stab), FALSE);
1152 stab_xhash(stab) = (HASH*)value->str_ptr;
1153 value->str_ptr = Nullch;
1156 case SS_SINT: /* int reference */
1157 *((int*)value->str_ptr) = (int)value->str_u.str_useful;
1158 value->str_ptr = Nullch;
1161 case SS_SLONG: /* long reference */
1162 *((long*)value->str_ptr) = value->str_u.str_useful;
1163 value->str_ptr = Nullch;
1166 case SS_SSTRP: /* STR* reference */
1167 *((STR**)value->str_ptr) = value->str_magic;
1168 value->str_magic = Nullstr;
1169 value->str_ptr = Nullch;
1172 case SS_SHPTR: /* HASH* reference */
1173 *((HASH**)value->str_ptr) = value->str_u.str_hash;
1174 value->str_ptr = Nullch;
1178 stab = (STAB*)value->str_magic;
1179 value->str_magic = Nullstr;
1180 (void)stab_clear(stab);
1183 case SS_SCSV: /* callsave structure */
1185 CSV *csv = (CSV*) value->str_ptr;
1187 curcmd = csv->curcmd;
1188 curcsv = csv->curcsv;
1189 csv->sub->depth = csv->depth;
1190 if (csv->hasargs) { /* put back old @_ */
1191 afree(csv->argarray);
1192 stab_xarray(defstab) = csv->savearray;
1198 fatal("panic: restorelist inconsistency");
1208 Renew(debname, dlmax, char);
1209 Renew(debdelim, dlmax, char);