X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=toke.c;h=e7e217473ea0b19e09cbc6043f968a19e4d878af;hb=030866aa8d0911636ef2210b710f544fd2c85c8e;hp=4803bc84258dab52e29e7624b385a147ebcbd77d;hpb=79cb57f6e01f91d8fff40d69caa187aaa669671b;p=p5sagit%2Fp5-mst-13.2.git diff --git a/toke.c b/toke.c index 4803bc8..e7e2174 100644 --- a/toke.c +++ b/toke.c @@ -11,55 +11,27 @@ * "It all comes from here, the stench and the peril." --Frodo */ +/* + * This file is the lexer for Perl. It's closely linked to the + * parser, perly.y. + * + * The main routine is yylex(), which returns the next token. + */ + #include "EXTERN.h" +#define PERL_IN_TOKE_C #include "perl.h" #define yychar PL_yychar #define yylval PL_yylval -#ifndef PERL_OBJECT -static void check_uni _((void)); -static void force_next _((I32 type)); -static char *force_version _((char *start)); -static char *force_word _((char *start, int token, int check_keyword, int allow_pack, int allow_tick)); -static SV *tokeq _((SV *sv)); -static char *scan_const _((char *start)); -static char *scan_formline _((char *s)); -static char *scan_heredoc _((char *s)); -static char *scan_ident _((char *s, char *send, char *dest, STRLEN destlen, - I32 ck_uni)); -static char *scan_inputsymbol _((char *start)); -static char *scan_pat _((char *start, I32 type)); -static char *scan_str _((char *start)); -static char *scan_subst _((char *start)); -static char *scan_trans _((char *start)); -static char *scan_word _((char *s, char *dest, STRLEN destlen, - int allow_package, STRLEN *slp)); -static char *skipspace _((char *s)); -static void checkcomma _((char *s, char *name, char *what)); -static void force_ident _((char *s, int kind)); -static void incline _((char *s)); -static int intuit_method _((char *s, GV *gv)); -static int intuit_more _((char *s)); -static I32 lop _((I32 f, expectation x, char *s)); -static void missingterm _((char *s)); -static void no_op _((char *what, char *s)); -static void set_csh _((void)); -static I32 sublex_done _((void)); -static I32 sublex_push _((void)); -static I32 sublex_start _((void)); -#ifdef CRIPPLED_CC -static int uni _((I32 f, char *s)); -#endif -static char * filter_gets _((SV *sv, PerlIO *fp, STRLEN append)); -static void restore_rsfp _((void *f)); -static SV *new_constant _((char *s, STRLEN len, char *key, SV *sv, SV *pv, char *type)); -static void restore_expect _((void *e)); -static void restore_lex_expect _((void *e)); -#endif /* PERL_OBJECT */ - static char ident_too_long[] = "Identifier too long"; +static void restore_rsfp(pTHXo_ void *f); + +#define XFAKEBRACK 128 +#define XENUMMASK 127 + #define UTF (PL_hints & HINT_UTF8) /* * Note: we try to be careful never to call the isXXX_utf8() functions @@ -78,7 +50,8 @@ static char ident_too_long[] = "Identifier too long"; * 1999-02-27 mjd-perl-patch@plover.com */ #define isCONTROLVAR(x) (isUPPER(x) || strchr("[\\]^_?", (x))) -/* The following are arranged oddly so that the guard on the switch statement +/* LEX_* are values for PL_lex_state, the state of the lexer. + * They are arranged oddly so that the guard on the switch statement * can get by with a single comparison (if the compiler is smart enough). */ @@ -121,16 +94,46 @@ int* yychar_pointer = NULL; # define yylval (*yylval_pointer) # define yychar (*yychar_pointer) # define PERL_YYLEX_PARAM yylval_pointer,yychar_pointer -#else -# define PERL_YYLEX_PARAM +# undef yylex +# define yylex() Perl_yylex(aTHX_ yylval_pointer, yychar_pointer) #endif #include "keywords.h" +/* CLINE is a macro that ensures PL_copline has a sane value */ + #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 + * lexer for the next token. They all take an argument. + * + * TOKEN : generic token (used for '(', DOLSHARP, etc) + * OPERATOR : generic operator + * AOPERATOR : assignment operator + * PREBLOCK : beginning the block after an if, while, foreach, ... + * PRETERMBLOCK : beginning a non-code-defining {} block (eg, hash ref) + * PREREF : *EXPR where EXPR is not a simple identifier + * TERM : expression term + * LOOPX : loop exiting command (goto, last, dump, etc) + * FTST : file test operator + * FUN0 : zero-argument function + * FUN1 : not used, except for not, which isn't a UNIOP + * BOop : bitwise or or xor + * BAop : bitwise and + * SHop : shift operator + * PWop : power operator + * PMop : pattern-matching operator + * Aop : addition-level operator + * Mop : multiplication-level operator + * Eop : equality-testing operator + * Rop : relational operator <= != gt + * + * Also see LOP and lop() below. + */ #define TOKEN(retval) return (PL_bufptr = s,(int)retval) #define OPERATOR(retval) return (PL_expect = XTERM,PL_bufptr = s,(int)retval) @@ -171,8 +174,15 @@ int* yychar_pointer = NULL; /* grandfather return to old style */ #define OLDLOP(f) return(yylval.ival=f,PL_expect = XTERM,PL_bufptr = s,(int)LSTOP) +/* + * S_ao + * + * This subroutine detects &&= and ||= and turns an ANDAND or OROR + * into an OP_ANDASSIGN or OP_ORASSIGN + */ + STATIC int -ao(int toketype) +S_ao(pTHX_ int toketype) { if (*PL_bufptr == '=') { PL_bufptr++; @@ -185,33 +195,57 @@ ao(int toketype) return toketype; } +/* + * S_no_op + * When Perl expects an operator and finds something else, no_op + * prints the warning. It always prints " found where + * operator expected. It prints "Missing semicolon on previous line?" + * if the surprise occurs at the start of the line. "do you need to + * predeclare ..." is printed out for code like "sub bar; foo bar $x" + * where the compiler doesn't know if foo is a method call or a function. + * It prints "Missing operator before end of line" if there's nothing + * after the missing operator, or "... before <...>" if there is something + * after the missing operator. + */ + STATIC void -no_op(char *what, char *s) +S_no_op(pTHX_ char *what, char *s) { char *oldbp = PL_bufptr; bool is_first = (PL_oldbufptr == PL_linestart); - PL_bufptr = s; - yywarn(form("%s found where operator expected", what)); + if (!s) + s = oldbp; + else { + assert(s >= oldbp); + PL_bufptr = s; + } + yywarn(Perl_form(aTHX_ "%s found where operator expected", what)); if (is_first) - warn("\t(Missing semicolon on previous line?)\n"); + Perl_warn(aTHX_ "\t(Missing semicolon on previous line?)\n"); else if (PL_oldoldbufptr && isIDFIRST_lazy(PL_oldoldbufptr)) { char *t; for (t = PL_oldoldbufptr; *t && (isALNUM_lazy(t) || *t == ':'); t++) ; if (t < PL_bufptr && isSPACE(*t)) - warn("\t(Do you need to predeclare %.*s?)\n", + Perl_warn(aTHX_ "\t(Do you need to predeclare %.*s?)\n", t - PL_oldoldbufptr, PL_oldoldbufptr); - } - else if (s <= oldbp) - warn("\t(Missing operator before end of line?)\n"); else - warn("\t(Missing operator before %.*s?)\n", s - oldbp, oldbp); + Perl_warn(aTHX_ "\t(Missing operator before %.*s?)\n", s - oldbp, oldbp); PL_bufptr = oldbp; } +/* + * S_missingterm + * Complain about missing quote/regexp/heredoc terminator. + * If it's called with (char *)NULL then it cauterizes the line buffer. + * If we're in a delimited string and the delimiter is a control + * character, it's reformatted into a two-char sequence like ^C. + * This is fatal. + */ + STATIC void -missingterm(char *s) +S_missingterm(pTHX_ char *s) { char tmpbuf[3]; char q; @@ -239,39 +273,72 @@ missingterm(char *s) s = tmpbuf; } q = strchr(s,'"') ? '\'' : '"'; - croak("Can't find string terminator %c%s%c anywhere before EOF",q,s,q); + Perl_croak(aTHX_ "Can't find string terminator %c%s%c anywhere before EOF",q,s,q); } +/* + * Perl_deprecate + */ + void -deprecate(char *s) +Perl_deprecate(pTHX_ char *s) { dTHR; if (ckWARN(WARN_DEPRECATED)) - warner(WARN_DEPRECATED, "Use of %s is deprecated", s); + Perl_warner(aTHX_ WARN_DEPRECATED, "Use of %s is deprecated", s); } +/* + * depcom + * Deprecate a comma-less variable list. + */ + STATIC void -depcom(void) +S_depcom(pTHX) { deprecate("comma-less variable list"); } -#ifdef WIN32 +/* + * experimental text filters for win32 carriage-returns, utf16-to-utf8 and + * utf16-to-utf8-reversed. + */ + +#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 -win32_textfilter(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 -#ifndef PERL_OBJECT - STATIC I32 -utf16_textfilter(int idx, SV *sv, int maxlen) +S_utf16_textfilter(pTHX_ int idx, SV *sv, int maxlen) { I32 count = FILTER_READ(idx+1, sv, maxlen); if (count) { @@ -286,7 +353,7 @@ utf16_textfilter(int idx, SV *sv, int maxlen) } STATIC I32 -utf16rev_textfilter(int idx, SV *sv, int maxlen) +S_utf16rev_textfilter(pTHX_ int idx, SV *sv, int maxlen) { I32 count = FILTER_READ(idx+1, sv, maxlen); if (count) { @@ -300,10 +367,14 @@ utf16rev_textfilter(int idx, SV *sv, int maxlen) return count; } -#endif +/* + * Perl_lex_start + * Initialize variables. Uses the Perl save_stack to save its state (for + * recursive calls to the parser). + */ void -lex_start(SV *line) +Perl_lex_start(pTHX_ SV *line) { dTHR; char *s; @@ -311,13 +382,12 @@ lex_start(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); @@ -326,18 +396,18 @@ lex_start(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); @@ -350,6 +420,7 @@ lex_start(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)); @@ -367,40 +438,30 @@ lex_start(SV *line) PL_rsfp = 0; } +/* + * Perl_lex_end + * Finalizer for lexing operations. Must be called when the parser is + * done with the lexer. + */ + void -lex_end(void) +Perl_lex_end(pTHX) { PL_doextract = FALSE; } -STATIC void -restore_rsfp(void *f) -{ - PerlIO *fp = (PerlIO*)f; - - if (PL_rsfp == PerlIO_stdin()) - PerlIO_clearerr(PL_rsfp); - else if (PL_rsfp && (PL_rsfp != fp)) - PerlIO_close(PL_rsfp); - PL_rsfp = fp; -} - -STATIC void -restore_expect(void *e) -{ - /* a safe way to store a small integer in a pointer */ - PL_expect = (expectation)((char *)e - PL_tokenbuf); -} - -STATIC void -restore_lex_expect(void *e) -{ - /* a safe way to store a small integer in a pointer */ - PL_lex_expect = (expectation)((char *)e - PL_tokenbuf); -} +/* + * 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 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. + */ STATIC void -incline(char *s) +S_incline(pTHX_ char *s) { dTHR; char *t; @@ -408,7 +469,7 @@ incline(char *s) char ch; int sawline = 0; - PL_curcop->cop_line++; + CopLINE_inc(PL_curcop); if (*s++ != '#') return; while (*s == ' ' || *s == '\t') s++; @@ -433,15 +494,19 @@ incline(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); } +/* + * S_skipspace + * Called to gobble the appropriate amount and type of whitespace. + * Skips comments as well. + */ + STATIC char * -skipspace(register char *s) +S_skipspace(pTHX_ register char *s) { dTHR; if (PL_lex_formbrack && PL_lex_brackets <= PL_lex_formbrack) { @@ -451,10 +516,14 @@ skipspace(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); } + + /* comment */ if (s < PL_bufend && *s == '#') { while (s < PL_bufend && *s != '\n') s++; @@ -466,9 +535,20 @@ skipspace(register char *s) } } } - if (s < PL_bufend || !PL_rsfp || PL_lex_state != LEX_NORMAL) + + /* only continue to recharge the buffer if we're at the end + * 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_sublex_info.sub_inwhat || + PL_lex_state == LEX_FORMLINE) return s; - if ((s = filter_gets(PL_linestr, PL_rsfp, (prevlen = SvCUR(PL_linestr)))) == Nullch) { + + /* try to recharge the buffer */ + if ((s = filter_gets(PL_linestr, PL_rsfp, + (prevlen = SvCUR(PL_linestr)))) == Nullch) + { + /* end of file. Add on the -p or -n magic */ if (PL_minus_n || PL_minus_p) { sv_setpv(PL_linestr,PL_minus_p ? ";}continue{print or die qq(-p destination: $!\\n)" : @@ -478,8 +558,19 @@ skipspace(register char *s) } else sv_setpv(PL_linestr,";"); - PL_oldoldbufptr = PL_oldbufptr = PL_bufptr = s = PL_linestart = SvPVX(PL_linestr); + + /* reset variables for next time we lex */ + PL_oldoldbufptr = PL_oldbufptr = PL_bufptr = s = PL_linestart + = SvPVX(PL_linestr); PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr); + + /* Close the filehandle. Could be from -P preprocessor, + * STDIN, or a regular file. If we were reading code from + * STDIN (because the commandline held no -e or filename) + * then we don't close it, we reset it so the code can + * read from STDIN too. + */ + if (PL_preprocess && !PL_in_eval) (void)PerlProc_pclose(PL_rsfp); else if ((PerlIO*)PL_rsfp == PerlIO_stdin()) @@ -489,25 +580,54 @@ skipspace(register char *s) PL_rsfp = Nullfp; return 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, + * so store the line into the debugger's array of lines + */ if (PERLDB_LINE && PL_curstash != PL_debstash) { SV *sv = NEWSV(85,0); 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); } } } +/* + * S_check_uni + * Check the unary operators to ensure there's no ambiguity in how they're + * used. An ambiguous piece of code would be: + * rand + 5 + * This doesn't mean rand() + 5. Because rand() is a unary operator, + * the +5 is its argument. + */ + STATIC void -check_uni(void) { +S_check_uni(pTHX) +{ char *s; - char ch; char *t; + dTHR; if (PL_oldoldbufptr != PL_last_uni) return; @@ -516,19 +636,28 @@ check_uni(void) { for (s = PL_last_uni; isALNUM_lazy(s) || *s == '-'; s++) ; if ((t = strchr(s, '(')) && t < PL_bufptr) return; - ch = *s; - *s = '\0'; - warn("Warning: Use of \"%s\" without parens is ambiguous", PL_last_uni); - *s = ch; + if (ckWARN_d(WARN_AMBIGUOUS)){ + char ch = *s; + *s = '\0'; + Perl_warner(aTHX_ WARN_AMBIGUOUS, + "Warning: Use of \"%s\" without parens is ambiguous", + PL_last_uni); + *s = ch; + } } +/* workaround to replace the UNI() macro with a function. Only the + * hints/uts.sh file mentions this. Other comments elsewhere in the + * source indicate Microport Unix might need it too. + */ + #ifdef CRIPPLED_CC #undef UNI #define UNI(f) return uni(f,s) STATIC int -uni(I32 f, char *s) +S_uni(pTHX_ I32 f, char *s) { yylval.ival = f; PL_expect = XTERM; @@ -546,10 +675,23 @@ uni(I32 f, char *s) #endif /* CRIPPLED_CC */ +/* + * LOP : macro to build a list operator. Its behaviour has been replaced + * with a subroutine, S_lop() for which LOP is just another name. + */ + #define LOP(f,x) return lop(f,x,s) +/* + * S_lop + * Build a list operator (or something that might be one). The rules: + * - if we have a next token, then it's a list operator [why?] + * - if the next thing is an opening paren, then it's a function + * - else it's a list operator + */ + STATIC I32 -lop(I32 f, expectation x, char *s) +S_lop(pTHX_ I32 f, int x, char *s) { dTHR; yylval.ival = f; @@ -569,8 +711,17 @@ lop(I32 f, expectation x, char *s) return LSTOP; } +/* + * S_force_next + * When the lexer realizes it knows the next token (for instance, + * it is reordering tokens for the parser) then it can call S_force_next + * to know what token to return the next time the lexer is called. Caller + * will need to set PL_nextval[], and possibly PL_expect to ensure the lexer + * handles the token correctly. + */ + STATIC void -force_next(I32 type) +S_force_next(pTHX_ I32 type) { PL_nexttype[PL_nexttoke] = type; PL_nexttoke++; @@ -581,8 +732,24 @@ force_next(I32 type) } } +/* + * S_force_word + * When the lexer knows the next thing is a word (for instance, it has + * just seen -> and it knows that the next char is a word char, then + * it calls S_force_word to stick the next word into the PL_next lookahead. + * + * Arguments: + * 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) + * int allow_pack : if true, : characters will also be allowed (require, + * use, etc. do this) + * int allow_initial_tick : used by the "sub" lexer only. + */ + STATIC char * -force_word(register char *start, int token, int check_keyword, int allow_pack, int allow_initial_tick) +S_force_word(pTHX_ register char *start, int token, int check_keyword, int allow_pack, int allow_initial_tick) { register char *s; STRLEN len; @@ -611,8 +778,17 @@ force_word(register char *start, int token, int check_keyword, int allow_pack, i return s; } +/* + * S_force_ident + * Called when the lexer wants $foo *foo &foo etc, but the program + * text only contains the "foo" portion. The first argument is a pointer + * to the "foo", and the second argument is the type symbol to prefix. + * Forces the next token to be a "WORD". + * Creates the symbol if it didn't already exist (via gv_fetchpv()). + */ + STATIC void -force_ident(register char *s, int kind) +S_force_ident(pTHX_ register char *s, int kind) { if (s && *s) { OP* o = (OP*)newSVOP(OP_CONST, 0, newSVpv(s,0)); @@ -634,20 +810,24 @@ force_ident(register char *s, int kind) } } +/* + * S_force_version + * Forces the next token to be a version number. + */ + STATIC char * -force_version(char *s) +S_force_version(pTHX_ char *s) { OP *version = Nullop; 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; @@ -661,8 +841,16 @@ force_version(char *s) return (s); } +/* + * S_tokeq + * Tokenize a quoted string passed in as an SV. It finds the next + * chunk, up to end of string or a backslash. It may make a new + * SV containing that chunk (if HINT_NEW_STRING is on). It also + * turns \\ into \. + */ + STATIC SV * -tokeq(SV *sv) +S_tokeq(pTHX_ SV *sv) { register char *s; register char *send; @@ -699,8 +887,40 @@ tokeq(SV *sv) return sv; } +/* + * Now come three functions related to double-quote context, + * S_sublex_start, S_sublex_push, and S_sublex_done. They're used when + * converting things like "\u\Lgnat" into ucfirst(lc("gnat")). They + * interact with PL_lex_state, and create fake ( ... ) argument lists + * to handle functions and concatenation. + * They assume that whoever calls them will be setting up a fake + * join call, because each subthing puts a ',' after it. This lets + * "lower \luPpEr" + * become + * join($, , 'lower ', lcfirst( 'uPpEr', ) ,) + * + * (I'm not sure whether the spurious commas at the end of lcfirst's + * arguments and join's arguments are created or not). + */ + +/* + * S_sublex_start + * Assumes that yylval.ival is the op we're creating (e.g. OP_LCFIRST). + * + * Pattern matching will set PL_lex_op to the pattern-matching op to + * make (we return THING if yylval.ival is OP_NULL, PMFUNC otherwise). + * + * OP_CONST and OP_READLINE are easy--just make the new op and return. + * + * Everything else becomes a FUNC. + * + * Sets PL_lex_state to LEX_INTERPPUSH unless (ival was OP_NULL or we + * had an OP_CONST or OP_READLINE). This just sets us up for a + * call to S_sublex_push(). + */ + STATIC I32 -sublex_start(void) +S_sublex_start(pTHX) { register I32 op_type = yylval.ival; @@ -743,8 +963,16 @@ sublex_start(void) return FUNC; } +/* + * S_sublex_push + * Create a new scope to save the lexing state. The scope will be + * ended in S_sublex_done. Returns a '(', starting the function arguments + * to the uc, lc, etc. found before. + * Sets PL_lex_state to LEX_INTERPCONCAT. + */ + STATIC I32 -sublex_push(void) +S_sublex_push(pTHX) { dTHR; ENTER; @@ -752,13 +980,12 @@ sublex_push(void) 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); @@ -770,13 +997,13 @@ sublex_push(void) PL_linestr = PL_lex_stuff; PL_lex_stuff = Nullsv; - PL_bufend = PL_bufptr = PL_oldbufptr = PL_oldoldbufptr = PL_linestart = SvPVX(PL_linestr); + PL_bufend = PL_bufptr = PL_oldbufptr = PL_oldoldbufptr = PL_linestart + = SvPVX(PL_linestr); PL_bufend += SvCUR(PL_linestr); SAVEFREESV(PL_linestr); 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); @@ -785,7 +1012,7 @@ sublex_push(void) *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) @@ -796,8 +1023,13 @@ sublex_push(void) return '('; } +/* + * S_sublex_done + * Restores lexer state after a S_sublex_push. + */ + STATIC I32 -sublex_done(void) +S_sublex_done(pTHX) { if (!PL_lex_starts++) { PL_expect = XOPERATOR; @@ -807,10 +1039,10 @@ sublex_done(void) if (PL_lex_casemods) { /* oops, we've got some unbalanced parens */ PL_lex_state = LEX_INTERPCASEMOD; - return yylex(PERL_YYLEX_PARAM); + return yylex(); } - /* Is there a right-hand side to take care of? */ + /* Is there a right-hand side to take care of? (s//RHS/ or tr//RHS/) */ if (PL_lex_repl && (PL_lex_inwhat == OP_SUBST || PL_lex_inwhat == OP_TRANS)) { PL_linestr = PL_lex_repl; PL_lex_inpat = 0; @@ -819,11 +1051,10 @@ sublex_done(void) 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; - if (SvCOMPILED(PL_lex_repl)) { + if (SvEVALED(PL_lex_repl)) { PL_lex_state = LEX_INTERPNORMAL; PL_lex_starts++; /* we don't clear PL_lex_repl here, so that we can check later @@ -842,6 +1073,7 @@ sublex_done(void) PL_bufend = SvPVX(PL_linestr); PL_bufend += SvCUR(PL_linestr); PL_expect = XOPERATOR; + PL_sublex_info.sub_inwhat = 0; return ')'; } } @@ -920,7 +1152,7 @@ sublex_done(void) */ STATIC char * -scan_const(char *start) +S_scan_const(pTHX_ char *start) { register char *send = PL_bufend; /* end of the constant */ SV *sv = NEWSV(93, send - start); /* sv for the constant */ @@ -928,15 +1160,14 @@ scan_const(char *start) register char *d = SvPVX(sv); /* destination for copies */ bool dorange = FALSE; /* are we in a translit range? */ I32 len; /* ? */ - I32 utf = PL_lex_inwhat == OP_TRANS + I32 utf = (PL_lex_inwhat == OP_TRANS && PL_sublex_info.sub_op) ? (PL_sublex_info.sub_op->op_private & (OPpTRANS_FROM_UTF|OPpTRANS_TO_UTF)) : UTF; - I32 thisutf = PL_lex_inwhat == OP_TRANS - ? (PL_sublex_info.sub_op->op_private & (PL_lex_repl ? OPpTRANS_FROM_UTF : OPpTRANS_TO_UTF)) + I32 thisutf = (PL_lex_inwhat == OP_TRANS && PL_sublex_info.sub_op) + ? (PL_sublex_info.sub_op->op_private & (PL_lex_repl ? + OPpTRANS_FROM_UTF : OPpTRANS_TO_UTF)) : UTF; - - /* leaveit is the set of acceptably-backslashed characters */ - char *leaveit = + const char *leaveit = /* set of acceptably-backslashed characters */ PL_lex_inpat ? "\\.^$@AGZdDwWsSbBpPXC+*?|()-nrtfeaxcz0123456789[{]} \t\n\r\f\v#" : ""; @@ -951,8 +1182,8 @@ scan_const(char *start) I32 max; /* last character in range */ i = d - SvPVX(sv); /* remember current offset */ - SvGROW(sv, SvLEN(sv) + 256); /* expand the sv -- there'll never be more'n 256 chars in a range for it to grow by */ - d = SvPVX(sv) + i; /* restore d after the grow potentially has changed the ptr */ + SvGROW(sv, SvLEN(sv) + 256); /* never more than 256 chars in a range */ + d = SvPVX(sv) + i; /* refresh d after realloc */ d -= 2; /* eat the first char and the - */ min = (U8)*d; /* first char in range */ @@ -1077,7 +1308,7 @@ scan_const(char *start) { dTHR; /* only for ckWARN */ if (ckWARN(WARN_SYNTAX)) - warner(WARN_SYNTAX, "\\%c better written as $%c", *s, *s); + Perl_warner(aTHX_ WARN_SYNTAX, "\\%c better written as $%c", *s, *s); *--s = '$'; break; } @@ -1102,7 +1333,7 @@ scan_const(char *start) { dTHR; if (ckWARN(WARN_UNSAFE) && isALPHA(*s)) - warner(WARN_UNSAFE, + Perl_warner(aTHX_ WARN_UNSAFE, "Unrecognized escape \\%c passed through", *s); /* default action is to copy the quoted character */ @@ -1113,7 +1344,7 @@ scan_const(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; @@ -1130,14 +1361,13 @@ scan_const(char *start) if (!utf) { dTHR; if (ckWARN(WARN_UTF8)) - warner(WARN_UTF8, + Perl_warner(aTHX_ WARN_UTF8, "Use of \\x{} without utf8 declaration"); } /* 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 { UV uv = (UV)scan_hex(s, 2, &len); @@ -1150,9 +1380,9 @@ scan_const(char *start) if (uv >= 127 && UTF) { dTHR; if (ckWARN(WARN_UTF8)) - warner(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; } @@ -1160,6 +1390,43 @@ scan_const(char *start) } continue; + /* \N{latin small letter a} is a named character */ + case 'N': + ++s; + if (*s == '{') { + char* e = strchr(s, '}'); + HV *hv; + SV **svp; + SV *res, *cv; + STRLEN len; + char *str; + char *why = Nullch; + + if (!e) { + 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, "\\N{...}" ); + str = SvPV(res,len); + if (len > e - s + 4) { + char *odest = SvPVX(sv); + + SvGROW(sv, (SvCUR(sv) + len - (e - s + 4))); + d = SvPVX(sv) + (d - odest); + } + Copy(str, d, len, char); + d += len; + SvREFCNT_dec(res); + cont_scan: + s = e + 1; + } + else + yyerror("Missing braces on \\N{}"); + continue; + /* \c is a control character */ case 'c': s++; @@ -1190,12 +1457,21 @@ scan_const(char *start) case 't': *d++ = '\t'; break; +#ifdef EBCDIC + case 'e': + *d++ = '\047'; /* CP 1047 */ + break; + case 'a': + *d++ = '\057'; /* CP 1047 */ + break; +#else case 'e': *d++ = '\033'; break; case 'a': *d++ = '\007'; break; +#endif } /* end switch */ s++; @@ -1232,9 +1508,29 @@ scan_const(char *start) return s; } +/* S_intuit_more + * Returns TRUE if there's more to the expression (e.g., a subscript), + * FALSE otherwise. + * + * It deals with "$foo[3]" and /$foo[3]/ and /$foo[0123456789$]+/ + * + * ->[ and ->{ return TRUE + * { and [ outside a pattern are always subscripts, so return TRUE + * if we're outside a pattern and it's not { or [, then return FALSE + * if we're in a pattern and the first char is a { + * {4,5} (any digits around the comma) returns FALSE + * if we're in a pattern and the first char is a [ + * [] returns FALSE + * [SOMETHING] has a funky algorithm to decide whether it's a + * character class or not. It has to deal with things like + * /$foo[-3]/ and /$foo[$bar]/ as well as /$foo[$\d]+/ + * anything else returns TRUE + */ + /* This is the one truly awful dwimmer necessary to conflate C and sed. */ + STATIC int -intuit_more(register char *s) +S_intuit_more(pTHX_ register char *s) { if (PL_lex_brackets) return TRUE; @@ -1268,6 +1564,7 @@ intuit_more(register char *s) if (*s == ']' || *s == '^') return FALSE; else { + /* this is terrifying, and it works */ int weight = 2; /* let's weigh the evidence */ char seen[256]; unsigned char un_char = 255, last_un_char; @@ -1363,8 +1660,29 @@ intuit_more(register char *s) return TRUE; } +/* + * S_intuit_method + * + * Does all the checking to disambiguate + * foo bar + * between foo(bar) and bar->foo. Returns 0 if not a method, otherwise + * FUNCMETH (bar->foo(args)) or METHOD (bar->foo args). + * + * First argument is the stuff after the first token, e.g. "bar". + * + * Not a method if bar is a filehandle. + * Not a method if foo is a subroutine prototyped to take a filehandle. + * Not a method if it's really "Foo $bar" + * Method if it's "foo $bar" + * Not a method if it's really "print foo $bar" + * Method if it's really "foo package::" (interpreted as package->foo) + * Not a method if bar is known to be a subroutne ("sub bar; foo bar") + * Not a method if bar is a filehandle or package, but is quotd with + * => + */ + STATIC int -intuit_method(char *start, GV *gv) +S_intuit_method(pTHX_ char *start, GV *gv) { char *s = start + (*start == '$'); char tmpbuf[sizeof PL_tokenbuf]; @@ -1387,6 +1705,11 @@ intuit_method(char *start, GV *gv) gv = 0; } s = scan_word(s, tmpbuf, sizeof tmpbuf, TRUE, &len); + /* start is the beginning of the possible filehandle/object, + * and s is the end of it + * tmpbuf is a copy of it + */ + if (*start == '$') { if (gv || PL_last_lop_op == OP_PRINT || isUPPER(*PL_tokenbuf)) return 0; @@ -1422,8 +1745,15 @@ intuit_method(char *start, GV *gv) return 0; } +/* + * S_incl_perldb + * Return a string of Perl code to load the debugger. If PERL5DB + * is set, it will return the contents of that, otherwise a + * compile-time require of perl5db.pl. + */ + STATIC char* -incl_perldb(void) +S_incl_perldb(pTHX) { if (PL_perldb) { char *pdb = PerlEnv_getenv("PERL5DB"); @@ -1448,29 +1778,28 @@ incl_perldb(void) * 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. */ SV * -filter_add(filter_t funcp, SV *datasv) +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) datasv = NEWSV(255,0); if (!SvUPGRADE(datasv, SVt_PVIO)) - die("Can't upgrade filter_add data to SVt_PVIO"); + Perl_die(aTHX_ "Can't upgrade filter_add data to SVt_PVIO"); IoDIRP(datasv) = (DIR*)funcp; /* stash funcp into spare field */ - if (PL_filter_debug) { - STRLEN n_a; - warn("filter_add func %p (%s)", funcp, SvPV(datasv, n_a)); - } + 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); @@ -1479,26 +1808,29 @@ filter_add(filter_t funcp, SV *datasv) /* Delete most recently added instance of this filter function. */ void -filter_del(filter_t funcp) +Perl_filter_del(pTHX_ filter_t funcp) { - if (PL_filter_debug) - warn("filter_del func %p", funcp); + 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){ + 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; } /* we need to search for the correct entry and clear it */ - die("filter_del can only delete in reverse order (currently)"); + Perl_die(aTHX_ "filter_del can only delete in reverse order (currently)"); } /* Invoke the n'th filter function for the current rsfp. */ I32 -filter_read(int idx, SV *buf_sv, int maxlen) +Perl_filter_read(pTHX_ int idx, SV *buf_sv, int maxlen) /* 0 = read one text line */ @@ -1511,8 +1843,8 @@ filter_read(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. */ - if (PL_filter_debug) - warn("filter_read %d: from rsfp\n", idx); + DEBUG_P(PerlIO_printf(Perl_debug_log, + "filter_read %d: from rsfp\n", idx)); if (maxlen) { /* Want a block */ int len ; @@ -1540,29 +1872,28 @@ filter_read(int idx, SV *buf_sv, int maxlen) } /* Skip this filter slot if filter has been deleted */ if ( (datasv = FILTER_DATA(idx)) == &PL_sv_undef){ - if (PL_filter_debug) - warn("filter_read %d: skipped (filter deleted)\n", idx); + 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); - if (PL_filter_debug) { - STRLEN n_a; - warn("filter_read %d: via function %p (%s)\n", - idx, funcp, SvPV(datasv,n_a)); - } + 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 */ - return (*funcp)(PERL_OBJECT_THIS_ idx, buf_sv, maxlen); + return (*funcp)(aTHXo_ idx, buf_sv, maxlen); } STATIC char * -filter_gets(register SV *sv, register PerlIO *fp, STRLEN append) +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) { @@ -1581,7 +1912,9 @@ filter_gets(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 /* @@ -1609,7 +1942,12 @@ filter_gets(register SV *sv, register PerlIO *fp, STRLEN append) if we already built the token before, use it. */ -int yylex(PERL_YYLEX_PARAM_DECL) +int +#ifdef USE_PURE_BISON +Perl_yylex(pTHX_ YYSTYPE *lvalp, int *lcharp) +#else +Perl_yylex(pTHX) +#endif { dTHR; register char *s; @@ -1637,12 +1975,21 @@ int yylex(PERL_YYLEX_PARAM_DECL) if it's a legal name, the OP is a PADANY. */ if (PL_in_my) { - if (strchr(PL_tokenbuf,':')) - yyerror(form(PL_no_myglob,PL_tokenbuf)); + 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 { + 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; + } } /* @@ -1670,6 +2017,26 @@ int yylex(PERL_YYLEX_PARAM_DECL) } #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(namesv) & SVpad_OUR) { + /* build ops for a bareword */ + 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(SvPVX(sym), + (PL_in_eval + ? (GV_ADDMULTI | GV_ADDINEVAL) + : TRUE + ), + ((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] == '$' && @@ -1681,7 +2048,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) d++) { if (strnEQ(d,"<=>",3) || strnEQ(d,"cmp",3)) { - croak("Can't use \"my %s\" in sort comparison", + Perl_croak(aTHX_ "Can't use \"my %s\" in sort comparison", PL_tokenbuf); } } @@ -1701,7 +2068,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) if (pit == '@' && PL_lex_state != LEX_NORMAL && !PL_lex_brackets) { GV *gv = gv_fetchpv(PL_tokenbuf+1, FALSE, SVt_PVAV); if (!gv || ((PL_tokenbuf[0] == '@') ? !GvAV(gv) : !GvHV(gv))) - yyerror(form("In string, %s now must be written as \\%s", + yyerror(Perl_form(aTHX_ "In string, %s now must be written as \\%s", PL_tokenbuf, PL_tokenbuf)); } @@ -1724,7 +2091,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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]; @@ -1741,7 +2108,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) case LEX_INTERPCASEMOD: #ifdef DEBUGGING if (PL_bufptr != PL_bufend && *PL_bufptr != '\\') - croak("panic: INTERPCASEMOD"); + Perl_croak(aTHX_ "panic: INTERPCASEMOD"); #endif /* handle \E or end of string */ if (PL_bufptr == PL_bufend || PL_bufptr[1] == 'E') { @@ -1761,7 +2128,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) if (PL_bufptr != PL_bufend) PL_bufptr += 2; PL_lex_state = LEX_INTERPCONCAT; - return yylex(PERL_YYLEX_PARAM); + return yylex(); } else { s = PL_bufptr + 1; @@ -1796,7 +2163,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) else if (*s == 'Q') PL_nextval[PL_nexttoke].ival = OP_QUOTEMETA; else - croak("panic: yylex"); + Perl_croak(aTHX_ "panic: yylex"); PL_bufptr = s + 1; force_next(FUNC); if (PL_lex_starts) { @@ -1805,7 +2172,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) Aop(OP_CONCAT); } else - return yylex(PERL_YYLEX_PARAM); + return yylex(); } case LEX_INTERPPUSH: @@ -1838,7 +2205,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) s = PL_bufptr; Aop(OP_CONCAT); } - return yylex(PERL_YYLEX_PARAM); + return yylex(); case LEX_INTERPENDMAYBE: if (intuit_more(PL_bufptr)) { @@ -1854,17 +2221,17 @@ int yylex(PERL_YYLEX_PARAM_DECL) return ')'; } if (PL_lex_inwhat == OP_SUBST && PL_linestr == PL_lex_repl - && SvCOMPILED(PL_lex_repl)) + && SvEVALED(PL_lex_repl)) { if (PL_bufptr != PL_bufend) - croak("Bad evalled substitution pattern"); + Perl_croak(aTHX_ "Bad evalled substitution pattern"); PL_lex_repl = Nullsv; } /* FALLTHROUGH */ case LEX_INTERPCONCAT: #ifdef DEBUGGING if (PL_lex_brackets) - croak("panic: INTERPCONCAT"); + Perl_croak(aTHX_ "panic: INTERPCONCAT"); #endif if (PL_bufptr == PL_bufend) return sublex_done(); @@ -1894,11 +2261,11 @@ int yylex(PERL_YYLEX_PARAM_DECL) Aop(OP_CONCAT); else { PL_bufptr = s; - return yylex(PERL_YYLEX_PARAM); + return yylex(); } } - return yylex(PERL_YYLEX_PARAM); + return yylex(); case LEX_FORMLINE: PL_lex_state = LEX_NORMAL; s = scan_formline(PL_bufptr); @@ -1911,7 +2278,8 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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: @@ -1919,7 +2287,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) default: if (isIDFIRST_lazy(s)) goto keylookup; - croak("Unrecognized character \\x%02X", *s & 255); + Perl_croak(aTHX_ "Unrecognized character \\x%02X", *s & 255); case 4: case 26: goto fake_eof; /* emulate EOF on ^D or ^Z */ @@ -1961,20 +2329,20 @@ int yylex(PERL_YYLEX_PARAM_DECL) if (PL_minus_F) { if (strchr("/'\"", *PL_splitstr) && strchr(PL_splitstr + 1, *PL_splitstr)) - sv_catpvf(PL_linestr, "@F=split(%s);", PL_splitstr); + Perl_sv_catpvf(aTHX_ PL_linestr, "@F=split(%s);", PL_splitstr); else { char delim; s = "'~#\200\1'"; /* surely one char is unused...*/ while (s[1] && strchr(PL_splitstr, *s)) s++; delim = *s; - sv_catpvf(PL_linestr, "@F=split(%s%c", + Perl_sv_catpvf(aTHX_ PL_linestr, "@F=split(%s%c", "q" + (delim == '\''), delim); for (s = PL_splitstr; *s; s++) { if (*s == '\\') sv_catpvn(PL_linestr, "\\", 1); sv_catpvn(PL_linestr, s, 1); } - sv_catpvf(PL_linestr, "%c);", delim); + Perl_sv_catpvf(aTHX_ PL_linestr, "%c);", delim); } } else @@ -1989,7 +2357,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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; } @@ -2038,10 +2406,10 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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 */ @@ -2079,7 +2447,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) */ 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); } @@ -2091,8 +2459,24 @@ int yylex(PERL_YYLEX_PARAM_DECL) * 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 @@ -2138,7 +2522,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) newargv = PL_origargv; newargv[0] = ipath; PerlProc_execv(ipath, newargv); - croak("Can't exec %s", ipath); + Perl_croak(aTHX_ "Can't exec %s", ipath); } if (d) { U32 oldpdb = PL_perldb; @@ -2153,7 +2537,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) if (*d == 'M' || *d == 'm') { char *m = d; while (*d && !isSPACE(*d)) d++; - croak("Too late for \"-%.*s\" option", + Perl_croak(aTHX_ "Too late for \"-%.*s\" option", (int)(d - m), m); } d = moreswitches(d); @@ -2178,13 +2562,13 @@ int yylex(PERL_YYLEX_PARAM_DECL) if (PL_lex_formbrack && PL_lex_brackets <= PL_lex_formbrack) { PL_bufptr = s; PL_lex_state = LEX_FORMLINE; - return yylex(PERL_YYLEX_PARAM); + return yylex(); } goto retry; case '\r': #ifdef PERL_STRICT_CR - warn("Illegal character \\%03o (carriage return)", '\r'); - croak( + Perl_warn(aTHX_ "Illegal character \\%03o (carriage return)", '\r'); + Perl_croak(aTHX_ "(Maybe you didn't strip carriage returns after a network transfer?)\n"); #endif case ' ': case '\t': case '\f': case 013: @@ -2202,7 +2586,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) if (PL_lex_formbrack && PL_lex_brackets <= PL_lex_formbrack) { PL_bufptr = s; PL_lex_state = LEX_FORMLINE; - return yylex(PERL_YYLEX_PARAM); + return yylex(); } } else { @@ -2254,7 +2638,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) case 'A': gv_fetchpv("\024",TRUE, SVt_PV); FTST(OP_FTATIME); case 'C': gv_fetchpv("\024",TRUE, SVt_PV); FTST(OP_FTCTIME); default: - croak("Unrecognized file test: -%c", (int)tmp); + Perl_croak(aTHX_ "Unrecognized file test: -%c", (int)tmp); break; } } @@ -2350,6 +2734,102 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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 (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) { + 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); + 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 != '=' || *s != ')')) { + 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(':'); + } + got_attrs: + if (attrs) { + PL_nextval[PL_nexttoke].opval = attrs; + force_next(THING); + } + TOKEN(COLONATTR); + } OPERATOR(':'); case '(': s++; @@ -2359,8 +2839,8 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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 ')': @@ -2427,10 +2907,12 @@ int yylex(PERL_YYLEX_PARAM_DECL) } } /* 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; @@ -2471,7 +2953,8 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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; @@ -2502,8 +2985,10 @@ int yylex(PERL_YYLEX_PARAM_DECL) } 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++; @@ -2513,7 +2998,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) || (*t == '=' && t[1] == '>'))) OPERATOR(HASHBRACK); if (PL_expect == XREF) - PL_expect = XSTATE; /* was XTERM, trying XSTATE */ + PL_expect = XTERM; else { PL_lex_brackstack[PL_lex_brackets-1] = XSTATE; PL_expect = XSTATE; @@ -2521,7 +3006,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) } 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('{'); @@ -2536,10 +3021,11 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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(PERL_YYLEX_PARAM); /* ignore fake brackets */ + return yylex(); /* ignore fake brackets */ } if (*s == '-' && s[1] == '>') PL_lex_state = LEX_INTERPENDMAYBE; @@ -2547,10 +3033,10 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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(PERL_YYLEX_PARAM); /* ignore fake brackets */ + return yylex(); /* ignore fake brackets */ } force_next('}'); TOKEN(';'); @@ -2562,9 +3048,9 @@ int yylex(PERL_YYLEX_PARAM_DECL) s--; if (PL_expect == XOPERATOR) { if (ckWARN(WARN_SEMICOLON) && isIDFIRST_lazy(s) && PL_bufptr == PL_linestart) { - PL_curcop->cop_line--; - warner(WARN_SEMICOLON, PL_warn_nosemi); - PL_curcop->cop_line++; + CopLINE_dec(PL_curcop); + Perl_warner(aTHX_ WARN_SEMICOLON, PL_warn_nosemi); + CopLINE_inc(PL_curcop); } BAop(OP_BIT_AND); } @@ -2596,7 +3082,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) if (tmp == '~') PMop(OP_MATCH); if (ckWARN(WARN_SYNTAX) && tmp && isSPACE(*s) && strchr("+-*/%.^&|<",tmp)) - warner(WARN_SYNTAX, "Reversed %c= operator",(int)tmp); + Perl_warner(aTHX_ WARN_SYNTAX, "Reversed %c= operator",(int)tmp); s--; if (PL_expect == XSTATE && isALPHA(tmp) && (s == PL_linestart+1 || s[-2] == '\n') ) @@ -2692,11 +3178,11 @@ int yylex(PERL_YYLEX_PARAM_DECL) } if (s[1] == '#' && (isIDFIRST_lazy(s+2) || strchr("{$:+-", s[2]))) { - if (PL_expect == XOPERATOR) - no_op("Array length", PL_bufptr); PL_tokenbuf[0] = '@'; - s = scan_ident(s + 1, PL_bufend, PL_tokenbuf + 1, sizeof PL_tokenbuf - 1, - FALSE); + s = scan_ident(s + 1, PL_bufend, PL_tokenbuf + 1, + sizeof PL_tokenbuf - 1, FALSE); + if (PL_expect == XOPERATOR) + no_op("Array length", s); if (!PL_tokenbuf[1]) PREREF(DOLSHARP); PL_expect = XOPERATOR; @@ -2704,10 +3190,11 @@ int yylex(PERL_YYLEX_PARAM_DECL) TOKEN(DOLSHARP); } - if (PL_expect == XOPERATOR) - no_op("Scalar", PL_bufptr); PL_tokenbuf[0] = '$'; - s = scan_ident(s, PL_bufend, PL_tokenbuf + 1, sizeof PL_tokenbuf - 1, FALSE); + s = scan_ident(s, PL_bufend, PL_tokenbuf + 1, + sizeof PL_tokenbuf - 1, FALSE); + if (PL_expect == XOPERATOR) + no_op("Scalar", s); if (!PL_tokenbuf[1]) { if (s == PL_bufend) yyerror("Final $ should be \\$ or $name"); @@ -2723,6 +3210,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) } d = s; + tmp = (I32)*s; if (PL_lex_state == LEX_NORMAL) s = skipspace(s); @@ -2738,7 +3226,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) PL_bufptr = skipspace(PL_bufptr); while (t < PL_bufend && *t != ']') t++; - warner(WARN_SYNTAX, + Perl_warner(aTHX_ WARN_SYNTAX, "Multidimensional syntax %.*s not supported", (t - PL_bufptr) + 1, PL_bufptr); } @@ -2755,8 +3243,8 @@ int yylex(PERL_YYLEX_PARAM_DECL) if (isIDFIRST_lazy(t)) { t = scan_word(t, tmpbuf, sizeof tmpbuf, TRUE, &len); for (; isSPACE(*t); t++) ; - if (*t == ';' && perl_get_cv(tmpbuf, FALSE)) - warner(WARN_SYNTAX, + if (*t == ';' && get_cv(tmpbuf, FALSE)) + Perl_warner(aTHX_ WARN_SYNTAX, "You need to quote \"%s\"", tmpbuf); } } @@ -2764,7 +3252,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) } PL_expect = XOPERATOR; - if (PL_lex_state == LEX_NORMAL && isSPACE(*d)) { + if (PL_lex_state == LEX_NORMAL && isSPACE((char)tmp)) { bool islop = (PL_last_lop == PL_oldoldbufptr); if (!islop || PL_last_lop_op == OP_GREPSTART) PL_expect = XOPERATOR; @@ -2835,7 +3323,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) if (*t == '}' || *t == ']') { t++; PL_bufptr = skipspace(PL_bufptr); - warner(WARN_SYNTAX, + Perl_warner(aTHX_ WARN_SYNTAX, "Scalar value %.*s better written as $%.*s", t-PL_bufptr, PL_bufptr, t-PL_bufptr-1, PL_bufptr+1); } @@ -2899,7 +3387,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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; @@ -2915,7 +3403,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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; @@ -2937,7 +3425,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) TERM(sublex_start()); case '`': - s = scan_str(s); + s = scan_str(s,FALSE,FALSE); if (PL_expect == XOPERATOR) no_op("Backticks",s); if (!s) @@ -2949,12 +3437,25 @@ int yylex(PERL_YYLEX_PARAM_DECL) case '\\': s++; if (ckWARN(WARN_SYNTAX) && PL_lex_inwhat && isDIGIT(*s)) - warner(WARN_SYNTAX,"Can't use \\%c to mean $%c in expression", + Perl_warner(aTHX_ WARN_SYNTAX,"Can't use \\%c to mean $%c in expression", *s, *s); if (PL_expect == XOPERATOR) 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++; @@ -2984,7 +3485,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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': @@ -3058,6 +3559,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) } 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 */ @@ -3068,7 +3570,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) gvp = 0; if (ckWARN(WARN_AMBIGUOUS) && hgv && tmp != KEY_x && tmp != KEY_CORE) /* never ambiguous */ - warner(WARN_AMBIGUOUS, + Perl_warner(aTHX_ WARN_AMBIGUOUS, "Ambiguous call resolved as CORE::%s(), %s", GvENAME(hgv), "qualify as such or use &"); } @@ -3089,16 +3591,16 @@ int yylex(PERL_YYLEX_PARAM_DECL) s = scan_word(s, PL_tokenbuf + len, sizeof PL_tokenbuf - len, TRUE, &morelen); if (!morelen) - croak("Bad name after %s%s", PL_tokenbuf, + Perl_croak(aTHX_ "Bad name after %s%s", PL_tokenbuf, *s == '\'' ? "'" : "::"); len += morelen; } if (PL_expect == XOPERATOR) { if (PL_bufptr == PL_linestart) { - PL_curcop->cop_line--; - warner(WARN_SEMICOLON, PL_warn_nosemi); - PL_curcop->cop_line++; + CopLINE_dec(PL_curcop); + Perl_warner(aTHX_ WARN_SEMICOLON, PL_warn_nosemi); + CopLINE_inc(PL_curcop); } else no_op("Bareword",s); @@ -3112,7 +3614,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) PL_tokenbuf[len - 2] == ':' && PL_tokenbuf[len - 1] == ':') { if (ckWARN(WARN_UNSAFE) && ! gv_fetchpv(PL_tokenbuf, FALSE, SVt_PVHV)) - warner(WARN_UNSAFE, + Perl_warner(aTHX_ WARN_UNSAFE, "Bareword \"%s\" refers to nonexistent package", PL_tokenbuf); len -= 2; @@ -3150,13 +3652,11 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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 - || (PL_last_lop_op == OP_ENTERSUB - && PL_last_proto - && PL_last_proto[PL_last_proto[0] == ';' ? 1 : 0] == '*')) ) + (PL_expect == XREF || + ((PL_opargs[PL_last_lop_op] >> OASHIFT)& 7) == OA_FILEREF)) { bool immediate_paren = *s == '('; @@ -3172,8 +3672,10 @@ int yylex(PERL_YYLEX_PARAM_DECL) /* (But it's an indir obj regardless for sort.) */ if ((PL_last_lop_op == OP_SORT || - (!immediate_paren && (!gv || !GvCVu(gv))) ) && - (PL_last_lop_op != OP_MAPSTART && PL_last_lop_op != OP_GREPSTART)){ + (!immediate_paren && (!gv || !GvCVu(gv)))) && + (PL_last_lop_op != OP_MAPSTART && + PL_last_lop_op != OP_GREPSTART)) + { PL_expect = (PL_last_lop == PL_oldoldbufptr) ? XTERM : XOPERATOR; goto bareword; } @@ -3186,11 +3688,8 @@ int yylex(PERL_YYLEX_PARAM_DECL) if (*s == '(') { CLINE; if (gv && GvCVu(gv)) { - CV *cv; - if ((cv = GvCV(gv)) && SvPOK(cv)) - PL_last_proto = SvPV((SV*)cv, n_a); for (d = s + 1; *d == ' ' || *d == '\t'; d++) ; - if (*d == ')' && (sv = cv_const_sv(cv))) { + if (*d == ')' && (sv = cv_const_sv(GvCV(gv)))) { s = d + 1; goto its_constant; } @@ -3199,7 +3698,6 @@ int yylex(PERL_YYLEX_PARAM_DECL) PL_expect = XOPERATOR; force_next(WORD); yylval.ival = 0; - PL_last_lop_op = OP_ENTERSUB; TOKEN('&'); } @@ -3220,11 +3718,10 @@ int yylex(PERL_YYLEX_PARAM_DECL) if (gv && GvCVu(gv)) { CV* cv; - if (lastchar == '-') - warn("Ambiguous use of -%s resolved as -&%s()", + if (lastchar == '-' && ckWARN_d(WARN_AMBIGUOUS)) + Perl_warner(aTHX_ WARN_AMBIGUOUS, + "Ambiguous use of -%s resolved as -&%s()", PL_tokenbuf, PL_tokenbuf); - PL_last_lop = PL_oldbufptr; - PL_last_lop_op = OP_ENTERSUB; /* Check for a constant sub */ cv = GvCV(gv); if ((sv = cv_const_sv(cv))) { @@ -3238,60 +3735,51 @@ int yylex(PERL_YYLEX_PARAM_DECL) /* Resolve to GV now. */ op_free(yylval.opval); yylval.opval = newCVREF(0, newGVOP(OP_GV, 0, gv)); + yylval.opval->op_private |= OPpENTERSUB_NOPAREN; + PL_last_lop = PL_oldbufptr; PL_last_lop_op = OP_ENTERSUB; /* Is there a prototype? */ if (SvPOK(cv)) { STRLEN len; - PL_last_proto = SvPV((SV*)cv, len); + char *proto = SvPV((SV*)cv, len); if (!len) TERM(FUNC0SUB); - if (strEQ(PL_last_proto, "$")) + if (strEQ(proto, "$")) OPERATOR(UNIOPSUB); - if (*PL_last_proto == '&' && *s == '{') { + if (*proto == '&' && *s == '{') { sv_setpv(PL_subname,"__ANON__"); PREBLOCK(LSTOPSUB); } - } else - PL_last_proto = NULL; + } PL_nextval[PL_nexttoke].opval = yylval.opval; PL_expect = XTERM; force_next(WORD); TOKEN(NOAMP); } - if (PL_hints & HINT_STRICT_SUBS && - lastchar != '-' && - strnNE(s,"->",2) && - PL_last_lop_op != OP_TRUNCATE && /* S/F prototype in opcode.pl */ - PL_last_lop_op != OP_ACCEPT && - PL_last_lop_op != OP_PIPE_OP && - PL_last_lop_op != OP_SOCKPAIR && - !(PL_last_lop_op == OP_ENTERSUB - && PL_last_proto - && PL_last_proto[PL_last_proto[0] == ';' ? 1 : 0] == '*')) - { - warn( - "Bareword \"%s\" not allowed while \"strict subs\" in use", - PL_tokenbuf); - ++PL_error_count; - } - /* Call it a bare word */ - bareword: - if (ckWARN(WARN_RESERVED)) { - if (lastchar != '-') { - for (d = PL_tokenbuf; *d && isLOWER(*d); d++) ; - if (!*d) - warner(WARN_RESERVED, PL_warn_reserved, PL_tokenbuf); + if (PL_hints & HINT_STRICT_SUBS) + yylval.opval->op_private |= OPpCONST_STRICT; + else { + bareword: + if (ckWARN(WARN_RESERVED)) { + if (lastchar != '-') { + for (d = PL_tokenbuf; *d && isLOWER(*d); d++) ; + if (!*d) + Perl_warner(aTHX_ WARN_RESERVED, PL_warn_reserved, + PL_tokenbuf); + } } } safe_bareword: - if (lastchar && strchr("*%&", lastchar)) { - warn("Operator or semicolon missing before %c%s", + if (lastchar && strchr("*%&", lastchar) && ckWARN_d(WARN_AMBIGUOUS)) { + Perl_warner(aTHX_ WARN_AMBIGUOUS, + "Operator or semicolon missing before %c%s", lastchar, PL_tokenbuf); - warn("Ambiguous use of %c resolved as operator %c", + Perl_warner(aTHX_ WARN_AMBIGUOUS, + "Ambiguous use of %c resolved as operator %c", lastchar, lastchar); } TOKEN(WORD); @@ -3299,12 +3787,12 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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__: - yylval.opval = (OP*)newSVOP(OP_CONST, 0, - newSVpvf("%ld", (long)PL_curcop->cop_line)); + yylval.opval = (OP*)newSVOP(OP_CONST, 0, + Perl_newSVpvf(aTHX_ "%"IVdf, (IV)CopLINE(PL_curcop))); TERM(THING); case KEY___PACKAGE__: @@ -3323,7 +3811,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) char *pname = "main"; if (PL_tokenbuf[2] == 'D') pname = HvNAME(PL_curstash ? PL_curstash : PL_defstash); - gv = gv_fetchpv(form("%s::DATA", pname), TRUE, SVt_PVIO); + gv = gv_fetchpv(Perl_form(aTHX_ "%s::DATA", pname), TRUE, SVt_PVIO); GvMULTI_on(gv); if (!GvIO(gv)) GvIOp(gv) = newIO(); @@ -3342,6 +3830,28 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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; @@ -3350,8 +3860,9 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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; @@ -3418,8 +3929,10 @@ int yylex(PERL_YYLEX_PARAM_DECL) case KEY_crypt: #ifdef FCRYPT - if (!PL_cryptseen++) + if (!PL_cryptseen) { + PL_cryptseen = TRUE; init_des(); + } #endif LOP(OP_CRYPT,XTERM); @@ -3427,7 +3940,8 @@ int yylex(PERL_YYLEX_PARAM_DECL) if (ckWARN(WARN_OCTAL)) { for (d = s; d < PL_bufend && (isSPACE(*d) || *d == '('); d++) ; if (*d != '0' && isDIGIT(*d)) - yywarn("chmod: mode argument is missing initial 0"); + Perl_warner(aTHX_ WARN_OCTAL, + "chmod: mode argument is missing initial 0"); } LOP(OP_CHMOD,XTERM); @@ -3479,7 +3993,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) PREBLOCK(ELSE); case KEY_elsif: - yylval.ival = PL_curcop->cop_line; + yylval.ival = CopLINE(PL_curcop); OPERATOR(ELSIF); case KEY_eq: @@ -3529,16 +4043,24 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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; 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)) - croak("Missing $ on loop variable"); + 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); @@ -3564,7 +4086,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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); @@ -3659,7 +4181,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) UNI(OP_HEX); case KEY_if: - yylval.ival = PL_curcop->cop_line; + yylval.ival = CopLINE(PL_curcop); OPERATOR(IF); case KEY_index: @@ -3691,6 +4213,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) UNI(OP_LCFIRST); case KEY_local: + yylval.ival = 0; OPERATOR(LOCAL); case KEY_length: @@ -3726,7 +4249,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) case KEY_map: LOP(OP_MAPSTART, XREF); - + case KEY_mkdir: LOP(OP_MKDIR,XTERM); @@ -3742,11 +4265,14 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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]; @@ -3755,6 +4281,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) yyerror(tmpbuf); } } + yylval.ival = 1; OPERATOR(MY); case KEY_next: @@ -3773,7 +4300,10 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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); @@ -3781,9 +4311,10 @@ int yylex(PERL_YYLEX_PARAM_DECL) char *t; for (d = s; isALNUM_lazy(d); d++) ; t = skipspace(d); - if (strchr("|&*+-=!?:.", *t)) - warn("Precedence problem: open %.*s should be open(%.*s)", - d-s,s, d-s,s); + if (strchr("|&*+-=!?:.", *t) && ckWARN_d(WARN_AMBIGUOUS)) + Perl_warner(aTHX_ WARN_AMBIGUOUS, + "Precedence problem: open %.*s should be open(%.*s)", + d-s,s, d-s,s); } LOP(OP_OPEN,XTERM); @@ -3831,7 +4362,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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; @@ -3841,7 +4372,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) UNI(OP_QUOTEMETA); case KEY_qw: - s = scan_str(s); + s = scan_str(s,FALSE,FALSE); if (!s) missingterm((char*)0); force_next(')'); @@ -3856,12 +4387,12 @@ int yylex(PERL_YYLEX_PARAM_DECL) if (!warned && ckWARN(WARN_SYNTAX)) { for (; !isSPACE(*d) && len; --len, ++d) { if (*d == ',') { - warner(WARN_SYNTAX, + Perl_warner(aTHX_ WARN_SYNTAX, "Possible attempt to separate words with commas"); ++warned; } else if (*d == '#') { - warner(WARN_SYNTAX, + Perl_warner(aTHX_ WARN_SYNTAX, "Possible attempt to put comments in qw() list"); ++warned; } @@ -3886,7 +4417,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) TOKEN('('); case KEY_qq: - s = scan_str(s); + s = scan_str(s,FALSE,FALSE); if (!s) missingterm((char*)0); yylval.ival = OP_STRINGIFY; @@ -3899,7 +4430,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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; @@ -3910,12 +4441,18 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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: @@ -4061,7 +4598,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) checkcomma(s,PL_tokenbuf,"subroutine name"); s = skipspace(s); if (*s == ';' || *s == ')') /* probably a close */ - croak("sort is now a reserved word"); + Perl_croak(aTHX_ "sort is now a reserved word"); PL_expect = XTERM; s = force_word(s,WORD,TRUE,TRUE,FALSE); LOP(OP_SORT,XREF); @@ -4085,7 +4622,6 @@ int yylex(PERL_YYLEX_PARAM_DECL) UNI(OP_STAT); case KEY_study: - PL_sawstudy++; UNI(OP_STUDY); case KEY_substr: @@ -4094,74 +4630,98 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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; + /* 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 = scan_str(s); - if (!s) { - if (PL_lex_stuff) - SvREFCNT_dec(PL_lex_stuff); - PL_lex_stuff = Nullsv; - croak("Prototype not terminated"); + s = skipspace(s); } - /* strip spaces */ - d = SvPVX(PL_lex_stuff); - tmp = 0; - for (p = d; *p; ++p) { - if (!isSPACE(*p)) - d[tmp++] = *p; + else + have_proto = FALSE; + + if (*s == ':' && s[1] != ':') + PL_expect = attrful; + + if (have_proto) { + PL_nextval[PL_nexttoke].opval = + (OP*)newSVOP(OP_CONST, 0, PL_lex_stuff); + PL_lex_stuff = Nullsv; + 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; + (void) force_word(PL_oldbufptr + tboffset, WORD, + FALSE, TRUE, TRUE); + if (key == KEY_my) + TOKEN(MYSUB); + TOKEN(SUB); } - if (*SvPV(PL_subname,n_a) == '?') { - sv_setpv(PL_subname,"__ANON__"); - TOKEN(ANONSUB); - } - PREBLOCK(SUB); - case KEY_system: set_csh(); LOP(OP_SYSTEM,XREF); @@ -4219,11 +4779,11 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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: @@ -4241,8 +4801,9 @@ int yylex(PERL_YYLEX_PARAM_DECL) case KEY_umask: if (ckWARN(WARN_OCTAL)) { for (d = s; d < PL_bufend && (isSPACE(*d) || *d == '('); d++) ; - if (*d != '0' && isDIGIT(*d)) - yywarn("umask: argument is missing initial 0"); + if (*d != '0' && isDIGIT(*d)) + Perl_warner(aTHX_ WARN_OCTAL, + "umask: argument is missing initial 0"); } UNI(OP_UMASK); @@ -4253,9 +4814,9 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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); } @@ -4271,11 +4832,10 @@ int yylex(PERL_YYLEX_PARAM_DECL) 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: @@ -4323,7 +4883,7 @@ int yylex(PERL_YYLEX_PARAM_DECL) } I32 -keyword(register char *d, I32 len) +Perl_keyword(pTHX_ register char *d, I32 len) { switch (*d) { case '_': @@ -4363,6 +4923,7 @@ keyword(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) { @@ -4446,7 +5007,7 @@ keyword(register char *d, I32 len) break; case 6: if (strEQ(d,"exists")) return KEY_exists; - if (strEQ(d,"elseif")) warn("elseif should be elsif"); + if (strEQ(d,"elseif")) Perl_warn(aTHX_ "elseif should be elsif"); break; case 8: if (strEQ(d,"endgrent")) return -KEY_endgrent; @@ -4667,8 +5228,7 @@ keyword(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; @@ -4942,7 +5502,7 @@ keyword(register char *d, I32 len) } STATIC void -checkcomma(register char *s, char *name, char *what) +S_checkcomma(pTHX_ register char *s, char *name, char *what) { char *w; @@ -4959,7 +5519,8 @@ checkcomma(register char *s, char *name, char *what) if (*w) for (; *w && isSPACE(*w); w++) ; if (!*w || !strchr(";|})]oaiuw!=", *w)) /* an advisory hack only... */ - warner(WARN_SYNTAX, "%s (...) interpreted as function",name); + Perl_warner(aTHX_ WARN_SYNTAX, + "%s (...) interpreted as function",name); } } while (s < PL_bufend && isSPACE(*s)) @@ -4977,93 +5538,119 @@ checkcomma(register char *s, char *name, char *what) if (*s == ',') { int kw; *s = '\0'; - kw = keyword(w, s - w) || perl_get_cv(w, FALSE) != 0; + kw = keyword(w, s - w) || get_cv(w, FALSE) != 0; *s = ','; if (kw) return; - croak("No comma allowed after %s", what); + Perl_croak(aTHX_ "No comma allowed after %s", what); } } } +/* Either returns sv, or mortalizes sv and returns a new SV*. + Best used as sv=new_constant(..., sv, ...). + If s, pv are NULL, calls subroutine with one argument, + and type is used with error messages only. */ + STATIC SV * -new_constant(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 */ - BINOP myop; SV *res; - bool oldcatch = CATCH_GET; SV **cvp; SV *cv, *typesv; - + const char *why, *why1, *why2; + + if (!(PL_hints & HINT_LOCALIZE_HH)) { + SV *msg; + + why = "%^H is not localized"; + report_short: + why1 = why2 = ""; + report: + msg = Perl_newSVpvf(aTHX_ "constant(%s): %s%s%s", + (type ? type: "undef"), why1, why2, why); + yyerror(SvPVX(msg)); + SvREFCNT_dec(msg); + return sv; + } if (!table) { - yyerror("%^H is not defined"); - return sv; + why = "%^H is not defined"; + goto report_short; } cvp = hv_fetch(table, key, strlen(key), FALSE); if (!cvp || !SvOK(*cvp)) { - char buf[128]; - sprintf(buf,"$^H{%s} is not defined", key); - yyerror(buf); - return sv; + why = "} is not defined"; + why1 = "$^H{"; + why2 = key; + goto report; } sv_2mortal(sv); /* Parent created it permanently */ cv = *cvp; - if (!pv) - pv = sv_2mortal(newSVpvn(s, len)); - if (type) - typesv = sv_2mortal(newSVpv(type, 0)); + if (!pv && s) + pv = sv_2mortal(newSVpvn(s, len)); + if (type && pv) + typesv = sv_2mortal(newSVpv(type, 0)); else - typesv = &PL_sv_undef; - CATCH_SET(TRUE); - Zero(&myop, 1, BINOP); - myop.op_last = (OP *) &myop; - myop.op_next = Nullop; - myop.op_flags = OPf_WANT_SCALAR | OPf_STACKED; - + typesv = &PL_sv_undef; + PUSHSTACKi(PERLSI_OVERLOAD); - ENTER; - SAVEOP(); - PL_op = (OP *) &myop; - if (PERLDB_SUB && PL_curstash != PL_debstash) - PL_op->op_private |= OPpENTERSUB_DB; - PUTBACK; - pp_pushmark(ARGS); - + ENTER ; + SAVETMPS; + + PUSHMARK(SP) ; EXTEND(sp, 4); - PUSHs(pv); + if (pv) + PUSHs(pv); PUSHs(sv); - PUSHs(typesv); + if (pv) + PUSHs(typesv); PUSHs(cv); PUTBACK; - - if (PL_op = pp_entersub(ARGS)) - CALLRUNOPS(); - LEAVE; - SPAGAIN; - - res = POPs; - PUTBACK; - CATCH_SET(oldcatch); + call_sv(cv, G_SCALAR | ( PL_in_eval ? 0 : G_EVAL)); + + SPAGAIN ; + + /* Check the eval first */ + if (!PL_in_eval && SvTRUE(ERRSV)) + { + STRLEN n_a; + sv_catpv(ERRSV, "Propagated"); + yyerror(SvPV(ERRSV, n_a)); /* Duplicates the message inside eval */ + (void)POPs; + res = SvREFCNT_inc(sv); + } + else { + res = POPs; + (void)SvREFCNT_inc(res); + } + + PUTBACK ; + FREETMPS ; + LEAVE ; POPSTACK; - + if (!SvOK(res)) { - char buf[128]; - sprintf(buf,"Call to &{$^H{%s}} did not return a defined value", key); - yyerror(buf); - } - return SvREFCNT_inc(res); + why = "}} did not return a defined value"; + why1 = "Call to &{$^H{"; + why2 = key; + sv = res; + goto report; + } + + return res; } - + STATIC char * -scan_word(register char *s, char *dest, STRLEN destlen, int allow_package, STRLEN *slp) +S_scan_word(pTHX_ register char *s, char *dest, STRLEN destlen, int allow_package, STRLEN *slp) { register char *d = dest; register char *e = d + destlen - 3; /* two-character token, ending NUL */ for (;;) { if (d >= e) - croak(ident_too_long); + Perl_croak(aTHX_ ident_too_long); if (isALNUM(*s)) /* UTF handled below */ *d++ = *s++; else if (*s == '\'' && allow_package && isIDFIRST_lazy(s+1)) { @@ -5080,7 +5667,7 @@ scan_word(register char *s, char *dest, STRLEN destlen, int allow_package, STRLE while (*t & 0x80 && is_utf8_mark((U8*)t)) t += UTF8SKIP(t); if (d + (t - s) > e) - croak(ident_too_long); + Perl_croak(aTHX_ ident_too_long); Copy(s, d, t - s, char); d += t - s; s = t; @@ -5094,15 +5681,13 @@ scan_word(register char *s, char *dest, STRLEN destlen, int allow_package, STRLE } STATIC char * -scan_ident(register char *s, register char *send, char *dest, STRLEN destlen, I32 ck_uni) +S_scan_ident(pTHX_ register char *s, register char *send, char *dest, STRLEN destlen, I32 ck_uni) { register char *d; register char *e; char *bracket = 0; char funny = *s++; - if (PL_lex_brackets == 0) - PL_lex_fakebrack = 0; if (isSPACE(*s)) s = skipspace(s); d = dest; @@ -5110,14 +5695,14 @@ scan_ident(register char *s, register char *send, char *dest, STRLEN destlen, I3 if (isDIGIT(*s)) { while (isDIGIT(*s)) { if (d >= e) - croak(ident_too_long); + Perl_croak(aTHX_ ident_too_long); *d++ = *s++; } } else { for (;;) { if (d >= e) - croak(ident_too_long); + Perl_croak(aTHX_ ident_too_long); if (isALNUM(*s)) /* UTF handled below */ *d++ = *s++; else if (*s == '\'' && isIDFIRST_lazy(s+1)) { @@ -5134,7 +5719,7 @@ scan_ident(register char *s, register char *send, char *dest, STRLEN destlen, I3 while (*t & 0x80 && is_utf8_mark((U8*)t)) t += UTF8SKIP(t); if (d + (t - s) > e) - croak(ident_too_long); + Perl_croak(aTHX_ ident_too_long); Copy(s, d, t - s, char); d += t - s; s = t; @@ -5195,21 +5780,20 @@ scan_ident(register char *s, register char *send, char *dest, STRLEN destlen, I3 while ((isALNUM(*s) || *s == ':') && d < e) *d++ = *s++; if (d >= e) - croak(ident_too_long); + Perl_croak(aTHX_ ident_too_long); } *d = '\0'; while (s < send && (*s == ' ' || *s == '\t')) s++; if ((*s == '[' || (*s == '{' && strNE(dest, "sub")))) { dTHR; /* only for ckWARN */ if (ckWARN(WARN_AMBIGUOUS) && keyword(dest, d - dest)) { - char *brack = *s == '[' ? "[...]" : "{...}"; - warner(WARN_AMBIGUOUS, + 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; } } @@ -5223,7 +5807,7 @@ scan_ident(register char *s, register char *send, char *dest, STRLEN destlen, I3 *d++ = *s++; } if (d >= e) - croak(ident_too_long); + Perl_croak(aTHX_ ident_too_long); *d = '\0'; } if (*s == '}') { @@ -5235,9 +5819,9 @@ scan_ident(register char *s, register char *send, char *dest, STRLEN destlen, I3 if (PL_lex_state == LEX_NORMAL) { dTHR; /* only for ckWARN */ if (ckWARN(WARN_AMBIGUOUS) && - (keyword(dest, d - dest) || perl_get_cv(dest, FALSE))) + (keyword(dest, d - dest) || get_cv(dest, FALSE))) { - warner(WARN_AMBIGUOUS, + Perl_warner(aTHX_ WARN_AMBIGUOUS, "Ambiguous use of %c{%s} resolved to %c%s", funny, dest, funny, dest); } @@ -5253,7 +5837,8 @@ scan_ident(register char *s, register char *send, char *dest, STRLEN destlen, I3 return s; } -void pmflag(U16 *pmfl, int ch) +void +Perl_pmflag(pTHX_ U16 *pmfl, int ch) { if (ch == 'i') *pmfl |= PMf_FOLD; @@ -5272,17 +5857,17 @@ void pmflag(U16 *pmfl, int ch) } STATIC char * -scan_pat(char *start, I32 type) +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); PL_lex_stuff = Nullsv; - croak("Search pattern not terminated"); + Perl_croak(aTHX_ "Search pattern not terminated"); } pm = (PMOP*)newPMOP(type, 0); @@ -5304,7 +5889,7 @@ scan_pat(char *start, I32 type) } STATIC char * -scan_subst(char *start) +S_scan_subst(pTHX_ char *start) { register char *s; register PMOP *pm; @@ -5313,20 +5898,20 @@ scan_subst(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); PL_lex_stuff = Nullsv; - croak("Substitution pattern not terminated"); + Perl_croak(aTHX_ "Substitution pattern not terminated"); } if (s[-1] == PL_multi_open) 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); @@ -5334,7 +5919,7 @@ scan_subst(char *start) if (PL_lex_repl) SvREFCNT_dec(PL_lex_repl); PL_lex_repl = Nullsv; - croak("Substitution replacement not terminated"); + Perl_croak(aTHX_ "Substitution replacement not terminated"); } PL_multi_start = first_start; /* so whole substitution is taken together */ @@ -5362,7 +5947,7 @@ scan_subst(char *start) sv_catpvn(repl, "{ ", 2); sv_catsv(repl, PL_lex_repl); sv_catpvn(repl, " };", 2); - SvCOMPILED_on(repl); + SvEVALED_on(repl); SvREFCNT_dec(PL_lex_repl); PL_lex_repl = repl; } @@ -5374,7 +5959,7 @@ scan_subst(char *start) } STATIC char * -scan_trans(char *start) +S_scan_trans(pTHX_ char *start) { register char* s; OP *o; @@ -5387,17 +5972,17 @@ scan_trans(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); PL_lex_stuff = Nullsv; - croak("Transliteration pattern not terminated"); + Perl_croak(aTHX_ "Transliteration pattern not terminated"); } 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); @@ -5405,7 +5990,7 @@ scan_trans(char *start) if (PL_lex_repl) SvREFCNT_dec(PL_lex_repl); PL_lex_repl = Nullsv; - croak("Transliteration replacement not terminated"); + Perl_croak(aTHX_ "Transliteration replacement not terminated"); } if (UTF) { @@ -5441,7 +6026,7 @@ scan_trans(char *start) utf8 |= OPpTRANS_TO_UTF; break; default: - croak("Too many /C and /U options"); + Perl_croak(aTHX_ "Too many /C and /U options"); } } s++; @@ -5454,7 +6039,7 @@ scan_trans(char *start) } STATIC char * -scan_heredoc(register char *s) +S_scan_heredoc(pTHX_ register char *s) { dTHR; SV *herewas; @@ -5494,7 +6079,7 @@ scan_heredoc(register char *s) } } if (d >= PL_tokenbuf + sizeof PL_tokenbuf - 1) - croak("Delimiter for here document is too long"); + Perl_croak(aTHX_ "Delimiter for here document is too long"); *d++ = '\n'; *d = '\0'; len = d - PL_tokenbuf; @@ -5541,7 +6126,7 @@ scan_heredoc(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) { @@ -5555,10 +6140,10 @@ scan_heredoc(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); @@ -5575,15 +6160,15 @@ scan_heredoc(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); @@ -5595,10 +6180,10 @@ scan_heredoc(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) { @@ -5620,8 +6205,7 @@ scan_heredoc(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; @@ -5636,7 +6220,7 @@ scan_heredoc(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); @@ -5664,25 +6248,29 @@ retval: */ STATIC char * -scan_inputsymbol(char *start) +S_scan_inputsymbol(pTHX_ char *start) { register char *s = start; /* current position in buffer */ register char *d; register char *e; + char *end; I32 len; d = PL_tokenbuf; /* start of temp holding space */ e = PL_tokenbuf + sizeof PL_tokenbuf; /* end of temp holding space */ - s = delimcpy(d, e, s + 1, PL_bufend, '>', &len); /* extract until > */ + end = strchr(s, '\n'); + if (!end) + end = PL_bufend; + s = delimcpy(d, e, s + 1, end, '>', &len); /* extract until > */ /* die if we didn't have space for the contents of the <>, - or if it didn't end + or if it didn't end, or if we see a newline */ if (len >= sizeof PL_tokenbuf) - croak("Excessively long <> operator"); - if (s >= PL_bufend) - croak("Unterminated <> operator"); + Perl_croak(aTHX_ "Excessively long <> operator"); + if (s >= end) + Perl_croak(aTHX_ "Unterminated <> operator"); s++; @@ -5708,9 +6296,9 @@ scan_inputsymbol(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) - croak("Glob not terminated"); + Perl_croak(aTHX_ "Glob not terminated"); return s; } else { @@ -5761,6 +6349,8 @@ scan_inputsymbol(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. @@ -5778,6 +6368,7 @@ scan_inputsymbol(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) @@ -5800,7 +6391,7 @@ scan_inputsymbol(char *start) */ STATIC char * -scan_str(char *start) +S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims) { dTHR; SV *sv; /* scalar value: string */ @@ -5820,7 +6411,7 @@ scan_str(char *start) /* 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 */ @@ -5836,22 +6427,24 @@ scan_str(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++) { /* 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 (s[1] == term) + if (!keep_quoted && s[1] == term) s++; /* any other quotes are simply copied straight through */ else @@ -5874,10 +6467,11 @@ scan_str(char *start) 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 ((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++; @@ -5922,11 +6516,11 @@ scan_str(char *start) 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) { @@ -5934,8 +6528,7 @@ scan_str(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)CopLINE(PL_curcop), sv); } /* having changed the buffer, we must update PL_bufend */ @@ -5944,7 +6537,9 @@ scan_str(char *start) /* at this point, we have successfully read the delimited string */ - PL_multi_end = PL_curcop->cop_line; + if (keep_delims) + sv_catpvn(sv, s, 1); + PL_multi_end = CopLINE(PL_curcop); s++; /* if we allocated too much space, give some back */ @@ -5987,15 +6582,15 @@ scan_str(char *start) */ char * -scan_num(char *start) +Perl_scan_num(pTHX_ char *start) { register char *s = start; /* current position in buffer */ register char *d; /* destination in temp buffer */ register char *e; /* end of temp buffer */ - I32 tryiv; /* used to see if it can be an int */ - double value; /* number read, as a double */ - SV *sv; /* place to put the converted number */ - I32 floatit; /* boolean: int or float? */ + IV tryiv; /* used to see if it can be an IV */ + NV value; /* number read, as a double */ + 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"; @@ -6003,11 +6598,10 @@ scan_num(char *start) switch (*s) { default: - croak("panic: scan_num"); + 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: @@ -6020,9 +6614,22 @@ scan_num(char *start) we in octal/hex/binary?" indicator to disallow hex characters when in octal mode. */ - UV u; + dTHR; + NV n = 0.0; + UV u = 0; I32 shift; bool overflowed = FALSE; + static NV nvshift[5] = { 1.0, 2.0, 4.0, 8.0, 16.0 }; + static char* bases[5] = { "", "binary", "", "octal", + "hexadecimal" }; + static char* Bases[5] = { "", "Binary", "", "Octal", + "Hexadecimal" }; + static char *maxima[5] = { "", + "0b11111111111111111111111111111111", + "", + "037777777777", + "0xffffffff" }; + char *base, *Base, *max; /* check for hex */ if (s[1] == 'x') { @@ -6033,16 +6640,21 @@ scan_num(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 shift = 3; - u = 0; + + base = bases[shift]; + Base = Bases[shift]; + max = maxima[shift]; /* read the rest of the number */ for (;;) { - UV n, b; /* n is used in the overflow test, b is the digit we're adding on */ + /* x is used in the overflow test, + b is the digit we're adding on. */ + UV x, b; switch (*s) { @@ -6058,17 +6670,14 @@ scan_num(char *start) /* 8 and 9 are not octal */ case '8': case '9': if (shift == 3) - yyerror(form("Illegal octal digit '%c'", *s)); - else - if (shift == 1) - yyerror(form("Illegal binary digit '%c'", *s)); + yyerror(Perl_form(aTHX_ "Illegal octal digit '%c'", *s)); /* FALL THROUGH */ /* octal digits */ case '2': case '3': case '4': case '5': case '6': case '7': if (shift == 1) - yyerror(form("Illegal binary digit '%c'", *s)); + yyerror(Perl_form(aTHX_ "Illegal binary digit '%c'", *s)); /* FALL THROUGH */ case '0': case '1': @@ -6088,15 +6697,33 @@ scan_num(char *start) */ digit: - n = u << shift; /* make room for the digit */ - if (!overflowed && (n >> shift) != u - && !(PL_hints & HINT_NEW_BINARY)) { - warn("Integer overflow in %s number", - (shift == 4) ? "hex" - : ((shift == 3) ? "octal" : "binary")); - overflowed = TRUE; + if (!overflowed) { + x = u << shift; /* make room for the digit */ + + if ((x >> shift) != u + && !(PL_hints & HINT_NEW_BINARY)) { + dTHR; + overflowed = TRUE; + n = (NV) u; + if (ckWARN_d(WARN_OVERFLOW)) + Perl_warner(aTHX_ WARN_OVERFLOW, + "Integer overflow in %s number", + base); + } else + u = x | b; /* add the digit to the end */ + } + if (overflowed) { + n *= nvshift[shift]; + /* If an NV has not enough bits in its + * mantissa to represent an UV this summing of + * small low-order numbers is a waste of time + * (because the NV cannot preserve the + * low-order bits anyway): we could just + * remember when did we overflow and in the + * end just multiply n by the right + * amount. */ + n += (NV) b; } - u = n | b; /* add the digit to the end */ break; } } @@ -6106,8 +6733,25 @@ scan_num(char *start) */ out: sv = NEWSV(92,0); - sv_setuv(sv, u); - if ( PL_hints & HINT_NEW_BINARY) + if (overflowed) { + dTHR; + 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 UVSIZE > 4 + dTHR; + if (ckWARN(WARN_PORTABLE) && u > 0xffffffff) + Perl_warner(aTHX_ WARN_PORTABLE, + "%s number > %s non-portable", + Base, max); +#endif + sv_setuv(sv, u); + } + if (PL_hints & HINT_NEW_BINARY) sv = new_constant(start, s - start, "binary", sv, Nullsv, NULL); } break; @@ -6131,13 +6775,13 @@ scan_num(char *start) if (*s == '_') { dTHR; /* only for ckWARN */ if (ckWARN(WARN_SYNTAX) && lastub && s - lastub != 3) - warner(WARN_SYNTAX, "Misplaced _ in number"); + Perl_warner(aTHX_ WARN_SYNTAX, "Misplaced _ in number"); lastub = ++s; } else { /* check for end of fixed-length buffer */ if (d >= e) - croak(number_too_long); + Perl_croak(aTHX_ number_too_long); /* if we're ok, copy the character */ *d++ = *s++; } @@ -6147,7 +6791,7 @@ scan_num(char *start) if (lastub && s - lastub != 3) { dTHR; if (ckWARN(WARN_SYNTAX)) - warner(WARN_SYNTAX, "Misplaced _ in number"); + Perl_warner(aTHX_ WARN_SYNTAX, "Misplaced _ in number"); } /* read a decimal portion if there is one. avoid @@ -6164,7 +6808,7 @@ scan_num(char *start) for (; isDIGIT(*s) || *s == '_'; s++) { /* fixed length buffer check */ if (d >= e) - croak(number_too_long); + Perl_croak(aTHX_ number_too_long); if (*s != '_') *d++ = *s; } @@ -6185,7 +6829,7 @@ scan_num(char *start) /* read digits of exponent (no underbars :-) */ while (isDIGIT(*s)) { if (d >= e) - croak(number_too_long); + Perl_croak(aTHX_ number_too_long); *d++ = *s++; } } @@ -6195,9 +6839,8 @@ scan_num(char *start) /* make an sv from the string */ sv = NEWSV(92,0); - /* reset numeric locale in case we were earlier left in Swaziland */ - SET_NUMERIC_STANDARD(); - value = atof(PL_tokenbuf); + + value = Atof(PL_tokenbuf); /* See if we can make do with an integer value without loss of @@ -6210,25 +6853,77 @@ scan_num(char *start) conversion at all. */ tryiv = I_V(value); - if (!floatit && (double)tryiv == value) + if (!floatit && (NV)tryiv == value) sv_setiv(sv, tryiv); else sv_setnv(sv, value); - if ( floatit ? (PL_hints & HINT_NEW_FLOAT) : (PL_hints & HINT_NEW_INTEGER) ) + if ( floatit ? (PL_hints & HINT_NEW_FLOAT) : + (PL_hints & HINT_NEW_INTEGER) ) sv = new_constant(PL_tokenbuf, d - PL_tokenbuf, - (floatit ? "float" : "integer"), sv, Nullsv, NULL); + (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; } STATIC char * -scan_formline(register char *s) +S_scan_formline(pTHX_ register char *s) { dTHR; register char *eol; @@ -6264,6 +6959,14 @@ scan_formline(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) { @@ -6302,7 +7005,7 @@ scan_formline(register char *s) } STATIC void -set_csh(void) +S_set_csh(pTHX) { #ifdef CSH if (!PL_cshlen) @@ -6311,7 +7014,7 @@ set_csh(void) } I32 -start_subparse(I32 is_format, U32 flags) +Perl_start_subparse(pTHX_ I32 is_format, U32 flags) { dTHR; I32 oldsavestack_ix = PL_savestack_ix; @@ -6321,10 +7024,10 @@ start_subparse(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); @@ -6344,7 +7047,7 @@ start_subparse(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(); @@ -6368,18 +7071,17 @@ start_subparse(I32 is_format, U32 flags) } int -yywarn(char *s) +Perl_yywarn(pTHX_ char *s) { dTHR; - --PL_error_count; - PL_in_eval |= 2; + PL_in_eval |= EVAL_WARNONLY; yyerror(s); - PL_in_eval &= ~2; + PL_in_eval &= ~EVAL_WARNONLY; return 0; } int -yyerror(char *s) +Perl_yyerror(pTHX_ char *s) { dTHR; char *where = NULL; @@ -6417,37 +7119,55 @@ yyerror(char *s) else { SV *where_sv = sv_2mortal(newSVpvn("next char ", 10)); if (yychar < 32) - sv_catpvf(where_sv, "^%c", toCTRL(yychar)); + Perl_sv_catpvf(aTHX_ where_sv, "^%c", toCTRL(yychar)); else if (isPRINT_LC(yychar)) - sv_catpvf(where_sv, "%c", yychar); + Perl_sv_catpvf(aTHX_ where_sv, "%c", yychar); else - sv_catpvf(where_sv, "\\%03o", yychar & 255); + Perl_sv_catpvf(aTHX_ where_sv, "\\%03o", yychar & 255); where = SvPVX(where_sv); } msg = sv_2mortal(newSVpv(s, 0)); - sv_catpvf(msg, " at %_ line %ld, ", - GvSV(PL_curcop->cop_filegv), (long)PL_curcop->cop_line); + Perl_sv_catpvf(aTHX_ msg, " at %s line %"IVdf", ", + CopFILE(PL_curcop), (IV)CopLINE(PL_curcop)); if (context) - sv_catpvf(msg, "near \"%.*s\"\n", contlen, context); + Perl_sv_catpvf(aTHX_ msg, "near \"%.*s\"\n", contlen, context); else - sv_catpvf(msg, "%s\n", where); - if (PL_multi_start < PL_multi_end && (U32)(PL_curcop->cop_line - PL_multi_end) <= 1) { - sv_catpvf(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); + Perl_sv_catpvf(aTHX_ msg, "%s\n", where); + 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 %"IVdf")\n", + (int)PL_multi_open,(int)PL_multi_close,(IV)PL_multi_start); PL_multi_end = 0; } - if (PL_in_eval & 2) - warn("%_", msg); - else if (PL_in_eval) - sv_catsv(ERRSV, msg); + if (PL_in_eval & EVAL_WARNONLY) + Perl_warn(aTHX_ "%"SVf, msg); else - PerlIO_write(PerlIO_stderr(), SvPVX(msg), SvCUR(msg)); - if (++PL_error_count >= 10) - croak("%_ has too many errors.\n", GvSV(PL_curcop->cop_filegv)); + qerror(msg); + if (PL_error_count >= 10) + Perl_croak(aTHX_ "%s has too many errors.\n", CopFILE(PL_curcop)); PL_in_my = 0; PL_in_my_stash = Nullhv; return 0; } +#ifdef PERL_OBJECT +#include "XSUB.h" +#endif + +/* + * restore_rsfp + * Restore a source filter. + */ + +static void +restore_rsfp(pTHXo_ void *f) +{ + PerlIO *fp = (PerlIO*)f; + + if (PL_rsfp == PerlIO_stdin()) + PerlIO_clearerr(PL_rsfp); + else if (PL_rsfp && (PL_rsfp != fp)) + PerlIO_close(PL_rsfp); + PL_rsfp = fp; +}