X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=toke.c;h=0ef7d5274b727c99e2202e55ea74d75987a62532;hb=cc49e20bd7575d1d37e92731860d63daa4d52ecc;hp=83086042b54e854f6157552c927222f349da55ca;hpb=4438c4b75b842b6c829a7da9841e97abb875b1d8;p=p5sagit%2Fp5-mst-13.2.git diff --git a/toke.c b/toke.c index 8308604..0ef7d52 100644 --- a/toke.c +++ b/toke.c @@ -120,7 +120,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 @@ -213,8 +213,12 @@ S_no_op(pTHX_ char *what, char *s) char *oldbp = PL_bufptr; bool is_first = (PL_oldbufptr == PL_linestart); - assert(s >= oldbp); - PL_bufptr = s; + if (!s) + s = oldbp; + else { + assert(s >= oldbp); + PL_bufptr = s; + } yywarn(Perl_form(aTHX_ "%s found where operator expected", what)); if (is_first) Perl_warn(aTHX_ "\t(Missing semicolon on previous line?)\n"); @@ -371,12 +375,13 @@ 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); + SAVEDESTRUCTOR_X(restore_expect, PL_tokenbuf + PL_expect); /* encode as pointer */ + SAVEDESTRUCTOR_X(restore_lex_expect, PL_tokenbuf + PL_expect); PL_lex_state = LEX_NORMAL; PL_lex_defer = 0; @@ -395,6 +400,7 @@ Perl_lex_start(pTHX_ SV *line) PL_lex_repl = Nullsv; PL_lex_inpat = 0; PL_lex_inwhat = 0; + PL_sublex_info.sub_inwhat = 0; PL_linestr = line; if (SvREADONLY(PL_linestr)) PL_linestr = sv_2mortal(newSVsv(PL_linestr)); @@ -468,9 +474,9 @@ S_incline(pTHX_ char *s) ch = *t; *t = '\0'; if (t - s > 0) - PL_curcop->cop_filegv = gv_fetchfile(s); + CopFILEGV_set(PL_curcop, gv_fetchfile(s)); else - PL_curcop->cop_filegv = gv_fetchfile(PL_origfilename); + CopFILEGV_set(PL_curcop, gv_fetchfile(PL_origfilename)); *t = ch; PL_curcop->cop_line = atoi(n)-1; } @@ -492,6 +498,8 @@ S_skipspace(pTHX_ register char *s) } for (;;) { STRLEN prevlen; + SSize_t oldprevlen, oldoldprevlen; + SSize_t oldloplen, oldunilen; while (s < PL_bufend && isSPACE(*s)) { if (*s++ == '\n' && PL_in_eval && !PL_rsfp) incline(s); @@ -514,7 +522,8 @@ S_skipspace(pTHX_ register char *s) * of the buffer, we're not reading from a source filter, and * we're in normal lexing mode */ - if (s < PL_bufend || !PL_rsfp || PL_lex_state != LEX_NORMAL) + if (s < PL_bufend || !PL_rsfp || PL_sublex_info.sub_inwhat || + PL_lex_state == LEX_FORMLINE) return s; /* try to recharge the buffer */ @@ -555,9 +564,22 @@ S_skipspace(pTHX_ register char *s) } /* not at end of file, so we only read another line */ + /* make corresponding updates to old pointers, for yyerror() */ + oldprevlen = PL_oldbufptr - PL_bufend; + oldoldprevlen = PL_oldoldbufptr - PL_bufend; + if (PL_last_uni) + oldunilen = PL_last_uni - PL_bufend; + if (PL_last_lop) + oldloplen = PL_last_lop - PL_bufend; PL_linestart = PL_bufptr = s + prevlen; PL_bufend = s + SvCUR(PL_linestr); s = PL_bufptr; + PL_oldbufptr = s + oldprevlen; + PL_oldoldbufptr = s + oldoldprevlen; + if (PL_last_uni) + PL_last_uni = s + oldunilen; + if (PL_last_lop) + PL_last_lop = s + oldloplen; incline(s); /* debugger active and we're not compiling the debugger code, @@ -568,7 +590,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)PL_curcop->cop_line,sv); } } } @@ -699,7 +721,7 @@ S_force_next(pTHX_ I32 type) * it calls S_force_word to stick the next word into the PL_next lookahead. * * Arguments: - * char *start : start of the buffer + * char *start : buffer position (must be within PL_linestr) * int token : PL_next will be this type of bare word (e.g., METHOD,WORD) * int check_keyword : if true, Perl checks to make sure the word isn't * a keyword (do this if the word is a label, e.g. goto FOO) @@ -1037,6 +1059,7 @@ S_sublex_done(pTHX) PL_bufend = SvPVX(PL_linestr); PL_bufend += SvCUR(PL_linestr); PL_expect = XOPERATOR; + PL_sublex_info.sub_inwhat = 0; return ')'; } } @@ -1130,9 +1153,9 @@ 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 - ? "\\.^$@AGZdDwWsSbBpPXO+*?|()-nrtfeaxcz0123456789[{]} \t\n\r\f\v#" + ? "\\.^$@AGZdDwWsSbBpPXC+*?|()-nrtfeaxcz0123456789[{]} \t\n\r\f\v#" : ""; while (s < send || dorange) { @@ -1307,7 +1330,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; @@ -1329,7 +1352,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 { @@ -1353,8 +1376,8 @@ S_scan_const(pTHX_ char *start) } continue; - /* \C{latin small letter a} is a named character */ - case 'C': + /* \N{latin small letter a} is a named character */ + case 'N': ++s; if (*s == '{') { char* e = strchr(s, '}'); @@ -1366,13 +1389,13 @@ S_scan_const(pTHX_ char *start) char *why = Nullch; if (!e) { - yyerror("Missing right brace on \\C{}"); + yyerror("Missing right brace on \\N{}"); e = s - 1; goto cont_scan; } res = newSVpvn(s + 1, e - s - 1); res = new_constant( Nullch, 0, "charnames", - res, Nullsv, "\\C{...}" ); + res, Nullsv, "\\N{...}" ); str = SvPV(res,len); if (len > e - s + 4) { char *odest = SvPVX(sv); @@ -1387,7 +1410,7 @@ S_scan_const(pTHX_ char *start) s = e + 1; } else - yyerror("Missing braces on \\C{}"); + yyerror("Missing braces on \\N{}"); continue; /* \c is a control character */ @@ -1749,10 +1772,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) @@ -1760,12 +1782,8 @@ 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 */ + 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); @@ -1776,10 +1794,7 @@ 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 */ + 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 */ @@ -1809,10 +1824,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 ; @@ -1840,21 +1853,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 */ @@ -1885,7 +1893,9 @@ S_filter_gets(pTHX_ register SV *sv, register PerlIO *fp, STRLEN append) #ifdef DEBUGGING static char* exp_name[] = - { "OPERATOR", "TERM", "REF", "STATE", "BLOCK", "TERMBLOCK" }; + { "OPERATOR", "TERM", "REF", "STATE", "BLOCK", "ATTRBLOCK", + "ATTRTERM", "TERMBLOCK" + }; #endif /* @@ -1946,12 +1956,17 @@ Perl_yylex(pTHX) if it's a legal name, the OP is a PADANY. */ if (PL_in_my) { - if (strchr(PL_tokenbuf,':')) - yyerror(Perl_form(aTHX_ PL_no_myglob,PL_tokenbuf)); + if (PL_in_my == KEY_our) { /* "our" is merely analogous to "my" */ + tmp = pad_allocmy(PL_tokenbuf); + } + else { + if (strchr(PL_tokenbuf,':')) + yyerror(Perl_form(aTHX_ PL_no_myglob,PL_tokenbuf)); - yylval.opval = newOP(OP_PADANY, 0); - yylval.opval->op_targ = pad_allocmy(PL_tokenbuf); - return PRIVATEREF; + yylval.opval = newOP(OP_PADANY, 0); + yylval.opval->op_targ = pad_allocmy(PL_tokenbuf); + return PRIVATEREF; + } } /* @@ -1979,6 +1994,22 @@ Perl_yylex(pTHX) } #endif /* USE_THREADS */ if ((tmp = pad_findmy(PL_tokenbuf)) != NOT_IN_PAD) { + /* might be an "our" variable" */ + if (SvFLAGS(AvARRAY(PL_comppad_name)[tmp]) & SVpad_OUR) { + /* build ops for a bareword */ + yylval.opval = (OP*)newSVOP(OP_CONST, 0, newSVpv(PL_tokenbuf+1, 0)); + yylval.opval->op_private = OPpCONST_ENTERED; + gv_fetchpv(PL_tokenbuf+1, + (PL_in_eval + ? (GV_ADDMULTI | GV_ADDINEVAL | GV_ADDOUR) + : GV_ADDOUR + ), + ((PL_tokenbuf[0] == '$') ? SVt_PV + : (PL_tokenbuf[0] == '@') ? SVt_PVAV + : SVt_PVHV)); + return WORD; + } + /* if it's a sort block and they're naming $a or $b */ if (PL_last_lop_op == OP_SORT && PL_tokenbuf[0] == '$' && @@ -2033,7 +2064,7 @@ Perl_yylex(pTHX) break; #endif - /* when we're already built the next token, just pull it out the queue */ + /* when we've already built the next token, just pull it out of the queue */ case LEX_KNOWNEXT: PL_nexttoke--; yylval = PL_nextval[PL_nexttoke]; @@ -2220,7 +2251,8 @@ Perl_yylex(pTHX) PL_oldoldbufptr = PL_oldbufptr; PL_oldbufptr = s; DEBUG_p( { - PerlIO_printf(PerlIO_stderr(), "### Tokener expecting %s at %s\n", exp_name[PL_expect], s); + PerlIO_printf(Perl_debug_log, "### Tokener expecting %s at %s\n", + exp_name[PL_expect], s); } ) retry: @@ -2298,7 +2330,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)PL_curcop->cop_line,sv); } goto retry; } @@ -2347,7 +2379,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)PL_curcop->cop_line,sv); } PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr); if (PL_curcop->cop_line == 1) { @@ -2388,7 +2420,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); } @@ -2400,8 +2432,24 @@ Perl_yylex(pTHX) * Look for options. */ d = instr(s,"perl -"); - if (!d) + if (!d) { d = instr(s,"perl"); +#if defined(DOSISH) + /* avoid getting into infinite loops when shebang + * line contains "Perl" rather than "perl" */ + if (!d) { + for (d = ipathend-4; d >= ipath; --d) { + if ((*d == 'p' || *d == 'P') + && !ibcmp(d, "perl", 4)) + { + break; + } + } + if (d < ipath) + d = Nullch; + } +#endif + } #ifdef ALTERNATE_SHEBANG /* * If the ALTERNATE_SHEBANG on this system starts with a @@ -2659,6 +2707,84 @@ Perl_yylex(pTHX) goto just_a_word; } s++; + switch (PL_expect) { + OP *attrs; + case XOPERATOR: + if (!PL_in_my || PL_lex_state != LEX_NORMAL) + break; + PL_bufptr = s; /* update in case we back off */ + goto grabattrs; + case XATTRBLOCK: + PL_expect = XBLOCK; + goto grabattrs; + case XATTRTERM: + PL_expect = XTERMBLOCK; + grabattrs: + s = skipspace(s); + attrs = Nullop; + while (isIDFIRST_lazy(s)) { + d = scan_word(s, PL_tokenbuf, sizeof PL_tokenbuf, FALSE, &len); + if (*d == '(') { + d = scan_str(d,TRUE,TRUE); + if (!d) { + if (PL_lex_stuff) { + SvREFCNT_dec(PL_lex_stuff); + PL_lex_stuff = Nullsv; + } + /* MUST advance bufptr here to avoid bogus + "at end of line" context messages from yyerror(). + */ + PL_bufptr = s + len; + yyerror("Unterminated attribute parameter in attribute list"); + if (attrs) + op_free(attrs); + return 0; /* EOF indicator */ + } + } + if (PL_lex_stuff) { + SV *sv = newSVpvn(s, len); + sv_catsv(sv, PL_lex_stuff); + attrs = append_elem(OP_LIST, attrs, + newSVOP(OP_CONST, 0, sv)); + SvREFCNT_dec(PL_lex_stuff); + PL_lex_stuff = Nullsv; + } + else { + attrs = append_elem(OP_LIST, attrs, + newSVOP(OP_CONST, 0, + newSVpvn(s, len))); + } + s = skipspace(d); + while (*s == ',') + s = skipspace(s+1); + } + tmp = (PL_expect == XOPERATOR ? '=' : '{'); /*'}' for vi */ + if (*s != ';' && *s != tmp) { + char q = ((*s == '\'') ? '"' : '\''); + /* If here for an expression, and parsed no attrs, back off. */ + if (tmp == '=' && !attrs) { + s = PL_bufptr; + break; + } + /* MUST advance bufptr here to avoid bogus "at end of line" + context messages from yyerror(). + */ + PL_bufptr = s; + if (!*s) + yyerror("Unterminated attribute list"); + else + yyerror(Perl_form(aTHX_ "Invalid separator character %c%c%c in attribute list", + q, *s, q)); + if (attrs) + op_free(attrs); + OPERATOR(':'); + } + if (attrs) { + PL_nextval[PL_nexttoke].opval = attrs; + force_next(THING); + } + TOKEN(COLONATTR); + } OPERATOR(':'); case '(': s++; @@ -2736,10 +2862,12 @@ Perl_yylex(pTHX) } } /* FALL THROUGH */ + case XATTRBLOCK: case XBLOCK: PL_lex_brackstack[PL_lex_brackets++] = XSTATE; PL_expect = XSTATE; break; + case XATTRTERM: case XTERMBLOCK: PL_lex_brackstack[PL_lex_brackets++] = XOPERATOR; PL_expect = XSTATE; @@ -3210,7 +3338,7 @@ Perl_yylex(pTHX) TERM(THING); case '\'': - s = scan_str(s); + s = scan_str(s,FALSE,FALSE); if (PL_expect == XOPERATOR) { if (PL_lex_formbrack && PL_lex_brackets == PL_lex_formbrack) { PL_expect = XTERM; @@ -3226,7 +3354,7 @@ Perl_yylex(pTHX) TERM(sublex_start()); case '"': - s = scan_str(s); + s = scan_str(s,FALSE,FALSE); if (PL_expect == XOPERATOR) { if (PL_lex_formbrack && PL_lex_brackets == PL_lex_formbrack) { PL_expect = XTERM; @@ -3248,7 +3376,7 @@ Perl_yylex(pTHX) TERM(sublex_start()); case '`': - s = scan_str(s); + s = scan_str(s,FALSE,FALSE); if (PL_expect == XOPERATOR) no_op("Backticks",s); if (!s) @@ -3461,7 +3589,8 @@ Perl_yylex(pTHX) if (PL_oldoldbufptr && PL_oldoldbufptr < PL_bufptr && - (PL_oldoldbufptr == PL_last_lop || PL_oldoldbufptr == PL_last_uni) && + (PL_oldoldbufptr == PL_last_lop + || PL_oldoldbufptr == PL_last_uni) && /* NO SKIPSPACE BEFORE HERE! */ (PL_expect == XREF || ((PL_opargs[PL_last_lop_op] >> OASHIFT)& 7) == OA_FILEREF)) @@ -3595,17 +3724,12 @@ Perl_yylex(pTHX) case KEY___FILE__: yylval.opval = (OP*)newSVOP(OP_CONST, 0, - newSVsv(GvSV(PL_curcop->cop_filegv))); + newSVsv(CopFILESV(PL_curcop))); 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)PL_curcop->cop_line)); TERM(THING); case KEY___PACKAGE__: @@ -3719,8 +3843,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); @@ -3838,8 +3964,16 @@ Perl_yylex(pTHX) if ((PL_bufend - p) >= 3 && strnEQ(p, "my", 2) && isSPACE(*(p + 2))) p += 2; + else if ((PL_bufend - p) >= 4 && + strnEQ(p, "our", 3) && isSPACE(*(p + 3))) + p += 3; p = skipspace(p); - if (isIDFIRST_lazy(p)) + if (isIDFIRST_lazy(p)) { + p = scan_ident(p, PL_bufend, + PL_tokenbuf, sizeof PL_tokenbuf, TRUE); + p = skipspace(p); + } + if (*p != '$') Perl_croak(aTHX_ "Missing $ on loop variable"); } OPERATOR(FOR); @@ -3993,6 +4127,7 @@ Perl_yylex(pTHX) UNI(OP_LCFIRST); case KEY_local: + yylval.ival = 0; OPERATOR(LOCAL); case KEY_length: @@ -4044,11 +4179,14 @@ Perl_yylex(pTHX) case KEY_msgsnd: LOP(OP_MSGSND,XTERM); + case KEY_our: case KEY_my: - PL_in_my = TRUE; + PL_in_my = tmp; s = skipspace(s); if (isIDFIRST_lazy(s)) { s = scan_word(s, PL_tokenbuf, sizeof PL_tokenbuf, TRUE, &len); + if (len == 3 && strnEQ(PL_tokenbuf, "sub", 3)) + goto really_sub; PL_in_my_stash = gv_stashpv(PL_tokenbuf, FALSE); if (!PL_in_my_stash) { char tmpbuf[1024]; @@ -4057,6 +4195,7 @@ Perl_yylex(pTHX) yyerror(tmpbuf); } } + yylval.ival = 1; OPERATOR(MY); case KEY_next: @@ -4075,7 +4214,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); @@ -4134,7 +4276,7 @@ Perl_yylex(pTHX) LOP(OP_PIPE_OP,XTERM); case KEY_q: - s = scan_str(s); + s = scan_str(s,FALSE,FALSE); if (!s) missingterm((char*)0); yylval.ival = OP_CONST; @@ -4144,7 +4286,7 @@ Perl_yylex(pTHX) UNI(OP_QUOTEMETA); case KEY_qw: - s = scan_str(s); + s = scan_str(s,FALSE,FALSE); if (!s) missingterm((char*)0); force_next(')'); @@ -4189,7 +4331,7 @@ Perl_yylex(pTHX) TOKEN('('); case KEY_qq: - s = scan_str(s); + s = scan_str(s,FALSE,FALSE); if (!s) missingterm((char*)0); yylval.ival = OP_STRINGIFY; @@ -4202,7 +4344,7 @@ Perl_yylex(pTHX) TERM(sublex_start()); case KEY_qx: - s = scan_str(s); + s = scan_str(s,FALSE,FALSE); if (!s) missingterm((char*)0); yylval.ival = OP_BACKTICK; @@ -4388,7 +4530,6 @@ Perl_yylex(pTHX) UNI(OP_STAT); case KEY_study: - PL_sawstudy++; UNI(OP_STUDY); case KEY_substr: @@ -4397,73 +4538,97 @@ Perl_yylex(pTHX) case KEY_format: case KEY_sub: really_sub: - s = skipspace(s); - - if (isIDFIRST_lazy(s) || *s == '\'' || *s == ':') { + { char tmpbuf[sizeof PL_tokenbuf]; - PL_expect = XBLOCK; - d = scan_word(s, tmpbuf, sizeof tmpbuf, TRUE, &len); - if (strchr(tmpbuf, ':')) - sv_setpv(PL_subname, tmpbuf); + SSize_t tboffset; + expectation attrful; + bool have_name, have_proto; + int key = tmp; + + s = skipspace(s); + + if (isIDFIRST_lazy(s) || *s == '\'' || + (*s == ':' && s[1] == ':')) + { + PL_expect = XBLOCK; + attrful = XATTRBLOCK; + /* remember buffer pos'n for later force_word */ + tboffset = s - PL_oldbufptr; + d = scan_word(s, tmpbuf, sizeof tmpbuf, TRUE, &len); + if (strchr(tmpbuf, ':')) + sv_setpv(PL_subname, tmpbuf); + else { + sv_setsv(PL_subname,PL_curstname); + sv_catpvn(PL_subname,"::",2); + sv_catpvn(PL_subname,tmpbuf,len); + } + s = skipspace(d); + have_name = TRUE; + } else { - sv_setsv(PL_subname,PL_curstname); - sv_catpvn(PL_subname,"::",2); - sv_catpvn(PL_subname,tmpbuf,len); + if (key == KEY_my) + Perl_croak(aTHX_ "Missing name in \"my sub\""); + PL_expect = XTERMBLOCK; + attrful = XATTRTERM; + sv_setpv(PL_subname,"?"); + have_name = FALSE; } - s = force_word(s,WORD,FALSE,TRUE,TRUE); - s = skipspace(s); - } - else { - PL_expect = XTERMBLOCK; - sv_setpv(PL_subname,"?"); - } - if (tmp == KEY_format) { - s = skipspace(s); - if (*s == '=') - PL_lex_formbrack = PL_lex_brackets + 1; - OPERATOR(FORMAT); - } + if (key == KEY_format) { + if (*s == '=') + PL_lex_formbrack = PL_lex_brackets + 1; + if (have_name) + (void) force_word(PL_oldbufptr + tboffset, WORD, + FALSE, TRUE, TRUE); + OPERATOR(FORMAT); + } + + /* Look for a prototype */ + if (*s == '(') { + char *p; + + s = scan_str(s,FALSE,FALSE); + if (!s) { + if (PL_lex_stuff) + SvREFCNT_dec(PL_lex_stuff); + PL_lex_stuff = Nullsv; + Perl_croak(aTHX_ "Prototype not terminated"); + } + /* strip spaces */ + d = SvPVX(PL_lex_stuff); + tmp = 0; + for (p = d; *p; ++p) { + if (!isSPACE(*p)) + d[tmp++] = *p; + } + d[tmp] = '\0'; + SvCUR(PL_lex_stuff) = tmp; + have_proto = TRUE; + + s = skipspace(s); + } + else + have_proto = FALSE; - /* Look for a prototype */ - if (*s == '(') { - char *p; + if (*s == ':' && s[1] != ':') + PL_expect = attrful; - s = scan_str(s); - if (!s) { - if (PL_lex_stuff) - SvREFCNT_dec(PL_lex_stuff); + if (have_proto) { + PL_nextval[PL_nexttoke].opval = + (OP*)newSVOP(OP_CONST, 0, PL_lex_stuff); PL_lex_stuff = Nullsv; - Perl_croak(aTHX_ "Prototype not terminated"); - } - /* strip spaces */ - d = SvPVX(PL_lex_stuff); - tmp = 0; - for (p = d; *p; ++p) { - if (!isSPACE(*p)) - d[tmp++] = *p; + force_next(THING); } - d[tmp] = '\0'; - SvCUR(PL_lex_stuff) = tmp; - - PL_nexttoke++; - PL_nextval[1] = PL_nextval[0]; - PL_nexttype[1] = PL_nexttype[0]; - PL_nextval[0].opval = (OP*)newSVOP(OP_CONST, 0, PL_lex_stuff); - PL_nexttype[0] = THING; - if (PL_nexttoke == 1) { - PL_lex_defer = PL_lex_state; - PL_lex_expect = PL_expect; - PL_lex_state = LEX_KNOWNEXT; + if (!have_name) { + sv_setpv(PL_subname,"__ANON__"); + TOKEN(ANONSUB); } - PL_lex_stuff = Nullsv; - } - - if (*SvPV(PL_subname,n_a) == '?') { - sv_setpv(PL_subname,"__ANON__"); - TOKEN(ANONSUB); + (void) force_word(PL_oldbufptr + tboffset, WORD, + FALSE, TRUE, TRUE); + if (key == KEY_my) + TOKEN(MYSUB); + TOKEN(SUB); } - PREBLOCK(SUB); case KEY_system: set_csh(); @@ -4575,7 +4740,6 @@ Perl_yylex(pTHX) UNI(OP_VALUES); case KEY_vec: - PL_sawvec = TRUE; LOP(OP_VEC,XTERM); case KEY_while: @@ -4971,8 +5135,7 @@ Perl_keyword(pTHX_ register char *d, I32 len) case 3: if (strEQ(d,"ord")) return -KEY_ord; if (strEQ(d,"oct")) return -KEY_oct; - if (strEQ(d,"our")) { deprecate("reserved word \"our\""); - return 0;} + if (strEQ(d,"our")) return KEY_our; break; case 4: if (strEQ(d,"open")) return -KEY_open; @@ -5263,7 +5426,8 @@ S_checkcomma(pTHX_ register char *s, char *name, char *what) if (*w) for (; *w && isSPACE(*w); w++) ; if (!*w || !strchr(";|})]oaiuw!=", *w)) /* an advisory hack only... */ - Perl_warner(aTHX_ WARN_SYNTAX, "%s (...) interpreted as function",name); + Perl_warner(aTHX_ WARN_SYNTAX, + "%s (...) interpreted as function",name); } } while (s < PL_bufend && isSPACE(*s)) @@ -5296,14 +5460,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; @@ -5361,12 +5526,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 ; @@ -5531,7 +5696,7 @@ 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); @@ -5607,7 +5772,7 @@ S_scan_pat(pTHX_ char *start, I32 type) PMOP *pm; char *s; - s = scan_str(start); + s = scan_str(start,FALSE,FALSE); if (!s) { if (PL_lex_stuff) SvREFCNT_dec(PL_lex_stuff); @@ -5643,7 +5808,7 @@ S_scan_subst(pTHX_ char *start) yylval.ival = OP_NULL; - s = scan_str(start); + s = scan_str(start,FALSE,FALSE); if (!s) { if (PL_lex_stuff) @@ -5656,7 +5821,7 @@ S_scan_subst(pTHX_ char *start) s--; first_start = PL_multi_start; - s = scan_str(s); + s = scan_str(s,FALSE,FALSE); if (!s) { if (PL_lex_stuff) SvREFCNT_dec(PL_lex_stuff); @@ -5717,7 +5882,7 @@ S_scan_trans(pTHX_ char *start) yylval.ival = OP_NULL; - s = scan_str(start); + s = scan_str(start,FALSE,FALSE); if (!s) { if (PL_lex_stuff) SvREFCNT_dec(PL_lex_stuff); @@ -5727,7 +5892,7 @@ S_scan_trans(pTHX_ char *start) if (s[-1] == PL_multi_open) s--; - s = scan_str(s); + s = scan_str(s,FALSE,FALSE); if (!s) { if (PL_lex_stuff) SvREFCNT_dec(PL_lex_stuff); @@ -5950,8 +6115,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)PL_curcop->cop_line,sv); } if (*s == term && memEQ(s,PL_tokenbuf,len)) { s = PL_bufend - 1; @@ -6042,7 +6206,7 @@ S_scan_inputsymbol(pTHX_ char *start) if (d - PL_tokenbuf != len) { yylval.ival = OP_GLOB; set_csh(); - s = scan_str(start); + s = scan_str(start,FALSE,FALSE); if (!s) Perl_croak(aTHX_ "Glob not terminated"); return s; @@ -6095,6 +6259,8 @@ S_scan_inputsymbol(pTHX_ char *start) /* scan_str takes: start position in buffer + keep_quoted preserve \ on the embedded delimiter(s) + keep_delims preserve the delimiters around the string returns: position to continue reading from buffer side-effects: multi_start, multi_close, lex_repl or lex_stuff, and updates the read buffer. @@ -6112,6 +6278,7 @@ S_scan_inputsymbol(pTHX_ char *start) tr/// string transliterate tr/this/that/ y/// string transliterate y/this/that/ ($*@) sub prototypes sub foo ($) + (stuff) sub attr parameters sub foo : attr(stuff) <> readline or globs , <>, <$fh>, or <*.c> In most of these cases (all but <>, patterns and transliterate) @@ -6134,7 +6301,7 @@ S_scan_inputsymbol(pTHX_ char *start) */ STATIC char * -S_scan_str(pTHX_ char *start) +S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims) { dTHR; SV *sv; /* scalar value: string */ @@ -6170,13 +6337,15 @@ S_scan_str(pTHX_ char *start) (void)SvPOK_only(sv); /* validate pointer */ /* move past delimiter and try to read a complete string */ + if (keep_delims) + sv_catpvn(sv, s, 1); s++; for (;;) { /* extend sv if need be */ SvGROW(sv, SvCUR(sv) + (PL_bufend - s) + 1); /* set 'to' to the next character in the sv's string */ to = SvPVX(sv)+SvCUR(sv); - + /* if open delimiter is the close delimiter read unbridle */ if (PL_multi_open == PL_multi_close) { for (; s < PL_bufend; s++,to++) { @@ -6185,7 +6354,7 @@ S_scan_str(pTHX_ char *start) PL_curcop->cop_line++; /* handle quoted delimiters */ if (*s == '\\' && s+1 < PL_bufend && term != '\\') { - if (s[1] == term) + if (!keep_quoted && s[1] == term) s++; /* any other quotes are simply copied straight through */ else @@ -6211,7 +6380,8 @@ S_scan_str(pTHX_ char *start) PL_curcop->cop_line++; /* backslashes can escape the open or closing characters */ if (*s == '\\' && s+1 < PL_bufend) { - if ((s[1] == PL_multi_open) || (s[1] == PL_multi_close)) + if (!keep_quoted && + ((s[1] == PL_multi_open) || (s[1] == PL_multi_close))) s++; else *to++ = *s++; @@ -6268,8 +6438,7 @@ S_scan_str(pTHX_ char *start) 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)PL_curcop->cop_line, sv); } /* having changed the buffer, we must update PL_bufend */ @@ -6278,6 +6447,8 @@ S_scan_str(pTHX_ char *start) /* at this point, we have successfully read the delimited string */ + if (keep_delims) + sv_catpvn(sv, s, 1); PL_multi_end = PL_curcop->cop_line; s++; @@ -6380,7 +6551,7 @@ Perl_scan_num(pTHX_ char *start) s += 2; } /* check for a decimal in disguise */ - else if (s[1] == '.') + else if (s[1] == '.' || s[1] == 'e' || s[1] == 'E') goto decimal; /* so it must be octal */ else @@ -6411,9 +6582,6 @@ Perl_scan_num(pTHX_ char *start) case '8': case '9': if (shift == 3) yyerror(Perl_form(aTHX_ "Illegal octal digit '%c'", *s)); - else - if (shift == 1) - yyerror(Perl_form(aTHX_ "Illegal binary digit '%c'", *s)); /* FALL THROUGH */ /* octal digits */ @@ -6448,9 +6616,8 @@ Perl_scan_num(pTHX_ char *start) dTHR; overflowed = TRUE; n = (NV) u; - if (ckWARN_d(WARN_UNSAFE)) - Perl_warner(aTHX_ ((shift == 3) ? - WARN_OCTAL : WARN_UNSAFE), + if (ckWARN_d(WARN_OVERFLOW)) + Perl_warner(aTHX_ WARN_OVERFLOW, "Integer overflow in %s number", base); } else @@ -6479,17 +6646,17 @@ Perl_scan_num(pTHX_ char *start) sv = NEWSV(92,0); if (overflowed) { dTHR; - if (ckWARN(WARN_UNSAFE) && n > 4294967295.0) - Perl_warner(aTHX_ WARN_UNSAFE, + if (ckWARN(WARN_PORTABLE) && n > 4294967295.0) + Perl_warner(aTHX_ WARN_PORTABLE, "%s number > %s non-portable", Base, max); sv_setnv(sv, n); } else { -#if UV_SIZEOF > 4 +#if UVSIZE > 4 dTHR; - if (ckWARN(WARN_UNSAFE) && u > 0xffffffff) - Perl_warner(aTHX_ WARN_UNSAFE, + if (ckWARN(WARN_PORTABLE) && u > 0xffffffff) + Perl_warner(aTHX_ WARN_PORTABLE, "%s number > %s non-portable", Base, max); #endif @@ -6760,7 +6927,6 @@ int Perl_yywarn(pTHX_ char *s) { dTHR; - --PL_error_count; PL_in_eval |= EVAL_WARNONLY; yyerror(s); PL_in_eval &= ~EVAL_WARNONLY; @@ -6814,38 +6980,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 %_ line %"IVdf", ", + CopFILESV(PL_curcop), (IV)PL_curcop->cop_line); 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 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); - else if (PL_in_eval) - sv_catsv(ERRSV, msg); else - PerlIO_write(PerlIO_stderr(), SvPVX(msg), SvCUR(msg)); - if (++PL_error_count >= 10) - Perl_croak(aTHX_ "%_ has too many errors.\n", GvSV(PL_curcop->cop_filegv)); + qerror(msg); + if (PL_error_count >= 10) + Perl_croak(aTHX_ "%_ has too many errors.\n", CopFILESV(PL_curcop)); PL_in_my = 0; PL_in_my_stash = Nullhv; return 0;