1 /* $Header: cmd.c,v 3.0.1.4 89/12/21 19:17:41 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.4 89/12/21 19:17:41 lwall
10 * patch7: arranged for certain registers to be restored after longjmp()
11 * patch7: made nested or recursive foreach work right
13 * Revision 3.0.1.3 89/11/17 15:04:36 lwall
14 * patch5: nested foreach on same array didn't work
16 * Revision 3.0.1.2 89/11/11 04:08:56 lwall
17 * patch2: non-BSD machines required two ^D's for <>
18 * patch2: grow_dlevel() not inside #ifdef DEBUGGING
20 * Revision 3.0.1.1 89/10/26 23:04:21 lwall
21 * patch1: heuristically disabled optimization could cause core dump
23 * Revision 3.0 89/10/18 15:09:02 lwall
39 /* do longjmps() clobber register variables? */
41 #if defined(cray) || defined(__STDC__)
45 /* This is the main command loop. We try to spend as much time in this loop
46 * as possible, so lots of optimizations do their activities in here. This
47 * means things get a little sloppy.
51 cmd_exec(cmdparm,gimme,sp)
52 CMD *VOLATILE cmdparm;
56 register CMD *cmd = cmdparm;
57 SPAT *VOLATILE oldspat;
59 VOLATILE int aryoptsave;
61 VOLATILE int olddlevel;
62 VOLATILE int entdlevel;
64 register STR *retstr = &str_undef;
66 register int cmdflags;
68 register char *go_to = goto_targ;
69 register int newsp = -2;
70 register STR **st = stack->ary_array;
83 tainted = 0; /* Each statement is presumed innocent */
86 if (gimme == G_ARRAY && newsp > -2)
93 cmdflags = cmd->c_flags; /* hopefully load register */
95 if (cmd->c_label && strEQ(go_to,cmd->c_label))
96 goto_targ = go_to = Nullch; /* here at last */
98 switch (cmd->c_type) {
101 oldsave = savestack->ary_fill;
107 if (cmd->ucmd.ccmd.cc_true) {
110 debname[dlevel] = 't';
111 debdelim[dlevel] = '_';
112 if (++dlevel >= dlmax)
116 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme,sp);
117 st = stack->ary_array; /* possibly reallocated */
123 if (savestack->ary_fill > oldsave)
124 restorelist(oldsave);
128 cmd = cmd->ucmd.ccmd.cc_alt;
129 goto tail_recursion_entry;
132 oldsave = savestack->ary_fill;
138 if (cmd->ucmd.ccmd.cc_true) {
141 debname[dlevel] = 'e';
142 debdelim[dlevel] = '_';
143 if (++dlevel >= dlmax)
147 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme,sp);
148 st = stack->ary_array; /* possibly reallocated */
154 if (savestack->ary_fill > oldsave)
155 restorelist(oldsave);
162 if (!(cmdflags & CF_ONCE)) {
164 if (++loop_ptr >= loop_max) {
166 Renew(loop_stack, loop_max, struct loop);
168 loop_stack[loop_ptr].loop_label = cmd->c_label;
169 loop_stack[loop_ptr].loop_sp = sp;
172 deb("(Pushing label #%d %s)\n",
173 loop_ptr, cmd->c_label ? cmd->c_label : "");
180 if (match = setjmp(loop_stack[loop_ptr].loop_env)) {
182 st = stack->ary_array; /* possibly reallocated */
184 cmdflags = cmd->c_flags|CF_ONCE;
187 case O_LAST: /* not done unless go_to found */
194 newsp = sp + lastsize;
201 if (savestack->ary_fill > oldsave)
202 restorelist(oldsave);
204 case O_NEXT: /* not done unless go_to found */
211 case O_REDO: /* not done unless go_to found */
221 oldsave = savestack->ary_fill;
225 if (cmd->ucmd.ccmd.cc_true) {
228 debname[dlevel] = 't';
229 debdelim[dlevel] = '_';
230 if (++dlevel >= dlmax)
234 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme,sp);
235 st = stack->ary_array; /* possibly reallocated */
245 if (cmd->ucmd.ccmd.cc_alt) {
248 debname[dlevel] = 'a';
249 debdelim[dlevel] = '_';
250 if (++dlevel >= dlmax)
254 newsp = cmd_exec(cmd->ucmd.ccmd.cc_alt,gimme,sp);
255 st = stack->ary_array; /* possibly reallocated */
264 if (cmd && cmd->c_head == cmd)
265 /* reached end of while loop */
266 return sp; /* targ isn't in this block */
267 if (cmdflags & CF_ONCE) {
270 tmps = loop_stack[loop_ptr].loop_label;
271 deb("(Popping label #%d %s)\n",loop_ptr,
277 goto tail_recursion_entry;
283 /* Set line number so run-time errors can be located */
290 deb("%s (%lx) r%lx t%lx a%lx n%lx cs%lx\n",
291 cmdname[cmd->c_type],cmd,cmd->c_expr,
292 cmd->ucmd.ccmd.cc_true,cmd->ucmd.ccmd.cc_alt,cmd->c_next,
295 debname[dlevel] = cmdname[cmd->c_type][0];
296 debdelim[dlevel] = '!';
297 if (++dlevel >= dlmax)
302 /* Here is some common optimization */
304 if (cmdflags & CF_COND) {
305 switch (cmdflags & CF_OPTIMIZE) {
308 retstr = cmd->c_short;
311 if (cmdflags & CF_NESURE)
315 retstr = cmd->c_short;
318 if (cmdflags & CF_EQSURE)
323 retstr = STAB_STR(cmd->c_stab);
325 match = str_true(retstr); /* => retstr = retstr, c2 should fix */
326 if (cmdflags & (match ? CF_EQSURE : CF_NESURE))
330 case CFT_ANCHOR: /* /^pat/ optimization */
332 if (*cmd->c_short->str_ptr && !(cmdflags & CF_EQSURE))
333 goto scanner; /* just unanchor it */
335 break; /* must evaluate */
338 case CFT_STROP: /* string op optimization */
339 retstr = STAB_STR(cmd->c_stab);
342 if (*cmd->c_short->str_ptr == *str_get(retstr) &&
343 bcmp(cmd->c_short->str_ptr, str_get(retstr),
344 cmd->c_slen) == 0 ) {
345 if (cmdflags & CF_EQSURE) {
346 if (sawampersand && (cmdflags & CF_OPTIMIZE) != CFT_STROP) {
349 str_nset(stab_val(leftstab),"",0);
351 str_sset(stab_val(amperstab),cmd->c_short);
353 str_nset(stab_val(rightstab),
354 retstr->str_ptr + cmd->c_slen,
355 retstr->str_cur - cmd->c_slen);
357 match = !(cmdflags & CF_FIRSTNEG);
362 else if (cmdflags & CF_NESURE) {
363 match = cmdflags & CF_FIRSTNEG;
369 char *zap1, *zap2, zap1c, zap2c;
372 zap1 = cmd->c_short->str_ptr;
373 zap2 = str_get(retstr);
376 zaplen = cmd->c_slen;
377 if ((zap1c == zap2c) && (bcmp(zap1, zap2, zaplen) == 0)) {
378 if (cmdflags & CF_EQSURE) {
380 (cmdflags & CF_OPTIMIZE) != CFT_STROP) {
383 str_nset(stab_val(leftstab),"",0);
385 str_sset(stab_val(amperstab),cmd->c_short);
387 str_nset(stab_val(rightstab),
388 retstr->str_ptr + cmd->c_slen,
389 retstr->str_cur - cmd->c_slen);
391 match = !(cmdflags & CF_FIRSTNEG);
396 else if (cmdflags & CF_NESURE) {
397 match = cmdflags & CF_FIRSTNEG;
403 break; /* must evaluate */
405 case CFT_SCAN: /* non-anchored search */
407 retstr = STAB_STR(cmd->c_stab);
409 if (retstr->str_pok & SP_STUDIED)
410 if (screamfirst[cmd->c_short->str_rare] >= 0)
411 tmps = screaminstr(retstr, cmd->c_short);
415 tmps = str_get(retstr); /* make sure it's pok */
417 tmps = fbminstr((unsigned char*)tmps,
418 (unsigned char*)tmps + retstr->str_cur, cmd->c_short);
422 if (cmdflags & CF_EQSURE) {
423 ++cmd->c_short->str_u.str_useful;
427 str_nset(stab_val(leftstab),retstr->str_ptr,
428 tmps - retstr->str_ptr);
430 str_sset(stab_val(amperstab),cmd->c_short);
432 str_nset(stab_val(rightstab),
433 tmps + cmd->c_short->str_cur,
434 retstr->str_cur - (tmps - retstr->str_ptr) -
435 cmd->c_short->str_cur);
437 match = !(cmdflags & CF_FIRSTNEG);
445 if (cmdflags & CF_NESURE) {
446 ++cmd->c_short->str_u.str_useful;
447 match = cmdflags & CF_FIRSTNEG;
452 if (--cmd->c_short->str_u.str_useful < 0) {
453 cmdflags &= ~CF_OPTIMIZE;
454 cmdflags |= CFT_EVAL; /* never try this optimization again */
455 cmd->c_flags = cmdflags;
457 break; /* must evaluate */
459 case CFT_NUMOP: /* numeric op optimization */
460 retstr = STAB_STR(cmd->c_stab);
462 switch (cmd->c_slen) {
465 if ((!retstr->str_nok && !looks_like_number(retstr)))
466 warn("Possible use of == on string value");
468 match = (str_gnum(retstr) == cmd->c_short->str_u.str_nval);
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);
487 if (cmdflags & CF_EQSURE) {
492 else if (cmdflags & CF_NESURE) {
496 break; /* must evaluate */
498 case CFT_INDGETS: /* while (<$foo>) */
499 last_in_stab = stabent(str_get(STAB_STR(cmd->c_stab)),TRUE);
500 if (!stab_io(last_in_stab))
501 stab_io(last_in_stab) = stio_new();
503 case CFT_GETS: /* really a while (<file>) */
504 last_in_stab = cmd->c_stab;
506 fp = stab_io(last_in_stab)->ifp;
507 retstr = stab_val(defstab);
510 if (fp && str_gets(retstr, fp, 0)) {
511 if (*retstr->str_ptr == '0' && retstr->str_cur == 1)
515 stab_io(last_in_stab)->lines++;
517 else if (stab_io(last_in_stab)->flags & IOF_ARGV) {
519 goto doeval; /* first time through */
520 fp = nextargv(last_in_stab);
523 (void)do_close(last_in_stab,FALSE);
524 stab_io(last_in_stab)->flags |= IOF_START;
536 while (tmps_max > tmps_base) /* clean up after last eval */
537 str_free(tmps_list[tmps_max--]);
538 newsp = eval(cmd->c_expr,gimme && (cmdflags & CF_TERM),sp);
539 st = stack->ary_array; /* possibly reallocated */
541 match = str_true(retstr);
542 if (cmd->c_expr->arg_type == O_FLIP) /* undid itself? */
543 cmdflags = copyopt(cmd,cmd->c_expr[3].arg_ptr.arg_cmd);
546 retstr = stab_val(cmd->c_stab);
548 match = (retstr->str_cur != 0);
549 tmps = str_get(retstr);
550 tmps += retstr->str_cur - match;
551 str_nset(&str_chop,tmps,match);
554 retstr->str_cur = tmps - retstr->str_ptr;
558 match = cmd->c_short->str_u.str_useful; /* just to get register */
560 if (match < 0) { /* first time through here? */
561 ar = stab_array(cmd->c_expr[1].arg_ptr.arg_stab);
562 aryoptsave = savestack->ary_fill;
563 savesptr(&stab_val(cmd->c_stab));
564 savelong(&cmd->c_short->str_u.str_useful);
567 ar = stab_xarray(cmd->c_expr[1].arg_ptr.arg_stab);
569 if (match >= ar->ary_fill) { /* we're in LAST, probably */
571 cmd->c_short->str_u.str_useful = -1; /* actually redundant */
576 retstr = stab_val(cmd->c_stab) = ar->ary_array[match];
577 cmd->c_short->str_u.str_useful = match;
584 /* we have tried to make this normal case as abnormal as possible */
587 if (gimme == G_ARRAY) {
588 lastretstr = Nullstr;
590 lastsize = newsp - sp;
594 while (tmps_max > tmps_base) /* clean up after last eval */
595 str_free(tmps_list[tmps_max--]);
596 newsp = eval(cmd->c_expr,gimme && (cmdflags & CF_TERM),sp);
597 st = stack->ary_array; /* possibly reallocated */
599 if (newsp > sp && retstr)
600 match = str_true(retstr);
605 /* if flipflop was true, flop it */
608 if (match && cmdflags & CF_FLIP) {
609 while (tmps_max > tmps_base) /* clean up after last eval */
610 str_free(tmps_list[tmps_max--]);
611 if (cmd->c_expr->arg_type == O_FLOP) { /* currently toggled? */
612 newsp = eval(cmd->c_expr,G_SCALAR,sp);/*let eval undo it*/
613 cmdflags = copyopt(cmd,cmd->c_expr[3].arg_ptr.arg_cmd);
616 newsp = eval(cmd->c_expr,G_SCALAR,sp);/* let eval do it */
617 if (cmd->c_expr->arg_type == O_FLOP) /* still toggled? */
618 cmdflags = copyopt(cmd,cmd->c_expr[4].arg_ptr.arg_cmd);
621 else if (cmdflags & CF_FLIP) {
622 if (cmd->c_expr->arg_type == O_FLOP) { /* currently toggled? */
623 match = TRUE; /* force on */
627 /* at this point, match says whether our expression was true */
630 if (cmdflags & CF_INVERT)
636 tainted = 0; /* modifier doesn't affect regular expression */
639 /* now to do the actual command, if any */
641 switch (cmd->c_type) {
643 fatal("panic: cmd_exec");
644 case C_EXPR: /* evaluated for side effects */
645 if (cmd->ucmd.acmd.ac_expr) { /* more to do? */
646 if (gimme == G_ARRAY) {
647 lastretstr = Nullstr;
649 lastsize = newsp - sp;
653 while (tmps_max > tmps_base) /* clean up after last eval */
654 str_free(tmps_list[tmps_max--]);
655 newsp = eval(cmd->ucmd.acmd.ac_expr,gimme && (cmdflags&CF_TERM),sp);
656 st = stack->ary_array; /* possibly reallocated */
661 match = (int)str_gnum(STAB_STR(cmd->c_stab));
664 match = *(str_get(STAB_STR(cmd->c_stab))) & 255;
666 match -= cmd->ucmd.scmd.sc_offset;
669 else if (match > cmd->ucmd.scmd.sc_max)
671 cmd = cmd->ucmd.scmd.sc_next[match];
672 goto tail_recursion_entry;
674 cmd = cmd->ucmd.ccmd.cc_alt;
675 goto tail_recursion_entry;
677 fatal("panic: ELSIF");
680 oldsave = savestack->ary_fill;
686 if (cmd->ucmd.ccmd.cc_true) {
689 debname[dlevel] = 't';
690 debdelim[dlevel] = '_';
691 if (++dlevel >= dlmax)
695 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme,sp);
696 st = stack->ary_array; /* possibly reallocated */
700 if (savestack->ary_fill > oldsave)
701 restorelist(oldsave);
705 cmd = cmd->ucmd.ccmd.cc_alt;
706 goto tail_recursion_entry;
709 oldsave = savestack->ary_fill;
715 if (cmd->ucmd.ccmd.cc_true) {
718 debname[dlevel] = 'e';
719 debdelim[dlevel] = '_';
720 if (++dlevel >= dlmax)
724 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme,sp);
725 st = stack->ary_array; /* possibly reallocated */
729 if (savestack->ary_fill > oldsave)
730 restorelist(oldsave);
737 if (!(cmdflags & CF_ONCE)) { /* first time through here? */
739 if (++loop_ptr >= loop_max) {
741 Renew(loop_stack, loop_max, struct loop);
743 loop_stack[loop_ptr].loop_label = cmd->c_label;
744 loop_stack[loop_ptr].loop_sp = sp;
747 deb("(Pushing label #%d %s)\n",
748 loop_ptr, cmd->c_label ? cmd->c_label : "");
755 if (match = setjmp(loop_stack[loop_ptr].loop_env)) {
757 st = stack->ary_array; /* possibly reallocated */
759 cmdflags = cmd->c_flags|CF_ONCE;
769 newsp = sp + lastsize;
773 if (savestack->ary_fill > oldsave)
774 restorelist(oldsave);
794 oldsave = savestack->ary_fill;
799 if (cmd->ucmd.ccmd.cc_true) {
802 debname[dlevel] = 't';
803 debdelim[dlevel] = '_';
804 if (++dlevel >= dlmax)
808 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme,sp);
809 st = stack->ary_array; /* possibly reallocated */
812 /* actually, this spot is rarely reached anymore since the above
813 * cmd_exec() returns through longjmp(). Hooray for structure.
819 if (cmd->ucmd.ccmd.cc_alt) {
822 debname[dlevel] = 'a';
823 debdelim[dlevel] = '_';
824 if (++dlevel >= dlmax)
828 newsp = cmd_exec(cmd->ucmd.ccmd.cc_alt,gimme,sp);
829 st = stack->ary_array; /* possibly reallocated */
834 if (savestack->ary_fill > oldsave)
835 restorelist(oldsave);
837 dlevel = olddlevel - 1;
839 if (cmd->c_type != C_BLOCK)
840 goto until_loop; /* go back and evaluate conditional again */
842 if (cmdflags & CF_LOOP) {
843 cmdflags |= CF_COND; /* now test the condition */
850 if (cmdflags & CF_ONCE) {
853 tmps = loop_stack[loop_ptr].loop_label;
854 deb("(Popping label #%d %s)\n",loop_ptr, tmps ? tmps : "");
858 if ((cmdflags & CF_OPTIMIZE) == CFT_ARRAY)
859 restorelist(aryoptsave);
862 goto tail_recursion_entry;
868 deb(pat,a1,a2,a3,a4,a5,a6,a7,a8)
873 fprintf(stderr,"%-4ld",(long)line);
874 for (i=0; i<dlevel; i++)
875 fprintf(stderr,"%c%c ",debname[i],debdelim[i]);
876 fprintf(stderr,pat,a1,a2,a3,a4,a5,a6,a7,a8);
888 fprintf(stderr,"%-4ld",(long)line);
889 for (i=0; i<dlevel; i++)
890 fprintf(stderr,"%c%c ",debname[i],debdelim[i]);
892 pat = va_arg(args, char *);
893 (void) vfprintf(stderr,pat,args);
903 cmd->c_flags &= CF_ONCE|CF_COND|CF_LOOP;
904 cmd->c_flags |= which->c_flags;
905 cmd->c_short = which->c_short;
906 cmd->c_slen = which->c_slen;
907 cmd->c_stab = which->c_stab;
918 str->str_state = SS_SARY;
919 str->str_u.str_stab = stab;
921 Safefree(str->str_ptr);
924 str->str_ptr = (char*)stab_array(stab);
925 (void)apush(savestack,str); /* save array ptr */
926 stab_xarray(stab) = Null(ARRAY*);
927 return stab_xarray(aadd(stab));
937 str->str_state = SS_SHASH;
938 str->str_u.str_stab = stab;
940 Safefree(str->str_ptr);
943 str->str_ptr = (char*)stab_hash(stab);
944 (void)apush(savestack,str); /* save hash ptr */
945 stab_xhash(stab) = Null(HASH*);
946 return stab_xhash(hadd(stab));
955 (void)apush(savestack,item); /* remember the pointer */
958 (void)apush(savestack,str); /* remember the value */
968 str->str_state = SS_SINT;
969 str->str_u.str_useful = (long)*intp; /* remember value */
971 Safefree(str->str_ptr);
974 str->str_ptr = (char*)intp; /* remember pointer */
975 (void)apush(savestack,str);
985 str->str_state = SS_SLONG;
986 str->str_u.str_useful = *longp; /* remember value */
988 Safefree(str->str_ptr);
991 str->str_ptr = (char*)longp; /* remember pointer */
992 (void)apush(savestack,str);
1001 str = Str_new(15,0);
1002 str->str_state = SS_SSTRP;
1003 str->str_magic = *sptr; /* remember value */
1005 Safefree(str->str_ptr);
1008 str->str_ptr = (char*)sptr; /* remember pointer */
1009 (void)apush(savestack,str);
1018 str = Str_new(16,0);
1019 str->str_state = SS_SNSTAB;
1020 str->str_magic = (STR*)stab; /* remember which stab to free */
1021 (void)apush(savestack,str);
1030 str = Str_new(17,0);
1031 str->str_state = SS_SHPTR;
1032 str->str_u.str_hash = *hptr; /* remember value */
1034 Safefree(str->str_ptr);
1037 str->str_ptr = (char*)hptr; /* remember pointer */
1038 (void)apush(savestack,str);
1042 savelist(sarg,maxsarg)
1043 register STR **sarg;
1049 for (i = 1; i <= maxsarg; i++) {
1050 (void)apush(savestack,sarg[i]); /* remember the pointer */
1051 str = Str_new(18,0);
1052 str_sset(str,sarg[i]);
1053 (void)apush(savestack,str); /* remember the value */
1054 sarg[i]->str_u.str_useful = -1;
1063 register STR *value;
1064 register STAB *stab;
1067 fatal("panic: corrupt saved stack index");
1068 while (savestack->ary_fill > base) {
1069 value = apop(savestack);
1070 switch (value->str_state) {
1071 case SS_NORM: /* normal string */
1073 str = apop(savestack);
1074 str_replace(str,value);
1077 case SS_SARY: /* array reference */
1078 stab = value->str_u.str_stab;
1079 afree(stab_xarray(stab));
1080 stab_xarray(stab) = (ARRAY*)value->str_ptr;
1081 value->str_ptr = Nullch;
1084 case SS_SHASH: /* hash reference */
1085 stab = value->str_u.str_stab;
1086 (void)hfree(stab_xhash(stab));
1087 stab_xhash(stab) = (HASH*)value->str_ptr;
1088 value->str_ptr = Nullch;
1091 case SS_SINT: /* int reference */
1092 *((int*)value->str_ptr) = (int)value->str_u.str_useful;
1093 value->str_ptr = Nullch;
1096 case SS_SLONG: /* long reference */
1097 *((long*)value->str_ptr) = value->str_u.str_useful;
1098 value->str_ptr = Nullch;
1101 case SS_SSTRP: /* STR* reference */
1102 *((STR**)value->str_ptr) = value->str_magic;
1103 value->str_magic = Nullstr;
1104 value->str_ptr = Nullch;
1107 case SS_SHPTR: /* HASH* reference */
1108 *((HASH**)value->str_ptr) = value->str_u.str_hash;
1109 value->str_ptr = Nullch;
1113 stab = (STAB*)value->str_magic;
1114 value->str_magic = Nullstr;
1115 (void)stab_clear(stab);
1119 fatal("panic: restorelist inconsistency");
1129 Renew(debname, dlmax, char);
1130 Renew(debdelim, dlmax, char);