1 /* $Header: cmd.c,v 3.0.1.2 89/11/11 04:08:56 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.2 89/11/11 04:08:56 lwall
10 * patch2: non-BSD machines required two ^D's for <>
11 * patch2: grow_dlevel() not inside #ifdef DEBUGGING
13 * Revision 3.0.1.1 89/10/26 23:04:21 lwall
14 * patch1: heuristically disabled optimization could cause core dump
16 * Revision 3.0 89/10/18 15:09:02 lwall
32 /* This is the main command loop. We try to spend as much time in this loop
33 * as possible, so lots of optimizations do their activities in here. This
34 * means things get a little sloppy.
38 cmd_exec(cmd,gimme,sp)
39 #ifdef cray /* nobody else has complained yet */
54 register STR *retstr = &str_undef;
56 register int cmdflags;
58 register char *go_to = goto_targ;
59 register int newsp = -2;
60 register STR **st = stack->ary_array;
73 tainted = 0; /* Each statement is presumed innocent */
76 if (gimme == G_ARRAY && newsp > -2)
83 cmdflags = cmd->c_flags; /* hopefully load register */
85 if (cmd->c_label && strEQ(go_to,cmd->c_label))
86 goto_targ = go_to = Nullch; /* here at last */
88 switch (cmd->c_type) {
91 oldsave = savestack->ary_fill;
97 if (cmd->ucmd.ccmd.cc_true) {
100 debname[dlevel] = 't';
101 debdelim[dlevel] = '_';
102 if (++dlevel >= dlmax)
106 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme,sp);
107 st = stack->ary_array; /* possibly reallocated */
113 if (savestack->ary_fill > oldsave)
114 restorelist(oldsave);
118 cmd = cmd->ucmd.ccmd.cc_alt;
119 goto tail_recursion_entry;
122 oldsave = savestack->ary_fill;
128 if (cmd->ucmd.ccmd.cc_true) {
131 debname[dlevel] = 'e';
132 debdelim[dlevel] = '_';
133 if (++dlevel >= dlmax)
137 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme,sp);
138 st = stack->ary_array; /* possibly reallocated */
144 if (savestack->ary_fill > oldsave)
145 restorelist(oldsave);
152 if (!(cmdflags & CF_ONCE)) {
154 if (++loop_ptr >= loop_max) {
156 Renew(loop_stack, loop_max, struct loop);
158 loop_stack[loop_ptr].loop_label = cmd->c_label;
159 loop_stack[loop_ptr].loop_sp = sp;
162 deb("(Pushing label #%d %s)\n",
163 loop_ptr, cmd->c_label ? cmd->c_label : "");
167 switch (setjmp(loop_stack[loop_ptr].loop_env)) {
168 case O_LAST: /* not done unless go_to found */
170 st = stack->ary_array; /* possibly reallocated */
176 newsp = sp + lastsize;
183 if (savestack->ary_fill > oldsave)
184 restorelist(oldsave);
186 case O_NEXT: /* not done unless go_to found */
189 case O_REDO: /* not done unless go_to found */
194 oldsave = savestack->ary_fill;
198 if (cmd->ucmd.ccmd.cc_true) {
201 debname[dlevel] = 't';
202 debdelim[dlevel] = '_';
203 if (++dlevel >= dlmax)
207 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme,sp);
208 st = stack->ary_array; /* possibly reallocated */
218 if (cmd->ucmd.ccmd.cc_alt) {
221 debname[dlevel] = 'a';
222 debdelim[dlevel] = '_';
223 if (++dlevel >= dlmax)
227 newsp = cmd_exec(cmd->ucmd.ccmd.cc_alt,gimme,sp);
228 st = stack->ary_array; /* possibly reallocated */
237 if (cmd && cmd->c_head == cmd)
238 /* reached end of while loop */
239 return sp; /* targ isn't in this block */
240 if (cmdflags & CF_ONCE) {
243 tmps = loop_stack[loop_ptr].loop_label;
244 deb("(Popping label #%d %s)\n",loop_ptr,
250 goto tail_recursion_entry;
256 /* Set line number so run-time errors can be located */
263 deb("%s (%lx) r%lx t%lx a%lx n%lx cs%lx\n",
264 cmdname[cmd->c_type],cmd,cmd->c_expr,
265 cmd->ucmd.ccmd.cc_true,cmd->ucmd.ccmd.cc_alt,cmd->c_next,
268 debname[dlevel] = cmdname[cmd->c_type][0];
269 debdelim[dlevel] = '!';
270 if (++dlevel >= dlmax)
275 /* Here is some common optimization */
277 if (cmdflags & CF_COND) {
278 switch (cmdflags & CF_OPTIMIZE) {
281 retstr = cmd->c_short;
284 if (cmdflags & CF_NESURE)
288 retstr = cmd->c_short;
291 if (cmdflags & CF_EQSURE)
296 retstr = STAB_STR(cmd->c_stab);
298 match = str_true(retstr); /* => retstr = retstr, c2 should fix */
299 if (cmdflags & (match ? CF_EQSURE : CF_NESURE))
303 case CFT_ANCHOR: /* /^pat/ optimization */
305 if (*cmd->c_short->str_ptr && !(cmdflags & CF_EQSURE))
306 goto scanner; /* just unanchor it */
308 break; /* must evaluate */
311 case CFT_STROP: /* string op optimization */
312 retstr = STAB_STR(cmd->c_stab);
315 if (*cmd->c_short->str_ptr == *str_get(retstr) &&
316 bcmp(cmd->c_short->str_ptr, str_get(retstr),
317 cmd->c_slen) == 0 ) {
318 if (cmdflags & CF_EQSURE) {
319 if (sawampersand && (cmdflags & CF_OPTIMIZE) != CFT_STROP) {
322 str_nset(stab_val(leftstab),"",0);
324 str_sset(stab_val(amperstab),cmd->c_short);
326 str_nset(stab_val(rightstab),
327 retstr->str_ptr + cmd->c_slen,
328 retstr->str_cur - cmd->c_slen);
330 match = !(cmdflags & CF_FIRSTNEG);
335 else if (cmdflags & CF_NESURE) {
336 match = cmdflags & CF_FIRSTNEG;
342 char *zap1, *zap2, zap1c, zap2c;
345 zap1 = cmd->c_short->str_ptr;
346 zap2 = str_get(retstr);
349 zaplen = cmd->c_slen;
350 if ((zap1c == zap2c) && (bcmp(zap1, zap2, zaplen) == 0)) {
351 if (cmdflags & CF_EQSURE) {
353 (cmdflags & CF_OPTIMIZE) != CFT_STROP) {
356 str_nset(stab_val(leftstab),"",0);
358 str_sset(stab_val(amperstab),cmd->c_short);
360 str_nset(stab_val(rightstab),
361 retstr->str_ptr + cmd->c_slen,
362 retstr->str_cur - cmd->c_slen);
364 match = !(cmdflags & CF_FIRSTNEG);
369 else if (cmdflags & CF_NESURE) {
370 match = cmdflags & CF_FIRSTNEG;
376 break; /* must evaluate */
378 case CFT_SCAN: /* non-anchored search */
380 retstr = STAB_STR(cmd->c_stab);
382 if (retstr->str_pok & SP_STUDIED)
383 if (screamfirst[cmd->c_short->str_rare] >= 0)
384 tmps = screaminstr(retstr, cmd->c_short);
388 tmps = str_get(retstr); /* make sure it's pok */
390 tmps = fbminstr((unsigned char*)tmps,
391 (unsigned char*)tmps + retstr->str_cur, cmd->c_short);
395 if (cmdflags & CF_EQSURE) {
396 ++cmd->c_short->str_u.str_useful;
400 str_nset(stab_val(leftstab),retstr->str_ptr,
401 tmps - retstr->str_ptr);
403 str_sset(stab_val(amperstab),cmd->c_short);
405 str_nset(stab_val(rightstab),
406 tmps + cmd->c_short->str_cur,
407 retstr->str_cur - (tmps - retstr->str_ptr) -
408 cmd->c_short->str_cur);
410 match = !(cmdflags & CF_FIRSTNEG);
418 if (cmdflags & CF_NESURE) {
419 ++cmd->c_short->str_u.str_useful;
420 match = cmdflags & CF_FIRSTNEG;
425 if (--cmd->c_short->str_u.str_useful < 0) {
426 cmdflags &= ~CF_OPTIMIZE;
427 cmdflags |= CFT_EVAL; /* never try this optimization again */
428 cmd->c_flags = cmdflags;
430 break; /* must evaluate */
432 case CFT_NUMOP: /* numeric op optimization */
433 retstr = STAB_STR(cmd->c_stab);
435 switch (cmd->c_slen) {
438 if ((!retstr->str_nok && !looks_like_number(retstr)))
439 warn("Possible use of == on string value");
441 match = (str_gnum(retstr) == cmd->c_short->str_u.str_nval);
444 match = (str_gnum(retstr) != cmd->c_short->str_u.str_nval);
447 match = (str_gnum(retstr) < cmd->c_short->str_u.str_nval);
450 match = (str_gnum(retstr) <= cmd->c_short->str_u.str_nval);
453 match = (str_gnum(retstr) > cmd->c_short->str_u.str_nval);
456 match = (str_gnum(retstr) >= cmd->c_short->str_u.str_nval);
460 if (cmdflags & CF_EQSURE) {
465 else if (cmdflags & CF_NESURE) {
469 break; /* must evaluate */
471 case CFT_INDGETS: /* while (<$foo>) */
472 last_in_stab = stabent(str_get(STAB_STR(cmd->c_stab)),TRUE);
473 if (!stab_io(last_in_stab))
474 stab_io(last_in_stab) = stio_new();
476 case CFT_GETS: /* really a while (<file>) */
477 last_in_stab = cmd->c_stab;
479 fp = stab_io(last_in_stab)->ifp;
480 retstr = stab_val(defstab);
483 if (fp && str_gets(retstr, fp, 0)) {
484 if (*retstr->str_ptr == '0' && retstr->str_cur == 1)
488 stab_io(last_in_stab)->lines++;
490 else if (stab_io(last_in_stab)->flags & IOF_ARGV) {
492 goto doeval; /* first time through */
493 fp = nextargv(last_in_stab);
496 (void)do_close(last_in_stab,FALSE);
497 stab_io(last_in_stab)->flags |= IOF_START;
509 while (tmps_max > tmps_base) /* clean up after last eval */
510 str_free(tmps_list[tmps_max--]);
511 newsp = eval(cmd->c_expr,gimme && (cmdflags & CF_TERM),sp);
512 st = stack->ary_array; /* possibly reallocated */
514 match = str_true(retstr);
515 if (cmd->c_expr->arg_type == O_FLIP) /* undid itself? */
516 cmdflags = copyopt(cmd,cmd->c_expr[3].arg_ptr.arg_cmd);
519 retstr = stab_val(cmd->c_stab);
521 match = (retstr->str_cur != 0);
522 tmps = str_get(retstr);
523 tmps += retstr->str_cur - match;
524 str_nset(&str_chop,tmps,match);
527 retstr->str_cur = tmps - retstr->str_ptr;
531 ar = stab_array(cmd->c_expr[1].arg_ptr.arg_stab);
532 match = ar->ary_index; /* just to get register */
534 if (match < 0) { /* first time through here? */
535 aryoptsave = savestack->ary_fill;
536 savesptr(&stab_val(cmd->c_stab));
537 saveint(&ar->ary_index);
540 if (match >= ar->ary_fill) { /* we're in LAST, probably */
542 ar->ary_index = -1; /* this is actually redundant */
547 retstr = stab_val(cmd->c_stab) = ar->ary_array[match];
548 ar->ary_index = match;
555 /* we have tried to make this normal case as abnormal as possible */
558 if (gimme == G_ARRAY) {
559 lastretstr = Nullstr;
561 lastsize = newsp - sp;
565 while (tmps_max > tmps_base) /* clean up after last eval */
566 str_free(tmps_list[tmps_max--]);
567 newsp = eval(cmd->c_expr,gimme && (cmdflags & CF_TERM),sp);
568 st = stack->ary_array; /* possibly reallocated */
571 match = str_true(retstr);
576 /* if flipflop was true, flop it */
579 if (match && cmdflags & CF_FLIP) {
580 while (tmps_max > tmps_base) /* clean up after last eval */
581 str_free(tmps_list[tmps_max--]);
582 if (cmd->c_expr->arg_type == O_FLOP) { /* currently toggled? */
583 newsp = eval(cmd->c_expr,G_SCALAR,sp);/*let eval undo it*/
584 cmdflags = copyopt(cmd,cmd->c_expr[3].arg_ptr.arg_cmd);
587 newsp = eval(cmd->c_expr,G_SCALAR,sp);/* let eval do it */
588 if (cmd->c_expr->arg_type == O_FLOP) /* still toggled? */
589 cmdflags = copyopt(cmd,cmd->c_expr[4].arg_ptr.arg_cmd);
592 else if (cmdflags & CF_FLIP) {
593 if (cmd->c_expr->arg_type == O_FLOP) { /* currently toggled? */
594 match = TRUE; /* force on */
598 /* at this point, match says whether our expression was true */
601 if (cmdflags & CF_INVERT)
607 tainted = 0; /* modifier doesn't affect regular expression */
610 /* now to do the actual command, if any */
612 switch (cmd->c_type) {
614 fatal("panic: cmd_exec");
615 case C_EXPR: /* evaluated for side effects */
616 if (cmd->ucmd.acmd.ac_expr) { /* more to do? */
617 if (gimme == G_ARRAY) {
618 lastretstr = Nullstr;
620 lastsize = newsp - sp;
624 while (tmps_max > tmps_base) /* clean up after last eval */
625 str_free(tmps_list[tmps_max--]);
626 newsp = eval(cmd->ucmd.acmd.ac_expr,gimme && (cmdflags&CF_TERM),sp);
627 st = stack->ary_array; /* possibly reallocated */
632 match = (int)str_gnum(STAB_STR(cmd->c_stab));
635 match = *(str_get(STAB_STR(cmd->c_stab))) & 255;
637 match -= cmd->ucmd.scmd.sc_offset;
640 else if (match > cmd->ucmd.scmd.sc_max)
642 cmd = cmd->ucmd.scmd.sc_next[match];
643 goto tail_recursion_entry;
645 cmd = cmd->ucmd.ccmd.cc_alt;
646 goto tail_recursion_entry;
648 fatal("panic: ELSIF");
651 oldsave = savestack->ary_fill;
657 if (cmd->ucmd.ccmd.cc_true) {
660 debname[dlevel] = 't';
661 debdelim[dlevel] = '_';
662 if (++dlevel >= dlmax)
666 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme,sp);
667 st = stack->ary_array; /* possibly reallocated */
671 if (savestack->ary_fill > oldsave)
672 restorelist(oldsave);
676 cmd = cmd->ucmd.ccmd.cc_alt;
677 goto tail_recursion_entry;
680 oldsave = savestack->ary_fill;
686 if (cmd->ucmd.ccmd.cc_true) {
689 debname[dlevel] = 'e';
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);
708 if (!(cmdflags & CF_ONCE)) { /* first time through here? */
710 if (++loop_ptr >= loop_max) {
712 Renew(loop_stack, loop_max, struct loop);
714 loop_stack[loop_ptr].loop_label = cmd->c_label;
715 loop_stack[loop_ptr].loop_sp = sp;
718 deb("(Pushing label #%d %s)\n",
719 loop_ptr, cmd->c_label ? cmd->c_label : "");
723 switch (setjmp(loop_stack[loop_ptr].loop_env)) {
725 /* retstr = lastretstr; */
726 st = stack->ary_array; /* possibly reallocated */
732 newsp = sp + lastsize;
736 if (savestack->ary_fill > oldsave)
737 restorelist(oldsave);
748 oldsave = savestack->ary_fill;
753 if (cmd->ucmd.ccmd.cc_true) {
756 debname[dlevel] = 't';
757 debdelim[dlevel] = '_';
758 if (++dlevel >= dlmax)
762 newsp = cmd_exec(cmd->ucmd.ccmd.cc_true,gimme,sp);
763 st = stack->ary_array; /* possibly reallocated */
766 /* actually, this spot is rarely reached anymore since the above
767 * cmd_exec() returns through longjmp(). Hooray for structure.
773 if (cmd->ucmd.ccmd.cc_alt) {
776 debname[dlevel] = 'a';
777 debdelim[dlevel] = '_';
778 if (++dlevel >= dlmax)
782 newsp = cmd_exec(cmd->ucmd.ccmd.cc_alt,gimme,sp);
783 st = stack->ary_array; /* possibly reallocated */
788 if (savestack->ary_fill > oldsave)
789 restorelist(oldsave);
791 dlevel = olddlevel - 1;
793 if (cmd->c_type != C_BLOCK)
794 goto until_loop; /* go back and evaluate conditional again */
796 if (cmdflags & CF_LOOP) {
797 cmdflags |= CF_COND; /* now test the condition */
804 if (cmdflags & CF_ONCE) {
807 tmps = loop_stack[loop_ptr].loop_label;
808 deb("(Popping label #%d %s)\n",loop_ptr, tmps ? tmps : "");
812 if ((cmdflags & CF_OPTIMIZE) == CFT_ARRAY)
813 restorelist(aryoptsave);
816 goto tail_recursion_entry;
822 deb(pat,a1,a2,a3,a4,a5,a6,a7,a8)
827 fprintf(stderr,"%-4ld",(long)line);
828 for (i=0; i<dlevel; i++)
829 fprintf(stderr,"%c%c ",debname[i],debdelim[i]);
830 fprintf(stderr,pat,a1,a2,a3,a4,a5,a6,a7,a8);
842 fprintf(stderr,"%-4ld",(long)line);
843 for (i=0; i<dlevel; i++)
844 fprintf(stderr,"%c%c ",debname[i],debdelim[i]);
846 pat = va_arg(args, char *);
847 (void) vfprintf(stderr,pat,args);
857 cmd->c_flags &= CF_ONCE|CF_COND|CF_LOOP;
858 cmd->c_flags |= which->c_flags;
859 cmd->c_short = which->c_short;
860 cmd->c_slen = which->c_slen;
861 cmd->c_stab = which->c_stab;
872 str->str_state = SS_SARY;
873 str->str_u.str_stab = stab;
875 Safefree(str->str_ptr);
878 str->str_ptr = (char*)stab_array(stab);
879 (void)apush(savestack,str); /* save array ptr */
880 stab_xarray(stab) = Null(ARRAY*);
881 return stab_xarray(aadd(stab));
891 str->str_state = SS_SHASH;
892 str->str_u.str_stab = stab;
894 Safefree(str->str_ptr);
897 str->str_ptr = (char*)stab_hash(stab);
898 (void)apush(savestack,str); /* save hash ptr */
899 stab_xhash(stab) = Null(HASH*);
900 return stab_xhash(hadd(stab));
909 (void)apush(savestack,item); /* remember the pointer */
912 (void)apush(savestack,str); /* remember the value */
922 str->str_state = SS_SINT;
923 str->str_u.str_useful = (long)*intp; /* remember value */
925 Safefree(str->str_ptr);
928 str->str_ptr = (char*)intp; /* remember pointer */
929 (void)apush(savestack,str);
939 str->str_state = SS_SLONG;
940 str->str_u.str_useful = *longp; /* remember value */
942 Safefree(str->str_ptr);
945 str->str_ptr = (char*)longp; /* remember pointer */
946 (void)apush(savestack,str);
956 str->str_state = SS_SSTRP;
957 str->str_magic = *sptr; /* remember value */
959 Safefree(str->str_ptr);
962 str->str_ptr = (char*)sptr; /* remember pointer */
963 (void)apush(savestack,str);
973 str->str_state = SS_SNSTAB;
974 str->str_magic = (STR*)stab; /* remember which stab to free */
975 (void)apush(savestack,str);
985 str->str_state = SS_SHPTR;
986 str->str_u.str_hash = *hptr; /* remember value */
988 Safefree(str->str_ptr);
991 str->str_ptr = (char*)hptr; /* remember pointer */
992 (void)apush(savestack,str);
996 savelist(sarg,maxsarg)
1003 for (i = 1; i <= maxsarg; i++) {
1004 (void)apush(savestack,sarg[i]); /* remember the pointer */
1005 str = Str_new(18,0);
1006 str_sset(str,sarg[i]);
1007 (void)apush(savestack,str); /* remember the value */
1016 register STR *value;
1017 register STAB *stab;
1020 fatal("panic: corrupt saved stack index");
1021 while (savestack->ary_fill > base) {
1022 value = apop(savestack);
1023 switch (value->str_state) {
1024 case SS_NORM: /* normal string */
1026 str = apop(savestack);
1027 str_replace(str,value);
1030 case SS_SARY: /* array reference */
1031 stab = value->str_u.str_stab;
1032 afree(stab_xarray(stab));
1033 stab_xarray(stab) = (ARRAY*)value->str_ptr;
1034 value->str_ptr = Nullch;
1037 case SS_SHASH: /* hash reference */
1038 stab = value->str_u.str_stab;
1039 (void)hfree(stab_xhash(stab));
1040 stab_xhash(stab) = (HASH*)value->str_ptr;
1041 value->str_ptr = Nullch;
1044 case SS_SINT: /* int reference */
1045 *((int*)value->str_ptr) = (int)value->str_u.str_useful;
1046 value->str_ptr = Nullch;
1049 case SS_SLONG: /* long reference */
1050 *((long*)value->str_ptr) = value->str_u.str_useful;
1051 value->str_ptr = Nullch;
1054 case SS_SSTRP: /* STR* reference */
1055 *((STR**)value->str_ptr) = value->str_magic;
1056 value->str_magic = Nullstr;
1057 value->str_ptr = Nullch;
1060 case SS_SHPTR: /* HASH* reference */
1061 *((HASH**)value->str_ptr) = value->str_u.str_hash;
1062 value->str_ptr = Nullch;
1066 stab = (STAB*)value->str_magic;
1067 value->str_magic = Nullstr;
1068 (void)stab_clear(stab);
1072 fatal("panic: restorelist inconsistency");
1082 Renew(debname, dlmax, char);
1083 Renew(debdelim, dlmax, char);