1 /* $Header: cmd.c,v 3.0.1.8 90/08/09 02:28:49 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.8 90/08/09 02:28:49 lwall
10 * patch19: did preliminary work toward debugging packages and evals
11 * patch19: conditionals now always supply a scalar context to expression
12 * patch19: switch optimizer was confused by negative fractional values
14 * Revision 3.0.1.7 90/03/27 15:32:37 lwall
15 * patch16: non-terminal blocks should never have arrays requested of them
17 * Revision 3.0.1.6 90/03/12 16:21:09 lwall
18 * patch13: fixed some backwards VOLATILE declarations
19 * patch13: while (s/x//) {} still caused some anomolies
20 * patch13: greater-than test of numeric switch structures did less-than action
22 * Revision 3.0.1.5 90/02/28 16:38:31 lwall
23 * patch9: volatilized some more variables for super-optimizing compilers
24 * patch9: nested foreach loops didn't reset inner loop on next to outer loop
25 * patch9: returned values were read from obsolete stack
26 * patch9: added sanity check on longjmp() return value
27 * patch9: substitutions that almost always succeed can corrupt label stack
28 * patch9: subs which return by both mechanisms can clobber local return data
30 * Revision 3.0.1.4 89/12/21 19:17:41 lwall
31 * patch7: arranged for certain registers to be restored after longjmp()
32 * patch7: made nested or recursive foreach work right
34 * Revision 3.0.1.3 89/11/17 15:04:36 lwall
35 * patch5: nested foreach on same array didn't work
37 * Revision 3.0.1.2 89/11/11 04:08:56 lwall
38 * patch2: non-BSD machines required two ^D's for <>
39 * patch2: grow_dlevel() not inside #ifdef DEBUGGING
41 * Revision 3.0.1.1 89/10/26 23:04:21 lwall
42 * patch1: heuristically disabled optimization could cause core dump
44 * Revision 3.0 89/10/18 15:09:02 lwall
60 /* do longjmps() clobber register variables? */
62 #if defined(cray) || defined(__STDC__)
66 /* This is the main command loop. We try to spend as much time in this loop
67 * as possible, so lots of optimizations do their activities in here. This
68 * means things get a little sloppy.
72 cmd_exec(cmdparm,gimme,sp)
73 CMD *VOLATILE cmdparm;
77 register CMD *cmd = cmdparm;
78 SPAT *VOLATILE oldspat;
79 VOLATILE int firstsave = savestack->ary_fill;
81 VOLATILE int aryoptsave;
83 VOLATILE int olddlevel;
84 VOLATILE int entdlevel;
86 register STR *retstr = &str_undef;
88 register int cmdflags;
90 register char *go_to = goto_targ;
91 register int newsp = -2;
92 register STR **st = stack->ary_array;
100 tail_recursion_entry:
105 tainted = 0; /* Each statement is presumed innocent */
107 if (cmd == Nullcmd) {
108 if (gimme == G_ARRAY && newsp > -2)
115 cmdflags = cmd->c_flags; /* hopefully load register */
117 if (cmd->c_label && strEQ(go_to,cmd->c_label))
118 goto_targ = go_to = Nullch; /* here at last */
120 switch (cmd->c_type) {
123 oldsave = savestack->ary_fill;
129 if (cmd->ucmd.ccmd.cc_true) {
132 debname[dlevel] = 't';
133 debdelim[dlevel] = '_';
134 if (++dlevel >= dlmax)
138 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
139 st = stack->ary_array; /* possibly reallocated */
145 if (savestack->ary_fill > oldsave)
146 restorelist(oldsave);
150 cmd = cmd->ucmd.ccmd.cc_alt;
151 goto tail_recursion_entry;
154 oldsave = savestack->ary_fill;
160 if (cmd->ucmd.ccmd.cc_true) {
163 debname[dlevel] = 'e';
164 debdelim[dlevel] = '_';
165 if (++dlevel >= dlmax)
169 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
170 st = stack->ary_array; /* possibly reallocated */
176 if (savestack->ary_fill > oldsave)
177 restorelist(oldsave);
184 if (!(cmdflags & CF_ONCE)) {
186 if (++loop_ptr >= loop_max) {
188 Renew(loop_stack, loop_max, struct loop);
190 loop_stack[loop_ptr].loop_label = cmd->c_label;
191 loop_stack[loop_ptr].loop_sp = sp;
194 deb("(Pushing label #%d %s)\n",
195 loop_ptr, cmd->c_label ? cmd->c_label : "");
202 if (match = setjmp(loop_stack[loop_ptr].loop_env)) {
203 st = stack->ary_array; /* possibly reallocated */
206 cmdflags = cmd->c_flags|CF_ONCE;
208 if (savestack->ary_fill > oldsave)
209 restorelist(oldsave);
212 fatal("longjmp returned bad value (%d)",match);
213 case O_LAST: /* not done unless go_to found */
220 newsp = sp + lastsize;
228 case O_NEXT: /* not done unless go_to found */
235 case O_REDO: /* not done unless go_to found */
245 oldsave = savestack->ary_fill;
249 if (cmd->ucmd.ccmd.cc_true) {
252 debname[dlevel] = 't';
253 debdelim[dlevel] = '_';
254 if (++dlevel >= dlmax)
258 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
259 st = stack->ary_array; /* possibly reallocated */
269 if (cmd->ucmd.ccmd.cc_alt) {
272 debname[dlevel] = 'a';
273 debdelim[dlevel] = '_';
274 if (++dlevel >= dlmax)
278 newsp = cmd_exec(cmd->ucmd.ccmd.cc_alt,gimme && (cmdflags & CF_TERM),sp);
279 st = stack->ary_array; /* possibly reallocated */
288 if (cmd && cmd->c_head == cmd)
289 /* reached end of while loop */
290 return sp; /* targ isn't in this block */
291 if (cmdflags & CF_ONCE) {
294 tmps = loop_stack[loop_ptr].loop_label;
295 deb("(Popping label #%d %s)\n",loop_ptr,
301 goto tail_recursion_entry;
307 /* Set line number so run-time errors can be located */
314 deb("%s (%lx) r%lx t%lx a%lx n%lx cs%lx\n",
315 cmdname[cmd->c_type],cmd,cmd->c_expr,
316 cmd->ucmd.ccmd.cc_true,cmd->ucmd.ccmd.cc_alt,cmd->c_next,
319 debname[dlevel] = cmdname[cmd->c_type][0];
320 debdelim[dlevel] = '!';
321 if (++dlevel >= dlmax)
326 /* Here is some common optimization */
328 if (cmdflags & CF_COND) {
329 switch (cmdflags & CF_OPTIMIZE) {
332 retstr = cmd->c_short;
335 if (cmdflags & CF_NESURE)
339 retstr = cmd->c_short;
342 if (cmdflags & CF_EQSURE)
347 retstr = STAB_STR(cmd->c_stab);
349 match = str_true(retstr); /* => retstr = retstr, c2 should fix */
350 if (cmdflags & (match ? CF_EQSURE : CF_NESURE))
354 case CFT_ANCHOR: /* /^pat/ optimization */
356 if (*cmd->c_short->str_ptr && !(cmdflags & CF_EQSURE))
357 goto scanner; /* just unanchor it */
359 break; /* must evaluate */
362 case CFT_STROP: /* string op optimization */
363 retstr = STAB_STR(cmd->c_stab);
366 if (*cmd->c_short->str_ptr == *str_get(retstr) &&
367 bcmp(cmd->c_short->str_ptr, str_get(retstr),
368 cmd->c_slen) == 0 ) {
369 if (cmdflags & CF_EQSURE) {
370 if (sawampersand && (cmdflags & CF_OPTIMIZE) != CFT_STROP) {
373 str_nset(stab_val(leftstab),"",0);
375 str_sset(stab_val(amperstab),cmd->c_short);
377 str_nset(stab_val(rightstab),
378 retstr->str_ptr + cmd->c_slen,
379 retstr->str_cur - cmd->c_slen);
381 match = !(cmdflags & CF_FIRSTNEG);
386 else if (cmdflags & CF_NESURE) {
387 match = cmdflags & CF_FIRSTNEG;
393 char *zap1, *zap2, zap1c, zap2c;
396 zap1 = cmd->c_short->str_ptr;
397 zap2 = str_get(retstr);
400 zaplen = cmd->c_slen;
401 if ((zap1c == zap2c) && (bcmp(zap1, zap2, zaplen) == 0)) {
402 if (cmdflags & CF_EQSURE) {
404 (cmdflags & CF_OPTIMIZE) != CFT_STROP) {
407 str_nset(stab_val(leftstab),"",0);
409 str_sset(stab_val(amperstab),cmd->c_short);
411 str_nset(stab_val(rightstab),
412 retstr->str_ptr + cmd->c_slen,
413 retstr->str_cur - cmd->c_slen);
415 match = !(cmdflags & CF_FIRSTNEG);
420 else if (cmdflags & CF_NESURE) {
421 match = cmdflags & CF_FIRSTNEG;
427 break; /* must evaluate */
429 case CFT_SCAN: /* non-anchored search */
431 retstr = STAB_STR(cmd->c_stab);
433 if (retstr->str_pok & SP_STUDIED)
434 if (screamfirst[cmd->c_short->str_rare] >= 0)
435 tmps = screaminstr(retstr, cmd->c_short);
439 tmps = str_get(retstr); /* make sure it's pok */
441 tmps = fbminstr((unsigned char*)tmps,
442 (unsigned char*)tmps + retstr->str_cur, cmd->c_short);
446 if (cmdflags & CF_EQSURE) {
447 ++cmd->c_short->str_u.str_useful;
451 str_nset(stab_val(leftstab),retstr->str_ptr,
452 tmps - retstr->str_ptr);
454 str_sset(stab_val(amperstab),cmd->c_short);
456 str_nset(stab_val(rightstab),
457 tmps + cmd->c_short->str_cur,
458 retstr->str_cur - (tmps - retstr->str_ptr) -
459 cmd->c_short->str_cur);
461 match = !(cmdflags & CF_FIRSTNEG);
469 if (cmdflags & CF_NESURE) {
470 ++cmd->c_short->str_u.str_useful;
471 match = cmdflags & CF_FIRSTNEG;
476 if (--cmd->c_short->str_u.str_useful < 0) {
477 cmdflags &= ~CF_OPTIMIZE;
478 cmdflags |= CFT_EVAL; /* never try this optimization again */
479 cmd->c_flags = (cmdflags & ~CF_ONCE);
481 break; /* must evaluate */
483 case CFT_NUMOP: /* numeric op optimization */
484 retstr = STAB_STR(cmd->c_stab);
486 switch (cmd->c_slen) {
489 if ((!retstr->str_nok && !looks_like_number(retstr)))
490 warn("Possible use of == on string value");
492 match = (str_gnum(retstr) == cmd->c_short->str_u.str_nval);
495 match = (str_gnum(retstr) != cmd->c_short->str_u.str_nval);
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);
511 if (cmdflags & CF_EQSURE) {
516 else if (cmdflags & CF_NESURE) {
520 break; /* must evaluate */
522 case CFT_INDGETS: /* while (<$foo>) */
523 last_in_stab = stabent(str_get(STAB_STR(cmd->c_stab)),TRUE);
524 if (!stab_io(last_in_stab))
525 stab_io(last_in_stab) = stio_new();
527 case CFT_GETS: /* really a while (<file>) */
528 last_in_stab = cmd->c_stab;
530 fp = stab_io(last_in_stab)->ifp;
531 retstr = stab_val(defstab);
534 if (fp && str_gets(retstr, fp, 0)) {
535 if (*retstr->str_ptr == '0' && retstr->str_cur == 1)
539 stab_io(last_in_stab)->lines++;
541 else if (stab_io(last_in_stab)->flags & IOF_ARGV) {
543 goto doeval; /* first time through */
544 fp = nextargv(last_in_stab);
547 (void)do_close(last_in_stab,FALSE);
548 stab_io(last_in_stab)->flags |= IOF_START;
560 while (tmps_max > tmps_base) /* clean up after last eval */
561 str_free(tmps_list[tmps_max--]);
562 newsp = eval(cmd->c_expr,gimme && (cmdflags & CF_TERM),sp);
563 st = stack->ary_array; /* possibly reallocated */
565 match = str_true(retstr);
566 if (cmd->c_expr->arg_type == O_FLIP) /* undid itself? */
567 cmdflags = copyopt(cmd,cmd->c_expr[3].arg_ptr.arg_cmd);
570 retstr = stab_val(cmd->c_stab);
572 match = (retstr->str_cur != 0);
573 tmps = str_get(retstr);
574 tmps += retstr->str_cur - match;
575 str_nset(&str_chop,tmps,match);
578 retstr->str_cur = tmps - retstr->str_ptr;
582 match = cmd->c_short->str_u.str_useful; /* just to get register */
584 if (match < 0) { /* first time through here? */
585 ar = stab_array(cmd->c_expr[1].arg_ptr.arg_stab);
586 aryoptsave = savestack->ary_fill;
587 savesptr(&stab_val(cmd->c_stab));
588 savelong(&cmd->c_short->str_u.str_useful);
591 ar = stab_xarray(cmd->c_expr[1].arg_ptr.arg_stab);
592 if (cmd->c_type != C_WHILE && savestack->ary_fill > firstsave)
593 restorelist(firstsave);
596 if (match >= ar->ary_fill) { /* we're in LAST, probably */
598 cmd->c_short->str_u.str_useful = -1; /* actually redundant */
603 retstr = stab_val(cmd->c_stab) = ar->ary_array[match];
604 cmd->c_short->str_u.str_useful = match;
611 /* we have tried to make this normal case as abnormal as possible */
614 if (gimme == G_ARRAY) {
615 lastretstr = Nullstr;
617 lastsize = newsp - sp;
621 while (tmps_max > tmps_base) /* clean up after last eval */
622 str_free(tmps_list[tmps_max--]);
623 newsp = eval(cmd->c_expr,
624 gimme && (cmdflags & CF_TERM) && cmd->c_type == C_EXPR &&
625 !cmd->ucmd.acmd.ac_expr,
627 st = stack->ary_array; /* possibly reallocated */
629 if (newsp > sp && retstr)
630 match = str_true(retstr);
635 /* if flipflop was true, flop it */
638 if (match && cmdflags & CF_FLIP) {
639 while (tmps_max > tmps_base) /* clean up after last eval */
640 str_free(tmps_list[tmps_max--]);
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;
683 while (tmps_max > tmps_base) /* clean up after last eval */
684 str_free(tmps_list[tmps_max--]);
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 if (match = setjmp(loop_stack[loop_ptr].loop_env)) {
794 st = stack->ary_array; /* possibly reallocated */
797 cmdflags = cmd->c_flags|CF_ONCE;
800 if (savestack->ary_fill > oldsave)
801 restorelist(oldsave);
804 fatal("longjmp returned bad value (%d)",match);
811 newsp = sp + lastsize;
834 oldsave = savestack->ary_fill;
839 if (cmd->ucmd.ccmd.cc_true) {
842 debname[dlevel] = 't';
843 debdelim[dlevel] = '_';
844 if (++dlevel >= dlmax)
848 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme && (cmdflags & CF_TERM),sp);
849 st = stack->ary_array; /* possibly reallocated */
852 /* actually, this spot is rarely reached anymore since the above
853 * cmd_exec() returns through longjmp(). Hooray for structure.
859 if (cmd->ucmd.ccmd.cc_alt) {
862 debname[dlevel] = 'a';
863 debdelim[dlevel] = '_';
864 if (++dlevel >= dlmax)
868 newsp = cmd_exec(cmd->ucmd.ccmd.cc_alt,gimme && (cmdflags & CF_TERM),sp);
869 st = stack->ary_array; /* possibly reallocated */
874 if (savestack->ary_fill > oldsave) {
875 if (cmdflags & CF_TERM) {
876 for (match = sp + 1; match <= newsp; match++)
877 st[match] = str_static(st[match]);
880 restorelist(oldsave);
883 dlevel = olddlevel - 1;
885 if (cmd->c_type != C_BLOCK)
886 goto until_loop; /* go back and evaluate conditional again */
888 if (cmdflags & CF_LOOP) {
889 cmdflags |= CF_COND; /* now test the condition */
896 if (cmdflags & CF_ONCE) {
899 tmps = loop_stack[loop_ptr].loop_label;
900 deb("(Popping label #%d %s)\n",loop_ptr, tmps ? tmps : "");
904 if ((cmdflags & CF_OPTIMIZE) == CFT_ARRAY &&
905 savestack->ary_fill > aryoptsave)
906 restorelist(aryoptsave);
909 goto tail_recursion_entry;
915 deb(pat,a1,a2,a3,a4,a5,a6,a7,a8)
920 fprintf(stderr,"%-4ld",(long)curcmd->c_line);
921 for (i=0; i<dlevel; i++)
922 fprintf(stderr,"%c%c ",debname[i],debdelim[i]);
923 fprintf(stderr,pat,a1,a2,a3,a4,a5,a6,a7,a8);
935 fprintf(stderr,"%-4ld",(long)curcmd->c_line);
936 for (i=0; i<dlevel; i++)
937 fprintf(stderr,"%c%c ",debname[i],debdelim[i]);
939 pat = va_arg(args, char *);
940 (void) vfprintf(stderr,pat,args);
950 cmd->c_flags &= CF_ONCE|CF_COND|CF_LOOP;
951 cmd->c_flags |= which->c_flags;
952 cmd->c_short = which->c_short;
953 cmd->c_slen = which->c_slen;
954 cmd->c_stab = which->c_stab;
965 str->str_state = SS_SARY;
966 str->str_u.str_stab = stab;
968 Safefree(str->str_ptr);
971 str->str_ptr = (char*)stab_array(stab);
972 (void)apush(savestack,str); /* save array ptr */
973 stab_xarray(stab) = Null(ARRAY*);
974 return stab_xarray(aadd(stab));
984 str->str_state = SS_SHASH;
985 str->str_u.str_stab = stab;
987 Safefree(str->str_ptr);
990 str->str_ptr = (char*)stab_hash(stab);
991 (void)apush(savestack,str); /* save hash ptr */
992 stab_xhash(stab) = Null(HASH*);
993 return stab_xhash(hadd(stab));
1002 (void)apush(savestack,item); /* remember the pointer */
1003 str = Str_new(12,0);
1005 (void)apush(savestack,str); /* remember the value */
1014 str = Str_new(13,0);
1015 str->str_state = SS_SINT;
1016 str->str_u.str_useful = (long)*intp; /* remember value */
1018 Safefree(str->str_ptr);
1021 str->str_ptr = (char*)intp; /* remember pointer */
1022 (void)apush(savestack,str);
1031 str = Str_new(14,0);
1032 str->str_state = SS_SLONG;
1033 str->str_u.str_useful = *longp; /* remember value */
1035 Safefree(str->str_ptr);
1038 str->str_ptr = (char*)longp; /* remember pointer */
1039 (void)apush(savestack,str);
1048 str = Str_new(15,0);
1049 str->str_state = SS_SSTRP;
1050 str->str_magic = *sptr; /* remember value */
1052 Safefree(str->str_ptr);
1055 str->str_ptr = (char*)sptr; /* remember pointer */
1056 (void)apush(savestack,str);
1065 str = Str_new(16,0);
1066 str->str_state = SS_SNSTAB;
1067 str->str_magic = (STR*)stab; /* remember which stab to free */
1068 (void)apush(savestack,str);
1077 str = Str_new(17,0);
1078 str->str_state = SS_SHPTR;
1079 str->str_u.str_hash = *hptr; /* remember value */
1081 Safefree(str->str_ptr);
1084 str->str_ptr = (char*)hptr; /* remember pointer */
1085 (void)apush(savestack,str);
1089 savelist(sarg,maxsarg)
1090 register STR **sarg;
1096 for (i = 1; i <= maxsarg; i++) {
1097 (void)apush(savestack,sarg[i]); /* remember the pointer */
1098 str = Str_new(18,0);
1099 str_sset(str,sarg[i]);
1100 (void)apush(savestack,str); /* remember the value */
1101 sarg[i]->str_u.str_useful = -1;
1110 register STR *value;
1111 register STAB *stab;
1114 fatal("panic: corrupt saved stack index");
1115 while (savestack->ary_fill > base) {
1116 value = apop(savestack);
1117 switch (value->str_state) {
1118 case SS_NORM: /* normal string */
1120 str = apop(savestack);
1121 str_replace(str,value);
1124 case SS_SARY: /* array reference */
1125 stab = value->str_u.str_stab;
1126 afree(stab_xarray(stab));
1127 stab_xarray(stab) = (ARRAY*)value->str_ptr;
1128 value->str_ptr = Nullch;
1131 case SS_SHASH: /* hash reference */
1132 stab = value->str_u.str_stab;
1133 (void)hfree(stab_xhash(stab));
1134 stab_xhash(stab) = (HASH*)value->str_ptr;
1135 value->str_ptr = Nullch;
1138 case SS_SINT: /* int reference */
1139 *((int*)value->str_ptr) = (int)value->str_u.str_useful;
1140 value->str_ptr = Nullch;
1143 case SS_SLONG: /* long reference */
1144 *((long*)value->str_ptr) = value->str_u.str_useful;
1145 value->str_ptr = Nullch;
1148 case SS_SSTRP: /* STR* reference */
1149 *((STR**)value->str_ptr) = value->str_magic;
1150 value->str_magic = Nullstr;
1151 value->str_ptr = Nullch;
1154 case SS_SHPTR: /* HASH* reference */
1155 *((HASH**)value->str_ptr) = value->str_u.str_hash;
1156 value->str_ptr = Nullch;
1160 stab = (STAB*)value->str_magic;
1161 value->str_magic = Nullstr;
1162 (void)stab_clear(stab);
1166 fatal("panic: restorelist inconsistency");
1176 Renew(debname, dlmax, char);
1177 Renew(debdelim, dlmax, char);