X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=toke.c;h=e7e217473ea0b19e09cbc6043f968a19e4d878af;hb=030866aa8d0911636ef2210b710f544fd2c85c8e;hp=ea95f3a63dd54cb3f0f8ca92d0824774494769e8;hpb=bf49b057b09bec860588a9b554c3a77683394722;p=p5sagit%2Fp5-mst-13.2.git diff --git a/toke.c b/toke.c index ea95f3a..e7e2174 100644 --- a/toke.c +++ b/toke.c @@ -28,8 +28,9 @@ static char ident_too_long[] = "Identifier too long"; static void restore_rsfp(pTHXo_ void *f); -static void restore_expect(pTHXo_ void *e); -static void restore_lex_expect(pTHXo_ void *e); + +#define XFAKEBRACK 128 +#define XENUMMASK 127 #define UTF (PL_hints & HINT_UTF8) /* @@ -104,7 +105,7 @@ int* yychar_pointer = NULL; #ifdef CLINE #undef CLINE #endif -#define CLINE (PL_copline = (PL_curcop->cop_line < PL_copline ? PL_curcop->cop_line : PL_copline)) +#define CLINE (PL_copline = (CopLINE(PL_curcop) < PL_copline ? CopLINE(PL_curcop) : PL_copline)) /* * Convenience functions to return different tokens and prime the @@ -120,7 +121,7 @@ int* yychar_pointer = NULL; * LOOPX : loop exiting command (goto, last, dump, etc) * FTST : file test operator * FUN0 : zero-argument function - * FUN1 : not used + * FUN1 : not used, except for not, which isn't a UNIOP * BOop : bitwise or or xor * BAop : bitwise and * SHop : shift operator @@ -303,15 +304,36 @@ S_depcom(pTHX) * utf16-to-utf8-reversed. */ -#ifdef WIN32 +#ifdef PERL_CR_FILTER +static void +strip_return(SV *sv) +{ + register char *s = SvPVX(sv); + register char *e = s + SvCUR(sv); + /* outer loop optimized to do nothing if there are no CR-LFs */ + while (s < e) { + if (*s++ == '\r' && *s == '\n') { + /* hit a CR-LF, need to copy the rest */ + register char *d = s - 1; + *d++ = *s++; + while (s < e) { + if (*s == '\r' && s[1] == '\n') + s++; + *d++ = *s++; + } + SvCUR(sv) -= s - d; + return; + } + } +} STATIC I32 -S_win32_textfilter(pTHX_ int idx, SV *sv, int maxlen) +S_cr_textfilter(pTHX_ int idx, SV *sv, int maxlen) { - I32 count = FILTER_READ(idx+1, sv, maxlen); - if (count > 0 && !maxlen) - win32_strip_return(sv); - return count; + I32 count = FILTER_READ(idx+1, sv, maxlen); + if (count > 0 && !maxlen) + strip_return(sv); + return count; } #endif @@ -360,13 +382,12 @@ Perl_lex_start(pTHX_ SV *line) SAVEI32(PL_lex_dojoin); SAVEI32(PL_lex_brackets); - SAVEI32(PL_lex_fakebrack); SAVEI32(PL_lex_casemods); SAVEI32(PL_lex_starts); SAVEI32(PL_lex_state); - SAVESPTR(PL_lex_inpat); + SAVEVPTR(PL_lex_inpat); SAVEI32(PL_lex_inwhat); - SAVEI16(PL_curcop->cop_line); + SAVECOPLINE(PL_curcop); SAVEPPTR(PL_bufptr); SAVEPPTR(PL_bufend); SAVEPPTR(PL_oldbufptr); @@ -375,19 +396,18 @@ Perl_lex_start(pTHX_ SV *line) SAVESPTR(PL_linestr); SAVEPPTR(PL_lex_brackstack); SAVEPPTR(PL_lex_casestack); - SAVEDESTRUCTOR(restore_rsfp, PL_rsfp); + SAVEDESTRUCTOR_X(restore_rsfp, PL_rsfp); SAVESPTR(PL_lex_stuff); SAVEI32(PL_lex_defer); SAVEI32(PL_sublex_info.sub_inwhat); SAVESPTR(PL_lex_repl); - SAVEDESTRUCTOR(restore_expect, PL_tokenbuf + PL_expect); /* encode as pointer */ - SAVEDESTRUCTOR(restore_lex_expect, PL_tokenbuf + PL_expect); + SAVEINT(PL_expect); + SAVEINT(PL_lex_expect); PL_lex_state = LEX_NORMAL; PL_lex_defer = 0; PL_expect = XSTATE; PL_lex_brackets = 0; - PL_lex_fakebrack = 0; New(899, PL_lex_brackstack, 120, char); New(899, PL_lex_casestack, 12, char); SAVEFREEPV(PL_lex_brackstack); @@ -434,7 +454,7 @@ Perl_lex_end(pTHX) * S_incline * This subroutine has nothing to do with tilting, whether at windmills * or pinball tables. Its name is short for "increment line". It - * increments the current line number in PL_curcop->cop_line and checks + * increments the current line number in CopLINE(PL_curcop) and checks * to see whether the line starts with a comment of the form * # line 500 "foo.pm" * If so, it sets the current line number and file to the values in the comment. @@ -449,7 +469,7 @@ S_incline(pTHX_ char *s) char ch; int sawline = 0; - PL_curcop->cop_line++; + CopLINE_inc(PL_curcop); if (*s++ != '#') return; while (*s == ' ' || *s == '\t') s++; @@ -474,11 +494,9 @@ S_incline(pTHX_ char *s) ch = *t; *t = '\0'; if (t - s > 0) - PL_curcop->cop_filegv = gv_fetchfile(s); - else - PL_curcop->cop_filegv = gv_fetchfile(PL_origfilename); + CopFILE_set(PL_curcop, s); *t = ch; - PL_curcop->cop_line = atoi(n)-1; + CopLINE_set(PL_curcop, atoi(n)-1); } /* @@ -590,7 +608,7 @@ S_skipspace(pTHX_ register char *s) sv_upgrade(sv, SVt_PVMG); sv_setpvn(sv,PL_bufptr,PL_bufend-PL_bufptr); - av_store(GvAV(PL_curcop->cop_filegv),(I32)PL_curcop->cop_line,sv); + av_store(CopFILEAV(PL_curcop),(I32)CopLINE(PL_curcop),sv); } } } @@ -673,7 +691,7 @@ S_uni(pTHX_ I32 f, char *s) */ STATIC I32 -S_lop(pTHX_ I32 f, expectation x, char *s) +S_lop(pTHX_ I32 f, int x, char *s) { dTHR; yylval.ival = f; @@ -804,13 +822,12 @@ S_force_version(pTHX_ char *s) s = skipspace(s); - /* default VERSION number -- GBARR */ - - if(isDIGIT(*s)) { - char *d; - int c; - for( d=s, c = 1; isDIGIT(*d) || *d == '_' || (*d == '.' && c--); d++); - if((*d == ';' || isSPACE(*d)) && *(skipspace(d)) != ',') { + if (isDIGIT(*s) || (*s == 'v' && isDIGIT(s[1]))) { + char *d = s; + if (*d == 'v') + d++; + for (; isDIGIT(*d) || *d == '_' || *d == '.'; d++); + if ((*d == ';' || isSPACE(*d)) && *(skipspace(d)) != ',') { s = scan_num(s); /* real VERSION number -- GBARR */ version = yylval.opval; @@ -963,13 +980,12 @@ S_sublex_push(pTHX) PL_lex_state = PL_sublex_info.super_state; SAVEI32(PL_lex_dojoin); SAVEI32(PL_lex_brackets); - SAVEI32(PL_lex_fakebrack); SAVEI32(PL_lex_casemods); SAVEI32(PL_lex_starts); SAVEI32(PL_lex_state); - SAVESPTR(PL_lex_inpat); + SAVEVPTR(PL_lex_inpat); SAVEI32(PL_lex_inwhat); - SAVEI16(PL_curcop->cop_line); + SAVECOPLINE(PL_curcop); SAVEPPTR(PL_bufptr); SAVEPPTR(PL_oldbufptr); SAVEPPTR(PL_oldoldbufptr); @@ -988,7 +1004,6 @@ S_sublex_push(pTHX) PL_lex_dojoin = FALSE; PL_lex_brackets = 0; - PL_lex_fakebrack = 0; New(899, PL_lex_brackstack, 120, char); New(899, PL_lex_casestack, 12, char); SAVEFREEPV(PL_lex_brackstack); @@ -997,7 +1012,7 @@ S_sublex_push(pTHX) *PL_lex_casestack = '\0'; PL_lex_starts = 0; PL_lex_state = LEX_INTERPCONCAT; - PL_curcop->cop_line = PL_multi_start; + CopLINE_set(PL_curcop, PL_multi_start); PL_lex_inwhat = PL_sublex_info.sub_inwhat; if (PL_lex_inwhat == OP_MATCH || PL_lex_inwhat == OP_QR || PL_lex_inwhat == OP_SUBST) @@ -1036,7 +1051,6 @@ S_sublex_done(pTHX) SAVEFREESV(PL_linestr); PL_lex_dojoin = FALSE; PL_lex_brackets = 0; - PL_lex_fakebrack = 0; PL_lex_casemods = 0; *PL_lex_casestack = '\0'; PL_lex_starts = 0; @@ -1153,7 +1167,7 @@ S_scan_const(pTHX_ char *start) ? (PL_sublex_info.sub_op->op_private & (PL_lex_repl ? OPpTRANS_FROM_UTF : OPpTRANS_TO_UTF)) : UTF; - char *leaveit = /* set of acceptably-backslashed characters */ + const char *leaveit = /* set of acceptably-backslashed characters */ PL_lex_inpat ? "\\.^$@AGZdDwWsSbBpPXC+*?|()-nrtfeaxcz0123456789[{]} \t\n\r\f\v#" : ""; @@ -1330,7 +1344,7 @@ S_scan_const(pTHX_ char *start) /* \132 indicates an octal constant */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': - *d++ = scan_oct(s, 3, &len); + *d++ = (char)scan_oct(s, 3, &len); s += len; continue; @@ -1352,7 +1366,7 @@ S_scan_const(pTHX_ char *start) } /* note: utf always shorter than hex */ d = (char*)uv_to_utf8((U8*)d, - scan_hex(s + 1, e - s - 1, &len)); + (UV)scan_hex(s + 1, e - s - 1, &len)); s = e + 1; } else { @@ -1368,7 +1382,7 @@ S_scan_const(pTHX_ char *start) if (ckWARN(WARN_UTF8)) Perl_warner(aTHX_ WARN_UTF8, "\\x%.*s will produce malformed UTF-8 character; use \\x{%.*s} for that", - len,s,len,s); + (int)len,s,(int)len,s); } *d++ = (char)uv; } @@ -1764,7 +1778,8 @@ S_incl_perldb(pTHX) * store private buffers and state information. * * The supplied datasv parameter is upgraded to a PVIO type - * and the IoDIRP field is used to store the function pointer. + * and the IoDIRP field is used to store the function pointer, + * and IOf_FAKE_DIRP is enabled on datasv to mark this as such. * Note that IoTOP_NAME, IoFMT_NAME, IoBOTTOM_NAME, if set for * private use must be set using malloc'd pointers. */ @@ -1772,10 +1787,9 @@ S_incl_perldb(pTHX) SV * Perl_filter_add(pTHX_ filter_t funcp, SV *datasv) { - if (!funcp){ /* temporary handy debugging hack to be deleted */ - PL_filter_debug = atoi((char*)datasv); - return NULL; - } + if (!funcp) + return Nullsv; + if (!PL_rsfp_filters) PL_rsfp_filters = newAV(); if (!datasv) @@ -1783,12 +1797,9 @@ Perl_filter_add(pTHX_ filter_t funcp, SV *datasv) if (!SvUPGRADE(datasv, SVt_PVIO)) Perl_die(aTHX_ "Can't upgrade filter_add data to SVt_PVIO"); IoDIRP(datasv) = (DIR*)funcp; /* stash funcp into spare field */ -#ifdef DEBUGGING - if (PL_filter_debug) { - STRLEN n_a; - Perl_warn(aTHX_ "filter_add func %p (%s)", funcp, SvPV(datasv, n_a)); - } -#endif /* DEBUGGING */ + IoFLAGS(datasv) |= IOf_FAKE_DIRP; + DEBUG_P(PerlIO_printf(Perl_debug_log, "filter_add func %p (%s)\n", + funcp, SvPV_nolen(datasv))); av_unshift(PL_rsfp_filters, 1); av_store(PL_rsfp_filters, 0, datasv) ; return(datasv); @@ -1799,15 +1810,15 @@ Perl_filter_add(pTHX_ filter_t funcp, SV *datasv) void Perl_filter_del(pTHX_ filter_t funcp) { -#ifdef DEBUGGING - if (PL_filter_debug) - Perl_warn(aTHX_ "filter_del func %p", funcp); -#endif /* DEBUGGING */ + SV *datasv; + DEBUG_P(PerlIO_printf(Perl_debug_log, "filter_del func %p", funcp)); if (!PL_rsfp_filters || AvFILLp(PL_rsfp_filters)<0) return; /* if filter is on top of stack (usual case) just pop it off */ - if (IoDIRP(FILTER_DATA(AvFILLp(PL_rsfp_filters))) == (DIR*)funcp){ - IoDIRP(FILTER_DATA(AvFILLp(PL_rsfp_filters))) = NULL; + datasv = FILTER_DATA(AvFILLp(PL_rsfp_filters)); + if (IoDIRP(datasv) == (DIR*)funcp) { + IoFLAGS(datasv) &= ~IOf_FAKE_DIRP; + IoDIRP(datasv) = (DIR*)NULL; sv_free(av_pop(PL_rsfp_filters)); return; @@ -1832,10 +1843,8 @@ Perl_filter_read(pTHX_ int idx, SV *buf_sv, int maxlen) if (idx > AvFILLp(PL_rsfp_filters)){ /* Any more filters? */ /* Provide a default input filter to make life easy. */ /* Note that we append to the line. This is handy. */ -#ifdef DEBUGGING - if (PL_filter_debug) - Perl_warn(aTHX_ "filter_read %d: from rsfp\n", idx); -#endif /* DEBUGGING */ + DEBUG_P(PerlIO_printf(Perl_debug_log, + "filter_read %d: from rsfp\n", idx)); if (maxlen) { /* Want a block */ int len ; @@ -1863,21 +1872,16 @@ Perl_filter_read(pTHX_ int idx, SV *buf_sv, int maxlen) } /* Skip this filter slot if filter has been deleted */ if ( (datasv = FILTER_DATA(idx)) == &PL_sv_undef){ -#ifdef DEBUGGING - if (PL_filter_debug) - Perl_warn(aTHX_ "filter_read %d: skipped (filter deleted)\n", idx); -#endif /* DEBUGGING */ + DEBUG_P(PerlIO_printf(Perl_debug_log, + "filter_read %d: skipped (filter deleted)\n", + idx)); return FILTER_READ(idx+1, buf_sv, maxlen); /* recurse */ } /* Get function pointer hidden within datasv */ funcp = (filter_t)IoDIRP(datasv); -#ifdef DEBUGGING - if (PL_filter_debug) { - STRLEN n_a; - Perl_warn(aTHX_ "filter_read %d: via function %p (%s)\n", - idx, funcp, SvPV(datasv,n_a)); - } -#endif /* DEBUGGING */ + DEBUG_P(PerlIO_printf(Perl_debug_log, + "filter_read %d: via function %p (%s)\n", + idx, funcp, SvPV_nolen(datasv))); /* Call function. The function is expected to */ /* call "FILTER_READ(idx+1, buf_sv)" first. */ /* Return: <0:error, =0:eof, >0:not eof */ @@ -1887,9 +1891,9 @@ Perl_filter_read(pTHX_ int idx, SV *buf_sv, int maxlen) STATIC char * S_filter_gets(pTHX_ register SV *sv, register PerlIO *fp, STRLEN append) { -#ifdef WIN32FILTER +#ifdef PERL_CR_FILTER if (!PL_rsfp_filters) { - filter_add(win32_textfilter,NULL); + filter_add(S_cr_textfilter,NULL); } #endif if (PL_rsfp_filters) { @@ -1972,6 +1976,10 @@ Perl_yylex(pTHX) */ if (PL_in_my) { if (PL_in_my == KEY_our) { /* "our" is merely analogous to "my" */ + if (strchr(PL_tokenbuf,':')) + yyerror(Perl_form(aTHX_ "No package name allowed for " + "variable %s in \"our\"", + PL_tokenbuf)); tmp = pad_allocmy(PL_tokenbuf); } else { @@ -2009,15 +2017,19 @@ Perl_yylex(pTHX) } #endif /* USE_THREADS */ if ((tmp = pad_findmy(PL_tokenbuf)) != NOT_IN_PAD) { + SV *namesv = AvARRAY(PL_comppad_name)[tmp]; /* might be an "our" variable" */ - if (SvFLAGS(AvARRAY(PL_comppad_name)[tmp]) & SVpad_OUR) { + if (SvFLAGS(namesv) & SVpad_OUR) { /* build ops for a bareword */ - yylval.opval = (OP*)newSVOP(OP_CONST, 0, newSVpv(PL_tokenbuf+1, 0)); + SV *sym = newSVpv(HvNAME(GvSTASH(namesv)),0); + sv_catpvn(sym, "::", 2); + sv_catpv(sym, PL_tokenbuf+1); + yylval.opval = (OP*)newSVOP(OP_CONST, 0, sym); yylval.opval->op_private = OPpCONST_ENTERED; - gv_fetchpv(PL_tokenbuf+1, + gv_fetchpv(SvPVX(sym), (PL_in_eval - ? (GV_ADDMULTI | GV_ADDINEVAL | GV_ADDOUR) - : GV_ADDOUR + ? (GV_ADDMULTI | GV_ADDINEVAL) + : TRUE ), ((PL_tokenbuf[0] == '$') ? SVt_PV : (PL_tokenbuf[0] == '@') ? SVt_PVAV @@ -2345,7 +2357,7 @@ Perl_yylex(pTHX) sv_upgrade(sv, SVt_PVMG); sv_setsv(sv,PL_linestr); - av_store(GvAV(PL_curcop->cop_filegv),(I32)PL_curcop->cop_line,sv); + av_store(CopFILEAV(PL_curcop),(I32)CopLINE(PL_curcop),sv); } goto retry; } @@ -2394,10 +2406,10 @@ Perl_yylex(pTHX) sv_upgrade(sv, SVt_PVMG); sv_setsv(sv,PL_linestr); - av_store(GvAV(PL_curcop->cop_filegv),(I32)PL_curcop->cop_line,sv); + av_store(CopFILEAV(PL_curcop),(I32)CopLINE(PL_curcop),sv); } PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr); - if (PL_curcop->cop_line == 1) { + if (CopLINE(PL_curcop) == 1) { while (s < PL_bufend && isSPACE(*s)) s++; if (*s == ':' && s[1] != ':') /* for csh execing sh scripts */ @@ -2435,7 +2447,7 @@ Perl_yylex(pTHX) */ SV *x = GvSV(gv_fetchpv("\030", TRUE, SVt_PV)); assert(SvPOK(x) || SvGMAGICAL(x)); - if (sv_eq(x, GvSV(PL_curcop->cop_filegv))) { + if (sv_eq(x, CopFILESV(PL_curcop))) { sv_setpvn(x, ipath, ipathend - ipath); SvSETMAGIC(x); } @@ -2739,6 +2751,21 @@ Perl_yylex(pTHX) attrs = Nullop; while (isIDFIRST_lazy(s)) { d = scan_word(s, PL_tokenbuf, sizeof PL_tokenbuf, FALSE, &len); + if (isLOWER(*s) && (tmp = keyword(PL_tokenbuf, len))) { + if (tmp < 0) tmp = -tmp; + switch (tmp) { + case KEY_or: + case KEY_and: + case KEY_for: + case KEY_unless: + case KEY_if: + case KEY_while: + case KEY_until: + goto got_attrs; + default: + break; + } + } if (*d == '(') { d = scan_str(d,TRUE,TRUE); if (!d) { @@ -2770,11 +2797,13 @@ Perl_yylex(pTHX) newSVpvn(s, len))); } s = skipspace(d); - while (*s == ',') + if (*s == ':' && s[1] != ':') s = skipspace(s+1); + else if (s == d) + break; /* require real whitespace or :'s */ } - tmp = (PL_expect == XOPERATOR ? '=' : '{'); /*'}' for vi */ - if (*s != ';' && *s != tmp) { + tmp = (PL_expect == XOPERATOR ? '=' : '{'); /*'}(' for vi */ + if (*s != ';' && *s != tmp && (tmp != '=' || *s != ')')) { char q = ((*s == '\'') ? '"' : '\''); /* If here for an expression, and parsed no attrs, back off. */ if (tmp == '=' && !attrs) { @@ -2794,6 +2823,7 @@ Perl_yylex(pTHX) op_free(attrs); OPERATOR(':'); } + got_attrs: if (attrs) { PL_nextval[PL_nexttoke].opval = attrs; force_next(THING); @@ -2809,8 +2839,8 @@ Perl_yylex(pTHX) PL_expect = XTERM; TOKEN('('); case ';': - if (PL_curcop->cop_line < PL_copline) - PL_copline = PL_curcop->cop_line; + if (CopLINE(PL_curcop) < PL_copline) + PL_copline = CopLINE(PL_curcop); tmp = *s++; OPERATOR(tmp); case ')': @@ -2923,7 +2953,8 @@ Perl_yylex(pTHX) if (++t < PL_bufend && (!isALNUM(*t) || ((*t == 'q' || *t == 'x') && ++t < PL_bufend - && !isALNUM(*t)))) { + && !isALNUM(*t)))) + { char *tmps; char open, close, term; I32 brackets = 1; @@ -2954,8 +2985,10 @@ Perl_yylex(pTHX) } t++; } - else if (isIDFIRST_lazy(s)) { - for (t++; t < PL_bufend && isALNUM_lazy(t); t++) ; + else if (isALNUM_lazy(t)) { + t += UTF8SKIP(t); + while (t < PL_bufend && isALNUM_lazy(t)) + t += UTF8SKIP(t); } while (t < PL_bufend && isSPACE(*t)) t++; @@ -2973,7 +3006,7 @@ Perl_yylex(pTHX) } break; } - yylval.ival = PL_curcop->cop_line; + yylval.ival = CopLINE(PL_curcop); if (isSPACE(*s) || *s == '#') PL_copline = NOLINE; /* invalidate current command line number */ TOKEN('{'); @@ -2988,7 +3021,8 @@ Perl_yylex(pTHX) PL_lex_formbrack = 0; if (PL_lex_state == LEX_INTERPNORMAL) { if (PL_lex_brackets == 0) { - if (PL_lex_fakebrack) { + if (PL_expect & XFAKEBRACK) { + PL_expect &= XENUMMASK; PL_lex_state = LEX_INTERPEND; PL_bufptr = s; return yylex(); /* ignore fake brackets */ @@ -2999,9 +3033,9 @@ Perl_yylex(pTHX) PL_lex_state = LEX_INTERPEND; } } - if (PL_lex_brackets < PL_lex_fakebrack) { + if (PL_expect & XFAKEBRACK) { + PL_expect &= XENUMMASK; PL_bufptr = s; - PL_lex_fakebrack = 0; return yylex(); /* ignore fake brackets */ } force_next('}'); @@ -3014,9 +3048,9 @@ Perl_yylex(pTHX) s--; if (PL_expect == XOPERATOR) { if (ckWARN(WARN_SEMICOLON) && isIDFIRST_lazy(s) && PL_bufptr == PL_linestart) { - PL_curcop->cop_line--; + CopLINE_dec(PL_curcop); Perl_warner(aTHX_ WARN_SEMICOLON, PL_warn_nosemi); - PL_curcop->cop_line++; + CopLINE_inc(PL_curcop); } BAop(OP_BIT_AND); } @@ -3409,6 +3443,19 @@ Perl_yylex(pTHX) no_op("Backslash",s); OPERATOR(REFGEN); + case 'v': + if (isDIGIT(s[1]) && PL_expect == XTERM) { + char *start = s; + start++; + start++; + while (isDIGIT(*start)) + start++; + if (*start == '.' && isDIGIT(start[1])) { + s = scan_num(s); + TERM(THING); + } + } + goto keylookup; case 'x': if (isDIGIT(s[1]) && PL_expect == XOPERATOR) { s++; @@ -3438,7 +3485,7 @@ Perl_yylex(pTHX) case 's': case 'S': case 't': case 'T': case 'u': case 'U': - case 'v': case 'V': + case 'V': case 'w': case 'W': case 'X': case 'y': case 'Y': @@ -3512,6 +3559,7 @@ Perl_yylex(pTHX) } else if (gv && !gvp && -tmp==KEY_lock /* XXX generalizable kludge */ + && GvCVu(gv) && !hv_fetch(GvHVn(PL_incgv), "Thread.pm", 9, FALSE)) { tmp = 0; /* any sub overrides "weak" keyword */ @@ -3550,9 +3598,9 @@ Perl_yylex(pTHX) if (PL_expect == XOPERATOR) { if (PL_bufptr == PL_linestart) { - PL_curcop->cop_line--; + CopLINE_dec(PL_curcop); Perl_warner(aTHX_ WARN_SEMICOLON, PL_warn_nosemi); - PL_curcop->cop_line++; + CopLINE_inc(PL_curcop); } else no_op("Bareword",s); @@ -3739,17 +3787,12 @@ Perl_yylex(pTHX) case KEY___FILE__: yylval.opval = (OP*)newSVOP(OP_CONST, 0, - newSVsv(GvSV(PL_curcop->cop_filegv))); + newSVpv(CopFILE(PL_curcop),0)); TERM(THING); case KEY___LINE__: -#ifdef IV_IS_QUAD - yylval.opval = (OP*)newSVOP(OP_CONST, 0, - Perl_newSVpvf(aTHX_ "%" PERL_PRId64, (IV)PL_curcop->cop_line)); -#else yylval.opval = (OP*)newSVOP(OP_CONST, 0, - Perl_newSVpvf(aTHX_ "%ld", (long)PL_curcop->cop_line)); -#endif + Perl_newSVpvf(aTHX_ "%"IVdf, (IV)CopLINE(PL_curcop))); TERM(THING); case KEY___PACKAGE__: @@ -3787,6 +3830,28 @@ Perl_yylex(pTHX) IoTYPE(GvIOp(gv)) = '-'; else IoTYPE(GvIOp(gv)) = '<'; +#if defined(WIN32) && !defined(PERL_TEXTMODE_SCRIPTS) + /* if the script was opened in binmode, we need to revert + * it to text mode for compatibility; but only iff it has CRs + * XXX this is a questionable hack at best. */ + if (PL_bufend-PL_bufptr > 2 + && PL_bufend[-1] == '\n' && PL_bufend[-2] == '\r') + { + Off_t loc = 0; + if (IoTYPE(GvIOp(gv)) == '<') { + loc = PerlIO_tell(PL_rsfp); + (void)PerlIO_seek(PL_rsfp, 0L, 0); + } + if (PerlLIO_setmode(PerlIO_fileno(PL_rsfp), O_TEXT) != -1) { +#if defined(__BORLANDC__) + /* XXX see note in do_binmode() */ + ((FILE*)PL_rsfp)->flags |= _F_BIN; +#endif + if (loc > 0) + PerlIO_seek(PL_rsfp, loc, 0); + } + } +#endif PL_rsfp = Nullfp; } goto fake_eof; @@ -3795,8 +3860,9 @@ Perl_yylex(pTHX) case KEY_AUTOLOAD: case KEY_DESTROY: case KEY_BEGIN: - case KEY_END: + case KEY_CHECK: case KEY_INIT: + case KEY_END: if (PL_expect == XSTATE) { s = PL_bufptr; goto really_sub; @@ -3863,8 +3929,10 @@ Perl_yylex(pTHX) case KEY_crypt: #ifdef FCRYPT - if (!PL_cryptseen++) + if (!PL_cryptseen) { + PL_cryptseen = TRUE; init_des(); + } #endif LOP(OP_CRYPT,XTERM); @@ -3925,7 +3993,7 @@ Perl_yylex(pTHX) PREBLOCK(ELSE); case KEY_elsif: - yylval.ival = PL_curcop->cop_line; + yylval.ival = CopLINE(PL_curcop); OPERATOR(ELSIF); case KEY_eq: @@ -3975,7 +4043,7 @@ Perl_yylex(pTHX) case KEY_for: case KEY_foreach: - yylval.ival = PL_curcop->cop_line; + yylval.ival = CopLINE(PL_curcop); s = skipspace(s); if (PL_expect == XSTATE && isIDFIRST_lazy(s)) { char *p = s; @@ -4018,7 +4086,7 @@ Perl_yylex(pTHX) Rop(OP_SGE); case KEY_grep: - LOP(OP_GREPSTART, *s == '(' ? XTERM : XREF); + LOP(OP_GREPSTART, XREF); case KEY_goto: s = force_word(s,WORD,TRUE,FALSE,FALSE); @@ -4113,7 +4181,7 @@ Perl_yylex(pTHX) UNI(OP_HEX); case KEY_if: - yylval.ival = PL_curcop->cop_line; + yylval.ival = CopLINE(PL_curcop); OPERATOR(IF); case KEY_index: @@ -4180,7 +4248,7 @@ Perl_yylex(pTHX) TERM(sublex_start()); case KEY_map: - LOP(OP_MAPSTART, *s == '(' ? XTERM : XREF); + LOP(OP_MAPSTART, XREF); case KEY_mkdir: LOP(OP_MKDIR,XTERM); @@ -4232,7 +4300,10 @@ Perl_yylex(pTHX) OPERATOR(USE); case KEY_not: - OPERATOR(NOTOP); + if (*s == '(' || (s = skipspace(s), *s == '(')) + FUN1(OP_NOT); + else + OPERATOR(NOTOP); case KEY_open: s = skipspace(s); @@ -4370,12 +4441,18 @@ Perl_yylex(pTHX) OLDLOP(OP_RETURN); case KEY_require: - *PL_tokenbuf = '\0'; - s = force_word(s,WORD,TRUE,TRUE,FALSE); - if (isIDFIRST_lazy(PL_tokenbuf)) - gv_stashpvn(PL_tokenbuf, strlen(PL_tokenbuf), TRUE); - else if (*s == '<') - yyerror("<> should be quotes"); + s = skipspace(s); + if (isDIGIT(*s) || (*s == 'v' && isDIGIT(s[1]))) { + s = force_version(s); + } + else { + *PL_tokenbuf = '\0'; + s = force_word(s,WORD,TRUE,TRUE,FALSE); + if (isIDFIRST_lazy(PL_tokenbuf)) + gv_stashpvn(PL_tokenbuf, strlen(PL_tokenbuf), TRUE); + else if (*s == '<') + yyerror("<> should be quotes"); + } UNI(OP_REQUIRE); case KEY_reset: @@ -4545,7 +4622,6 @@ Perl_yylex(pTHX) UNI(OP_STAT); case KEY_study: - PL_sawstudy++; UNI(OP_STUDY); case KEY_substr: @@ -4703,11 +4779,11 @@ Perl_yylex(pTHX) UNI(OP_UNTIE); case KEY_until: - yylval.ival = PL_curcop->cop_line; + yylval.ival = CopLINE(PL_curcop); OPERATOR(UNTIL); case KEY_unless: - yylval.ival = PL_curcop->cop_line; + yylval.ival = CopLINE(PL_curcop); OPERATOR(UNLESS); case KEY_unlink: @@ -4738,9 +4814,9 @@ Perl_yylex(pTHX) if (PL_expect != XSTATE) yyerror("\"use\" not allowed in expression"); s = skipspace(s); - if(isDIGIT(*s)) { + if (isDIGIT(*s) || (*s == 'v' && isDIGIT(s[1]))) { s = force_version(s); - if(*s == ';' || (s = skipspace(s), *s == ';')) { + if (*s == ';' || (s = skipspace(s), *s == ';')) { PL_nextval[PL_nexttoke].opval = Nullop; force_next(WORD); } @@ -4756,11 +4832,10 @@ Perl_yylex(pTHX) UNI(OP_VALUES); case KEY_vec: - PL_sawvec = TRUE; LOP(OP_VEC,XTERM); case KEY_while: - yylval.ival = PL_curcop->cop_line; + yylval.ival = CopLINE(PL_curcop); OPERATOR(WHILE); case KEY_warn: @@ -4848,6 +4923,7 @@ Perl_keyword(pTHX_ register char *d, I32 len) break; case 'C': if (strEQ(d,"CORE")) return -KEY_CORE; + if (strEQ(d,"CHECK")) return KEY_CHECK; break; case 'c': switch (len) { @@ -5477,14 +5553,15 @@ S_checkcomma(pTHX_ register char *s, char *name, char *what) and type is used with error messages only. */ STATIC SV * -S_new_constant(pTHX_ char *s, STRLEN len, char *key, SV *sv, SV *pv, char *type) +S_new_constant(pTHX_ char *s, STRLEN len, const char *key, SV *sv, SV *pv, + const char *type) { dSP; HV *table = GvHV(PL_hintgv); /* ^H */ SV *res; SV **cvp; SV *cv, *typesv; - char *why, *why1, *why2; + const char *why, *why1, *why2; if (!(PL_hints & HINT_LOCALIZE_HH)) { SV *msg; @@ -5542,12 +5619,12 @@ S_new_constant(pTHX_ char *s, STRLEN len, char *key, SV *sv, SV *pv, char *type) STRLEN n_a; sv_catpv(ERRSV, "Propagated"); yyerror(SvPV(ERRSV, n_a)); /* Duplicates the message inside eval */ - POPs ; + (void)POPs; res = SvREFCNT_inc(sv); } else { res = POPs; - SvREFCNT_inc(res); + (void)SvREFCNT_inc(res); } PUTBACK ; @@ -5611,8 +5688,6 @@ S_scan_ident(pTHX_ register char *s, register char *send, char *dest, STRLEN des char *bracket = 0; char funny = *s++; - if (PL_lex_brackets == 0) - PL_lex_fakebrack = 0; if (isSPACE(*s)) s = skipspace(s); d = dest; @@ -5712,14 +5787,13 @@ S_scan_ident(pTHX_ register char *s, register char *send, char *dest, STRLEN des if ((*s == '[' || (*s == '{' && strNE(dest, "sub")))) { dTHR; /* only for ckWARN */ if (ckWARN(WARN_AMBIGUOUS) && keyword(dest, d - dest)) { - char *brack = *s == '[' ? "[...]" : "{...}"; + const char *brack = *s == '[' ? "[...]" : "{...}"; Perl_warner(aTHX_ WARN_AMBIGUOUS, "Ambiguous use of %c{%s%s} resolved to %c%s%s", funny, dest, brack, funny, dest, brack); } - PL_lex_fakebrack = PL_lex_brackets+1; bracket++; - PL_lex_brackstack[PL_lex_brackets++] = XOPERATOR; + PL_lex_brackstack[PL_lex_brackets++] = (char)(XOPERATOR | XFAKEBRACK); return s; } } @@ -6052,7 +6126,7 @@ S_scan_heredoc(pTHX_ register char *s) } CLINE; - PL_multi_start = PL_curcop->cop_line; + PL_multi_start = CopLINE(PL_curcop); PL_multi_open = PL_multi_close = '<'; term = *PL_tokenbuf; if (PL_lex_inwhat == OP_SUBST && PL_in_eval && !PL_rsfp) { @@ -6066,10 +6140,10 @@ S_scan_heredoc(pTHX_ register char *s) while (s < bufend && (*s != term || memNE(s,PL_tokenbuf,len)) ) { if (*s++ == '\n') - PL_curcop->cop_line++; + CopLINE_inc(PL_curcop); } if (s >= bufend) { - PL_curcop->cop_line = PL_multi_start; + CopLINE_set(PL_curcop, PL_multi_start); missingterm(PL_tokenbuf); } sv_setpvn(herewas,bufptr,d-bufptr+1); @@ -6086,15 +6160,15 @@ S_scan_heredoc(pTHX_ register char *s) while (s < PL_bufend && (*s != term || memNE(s,PL_tokenbuf,len)) ) { if (*s++ == '\n') - PL_curcop->cop_line++; + CopLINE_inc(PL_curcop); } if (s >= PL_bufend) { - PL_curcop->cop_line = PL_multi_start; + CopLINE_set(PL_curcop, PL_multi_start); missingterm(PL_tokenbuf); } sv_setpvn(tmpstr,d+1,s-d); s += len - 1; - PL_curcop->cop_line++; /* the preceding stmt passes a newline */ + CopLINE_inc(PL_curcop); /* the preceding stmt passes a newline */ sv_catpvn(herewas,s,PL_bufend-s); sv_setsv(PL_linestr,herewas); @@ -6106,10 +6180,10 @@ S_scan_heredoc(pTHX_ register char *s) while (s >= PL_bufend) { /* multiple line string? */ if (!outer || !(PL_oldoldbufptr = PL_oldbufptr = s = PL_linestart = filter_gets(PL_linestr, PL_rsfp, 0))) { - PL_curcop->cop_line = PL_multi_start; + CopLINE_set(PL_curcop, PL_multi_start); missingterm(PL_tokenbuf); } - PL_curcop->cop_line++; + CopLINE_inc(PL_curcop); PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr); #ifndef PERL_STRICT_CR if (PL_bufend - PL_linestart >= 2) { @@ -6131,8 +6205,7 @@ S_scan_heredoc(pTHX_ register char *s) sv_upgrade(sv, SVt_PVMG); sv_setsv(sv,PL_linestr); - av_store(GvAV(PL_curcop->cop_filegv), - (I32)PL_curcop->cop_line,sv); + av_store(CopFILEAV(PL_curcop), (I32)CopLINE(PL_curcop),sv); } if (*s == term && memEQ(s,PL_tokenbuf,len)) { s = PL_bufend - 1; @@ -6147,7 +6220,7 @@ S_scan_heredoc(pTHX_ register char *s) } s++; retval: - PL_multi_end = PL_curcop->cop_line; + PL_multi_end = CopLINE(PL_curcop); if (SvCUR(tmpstr) + 5 < SvLEN(tmpstr)) { SvLEN_set(tmpstr, SvCUR(tmpstr) + 1); Renew(SvPVX(tmpstr), SvLEN(tmpstr), char); @@ -6338,7 +6411,7 @@ S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims) /* after skipping whitespace, the next character is the terminator */ term = *s; /* mark where we are */ - PL_multi_start = PL_curcop->cop_line; + PL_multi_start = CopLINE(PL_curcop); PL_multi_open = term; /* find corresponding closing delimiter */ @@ -6368,7 +6441,7 @@ S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims) for (; s < PL_bufend; s++,to++) { /* embedded newlines increment the current line number */ if (*s == '\n' && !PL_rsfp) - PL_curcop->cop_line++; + CopLINE_inc(PL_curcop); /* handle quoted delimiters */ if (*s == '\\' && s+1 < PL_bufend && term != '\\') { if (!keep_quoted && s[1] == term) @@ -6394,7 +6467,7 @@ S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims) for (; s < PL_bufend; s++,to++) { /* embedded newlines increment the line count */ if (*s == '\n' && !PL_rsfp) - PL_curcop->cop_line++; + CopLINE_inc(PL_curcop); /* backslashes can escape the open or closing characters */ if (*s == '\\' && s+1 < PL_bufend) { if (!keep_quoted && @@ -6443,11 +6516,11 @@ S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims) if (!PL_rsfp || !(PL_oldoldbufptr = PL_oldbufptr = s = PL_linestart = filter_gets(PL_linestr, PL_rsfp, 0))) { sv_free(sv); - PL_curcop->cop_line = PL_multi_start; + CopLINE_set(PL_curcop, PL_multi_start); return Nullch; } /* we read a line, so increment our line counter */ - PL_curcop->cop_line++; + CopLINE_inc(PL_curcop); /* update debugger info */ if (PERLDB_LINE && PL_curstash != PL_debstash) { @@ -6455,8 +6528,7 @@ S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims) sv_upgrade(sv, SVt_PVMG); sv_setsv(sv,PL_linestr); - av_store(GvAV(PL_curcop->cop_filegv), - (I32)PL_curcop->cop_line, sv); + av_store(CopFILEAV(PL_curcop), (I32)CopLINE(PL_curcop), sv); } /* having changed the buffer, we must update PL_bufend */ @@ -6467,7 +6539,7 @@ S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims) if (keep_delims) sv_catpvn(sv, s, 1); - PL_multi_end = PL_curcop->cop_line; + PL_multi_end = CopLINE(PL_curcop); s++; /* if we allocated too much space, give some back */ @@ -6517,7 +6589,7 @@ Perl_scan_num(pTHX_ char *start) register char *e; /* end of temp buffer */ IV tryiv; /* used to see if it can be an IV */ NV value; /* number read, as a double */ - SV *sv; /* place to put the converted number */ + SV *sv = Nullsv; /* place to put the converted number */ bool floatit; /* boolean: int or float? */ char *lastub = 0; /* position of last underbar */ static char number_too_long[] = "Number too long"; @@ -6529,8 +6601,7 @@ Perl_scan_num(pTHX_ char *start) Perl_croak(aTHX_ "panic: scan_num"); /* if it starts with a 0, it could be an octal number, a decimal in - 0.13 disguise, or a hexadecimal number, or a binary number. - */ + 0.13 disguise, or a hexadecimal number, or a binary number. */ case '0': { /* variables: @@ -6792,11 +6863,61 @@ Perl_scan_num(pTHX_ char *start) (floatit ? "float" : "integer"), sv, Nullsv, NULL); break; + /* if it starts with a v, it could be a version number */ + case 'v': + { + char *pos = s; + pos++; + while (isDIGIT(*pos)) + pos++; + if (*pos == '.' && isDIGIT(pos[1])) { + UV rev; + U8 tmpbuf[10]; + U8 *tmpend; + NV nshift = 1.0; + s++; /* get past 'v' */ + + sv = NEWSV(92,5); + SvUPGRADE(sv, SVt_PVNV); + sv_setpvn(sv, "", 0); + + do { + rev = atoi(s); + s = ++pos; + while (isDIGIT(*pos)) + pos++; + + tmpend = uv_to_utf8(tmpbuf, rev); + *tmpend = '\0'; + sv_catpvn(sv, (const char*)tmpbuf, tmpend - tmpbuf); + if (rev > 0) + SvNVX(sv) += (NV)rev/nshift; + nshift *= 1000; + } while (*pos == '.' && isDIGIT(pos[1])); + + rev = atoi(s); + s = pos; + tmpend = uv_to_utf8(tmpbuf, rev); + *tmpend = '\0'; + sv_catpvn(sv, (const char*)tmpbuf, tmpend - tmpbuf); + if (rev > 0) + SvNVX(sv) += (NV)rev/nshift; + + SvPOK_on(sv); + SvNOK_on(sv); + SvREADONLY_on(sv); + SvUTF8_on(sv); + } + } + break; } /* make the op for the constant and return */ - yylval.opval = newSVOP(OP_CONST, 0, sv); + if (sv) + yylval.opval = newSVOP(OP_CONST, 0, sv); + else + yylval.opval = Nullop; return s; } @@ -6838,6 +6959,14 @@ S_scan_formline(pTHX_ register char *s) needargs = TRUE; } sv_catpvn(stuff, s, eol-s); +#ifndef PERL_STRICT_CR + if (eol-s > 1 && eol[-2] == '\r' && eol[-1] == '\n') { + char *end = SvPVX(stuff) + SvCUR(stuff); + end[-2] = '\n'; + end[-1] = '\0'; + SvCUR(stuff)--; + } +#endif } s = eol; if (PL_rsfp) { @@ -6895,10 +7024,10 @@ Perl_start_subparse(pTHX_ I32 is_format, U32 flags) if (PL_compcv) { assert(SvTYPE(PL_compcv) == SVt_PVCV); } - save_I32(&PL_subline); + SAVEI32(PL_subline); save_item(PL_subname); SAVEI32(PL_padix); - SAVESPTR(PL_curpad); + SAVEVPTR(PL_curpad); SAVESPTR(PL_comppad); SAVESPTR(PL_comppad_name); SAVESPTR(PL_compcv); @@ -6918,7 +7047,7 @@ Perl_start_subparse(pTHX_ I32 is_format, U32 flags) PL_comppad_name_fill = 0; PL_min_intro_pending = 0; PL_padix = 0; - PL_subline = PL_curcop->cop_line; + PL_subline = CopLINE(PL_curcop); #ifdef USE_THREADS av_store(PL_comppad_name, 0, newSVpvn("@_", 2)); PL_curpad[0] = (SV*)newAV(); @@ -6998,36 +7127,24 @@ Perl_yyerror(pTHX_ char *s) where = SvPVX(where_sv); } msg = sv_2mortal(newSVpv(s, 0)); -#ifdef IV_IS_QUAD - Perl_sv_catpvf(aTHX_ msg, " at %_ line %" PERL_PRId64 ", ", - GvSV(PL_curcop->cop_filegv), (IV)PL_curcop->cop_line); -#else - Perl_sv_catpvf(aTHX_ msg, " at %_ line %ld, ", - GvSV(PL_curcop->cop_filegv), (long)PL_curcop->cop_line); -#endif + Perl_sv_catpvf(aTHX_ msg, " at %s line %"IVdf", ", + CopFILE(PL_curcop), (IV)CopLINE(PL_curcop)); if (context) Perl_sv_catpvf(aTHX_ msg, "near \"%.*s\"\n", contlen, context); else Perl_sv_catpvf(aTHX_ msg, "%s\n", where); - if (PL_multi_start < PL_multi_end && (U32)(PL_curcop->cop_line - PL_multi_end) <= 1) { -#ifdef IV_IS_QUAD + if (PL_multi_start < PL_multi_end && (U32)(CopLINE(PL_curcop) - PL_multi_end) <= 1) { Perl_sv_catpvf(aTHX_ msg, - " (Might be a runaway multi-line %c%c string starting on line %" PERL_\ -PRId64 ")\n", + " (Might be a runaway multi-line %c%c string starting on line %"IVdf")\n", (int)PL_multi_open,(int)PL_multi_close,(IV)PL_multi_start); -#else - Perl_sv_catpvf(aTHX_ msg, - " (Might be a runaway multi-line %c%c string starting on line %ld)\n", - (int)PL_multi_open,(int)PL_multi_close,(long)PL_multi_start); -#endif PL_multi_end = 0; } if (PL_in_eval & EVAL_WARNONLY) - Perl_warn(aTHX_ "%_", msg); + Perl_warn(aTHX_ "%"SVf, msg); else qerror(msg); if (PL_error_count >= 10) - Perl_croak(aTHX_ "%_ has too many errors.\n", GvSV(PL_curcop->cop_filegv)); + Perl_croak(aTHX_ "%s has too many errors.\n", CopFILE(PL_curcop)); PL_in_my = 0; PL_in_my_stash = Nullhv; return 0; @@ -7035,7 +7152,6 @@ PRId64 ")\n", #ifdef PERL_OBJECT -#define NO_XSLOCKS #include "XSUB.h" #endif @@ -7055,29 +7171,3 @@ restore_rsfp(pTHXo_ void *f) PerlIO_close(PL_rsfp); PL_rsfp = fp; } - -/* - * restore_expect - * Restores the state of PL_expect when the lexing that begun with a - * start_lex() call has ended. - */ - -static void -restore_expect(pTHXo_ void *e) -{ - /* a safe way to store a small integer in a pointer */ - PL_expect = (expectation)((char *)e - PL_tokenbuf); -} - -/* - * restore_lex_expect - * Restores the state of PL_lex_expect when the lexing that begun with a - * start_lex() call has ended. - */ - -static void -restore_lex_expect(pTHXo_ void *e) -{ - /* a safe way to store a small integer in a pointer */ - PL_lex_expect = (expectation)((char *)e - PL_tokenbuf); -}