1 /* $Header: cmd.c,v 3.0.1.5 90/02/28 16:38:31 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.5 90/02/28 16:38:31 lwall
10 * patch9: volatilized some more variables for super-optimizing compilers
11 * patch9: nested foreach loops didn't reset inner loop on next to outer loop
12 * patch9: returned values were read from obsolete stack
13 * patch9: added sanity check on longjmp() return value
14 * patch9: substitutions that almost always succeed can corrupt label stack
15 * patch9: subs which return by both mechanisms can clobber local return data
17 * Revision 3.0.1.4 89/12/21 19:17:41 lwall
18 * patch7: arranged for certain registers to be restored after longjmp()
19 * patch7: made nested or recursive foreach work right
21 * Revision 3.0.1.3 89/11/17 15:04:36 lwall
22 * patch5: nested foreach on same array didn't work
24 * Revision 3.0.1.2 89/11/11 04:08:56 lwall
25 * patch2: non-BSD machines required two ^D's for <>
26 * patch2: grow_dlevel() not inside #ifdef DEBUGGING
28 * Revision 3.0.1.1 89/10/26 23:04:21 lwall
29 * patch1: heuristically disabled optimization could cause core dump
31 * Revision 3.0 89/10/18 15:09:02 lwall
47 /* do longjmps() clobber register variables? */
49 #if defined(cray) || defined(__STDC__)
53 /* This is the main command loop. We try to spend as much time in this loop
54 * as possible, so lots of optimizations do their activities in here. This
55 * means things get a little sloppy.
59 cmd_exec(cmdparm,gimme,sp)
60 CMD *VOLATILE cmdparm;
64 register CMD *cmd = cmdparm;
65 SPAT *VOLATILE oldspat;
66 VOLATILE int firstsave = savestack->ary_fill;
68 VOLATILE int aryoptsave;
70 VOLATILE int olddlevel;
71 VOLATILE int entdlevel;
73 register STR *retstr = &str_undef;
75 register int cmdflags;
77 register char *go_to = goto_targ;
78 register int newsp = -2;
79 register STR **st = stack->ary_array;
92 tainted = 0; /* Each statement is presumed innocent */
95 if (gimme == G_ARRAY && newsp > -2)
102 cmdflags = cmd->c_flags; /* hopefully load register */
104 if (cmd->c_label && strEQ(go_to,cmd->c_label))
105 goto_targ = go_to = Nullch; /* here at last */
107 switch (cmd->c_type) {
110 oldsave = savestack->ary_fill;
116 if (cmd->ucmd.ccmd.cc_true) {
119 debname[dlevel] = 't';
120 debdelim[dlevel] = '_';
121 if (++dlevel >= dlmax)
125 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme,sp);
126 st = stack->ary_array; /* possibly reallocated */
132 if (savestack->ary_fill > oldsave)
133 restorelist(oldsave);
137 cmd = cmd->ucmd.ccmd.cc_alt;
138 goto tail_recursion_entry;
141 oldsave = savestack->ary_fill;
147 if (cmd->ucmd.ccmd.cc_true) {
150 debname[dlevel] = 'e';
151 debdelim[dlevel] = '_';
152 if (++dlevel >= dlmax)
156 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme,sp);
157 st = stack->ary_array; /* possibly reallocated */
163 if (savestack->ary_fill > oldsave)
164 restorelist(oldsave);
171 if (!(cmdflags & CF_ONCE)) {
173 if (++loop_ptr >= loop_max) {
175 Renew(loop_stack, loop_max, struct loop);
177 loop_stack[loop_ptr].loop_label = cmd->c_label;
178 loop_stack[loop_ptr].loop_sp = sp;
181 deb("(Pushing label #%d %s)\n",
182 loop_ptr, cmd->c_label ? cmd->c_label : "");
189 if (match = setjmp(loop_stack[loop_ptr].loop_env)) {
190 st = stack->ary_array; /* possibly reallocated */
193 cmdflags = cmd->c_flags|CF_ONCE;
195 if (savestack->ary_fill > oldsave)
196 restorelist(oldsave);
199 fatal("longjmp returned bad value (%d)",match);
200 case O_LAST: /* not done unless go_to found */
207 newsp = sp + lastsize;
215 case O_NEXT: /* not done unless go_to found */
222 case O_REDO: /* not done unless go_to found */
232 oldsave = savestack->ary_fill;
236 if (cmd->ucmd.ccmd.cc_true) {
239 debname[dlevel] = 't';
240 debdelim[dlevel] = '_';
241 if (++dlevel >= dlmax)
245 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme,sp);
246 st = stack->ary_array; /* possibly reallocated */
256 if (cmd->ucmd.ccmd.cc_alt) {
259 debname[dlevel] = 'a';
260 debdelim[dlevel] = '_';
261 if (++dlevel >= dlmax)
265 newsp = cmd_exec(cmd->ucmd.ccmd.cc_alt,gimme,sp);
266 st = stack->ary_array; /* possibly reallocated */
275 if (cmd && cmd->c_head == cmd)
276 /* reached end of while loop */
277 return sp; /* targ isn't in this block */
278 if (cmdflags & CF_ONCE) {
281 tmps = loop_stack[loop_ptr].loop_label;
282 deb("(Popping label #%d %s)\n",loop_ptr,
288 goto tail_recursion_entry;
294 /* Set line number so run-time errors can be located */
301 deb("%s (%lx) r%lx t%lx a%lx n%lx cs%lx\n",
302 cmdname[cmd->c_type],cmd,cmd->c_expr,
303 cmd->ucmd.ccmd.cc_true,cmd->ucmd.ccmd.cc_alt,cmd->c_next,
306 debname[dlevel] = cmdname[cmd->c_type][0];
307 debdelim[dlevel] = '!';
308 if (++dlevel >= dlmax)
313 /* Here is some common optimization */
315 if (cmdflags & CF_COND) {
316 switch (cmdflags & CF_OPTIMIZE) {
319 retstr = cmd->c_short;
322 if (cmdflags & CF_NESURE)
326 retstr = cmd->c_short;
329 if (cmdflags & CF_EQSURE)
334 retstr = STAB_STR(cmd->c_stab);
336 match = str_true(retstr); /* => retstr = retstr, c2 should fix */
337 if (cmdflags & (match ? CF_EQSURE : CF_NESURE))
341 case CFT_ANCHOR: /* /^pat/ optimization */
343 if (*cmd->c_short->str_ptr && !(cmdflags & CF_EQSURE))
344 goto scanner; /* just unanchor it */
346 break; /* must evaluate */
349 case CFT_STROP: /* string op optimization */
350 retstr = STAB_STR(cmd->c_stab);
353 if (*cmd->c_short->str_ptr == *str_get(retstr) &&
354 bcmp(cmd->c_short->str_ptr, str_get(retstr),
355 cmd->c_slen) == 0 ) {
356 if (cmdflags & CF_EQSURE) {
357 if (sawampersand && (cmdflags & CF_OPTIMIZE) != CFT_STROP) {
360 str_nset(stab_val(leftstab),"",0);
362 str_sset(stab_val(amperstab),cmd->c_short);
364 str_nset(stab_val(rightstab),
365 retstr->str_ptr + cmd->c_slen,
366 retstr->str_cur - cmd->c_slen);
368 match = !(cmdflags & CF_FIRSTNEG);
373 else if (cmdflags & CF_NESURE) {
374 match = cmdflags & CF_FIRSTNEG;
380 char *zap1, *zap2, zap1c, zap2c;
383 zap1 = cmd->c_short->str_ptr;
384 zap2 = str_get(retstr);
387 zaplen = cmd->c_slen;
388 if ((zap1c == zap2c) && (bcmp(zap1, zap2, zaplen) == 0)) {
389 if (cmdflags & CF_EQSURE) {
391 (cmdflags & CF_OPTIMIZE) != CFT_STROP) {
394 str_nset(stab_val(leftstab),"",0);
396 str_sset(stab_val(amperstab),cmd->c_short);
398 str_nset(stab_val(rightstab),
399 retstr->str_ptr + cmd->c_slen,
400 retstr->str_cur - cmd->c_slen);
402 match = !(cmdflags & CF_FIRSTNEG);
407 else if (cmdflags & CF_NESURE) {
408 match = cmdflags & CF_FIRSTNEG;
414 break; /* must evaluate */
416 case CFT_SCAN: /* non-anchored search */
418 retstr = STAB_STR(cmd->c_stab);
420 if (retstr->str_pok & SP_STUDIED)
421 if (screamfirst[cmd->c_short->str_rare] >= 0)
422 tmps = screaminstr(retstr, cmd->c_short);
426 tmps = str_get(retstr); /* make sure it's pok */
428 tmps = fbminstr((unsigned char*)tmps,
429 (unsigned char*)tmps + retstr->str_cur, cmd->c_short);
433 if (cmdflags & CF_EQSURE) {
434 ++cmd->c_short->str_u.str_useful;
438 str_nset(stab_val(leftstab),retstr->str_ptr,
439 tmps - retstr->str_ptr);
441 str_sset(stab_val(amperstab),cmd->c_short);
443 str_nset(stab_val(rightstab),
444 tmps + cmd->c_short->str_cur,
445 retstr->str_cur - (tmps - retstr->str_ptr) -
446 cmd->c_short->str_cur);
448 match = !(cmdflags & CF_FIRSTNEG);
456 if (cmdflags & CF_NESURE) {
457 ++cmd->c_short->str_u.str_useful;
458 match = cmdflags & CF_FIRSTNEG;
463 if (--cmd->c_short->str_u.str_useful < 0) {
464 cmdflags &= ~(CF_OPTIMIZE|CF_ONCE);
465 cmdflags |= CFT_EVAL; /* never try this optimization again */
466 cmd->c_flags = cmdflags;
468 break; /* must evaluate */
470 case CFT_NUMOP: /* numeric op optimization */
471 retstr = STAB_STR(cmd->c_stab);
473 switch (cmd->c_slen) {
476 if ((!retstr->str_nok && !looks_like_number(retstr)))
477 warn("Possible use of == on string value");
479 match = (str_gnum(retstr) == cmd->c_short->str_u.str_nval);
482 match = (str_gnum(retstr) != cmd->c_short->str_u.str_nval);
485 match = (str_gnum(retstr) < cmd->c_short->str_u.str_nval);
488 match = (str_gnum(retstr) <= cmd->c_short->str_u.str_nval);
491 match = (str_gnum(retstr) > cmd->c_short->str_u.str_nval);
494 match = (str_gnum(retstr) >= cmd->c_short->str_u.str_nval);
498 if (cmdflags & CF_EQSURE) {
503 else if (cmdflags & CF_NESURE) {
507 break; /* must evaluate */
509 case CFT_INDGETS: /* while (<$foo>) */
510 last_in_stab = stabent(str_get(STAB_STR(cmd->c_stab)),TRUE);
511 if (!stab_io(last_in_stab))
512 stab_io(last_in_stab) = stio_new();
514 case CFT_GETS: /* really a while (<file>) */
515 last_in_stab = cmd->c_stab;
517 fp = stab_io(last_in_stab)->ifp;
518 retstr = stab_val(defstab);
521 if (fp && str_gets(retstr, fp, 0)) {
522 if (*retstr->str_ptr == '0' && retstr->str_cur == 1)
526 stab_io(last_in_stab)->lines++;
528 else if (stab_io(last_in_stab)->flags & IOF_ARGV) {
530 goto doeval; /* first time through */
531 fp = nextargv(last_in_stab);
534 (void)do_close(last_in_stab,FALSE);
535 stab_io(last_in_stab)->flags |= IOF_START;
547 while (tmps_max > tmps_base) /* clean up after last eval */
548 str_free(tmps_list[tmps_max--]);
549 newsp = eval(cmd->c_expr,gimme && (cmdflags & CF_TERM),sp);
550 st = stack->ary_array; /* possibly reallocated */
552 match = str_true(retstr);
553 if (cmd->c_expr->arg_type == O_FLIP) /* undid itself? */
554 cmdflags = copyopt(cmd,cmd->c_expr[3].arg_ptr.arg_cmd);
557 retstr = stab_val(cmd->c_stab);
559 match = (retstr->str_cur != 0);
560 tmps = str_get(retstr);
561 tmps += retstr->str_cur - match;
562 str_nset(&str_chop,tmps,match);
565 retstr->str_cur = tmps - retstr->str_ptr;
569 match = cmd->c_short->str_u.str_useful; /* just to get register */
571 if (match < 0) { /* first time through here? */
572 ar = stab_array(cmd->c_expr[1].arg_ptr.arg_stab);
573 aryoptsave = savestack->ary_fill;
574 savesptr(&stab_val(cmd->c_stab));
575 savelong(&cmd->c_short->str_u.str_useful);
578 ar = stab_xarray(cmd->c_expr[1].arg_ptr.arg_stab);
579 if (cmd->c_type != C_WHILE && savestack->ary_fill > firstsave)
580 restorelist(firstsave);
583 if (match >= ar->ary_fill) { /* we're in LAST, probably */
585 cmd->c_short->str_u.str_useful = -1; /* actually redundant */
590 retstr = stab_val(cmd->c_stab) = ar->ary_array[match];
591 cmd->c_short->str_u.str_useful = match;
598 /* we have tried to make this normal case as abnormal as possible */
601 if (gimme == G_ARRAY) {
602 lastretstr = Nullstr;
604 lastsize = newsp - sp;
608 while (tmps_max > tmps_base) /* clean up after last eval */
609 str_free(tmps_list[tmps_max--]);
610 newsp = eval(cmd->c_expr,gimme && (cmdflags & CF_TERM),sp);
611 st = stack->ary_array; /* possibly reallocated */
613 if (newsp > sp && retstr)
614 match = str_true(retstr);
619 /* if flipflop was true, flop it */
622 if (match && cmdflags & CF_FLIP) {
623 while (tmps_max > tmps_base) /* clean up after last eval */
624 str_free(tmps_list[tmps_max--]);
625 if (cmd->c_expr->arg_type == O_FLOP) { /* currently toggled? */
626 newsp = eval(cmd->c_expr,G_SCALAR,sp);/*let eval undo it*/
627 cmdflags = copyopt(cmd,cmd->c_expr[3].arg_ptr.arg_cmd);
630 newsp = eval(cmd->c_expr,G_SCALAR,sp);/* let eval do it */
631 if (cmd->c_expr->arg_type == O_FLOP) /* still toggled? */
632 cmdflags = copyopt(cmd,cmd->c_expr[4].arg_ptr.arg_cmd);
635 else if (cmdflags & CF_FLIP) {
636 if (cmd->c_expr->arg_type == O_FLOP) { /* currently toggled? */
637 match = TRUE; /* force on */
641 /* at this point, match says whether our expression was true */
644 if (cmdflags & CF_INVERT)
650 tainted = 0; /* modifier doesn't affect regular expression */
653 /* now to do the actual command, if any */
655 switch (cmd->c_type) {
657 fatal("panic: cmd_exec");
658 case C_EXPR: /* evaluated for side effects */
659 if (cmd->ucmd.acmd.ac_expr) { /* more to do? */
660 if (gimme == G_ARRAY) {
661 lastretstr = Nullstr;
663 lastsize = newsp - sp;
667 while (tmps_max > tmps_base) /* clean up after last eval */
668 str_free(tmps_list[tmps_max--]);
669 newsp = eval(cmd->ucmd.acmd.ac_expr,gimme && (cmdflags&CF_TERM),sp);
670 st = stack->ary_array; /* possibly reallocated */
675 match = (int)str_gnum(STAB_STR(cmd->c_stab));
678 match = *(str_get(STAB_STR(cmd->c_stab))) & 255;
680 match -= cmd->ucmd.scmd.sc_offset;
683 else if (match > cmd->ucmd.scmd.sc_max)
685 cmd = cmd->ucmd.scmd.sc_next[match];
686 goto tail_recursion_entry;
688 cmd = cmd->ucmd.ccmd.cc_alt;
689 goto tail_recursion_entry;
691 fatal("panic: ELSIF");
694 oldsave = savestack->ary_fill;
700 if (cmd->ucmd.ccmd.cc_true) {
703 debname[dlevel] = 't';
704 debdelim[dlevel] = '_';
705 if (++dlevel >= dlmax)
709 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme,sp);
710 st = stack->ary_array; /* possibly reallocated */
714 if (savestack->ary_fill > oldsave)
715 restorelist(oldsave);
719 cmd = cmd->ucmd.ccmd.cc_alt;
720 goto tail_recursion_entry;
723 oldsave = savestack->ary_fill;
729 if (cmd->ucmd.ccmd.cc_true) {
732 debname[dlevel] = 'e';
733 debdelim[dlevel] = '_';
734 if (++dlevel >= dlmax)
738 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme,sp);
739 st = stack->ary_array; /* possibly reallocated */
743 if (savestack->ary_fill > oldsave)
744 restorelist(oldsave);
751 if (!(cmdflags & CF_ONCE)) { /* first time through here? */
753 if (++loop_ptr >= loop_max) {
755 Renew(loop_stack, loop_max, struct loop);
757 loop_stack[loop_ptr].loop_label = cmd->c_label;
758 loop_stack[loop_ptr].loop_sp = sp;
761 deb("(Pushing label #%d %s)\n",
762 loop_ptr, cmd->c_label ? cmd->c_label : "");
769 if (match = setjmp(loop_stack[loop_ptr].loop_env)) {
770 st = stack->ary_array; /* possibly reallocated */
773 cmdflags = cmd->c_flags|CF_ONCE;
776 if (savestack->ary_fill > oldsave)
777 restorelist(oldsave);
780 fatal("longjmp returned bad value (%d)",match);
787 newsp = sp + lastsize;
810 oldsave = savestack->ary_fill;
815 if (cmd->ucmd.ccmd.cc_true) {
818 debname[dlevel] = 't';
819 debdelim[dlevel] = '_';
820 if (++dlevel >= dlmax)
824 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme,sp);
825 st = stack->ary_array; /* possibly reallocated */
828 /* actually, this spot is rarely reached anymore since the above
829 * cmd_exec() returns through longjmp(). Hooray for structure.
835 if (cmd->ucmd.ccmd.cc_alt) {
838 debname[dlevel] = 'a';
839 debdelim[dlevel] = '_';
840 if (++dlevel >= dlmax)
844 newsp = cmd_exec(cmd->ucmd.ccmd.cc_alt,gimme,sp);
845 st = stack->ary_array; /* possibly reallocated */
850 if (savestack->ary_fill > oldsave) {
851 if (cmdflags & CF_TERM) {
852 for (match = sp + 1; match <= newsp; match++)
853 st[match] = str_static(st[match]);
856 restorelist(oldsave);
859 dlevel = olddlevel - 1;
861 if (cmd->c_type != C_BLOCK)
862 goto until_loop; /* go back and evaluate conditional again */
864 if (cmdflags & CF_LOOP) {
865 cmdflags |= CF_COND; /* now test the condition */
872 if (cmdflags & CF_ONCE) {
875 tmps = loop_stack[loop_ptr].loop_label;
876 deb("(Popping label #%d %s)\n",loop_ptr, tmps ? tmps : "");
880 if ((cmdflags & CF_OPTIMIZE) == CFT_ARRAY &&
881 savestack->ary_fill > aryoptsave)
882 restorelist(aryoptsave);
885 goto tail_recursion_entry;
891 deb(pat,a1,a2,a3,a4,a5,a6,a7,a8)
896 fprintf(stderr,"%-4ld",(long)line);
897 for (i=0; i<dlevel; i++)
898 fprintf(stderr,"%c%c ",debname[i],debdelim[i]);
899 fprintf(stderr,pat,a1,a2,a3,a4,a5,a6,a7,a8);
911 fprintf(stderr,"%-4ld",(long)line);
912 for (i=0; i<dlevel; i++)
913 fprintf(stderr,"%c%c ",debname[i],debdelim[i]);
915 pat = va_arg(args, char *);
916 (void) vfprintf(stderr,pat,args);
926 cmd->c_flags &= CF_ONCE|CF_COND|CF_LOOP;
927 cmd->c_flags |= which->c_flags;
928 cmd->c_short = which->c_short;
929 cmd->c_slen = which->c_slen;
930 cmd->c_stab = which->c_stab;
941 str->str_state = SS_SARY;
942 str->str_u.str_stab = stab;
944 Safefree(str->str_ptr);
947 str->str_ptr = (char*)stab_array(stab);
948 (void)apush(savestack,str); /* save array ptr */
949 stab_xarray(stab) = Null(ARRAY*);
950 return stab_xarray(aadd(stab));
960 str->str_state = SS_SHASH;
961 str->str_u.str_stab = stab;
963 Safefree(str->str_ptr);
966 str->str_ptr = (char*)stab_hash(stab);
967 (void)apush(savestack,str); /* save hash ptr */
968 stab_xhash(stab) = Null(HASH*);
969 return stab_xhash(hadd(stab));
978 (void)apush(savestack,item); /* remember the pointer */
981 (void)apush(savestack,str); /* remember the value */
991 str->str_state = SS_SINT;
992 str->str_u.str_useful = (long)*intp; /* remember value */
994 Safefree(str->str_ptr);
997 str->str_ptr = (char*)intp; /* remember pointer */
998 (void)apush(savestack,str);
1007 str = Str_new(14,0);
1008 str->str_state = SS_SLONG;
1009 str->str_u.str_useful = *longp; /* remember value */
1011 Safefree(str->str_ptr);
1014 str->str_ptr = (char*)longp; /* remember pointer */
1015 (void)apush(savestack,str);
1024 str = Str_new(15,0);
1025 str->str_state = SS_SSTRP;
1026 str->str_magic = *sptr; /* remember value */
1028 Safefree(str->str_ptr);
1031 str->str_ptr = (char*)sptr; /* remember pointer */
1032 (void)apush(savestack,str);
1041 str = Str_new(16,0);
1042 str->str_state = SS_SNSTAB;
1043 str->str_magic = (STR*)stab; /* remember which stab to free */
1044 (void)apush(savestack,str);
1053 str = Str_new(17,0);
1054 str->str_state = SS_SHPTR;
1055 str->str_u.str_hash = *hptr; /* remember value */
1057 Safefree(str->str_ptr);
1060 str->str_ptr = (char*)hptr; /* remember pointer */
1061 (void)apush(savestack,str);
1065 savelist(sarg,maxsarg)
1066 register STR **sarg;
1072 for (i = 1; i <= maxsarg; i++) {
1073 (void)apush(savestack,sarg[i]); /* remember the pointer */
1074 str = Str_new(18,0);
1075 str_sset(str,sarg[i]);
1076 (void)apush(savestack,str); /* remember the value */
1077 sarg[i]->str_u.str_useful = -1;
1086 register STR *value;
1087 register STAB *stab;
1090 fatal("panic: corrupt saved stack index");
1091 while (savestack->ary_fill > base) {
1092 value = apop(savestack);
1093 switch (value->str_state) {
1094 case SS_NORM: /* normal string */
1096 str = apop(savestack);
1097 str_replace(str,value);
1100 case SS_SARY: /* array reference */
1101 stab = value->str_u.str_stab;
1102 afree(stab_xarray(stab));
1103 stab_xarray(stab) = (ARRAY*)value->str_ptr;
1104 value->str_ptr = Nullch;
1107 case SS_SHASH: /* hash reference */
1108 stab = value->str_u.str_stab;
1109 (void)hfree(stab_xhash(stab));
1110 stab_xhash(stab) = (HASH*)value->str_ptr;
1111 value->str_ptr = Nullch;
1114 case SS_SINT: /* int reference */
1115 *((int*)value->str_ptr) = (int)value->str_u.str_useful;
1116 value->str_ptr = Nullch;
1119 case SS_SLONG: /* long reference */
1120 *((long*)value->str_ptr) = value->str_u.str_useful;
1121 value->str_ptr = Nullch;
1124 case SS_SSTRP: /* STR* reference */
1125 *((STR**)value->str_ptr) = value->str_magic;
1126 value->str_magic = Nullstr;
1127 value->str_ptr = Nullch;
1130 case SS_SHPTR: /* HASH* reference */
1131 *((HASH**)value->str_ptr) = value->str_u.str_hash;
1132 value->str_ptr = Nullch;
1136 stab = (STAB*)value->str_magic;
1137 value->str_magic = Nullstr;
1138 (void)stab_clear(stab);
1142 fatal("panic: restorelist inconsistency");
1152 Renew(debname, dlmax, char);
1153 Renew(debdelim, dlmax, char);