diff options
Diffstat (limited to 'oldcmdcruft')
-rw-r--r-- | oldcmdcruft | 592 |
1 files changed, 592 insertions, 0 deletions
diff --git a/oldcmdcruft b/oldcmdcruft new file mode 100644 index 0000000000..d4e65720de --- /dev/null +++ b/oldcmdcruft @@ -0,0 +1,592 @@ +#ifdef NOTDEF + if (go_to) { + if (op->cop_label && strEQ(go_to,op->cop_label)) + goto_targ = go_to = Nullch; /* here at last */ + else { + switch (op->cop_type) { + case COP_IF: + oldspat = curspat; + oldsave = savestack->av_fill; +#ifdef DEBUGGING + olddlevel = dlevel; +#endif + retstr = &sv_yes; + newsp = -2; + if (op->uop.ccop_true) { +#ifdef DEBUGGING + if (debug) { + debname[dlevel] = 't'; + debdelim[dlevel] = '_'; + if (++dlevel >= dlmax) + deb_growlevel(); + } +#endif + newsp = cop_exec(op->uop.ccop_true,gimme && (opflags & COPf_TERM),sp); + st = stack->av_array; /* possibly reallocated */ + retstr = st[newsp]; + } + if (!goto_targ) + go_to = Nullch; + curspat = oldspat; + if (savestack->av_fill > oldsave) + leave_scope(oldsave); +#ifdef DEBUGGING + dlevel = olddlevel; +#endif + op = op->uop.ccop_alt; + goto tail_recursion_entry; + case COP_ELSE: + oldspat = curspat; + oldsave = savestack->av_fill; +#ifdef DEBUGGING + olddlevel = dlevel; +#endif + retstr = &sv_undef; + newsp = -2; + if (op->uop.ccop_true) { +#ifdef DEBUGGING + if (debug) { + debname[dlevel] = 'e'; + debdelim[dlevel] = '_'; + if (++dlevel >= dlmax) + deb_growlevel(); + } +#endif + newsp = cop_exec(op->uop.ccop_true,gimme && (opflags & COPf_TERM),sp); + st = stack->av_array; /* possibly reallocated */ + retstr = st[newsp]; + } + if (!goto_targ) + go_to = Nullch; + curspat = oldspat; + if (savestack->av_fill > oldsave) + leave_scope(oldsave); +#ifdef DEBUGGING + dlevel = olddlevel; +#endif + break; + case COP_BLOCK: + case COP_WHILE: + if (!(opflags & COPf_ONCE)) { + opflags |= COPf_ONCE; + if (++loop_ptr >= loop_max) { + loop_max += 128; + Renew(loop_stack, loop_max, struct loop); + } + loop_stack[loop_ptr].loop_label = op->cop_label; + loop_stack[loop_ptr].loop_sp = sp; +#ifdef DEBUGGING + if (debug & 4) { + deb("(Pushing label #%d %s)\n", + loop_ptr, op->cop_label ? op->cop_label : ""); + } +#endif + } +#ifdef JMPCLOBBER + opparm = op; +#endif + match = setjmp(loop_stack[loop_ptr].loop_env); + if (match) { + st = stack->av_array; /* possibly reallocated */ +#ifdef JMPCLOBBER + op = opparm; + opflags = op->cop_flags|COPf_ONCE; +#endif + if (savestack->av_fill > oldsave) + leave_scope(oldsave); + switch (match) { + default: + fatal("longjmp returned bad value (%d)",match); + case OP_LAST: /* not done unless go_to found */ + go_to = Nullch; + if (lastretstr) { + retstr = lastretstr; + newsp = -2; + } + else { + newsp = sp + lastsize; + retstr = st[newsp]; + } +#ifdef DEBUGGING + olddlevel = dlevel; +#endif + curspat = oldspat; + goto next_op; + case OP_NEXT: /* not done unless go_to found */ + go_to = Nullch; +#ifdef JMPCLOBBER + newsp = -2; + retstr = &sv_undef; +#endif + goto next_iter; + case OP_REDO: /* not done unless go_to found */ + go_to = Nullch; +#ifdef JMPCLOBBER + newsp = -2; + retstr = &sv_undef; +#endif + goto doit; + } + } + oldspat = curspat; + oldsave = savestack->av_fill; +#ifdef DEBUGGING + olddlevel = dlevel; +#endif + if (op->uop.ccop_true) { +#ifdef DEBUGGING + if (debug) { + debname[dlevel] = 't'; + debdelim[dlevel] = '_'; + if (++dlevel >= dlmax) + deb_growlevel(); + } +#endif + newsp = cop_exec(op->uop.ccop_true,gimme && (opflags & COPf_TERM),sp); + st = stack->av_array; /* possibly reallocated */ + if (newsp >= 0) + retstr = st[newsp]; + } + if (!goto_targ) { + go_to = Nullch; + goto next_iter; + } +#ifdef DEBUGGING + dlevel = olddlevel; +#endif + if (op->uop.ccop_alt) { +#ifdef DEBUGGING + if (debug) { + debname[dlevel] = 'a'; + debdelim[dlevel] = '_'; + if (++dlevel >= dlmax) + deb_growlevel(); + } +#endif + newsp = cop_exec(op->uop.ccop_alt,gimme && (opflags & COPf_TERM),sp); + st = stack->av_array; /* possibly reallocated */ + if (newsp >= 0) + retstr = st[newsp]; + } + if (goto_targ) + break; + go_to = Nullch; + goto finish_while; + } + op = op->cop_next; + if (op && op->cop_head == op) + /* reached end of while loop */ + return sp; /* targ isn't in this block */ + if (opflags & COPf_ONCE) { +#ifdef DEBUGGING + if (debug & 4) { + tmps = loop_stack[loop_ptr].loop_label; + deb("(Popping label #%d %s)\n",loop_ptr, + tmps ? tmps : "" ); + } +#endif + loop_ptr--; + } + goto tail_recursion_entry; + } + } +#endif + +#ifdef DEBUGGING + if (debug) { + if (debug & 2) { + deb("%s (%lx) r%lx t%lx a%lx n%lx cs%lx\n", + cop_name[op->cop_type],op,op->cop_expr, + op->uop.ccop_true,op->uop.ccop_alt,op->cop_next, + curspat); + } + debname[dlevel] = cop_name[op->cop_type][0]; + debdelim[dlevel] = '!'; + if (++dlevel >= dlmax) + deb_growlevel(); + } +#endif + + /* Here is some common optimization */ + + if (opflags & COPf_COND) { + switch (opflags & COPf_OPTIMIZE) { + + case COPo_FALSE: + retstr = op->cop_short; + newsp = -2; + match = FALSE; + if (opflags & COPf_NESURE) + goto maybe; + break; + case COPo_TRUE: + retstr = op->cop_short; + newsp = -2; + match = TRUE; + if (opflags & COPf_EQSURE) + goto flipmaybe; + break; + + case COPo_REG: + retstr = GV_STR(op->cop_stab); + newsp = -2; + match = SvTRUE(retstr); /* => retstr = retstr, c2 should fix */ + if (opflags & (match ? COPf_EQSURE : COPf_NESURE)) + goto flipmaybe; + break; + + case COPo_ANCHOR: /* /^pat/ optimization */ + if (multiline) { + if (*op->cop_short->sv_ptr && !(opflags & COPf_EQSURE)) + goto scanner; /* just unanchor it */ + else + break; /* must evaluate */ + } + match = 0; + goto strop; + + case COPo_STROP: /* string op optimization */ + match = 1; + strop: + retstr = GV_STR(op->cop_stab); + newsp = -2; +#ifndef I286 + if (*op->cop_short->sv_ptr == *SvPV(retstr) && + (match ? retstr->sv_cur == op->cop_slen - 1 : + retstr->sv_cur >= op->cop_slen) && + bcmp(op->cop_short->sv_ptr, SvPV(retstr), + op->cop_slen) == 0 ) { + if (opflags & COPf_EQSURE) { + if (sawampersand && (opflags & COPf_OPTIMIZE) != COPo_STROP) { + curspat = Nullpm; + if (leftstab) + sv_setpvn(GvSV(leftstab),"",0); + if (amperstab) + sv_setsv(GvSV(amperstab),op->cop_short); + if (rightstab) + sv_setpvn(GvSV(rightstab), + retstr->sv_ptr + op->cop_slen, + retstr->sv_cur - op->cop_slen); + } + if (op->cop_spat) + lastspat = op->cop_spat; + match = !(opflags & COPf_FIRSTNEG); + retstr = match ? &sv_yes : &sv_no; + goto flipmaybe; + } + } + else if (opflags & COPf_NESURE) { + match = opflags & COPf_FIRSTNEG; + retstr = match ? &sv_yes : &sv_no; + goto flipmaybe; + } +#else + { + char *zap1, *zap2, zap1c, zap2c; + int zaplen; + int lenok; + + zap1 = op->cop_short->sv_ptr; + zap2 = SvPV(retstr); + zap1c = *zap1; + zap2c = *zap2; + zaplen = op->cop_slen; + if (match) + lenok = (retstr->sv_cur == op->cop_slen - 1); + else + lenok = (retstr->sv_cur >= op->cop_slen); + if ((zap1c == zap2c) && lenok && (bcmp(zap1, zap2, zaplen) == 0)) { + if (opflags & COPf_EQSURE) { + if (sawampersand && + (opflags & COPf_OPTIMIZE) != COPo_STROP) { + curspat = Nullpm; + if (leftstab) + sv_setpvn(GvSV(leftstab),"",0); + if (amperstab) + sv_setsv(GvSV(amperstab),op->cop_short); + if (rightstab) + sv_setpvn(GvSV(rightstab), + retstr->sv_ptr + op->cop_slen, + retstr->sv_cur - op->cop_slen); + } + if (op->cop_spat) + lastspat = op->cop_spat; + match = !(opflags & COPf_FIRSTNEG); + retstr = match ? &sv_yes : &sv_no; + goto flipmaybe; + } + } + else if (opflags & COPf_NESURE) { + match = opflags & COPf_FIRSTNEG; + retstr = match ? &sv_yes : &sv_no; + goto flipmaybe; + } + } +#endif + break; /* must evaluate */ + + case COPo_SCAN: /* non-anchored search */ + scanner: + retstr = GV_STR(op->cop_stab); + newsp = -2; + if (retstr->sv_pok & SVp_STUDIED) + if (screamfirst[op->cop_short->sv_rare] >= 0) + tmps = screaminstr(retstr, op->cop_short); + else + tmps = Nullch; + else { + tmps = SvPV(retstr); /* make sure it's pok */ +#ifndef lint + tmps = fbm_instr((unsigned char*)tmps, + (unsigned char*)tmps + retstr->sv_cur, op->cop_short); +#endif + } + if (tmps) { + if (opflags & COPf_EQSURE) { + ++op->cop_short->sv_u.sv_useful; + if (sawampersand) { + curspat = Nullpm; + if (leftstab) + sv_setpvn(GvSV(leftstab),retstr->sv_ptr, + tmps - retstr->sv_ptr); + if (amperstab) + sv_setpvn(GvSV(amperstab), + tmps, op->cop_short->sv_cur); + if (rightstab) + sv_setpvn(GvSV(rightstab), + tmps + op->cop_short->sv_cur, + retstr->sv_cur - (tmps - retstr->sv_ptr) - + op->cop_short->sv_cur); + } + lastspat = op->cop_spat; + match = !(opflags & COPf_FIRSTNEG); + retstr = match ? &sv_yes : &sv_no; + goto flipmaybe; + } + else + hint = tmps; + } + else { + if (opflags & COPf_NESURE) { + ++op->cop_short->sv_u.sv_useful; + match = opflags & COPf_FIRSTNEG; + retstr = match ? &sv_yes : &sv_no; + goto flipmaybe; + } + } + if (--op->cop_short->sv_u.sv_useful < 0) { + opflags &= ~COPf_OPTIMIZE; + opflags |= COPo_EVAL; /* never try this optimization again */ + op->cop_flags = (opflags & ~COPf_ONCE); + } + break; /* must evaluate */ + + case COPo_NUMOP: /* numeric op optimization */ + retstr = GV_STR(op->cop_stab); + newsp = -2; + switch (op->cop_slen) { + case OP_EQ: + if (dowarn) { + if ((!retstr->sv_nok && !looks_like_number(retstr))) + warn("Possible use of == on string value"); + } + match = (SvNV(retstr) == op->cop_short->sv_u.sv_nv); + break; + case OP_NE: + match = (SvNV(retstr) != op->cop_short->sv_u.sv_nv); + break; + case OP_LT: + match = (SvNV(retstr) < op->cop_short->sv_u.sv_nv); + break; + case OP_LE: + match = (SvNV(retstr) <= op->cop_short->sv_u.sv_nv); + break; + case OP_GT: + match = (SvNV(retstr) > op->cop_short->sv_u.sv_nv); + break; + case OP_GE: + match = (SvNV(retstr) >= op->cop_short->sv_u.sv_nv); + break; + } + if (match) { + if (opflags & COPf_EQSURE) { + retstr = &sv_yes; + goto flipmaybe; + } + } + else if (opflags & COPf_NESURE) { + retstr = &sv_no; + goto flipmaybe; + } + break; /* must evaluate */ + + case COPo_INDGETS: /* while (<$foo>) */ + last_in_stab = newGV(SvPV(GV_STR(op->cop_stab)),TRUE); + if (!GvIO(last_in_stab)) + GvIO(last_in_stab) = newIO(); + goto dogets; + case COPo_GETS: /* really a while (<file>) */ + last_in_stab = op->cop_stab; + dogets: + fp = GvIO(last_in_stab)->ifp; + retstr = GvSV(defstab); + newsp = -2; + keepgoing: + if (fp && sv_gets(retstr, fp, 0)) { + if (*retstr->sv_ptr == '0' && retstr->sv_cur == 1) + match = FALSE; + else + match = TRUE; + GvIO(last_in_stab)->lines++; + } + else if (GvIO(last_in_stab)->flags & IOf_ARGV) { + if (!fp) + goto doeval; /* first time through */ + fp = nextargv(last_in_stab); + if (fp) + goto keepgoing; + (void)do_close(last_in_stab,FALSE); + GvIO(last_in_stab)->flags |= IOf_START; + retstr = &sv_undef; + match = FALSE; + } + else { + retstr = &sv_undef; + match = FALSE; + } + goto flipmaybe; + case COPo_EVAL: + break; + case COPo_UNFLIP: + while (tmps_max > tmps_base) { /* clean up after last oldeval */ + sv_free(tmps_list[tmps_max]); + tmps_list[tmps_max--] = Nullsv; + } + newsp = oldeval(Nullsv,op->cop_expr,gimme && (opflags & COPf_TERM),sp); + st = stack->av_array; /* possibly reallocated */ + retstr = st[newsp]; + match = SvTRUE(retstr); + if (op->cop_expr->arg_type == OP_FLIP) /* undid itself? */ + opflags = copyopt(op,op->cop_expr[3].arg_ptr.arg_op); + goto maybe; + case COPo_CHOP: + retstr = GvSV(op->cop_stab); + newsp = -2; + match = (retstr->sv_cur != 0); + tmps = SvPV(retstr); + tmps += retstr->sv_cur - match; + sv_setpvn(&strchop,tmps,match); + *tmps = '\0'; + retstr->sv_nok = 0; + retstr->sv_cur = tmps - retstr->sv_ptr; + SvSETMAGIC(retstr); + retstr = &strchop; + goto flipmaybe; + case COPo_ARRAY: + match = op->cop_short->sv_u.sv_useful; /* just to get register */ + + if (match < 0) { /* first time through here? */ + ar = GvAVn(op->cop_expr[1].arg_ptr.arg_stab); + aryoptsave = savestack->av_fill; + save_sptr(&GvSV(op->cop_stab)); + save_long(&op->cop_short->sv_u.sv_useful); + } + else { + ar = GvAV(op->cop_expr[1].arg_ptr.arg_stab); + if (op->cop_type != COP_WHILE && savestack->av_fill > firstsave) + leave_scope(firstsave); + } + + if (match >= ar->av_fill) { /* we're in LAST, probably */ + if (match < 0 && /* er, probably not... */ + savestack->av_fill > aryoptsave) + leave_scope(aryoptsave); + retstr = &sv_undef; + op->cop_short->sv_u.sv_useful = -1; /* actually redundant */ + match = FALSE; + } + else { + match++; + if (!(retstr = ar->av_array[match])) + retstr = av_fetch(ar,match,TRUE); + GvSV(op->cop_stab) = retstr; + op->cop_short->sv_u.sv_useful = match; + match = TRUE; + } + newsp = -2; + goto maybe; + case COPo_D1: + break; + case COPo_D0: + if (DBsingle->sv_u.sv_nv != 0) + break; + if (DBsignal->sv_u.sv_nv != 0) + break; + if (DBtrace->sv_u.sv_nv != 0) + break; + goto next_op; + } + + /* we have tried to make this normal case as abnormal as possible */ + + doeval: + if (gimme == G_ARRAY) { + lastretstr = Nullsv; + lastspbase = sp; + lastsize = newsp - sp; + if (lastsize < 0) + lastsize = 0; + } + else + lastretstr = retstr; + while (tmps_max > tmps_base) { /* clean up after last oldeval */ + sv_free(tmps_list[tmps_max]); + tmps_list[tmps_max--] = Nullsv; + } + newsp = oldeval(Nullsv,op->cop_expr, + gimme && (opflags & COPf_TERM) && op->cop_type == COP_EXPR && + !op->uop.acop_expr, + sp); + st = stack->av_array; /* possibly reallocated */ + retstr = st[newsp]; + if (newsp > sp && retstr) + match = SvTRUE(retstr); + else + match = FALSE; + goto maybe; + + /* if flipflop was true, flop it */ + + flipmaybe: + if (match && opflags & COPf_FLIP) { + while (tmps_max > tmps_base) { /* clean up after last oldeval */ + sv_free(tmps_list[tmps_max]); + tmps_list[tmps_max--] = Nullsv; + } + if (op->cop_expr->arg_type == OP_FLOP) { /* currently toggled? */ + newsp = oldeval(Nullsv,op->cop_expr,G_SCALAR,sp);/*let oldeval undo it*/ + opflags = copyopt(op,op->cop_expr[3].arg_ptr.arg_op); + } + else { + newsp = oldeval(Nullsv,op->cop_expr,G_SCALAR,sp);/* let oldeval do it */ + if (op->cop_expr->arg_type == OP_FLOP) /* still toggled? */ + opflags = copyopt(op,op->cop_expr[4].arg_ptr.arg_op); + } + } + else if (opflags & COPf_FLIP) { + if (op->cop_expr->arg_type == OP_FLOP) { /* currently toggled? */ + match = TRUE; /* force on */ + } + } + + /* at this point, match says whether our expression was true */ + + maybe: + if (opflags & COPf_INVERT) + match = !match; + if (!match) + goto next_op; + } +#ifdef TAINT + tainted = 0; /* modifier doesn't affect regular expression */ +#endif |