summaryrefslogtreecommitdiffstats
path: root/contrib/perl5/toke.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/perl5/toke.c')
-rw-r--r--contrib/perl5/toke.c2681
1 files changed, 1920 insertions, 761 deletions
diff --git a/contrib/perl5/toke.c b/contrib/perl5/toke.c
index 52a42af..48dad64 100644
--- a/contrib/perl5/toke.c
+++ b/contrib/perl5/toke.c
@@ -1,6 +1,6 @@
/* toke.c
*
- * Copyright (c) 1991-1999, Larry Wall
+ * Copyright (c) 1991-2000, Larry Wall
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
@@ -11,56 +11,36 @@
* "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"
-#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));
-
-static char *PL_super_bufptr;
-static char *PL_super_bufend;
-#endif /* PERL_OBJECT */
+#define yychar PL_yychar
+#define yylval PL_yylval
static char ident_too_long[] = "Identifier too long";
-/* The following are arranged oddly so that the guard on the switch statement
+static void restore_rsfp(pTHXo_ void *f);
+
+#define XFAKEBRACK 128
+#define XENUMMASK 127
+
+/*#define UTF (SvUTF8(PL_linestr) && !(PL_hints & HINT_BYTE))*/
+#define UTF (PL_hints & HINT_UTF8)
+
+/* In variables name $^X, these are the legal values for X.
+ * 1999-02-27 mjd-perl-patch@plover.com */
+#define isCONTROLVAR(x) (isUPPER(x) || strchr("[\\]^_?", (x)))
+
+/* 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).
*/
@@ -78,13 +58,6 @@ static char ident_too_long[] = "Identifier too long";
#define LEX_FORMLINE 1
#define LEX_KNOWNEXT 0
-#ifdef I_FCNTL
-#include <fcntl.h>
-#endif
-#ifdef I_SYS_FILE
-#include <sys/file.h>
-#endif
-
/* XXX If this causes problems, set i_unistd=undef in the hint file. */
#ifdef I_UNISTD
# include <unistd.h> /* Needed for execv() */
@@ -95,12 +68,54 @@ static char ident_too_long[] = "Identifier too long";
#undef ff_next
#endif
+#ifdef USE_PURE_BISON
+YYSTYPE* yylval_pointer = NULL;
+int* yychar_pointer = NULL;
+# undef yylval
+# undef yychar
+# define yylval (*yylval_pointer)
+# define yychar (*yychar_pointer)
+# define PERL_YYLEX_PARAM yylval_pointer,yychar_pointer
+# 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)
@@ -141,8 +156,15 @@ static char ident_too_long[] = "Identifier too long";
/* 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++;
@@ -155,31 +177,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 "<something> 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");
- else if (PL_oldoldbufptr && isIDFIRST(*PL_oldoldbufptr)) {
+ Perl_warn(aTHX_ "\t(Missing semicolon on previous line?)\n");
+ else if (PL_oldoldbufptr && isIDFIRST_lazy_if(PL_oldoldbufptr,UTF)) {
char *t;
- for (t = PL_oldoldbufptr; *t && (isALNUM(*t) || *t == ':'); t++) ;
+ for (t = PL_oldoldbufptr; *t && (isALNUM_lazy_if(t,UTF) || *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
- 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;
@@ -207,37 +255,108 @@ 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)
{
- if (PL_dowarn)
- warn("Use of %s is deprecated", s);
+ dTHR;
+ if (ckWARN(WARN_DEPRECATED))
+ 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
+#if 0
+STATIC I32
+S_utf16_textfilter(pTHX_ int idx, SV *sv, int maxlen)
+{
+ I32 count = FILTER_READ(idx+1, sv, maxlen);
+ if (count) {
+ U8* tmps;
+ U8* tend;
+ New(898, tmps, SvCUR(sv) * 3 / 2 + 1, U8);
+ tend = utf16_to_utf8((U16*)SvPVX(sv), tmps, SvCUR(sv));
+ sv_usepvn(sv, (char*)tmps, tend - tmps);
+ }
+ return count;
+}
+
+STATIC I32
+S_utf16rev_textfilter(pTHX_ int idx, SV *sv, int maxlen)
+{
+ I32 count = FILTER_READ(idx+1, sv, maxlen);
+ if (count) {
+ U8* tmps;
+ U8* tend;
+ New(898, tmps, SvCUR(sv) * 3 / 2 + 1, U8);
+ tend = utf16_to_utf8_reversed((U16*)SvPVX(sv), tmps, SvCUR(sv));
+ sv_usepvn(sv, (char*)tmps, tend - tmps);
+ }
+ 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;
@@ -245,13 +364,21 @@ 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);
+ if (PL_lex_state == LEX_KNOWNEXT) {
+ I32 toke = PL_nexttoke;
+ while (--toke >= 0) {
+ SAVEI32(PL_nexttype[toke]);
+ SAVEVPTR(PL_nextval[toke]);
+ }
+ SAVEI32(PL_nexttoke);
+ PL_nexttoke = 0;
+ }
+ SAVECOPLINE(PL_curcop);
SAVEPPTR(PL_bufptr);
SAVEPPTR(PL_bufend);
SAVEPPTR(PL_oldbufptr);
@@ -260,18 +387,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);
@@ -284,6 +411,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));
@@ -297,59 +425,54 @@ lex_start(SV *line)
PL_oldoldbufptr = PL_oldbufptr = PL_bufptr = PL_linestart = SvPVX(PL_linestr);
PL_bufend = PL_bufptr + SvCUR(PL_linestr);
SvREFCNT_dec(PL_rs);
- PL_rs = newSVpv("\n", 1);
+ PL_rs = newSVpvn("\n", 1);
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;
char *n;
+ char *e;
char ch;
- int sawline = 0;
- PL_curcop->cop_line++;
+ CopLINE_inc(PL_curcop);
if (*s++ != '#')
return;
while (*s == ' ' || *s == '\t') s++;
- if (strnEQ(s, "line ", 5)) {
- s += 5;
- sawline = 1;
- }
+ if (strnEQ(s, "line", 4))
+ s += 4;
+ else
+ return;
+ if (*s == ' ' || *s == '\t')
+ s++;
+ else
+ return;
+ while (*s == ' ' || *s == '\t') s++;
if (!isDIGIT(*s))
return;
n = s;
@@ -357,25 +480,35 @@ incline(char *s)
s++;
while (*s == ' ' || *s == '\t')
s++;
- if (*s == '"' && (t = strchr(s+1, '"')))
+ if (*s == '"' && (t = strchr(s+1, '"'))) {
s++;
+ e = t + 1;
+ }
else {
- if (!sawline)
- return; /* false alarm */
for (t = s; !isSPACE(*t); t++) ;
+ e = t;
}
+ while (*e == ' ' || *e == '\t' || *e == '\r' || *e == '\f')
+ e++;
+ if (*e != '\n' && *e != '\0')
+ return; /* false alarm */
+
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) {
@@ -385,10 +518,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++;
@@ -400,9 +537,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)" :
@@ -412,8 +560,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())
@@ -423,46 +582,84 @@ 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;
while (isSPACE(*PL_last_uni))
PL_last_uni++;
- for (s = PL_last_uni; isALNUM(*s) || *s == '-'; s++) ;
+ for (s = PL_last_uni; isALNUM_lazy_if(s,UTF) || *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;
@@ -480,10 +677,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;
@@ -503,8 +713,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++;
@@ -515,15 +734,31 @@ 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;
start = skipspace(start);
s = start;
- if (isIDFIRST(*s) ||
+ if (isIDFIRST_lazy_if(s,UTF) ||
(allow_pack && *s == ':') ||
(allow_initial_tick && *s == '\'') )
{
@@ -536,8 +771,6 @@ force_word(register char *start, int token, int check_keyword, int allow_pack, i
PL_expect = XTERM;
else {
PL_expect = XOPERATOR;
- force_next(')');
- force_next('(');
}
}
PL_nextval[PL_nexttoke].opval = (OP*)newSVOP(OP_CONST,0, newSVpv(PL_tokenbuf,0));
@@ -547,8 +780,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));
@@ -570,23 +812,59 @@ force_ident(register char *s, int kind)
}
}
+NV
+Perl_str_to_version(pTHX_ SV *sv)
+{
+ NV retval = 0.0;
+ NV nshift = 1.0;
+ STRLEN len;
+ char *start = SvPVx(sv,len);
+ bool utf = SvUTF8(sv);
+ char *end = start + len;
+ while (start < end) {
+ I32 skip;
+ UV n;
+ if (utf)
+ n = utf8_to_uv((U8*)start, &skip);
+ else {
+ n = *(U8*)start;
+ skip = 1;
+ }
+ retval += ((NV)n)/nshift;
+ start += skip;
+ nshift *= 1000;
+ }
+ return retval;
+}
+
+/*
+ * 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;
+ char *d;
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)) != ',') {
+ d = s;
+ if (*d == 'v')
+ d++;
+ if (isDIGIT(*d)) {
+ for (; isDIGIT(*d) || *d == '_' || *d == '.'; d++);
+ if (*d == ';' || isSPACE(*d) || *d == '}' || !*d) {
+ SV *ver;
s = scan_num(s);
- /* real VERSION number -- GBARR */
version = yylval.opval;
+ ver = cSVOPx(version)->op_sv;
+ if (SvPOK(ver) && !SvNIOK(ver)) {
+ (void)SvUPGRADE(ver, SVt_PVNV);
+ SvNVX(ver) = str_to_version(ver);
+ SvNOK_on(ver); /* hint that it is a version */
+ }
}
}
@@ -597,8 +875,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;
@@ -619,7 +905,7 @@ tokeq(SV *sv)
goto finish;
d = s;
if ( PL_hints & HINT_NEW_STRING )
- pv = sv_2mortal(newSVpv(SvPVX(pv), len));
+ pv = sv_2mortal(newSVpvn(SvPVX(pv), len));
while (s < send) {
if (*s == '\\') {
if (s + 1 < send && (s[1] == '\\'))
@@ -635,8 +921,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;
@@ -655,7 +973,7 @@ sublex_start(void)
SV *nsv;
p = SvPV(sv, len);
- nsv = newSVpv(p, len);
+ nsv = newSVpvn(p, len);
SvREFCNT_dec(sv);
sv = nsv;
}
@@ -679,8 +997,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;
@@ -688,13 +1014,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);
@@ -706,13 +1031,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);
@@ -721,7 +1046,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)
@@ -732,12 +1057,17 @@ 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;
- yylval.opval = (OP*)newSVOP(OP_CONST, 0, newSVpv("",0));
+ yylval.opval = (OP*)newSVOP(OP_CONST, 0, newSVpvn("",0));
return THING;
}
@@ -746,7 +1076,7 @@ sublex_done(void)
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;
@@ -755,17 +1085,21 @@ 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
+ whether this is an evalled subst; that means we rely on the
+ logic to ensure sublex_done() is called again only via the
+ branch (in yylex()) that clears PL_lex_repl, else we'll loop */
}
- else
+ else {
PL_lex_state = LEX_INTERPCONCAT;
- PL_lex_repl = Nullsv;
+ PL_lex_repl = Nullsv;
+ }
return ',';
}
else {
@@ -773,6 +1107,7 @@ sublex_done(void)
PL_bufend = SvPVX(PL_linestr);
PL_bufend += SvCUR(PL_linestr);
PL_expect = XOPERATOR;
+ PL_sublex_info.sub_inwhat = 0;
return ')';
}
}
@@ -851,19 +1186,27 @@ 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 */
register char *s = start; /* start of the constant */
register char *d = SvPVX(sv); /* destination for copies */
bool dorange = FALSE; /* are we in a translit range? */
+ bool has_utf = FALSE; /* embedded \x{} */
I32 len; /* ? */
-
- /* leaveit is the set of acceptably-backslashed characters */
- char *leaveit =
+ UV uv;
+
+ 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)
+ ? (PL_sublex_info.sub_op->op_private & (PL_lex_repl ?
+ OPpTRANS_FROM_UTF : OPpTRANS_TO_UTF))
+ : UTF;
+ const char *leaveit = /* set of acceptably-backslashed characters */
PL_lex_inpat
- ? "\\.^$@AGZdDwWsSbB+*?|()-nrtfeaxcz0123456789[{]} \t\n\r\f\v#"
+ ? "\\.^$@AGZdDwWsSbBpPXC+*?|()-nrtfeaxcz0123456789[{]} \t\n\r\f\v#"
: "";
while (s < send || dorange) {
@@ -876,8 +1219,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 */
@@ -908,6 +1251,11 @@ scan_const(char *start)
/* range begins (ignore - as first or last char) */
else if (*s == '-' && s+1 < send && s != start) {
+ if (utf) {
+ *d++ = (char)0xff; /* use illegal utf8 byte--see pmtrans */
+ s++;
+ continue;
+ }
dorange = TRUE;
s++;
}
@@ -915,14 +1263,18 @@ scan_const(char *start)
/* if we get here, we're not doing a transliteration */
- /* skip for regexp comments /(?#comment)/ */
+ /* skip for regexp comments /(?#comment)/ and code /(?{code})/,
+ except for the last char, which will be done separately. */
else if (*s == '(' && PL_lex_inpat && s[1] == '?') {
if (s[2] == '#') {
while (s < send && *s != ')')
*d++ = *s++;
- } else if (s[2] == '{') { /* This should march regcomp.c */
+ }
+ else if (s[2] == '{' /* This should match regcomp.c */
+ || ((s[2] == 'p' || s[2] == '?') && s[3] == '{'))
+ {
I32 count = 1;
- char *regparse = s + 3;
+ char *regparse = s + (s[2] == '{' ? 3 : 4);
char c;
while (count && (c = *regparse)) {
@@ -934,11 +1286,11 @@ scan_const(char *start)
count--;
regparse++;
}
- if (*regparse == ')')
- regparse++;
- else
+ if (*regparse != ')') {
+ regparse--; /* Leave one char for continuation. */
yyerror("Sequence (?{...}) not terminated or not {}-balanced");
- while (s < regparse && *s != ')')
+ }
+ while (s < regparse)
*d++ = *s++;
}
}
@@ -951,7 +1303,8 @@ scan_const(char *start)
}
/* check for embedded arrays (@foo, @:foo, @'foo, @{foo}, @$foo) */
- else if (*s == '@' && s[1] && (isALNUM(s[1]) || strchr(":'{$", s[1])))
+ else if (*s == '@' && s[1]
+ && (isALNUM_lazy_if(s+1,UTF) || strchr(":'{$", s[1])))
break;
/* check for embedded scalars. only stop if we're sure it's a
@@ -964,12 +1317,31 @@ scan_const(char *start)
break; /* in regexp, $ might be tail anchor */
}
+ /* (now in tr/// code again) */
+
+ if (*s & 0x80 && thisutf) {
+ (void)utf8_to_uv((U8*)s, &len);
+ if (len == 1) {
+ /* illegal UTF8, make it valid */
+ char *old_pvx = SvPVX(sv);
+ /* need space for one extra char (NOTE: SvCUR() not set here) */
+ d = SvGROW(sv, SvLEN(sv) + 1) + (d - old_pvx);
+ d = (char*)uv_to_utf8((U8*)d, (U8)*s++);
+ }
+ else {
+ while (len--)
+ *d++ = *s++;
+ }
+ has_utf = TRUE;
+ continue;
+ }
+
/* backslashes */
if (*s == '\\' && s+1 < send) {
s++;
/* some backslashes we leave behind */
- if (*s && strchr(leaveit, *s)) {
+ if (*leaveit && *s && strchr(leaveit, *s)) {
*d++ = '\\';
*d++ = *s++;
continue;
@@ -979,8 +1351,9 @@ scan_const(char *start)
if (PL_lex_inwhat == OP_SUBST && !PL_lex_inpat &&
isDIGIT(*s) && *s != '0' && !isDIGIT(s[1]))
{
- if (PL_dowarn)
- warn("\\%c better written as $%c", *s, *s);
+ dTHR; /* only for ckWARN */
+ if (ckWARN(WARN_SYNTAX))
+ Perl_warner(aTHX_ WARN_SYNTAX, "\\%c better written as $%c", *s, *s);
*--s = '$';
break;
}
@@ -1001,22 +1374,133 @@ scan_const(char *start)
continue;
}
/* FALL THROUGH */
- /* default action is to copy the quoted character */
default:
- *d++ = *s++;
- continue;
+ {
+ dTHR;
+ if (ckWARN(WARN_MISC) && isALPHA(*s))
+ Perl_warner(aTHX_ WARN_MISC,
+ "Unrecognized escape \\%c passed through",
+ *s);
+ /* default action is to copy the quoted character */
+ *d++ = *s++;
+ continue;
+ }
/* \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);
+ uv = (UV)scan_oct(s, 3, &len);
s += len;
- continue;
+ goto NUM_ESCAPE_INSERT;
/* \x24 indicates a hex constant */
case 'x':
- *d++ = scan_hex(++s, 2, &len);
- s += len;
+ ++s;
+ if (*s == '{') {
+ char* e = strchr(s, '}');
+ if (!e) {
+ yyerror("Missing right brace on \\x{}");
+ e = s;
+ }
+ uv = (UV)scan_hex(s + 1, e - s - 1, &len);
+ s = e + 1;
+ }
+ else {
+ uv = (UV)scan_hex(s, 2, &len);
+ s += len;
+ }
+
+ NUM_ESCAPE_INSERT:
+ /* Insert oct or hex escaped character.
+ * There will always enough room in sv since such escapes will
+ * be longer than any utf8 sequence they can end up as
+ */
+ if (uv > 127) {
+ if (!thisutf && !has_utf && uv > 255) {
+ /* might need to recode whatever we have accumulated so far
+ * if it contains any hibit chars
+ */
+ int hicount = 0;
+ char *c;
+ for (c = SvPVX(sv); c < d; c++) {
+ if (*c & 0x80)
+ hicount++;
+ }
+ if (hicount) {
+ char *old_pvx = SvPVX(sv);
+ char *src, *dst;
+ d = SvGROW(sv, SvCUR(sv) + hicount + 1) + (d - old_pvx);
+
+ src = d - 1;
+ d += hicount;
+ dst = d - 1;
+
+ while (src < dst) {
+ if (*src & 0x80) {
+ dst--;
+ uv_to_utf8((U8*)dst, (U8)*src--);
+ dst--;
+ }
+ else {
+ *dst-- = *src--;
+ }
+ }
+ }
+ }
+
+ if (thisutf || uv > 255) {
+ d = (char*)uv_to_utf8((U8*)d, uv);
+ has_utf = TRUE;
+ }
+ else {
+ *d++ = (char)uv;
+ }
+ }
+ else {
+ *d++ = (char)uv;
+ }
+ continue;
+
+ /* \N{latin small letter a} is a named character */
+ case 'N':
+ ++s;
+ if (*s == '{') {
+ char* e = strchr(s, '}');
+ SV *res;
+ STRLEN len;
+ char *str;
+
+ 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 (!has_utf && SvUTF8(res)) {
+ char *ostart = SvPVX(sv);
+ SvCUR_set(sv, d - ostart);
+ SvPOK_on(sv);
+ sv_utf8_upgrade(sv);
+ d = SvPVX(sv) + SvCUR(sv);
+ has_utf = TRUE;
+ }
+ 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 */
@@ -1049,12 +1533,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++;
@@ -1068,6 +1561,8 @@ scan_const(char *start)
*d = '\0';
SvCUR_set(sv, d - SvPVX(sv));
SvPOK_on(sv);
+ if (has_utf)
+ SvUTF8_on(sv);
/* shrink the sv if we allocated more than we used */
if (SvCUR(sv) + 5 < SvLEN(sv)) {
@@ -1091,9 +1586,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;
@@ -1127,6 +1642,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;
@@ -1155,7 +1671,7 @@ intuit_more(register char *s)
case '&':
case '$':
weight -= seen[un_char] * 10;
- if (isALNUM(s[1])) {
+ if (isALNUM_lazy_if(s+1,UTF)) {
scan_ident(s, send, tmpbuf, sizeof tmpbuf, FALSE);
if ((int)strlen(tmpbuf) > 1 && gv_fetchpv(tmpbuf,FALSE, SVt_PV))
weight -= 100;
@@ -1222,8 +1738,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 quoted 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];
@@ -1246,6 +1783,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;
@@ -1270,7 +1812,7 @@ intuit_method(char *start, GV *gv)
return 0; /* no assumptions -- "=>" quotes bearword */
bare_package:
PL_nextval[PL_nexttoke].opval = (OP*)newSVOP(OP_CONST, 0,
- newSVpv(tmpbuf,0));
+ newSVpvn(tmpbuf,len));
PL_nextval[PL_nexttoke].opval->op_private = OPpCONST_BARE;
PL_expect = XTERM;
force_next(WORD);
@@ -1281,8 +1823,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");
@@ -1307,32 +1856,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.
*/
-#ifndef PERL_OBJECT
-static int filter_debug = 0;
-#endif
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 */
- 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 (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);
@@ -1341,26 +1886,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 (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 */
@@ -1373,8 +1921,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 (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 ;
@@ -1402,29 +1950,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 (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 (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) {
@@ -1443,11 +1990,11 @@ 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
-EXT int yychar; /* last token */
-
/*
yylex
@@ -1474,7 +2021,11 @@ EXT int yychar; /* last token */
*/
int
-yylex(void)
+#ifdef USE_PURE_BISON
+Perl_yylex(pTHX_ YYSTYPE *lvalp, int *lcharp)
+#else
+Perl_yylex(pTHX)
+#endif
{
dTHR;
register char *s;
@@ -1484,6 +2035,11 @@ yylex(void)
GV *gv = Nullgv;
GV **gvp = 0;
+#ifdef USE_PURE_BISON
+ yylval_pointer = lvalp;
+ yychar_pointer = lcharp;
+#endif
+
/* check if there's an identifier for us to look at */
if (PL_pending_ident) {
/* pit holds the identifier we read and pending_ident is reset */
@@ -1497,12 +2053,21 @@ yylex(void)
if it's a legal name, the OP is a PADANY.
*/
if (PL_in_my) {
- if (strchr(PL_tokenbuf,':'))
- croak(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;
+ }
}
/*
@@ -1530,6 +2095,26 @@ yylex(void)
}
#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] == '$' &&
@@ -1541,7 +2126,7 @@ yylex(void)
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);
}
}
@@ -1561,7 +2146,7 @@ yylex(void)
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));
}
@@ -1584,7 +2169,7 @@ yylex(void)
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];
@@ -1601,7 +2186,7 @@ yylex(void)
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') {
@@ -1656,7 +2241,7 @@ yylex(void)
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) {
@@ -1713,11 +2298,18 @@ yylex(void)
PL_lex_state = LEX_INTERPCONCAT;
return ')';
}
+ if (PL_lex_inwhat == OP_SUBST && PL_linestr == PL_lex_repl
+ && SvEVALED(PL_lex_repl))
+ {
+ if (PL_bufptr != PL_bufend)
+ 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();
@@ -1764,13 +2356,16 @@ yylex(void)
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:
switch (*s) {
default:
- croak("Unrecognized character \\%03o", *s & 255);
+ if (isIDFIRST_lazy_if(s,UTF))
+ goto keylookup;
+ Perl_croak(aTHX_ "Unrecognized character \\x%02X", *s & 255);
case 4:
case 26:
goto fake_eof; /* emulate EOF on ^D or ^Z */
@@ -1779,7 +2374,7 @@ yylex(void)
PL_last_uni = 0;
PL_last_lop = 0;
if (PL_lex_brackets)
- yyerror("Missing right bracket");
+ yyerror("Missing right curly or square bracket");
TOKEN(0);
}
if (s++ < PL_bufend)
@@ -1812,20 +2407,20 @@ yylex(void)
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
@@ -1840,7 +2435,7 @@ yylex(void)
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;
}
@@ -1889,10 +2484,10 @@ yylex(void)
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 */
@@ -1930,7 +2525,7 @@ yylex(void)
*/
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);
}
@@ -1942,8 +2537,24 @@ yylex(void)
* 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
@@ -1989,7 +2600,7 @@ yylex(void)
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;
@@ -2004,13 +2615,13 @@ yylex(void)
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);
} while (d);
- if (PERLDB_LINE && !oldpdb ||
- ( PL_minus_n || PL_minus_p ) && !(oldn || oldp) )
+ if ((PERLDB_LINE && !oldpdb) ||
+ ((PL_minus_n || PL_minus_p) && !(oldn || oldp)))
/* if we have already added "LINE: while (<>) {",
we must not do it again */
{
@@ -2034,9 +2645,9 @@ yylex(void)
goto retry;
case '\r':
#ifdef PERL_STRICT_CR
- warn("Illegal character \\%03o (carriage return)", '\r');
- croak(
- "(Maybe you didn't strip carriage returns after a network transfer?)\n");
+ Perl_warn(aTHX_ "Illegal character \\%03o (carriage return)", '\r');
+ Perl_croak(aTHX_
+ "\t(Maybe you didn't strip carriage returns after a network transfer?)\n");
#endif
case ' ': case '\t': case '\f': case 013:
s++;
@@ -2105,7 +2716,7 @@ yylex(void)
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;
}
}
@@ -2120,7 +2731,7 @@ yylex(void)
else if (*s == '>') {
s++;
s = skipspace(s);
- if (isIDFIRST(*s)) {
+ if (isIDFIRST_lazy_if(s,UTF)) {
s = force_word(s,METHOD,FALSE,TRUE,FALSE);
TOKEN(ARROW);
}
@@ -2201,6 +2812,102 @@ yylex(void)
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_if(s,UTF)) {
+ 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++;
@@ -2210,8 +2917,8 @@ yylex(void)
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 ')':
@@ -2223,7 +2930,7 @@ yylex(void)
case ']':
s++;
if (PL_lex_brackets <= 0)
- yyerror("Unmatched right bracket");
+ yyerror("Unmatched right square bracket");
else
--PL_lex_brackets;
if (PL_lex_state == LEX_INTERPNORMAL) {
@@ -2265,7 +2972,7 @@ yylex(void)
while (d < PL_bufend && (*d == ' ' || *d == '\t'))
d++;
}
- if (d < PL_bufend && isIDFIRST(*d)) {
+ if (d < PL_bufend && isIDFIRST_lazy_if(d,UTF)) {
d = scan_word(d, PL_tokenbuf + 1, sizeof PL_tokenbuf - 1,
FALSE, &len);
while (d < PL_bufend && (*d == ' ' || *d == '\t'))
@@ -2278,10 +2985,12 @@ yylex(void)
}
}
/* 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;
@@ -2322,7 +3031,8 @@ yylex(void)
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;
@@ -2353,8 +3063,10 @@ yylex(void)
}
t++;
}
- else if (isALPHA(*s)) {
- for (t++; t < PL_bufend && isALNUM(*t); t++) ;
+ else if (isALNUM_lazy_if(t,UTF)) {
+ t += UTF8SKIP(t);
+ while (t < PL_bufend && isALNUM_lazy_if(t,UTF))
+ t += UTF8SKIP(t);
}
while (t < PL_bufend && isSPACE(*t))
t++;
@@ -2372,7 +3084,7 @@ yylex(void)
}
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('{');
@@ -2380,17 +3092,18 @@ yylex(void)
rightbracket:
s++;
if (PL_lex_brackets <= 0)
- yyerror("Unmatched right bracket");
+ yyerror("Unmatched right curly bracket");
else
PL_expect = (expectation)PL_lex_brackstack[--PL_lex_brackets];
if (PL_lex_brackets < PL_lex_formbrack)
PL_lex_formbrack = 0;
if (PL_lex_state == LEX_INTERPNORMAL) {
if (PL_lex_brackets == 0) {
- if (PL_lex_fakebrack) {
+ if (PL_expect & XFAKEBRACK) {
+ PL_expect &= XENUMMASK;
PL_lex_state = LEX_INTERPEND;
PL_bufptr = s;
- return yylex(); /* ignore fake brackets */
+ return yylex(); /* ignore fake brackets */
}
if (*s == '-' && s[1] == '>')
PL_lex_state = LEX_INTERPENDMAYBE;
@@ -2398,9 +3111,9 @@ yylex(void)
PL_lex_state = LEX_INTERPEND;
}
}
- if (PL_lex_brackets < PL_lex_fakebrack) {
+ if (PL_expect & XFAKEBRACK) {
+ PL_expect &= XENUMMASK;
PL_bufptr = s;
- PL_lex_fakebrack = 0;
return yylex(); /* ignore fake brackets */
}
force_next('}');
@@ -2412,10 +3125,12 @@ yylex(void)
AOPERATOR(ANDAND);
s--;
if (PL_expect == XOPERATOR) {
- if (PL_dowarn && isALPHA(*s) && PL_bufptr == PL_linestart) {
- PL_curcop->cop_line--;
- warn(warn_nosemi);
- PL_curcop->cop_line++;
+ if (ckWARN(WARN_SEMICOLON)
+ && isIDFIRST_lazy_if(s,UTF) && PL_bufptr == PL_linestart)
+ {
+ CopLINE_dec(PL_curcop);
+ Perl_warner(aTHX_ WARN_SEMICOLON, PL_warn_nosemi);
+ CopLINE_inc(PL_curcop);
}
BAop(OP_BIT_AND);
}
@@ -2446,8 +3161,8 @@ yylex(void)
OPERATOR(',');
if (tmp == '~')
PMop(OP_MATCH);
- if (PL_dowarn && tmp && isSPACE(*s) && strchr("+-*/%.^&|<",tmp))
- warn("Reversed %c= operator",(int)tmp);
+ if (ckWARN(WARN_SYNTAX) && tmp && isSPACE(*s) && strchr("+-*/%.^&|<",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') )
@@ -2542,12 +3257,12 @@ yylex(void)
}
}
- if (s[1] == '#' && (isALPHA(s[2]) || strchr("_{$:", s[2]))) {
- if (PL_expect == XOPERATOR)
- no_op("Array length", PL_bufptr);
+ if (s[1] == '#' && (isIDFIRST_lazy_if(s+2,UTF) || strchr("{$:+-", s[2]))) {
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;
@@ -2555,10 +3270,11 @@ yylex(void)
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");
@@ -2568,12 +3284,13 @@ yylex(void)
/* This kludge not intended to be bulletproof. */
if (PL_tokenbuf[1] == '[' && !PL_tokenbuf[2]) {
yylval.opval = newSVOP(OP_CONST, 0,
- newSViv((IV)PL_compiling.cop_arybase));
+ newSViv(PL_compiling.cop_arybase));
yylval.opval->op_private = OPpCONST_ARYBASE;
TERM(THING);
}
d = s;
+ tmp = (I32)*s;
if (PL_lex_state == LEX_NORMAL)
s = skipspace(s);
@@ -2581,50 +3298,52 @@ yylex(void)
char *t;
if (*s == '[') {
PL_tokenbuf[0] = '@';
- if (PL_dowarn) {
+ if (ckWARN(WARN_SYNTAX)) {
for(t = s + 1;
- isSPACE(*t) || isALNUM(*t) || *t == '$';
+ isSPACE(*t) || isALNUM_lazy_if(t,UTF) || *t == '$';
t++) ;
if (*t++ == ',') {
PL_bufptr = skipspace(PL_bufptr);
while (t < PL_bufend && *t != ']')
t++;
- warn("Multidimensional syntax %.*s not supported",
- (t - PL_bufptr) + 1, PL_bufptr);
+ Perl_warner(aTHX_ WARN_SYNTAX,
+ "Multidimensional syntax %.*s not supported",
+ (t - PL_bufptr) + 1, PL_bufptr);
}
}
}
else if (*s == '{') {
PL_tokenbuf[0] = '%';
- if (PL_dowarn && strEQ(PL_tokenbuf+1, "SIG") &&
+ if (ckWARN(WARN_SYNTAX) && strEQ(PL_tokenbuf+1, "SIG") &&
(t = strchr(s, '}')) && (t = strchr(t, '=')))
{
char tmpbuf[sizeof PL_tokenbuf];
STRLEN len;
for (t++; isSPACE(*t); t++) ;
- if (isIDFIRST(*t)) {
+ if (isIDFIRST_lazy_if(t,UTF)) {
t = scan_word(t, tmpbuf, sizeof tmpbuf, TRUE, &len);
for (; isSPACE(*t); t++) ;
- if (*t == ';' && perl_get_cv(tmpbuf, FALSE))
- warn("You need to quote \"%s\"", tmpbuf);
+ if (*t == ';' && get_cv(tmpbuf, FALSE))
+ Perl_warner(aTHX_ WARN_SYNTAX,
+ "You need to quote \"%s\"", tmpbuf);
}
}
}
}
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;
else if (strchr("$@\"'`q", *s))
PL_expect = XTERM; /* e.g. print $fh "foo" */
- else if (strchr("&*<%", *s) && isIDFIRST(s[1]))
+ else if (strchr("&*<%", *s) && isIDFIRST_lazy_if(s+1,UTF))
PL_expect = XTERM; /* e.g. print $fh &sub */
- else if (isIDFIRST(*s)) {
+ else if (isIDFIRST_lazy_if(s,UTF)) {
char tmpbuf[sizeof PL_tokenbuf];
scan_word(s, tmpbuf, sizeof tmpbuf, TRUE, &len);
- if (tmp = keyword(tmpbuf, len)) {
+ if ((tmp = keyword(tmpbuf, len))) {
/* binary operators exclude handle interpretations */
switch (tmp) {
case -KEY_x:
@@ -2676,15 +3395,16 @@ yylex(void)
PL_tokenbuf[0] = '%';
/* Warn about @ where they meant $. */
- if (PL_dowarn) {
+ if (ckWARN(WARN_SYNTAX)) {
if (*s == '[' || *s == '{') {
char *t = s + 1;
- while (*t && (isALNUM(*t) || strchr(" \t$#+-'\"", *t)))
+ while (*t && (isALNUM_lazy_if(t,UTF) || strchr(" \t$#+-'\"", *t)))
t++;
if (*t == '}' || *t == ']') {
t++;
PL_bufptr = skipspace(PL_bufptr);
- warn("Scalar value %.*s better written as $%.*s",
+ Perl_warner(aTHX_ WARN_SYNTAX,
+ "Scalar value %.*s better written as $%.*s",
t-PL_bufptr, PL_bufptr, t-PL_bufptr-1, PL_bufptr+1);
}
}
@@ -2699,7 +3419,8 @@ yylex(void)
/* Disable warning on "study /blah/" */
if (PL_oldoldbufptr == PL_last_uni
&& (*PL_last_uni != 's' || s - PL_last_uni < 5
- || memNE(PL_last_uni, "study", 5) || isALNUM(PL_last_uni[5])))
+ || memNE(PL_last_uni, "study", 5)
+ || isALNUM_lazy_if(PL_last_uni+5,UTF)))
check_uni();
s = scan_pat(s,OP_MATCH);
TERM(sublex_start());
@@ -2747,7 +3468,7 @@ yylex(void)
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;
@@ -2763,7 +3484,7 @@ yylex(void)
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;
@@ -2777,7 +3498,7 @@ yylex(void)
missingterm((char*)0);
yylval.ival = OP_CONST;
for (d = SvPV(PL_lex_stuff, len); len; len--, d++) {
- if (*d == '$' || *d == '@' || *d == '\\') {
+ if (*d == '$' || *d == '@' || *d == '\\' || *d & 0x80) {
yylval.ival = OP_STRINGIFY;
break;
}
@@ -2785,7 +3506,7 @@ yylex(void)
TERM(sublex_start());
case '`':
- s = scan_str(s);
+ s = scan_str(s,FALSE,FALSE);
if (PL_expect == XOPERATOR)
no_op("Backticks",s);
if (!s)
@@ -2796,12 +3517,38 @@ yylex(void)
case '\\':
s++;
- if (PL_dowarn && PL_lex_inwhat && isDIGIT(*s))
- warn("Can't use \\%c to mean $%c in expression", *s, *s);
+ if (ckWARN(WARN_SYNTAX) && PL_lex_inwhat && isDIGIT(*s))
+ 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 != XOPERATOR) {
+ char *start = s;
+ start++;
+ start++;
+ while (isDIGIT(*start) || *start == '_')
+ start++;
+ if (*start == '.' && isDIGIT(start[1])) {
+ s = scan_num(s);
+ TERM(THING);
+ }
+ /* avoid v123abc() or $h{v1}, allow C<print v10;> */
+ else if (!isALPHA(*start) && (PL_expect == XTERM || PL_expect == XREF)) {
+ char c = *start;
+ GV *gv;
+ *start = '\0';
+ gv = gv_fetchpv(s, FALSE, SVt_PVCV);
+ *start = c;
+ if (!gv) {
+ s = scan_num(s);
+ TERM(THING);
+ }
+ }
+ }
+ goto keylookup;
case 'x':
if (isDIGIT(s[1]) && PL_expect == XOPERATOR) {
s++;
@@ -2831,14 +3578,13 @@ yylex(void)
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':
case 'z': case 'Z':
keylookup: {
- STRLEN n_a;
gv = Nullgv;
gvp = 0;
@@ -2846,10 +3592,10 @@ yylex(void)
s = scan_word(s, PL_tokenbuf, sizeof PL_tokenbuf, FALSE, &len);
/* Some keywords can be followed by any delimiter, including ':' */
- tmp = (len == 1 && strchr("msyq", PL_tokenbuf[0]) ||
- len == 2 && ((PL_tokenbuf[0] == 't' && PL_tokenbuf[1] == 'r') ||
- (PL_tokenbuf[0] == 'q' &&
- strchr("qwxr", PL_tokenbuf[1]))));
+ tmp = ((len == 1 && strchr("msyq", PL_tokenbuf[0])) ||
+ (len == 2 && ((PL_tokenbuf[0] == 't' && PL_tokenbuf[1] == 'r') ||
+ (PL_tokenbuf[0] == 'q' &&
+ strchr("qwxr", PL_tokenbuf[1])))));
/* x::* is just a word, unless x is "CORE" */
if (!tmp && *s == ':' && s[1] == ':' && strNE(PL_tokenbuf, "CORE"))
@@ -2905,6 +3651,7 @@ yylex(void)
}
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 */
@@ -2913,9 +3660,10 @@ yylex(void)
tmp = -tmp;
gv = Nullgv;
gvp = 0;
- if (PL_dowarn && hgv
- && tmp != KEY_x && tmp != KEY_CORE) /* never ambiguous */
- warn("Ambiguous call resolved as CORE::%s(), %s",
+ if (ckWARN(WARN_AMBIGUOUS) && hgv
+ && tmp != KEY_x && tmp != KEY_CORE) /* never ambiguous */
+ Perl_warner(aTHX_ WARN_AMBIGUOUS,
+ "Ambiguous call resolved as CORE::%s(), %s",
GvENAME(hgv), "qualify as such or use &");
}
}
@@ -2930,21 +3678,21 @@ yylex(void)
/* Get the rest if it looks like a package qualifier */
- if (*s == '\'' || *s == ':' && s[1] == ':') {
+ if (*s == '\'' || (*s == ':' && s[1] == ':')) {
STRLEN morelen;
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--;
- warn(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);
@@ -2957,8 +3705,9 @@ yylex(void)
if (len > 2 &&
PL_tokenbuf[len - 2] == ':' && PL_tokenbuf[len - 1] == ':')
{
- if (PL_dowarn && ! gv_fetchpv(PL_tokenbuf, FALSE, SVt_PVHV))
- warn("Bareword \"%s\" refers to nonexistent package",
+ if (ckWARN(WARN_BAREWORD) && ! gv_fetchpv(PL_tokenbuf, FALSE, SVt_PVHV))
+ Perl_warner(aTHX_ WARN_BAREWORD,
+ "Bareword \"%s\" refers to nonexistent package",
PL_tokenbuf);
len -= 2;
PL_tokenbuf[len] = '\0';
@@ -2974,7 +3723,7 @@ yylex(void)
/* if we saw a global override before, get the right name */
if (gvp) {
- sv = newSVpv("CORE::GLOBAL::",14);
+ sv = newSVpvn("CORE::GLOBAL::",14);
sv_catpv(sv,PL_tokenbuf);
}
else
@@ -2995,13 +3744,11 @@ yylex(void)
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
- || ((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 == '(';
@@ -3010,15 +3757,17 @@ yylex(void)
/* Two barewords in a row may indicate method call. */
- if ((isALPHA(*s) || *s == '$') && (tmp=intuit_method(s,gv)))
+ if ((isIDFIRST_lazy_if(s,UTF) || *s == '$') && (tmp=intuit_method(s,gv)))
return tmp;
/* If not a declared subroutine, it's an indirect object. */
/* (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;
}
@@ -3031,11 +3780,8 @@ yylex(void)
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;
}
@@ -3044,7 +3790,6 @@ yylex(void)
PL_expect = XOPERATOR;
force_next(WORD);
yylval.ival = 0;
- PL_last_lop_op = OP_ENTERSUB;
TOKEN('&');
}
@@ -3058,18 +3803,17 @@ yylex(void)
/* If followed by a bareword, see if it looks like indir obj. */
- if ((isALPHA(*s) || *s == '$') && (tmp = intuit_method(s,gv)))
+ if ((isIDFIRST_lazy_if(s,UTF) || *s == '$') && (tmp = intuit_method(s,gv)))
return tmp;
/* Not a method, so call it a subroutine (if defined) */
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))) {
@@ -3083,60 +3827,51 @@ yylex(void)
/* 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 (PL_dowarn) {
- if (lastchar != '-') {
- for (d = PL_tokenbuf; *d && isLOWER(*d); d++) ;
- if (!*d)
- warn(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);
@@ -3144,12 +3879,12 @@ yylex(void)
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__:
@@ -3168,7 +3903,7 @@ yylex(void)
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();
@@ -3187,6 +3922,28 @@ yylex(void)
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;
@@ -3195,8 +3952,9 @@ yylex(void)
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;
@@ -3208,7 +3966,8 @@ yylex(void)
s += 2;
d = s;
s = scan_word(s, PL_tokenbuf, sizeof PL_tokenbuf, FALSE, &len);
- tmp = keyword(PL_tokenbuf, len);
+ if (!(tmp = keyword(PL_tokenbuf, len)))
+ Perl_croak(aTHX_ "CORE::%s is not a keyword", PL_tokenbuf);
if (tmp < 0)
tmp = -tmp;
goto reserved_word;
@@ -3234,7 +3993,7 @@ yylex(void)
LOP(OP_BIND,XTERM);
case KEY_binmode:
- UNI(OP_BINMODE);
+ LOP(OP_BINMODE,XTERM);
case KEY_bless:
LOP(OP_BLESS,XTERM);
@@ -3263,16 +4022,19 @@ yylex(void)
case KEY_crypt:
#ifdef FCRYPT
- if (!PL_cryptseen++)
+ if (!PL_cryptseen) {
+ PL_cryptseen = TRUE;
init_des();
+ }
#endif
LOP(OP_CRYPT,XTERM);
case KEY_chmod:
- if (PL_dowarn) {
+ if (ckWARN(WARN_CHMOD)) {
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_CHMOD,
+ "chmod() mode argument is missing initial 0");
}
LOP(OP_CHMOD,XTERM);
@@ -3324,7 +4086,7 @@ yylex(void)
PREBLOCK(ELSE);
case KEY_elsif:
- yylval.ival = PL_curcop->cop_line;
+ yylval.ival = CopLINE(PL_curcop);
OPERATOR(ELSIF);
case KEY_eq:
@@ -3374,16 +4136,24 @@ yylex(void)
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(*s)) {
+ if (PL_expect == XSTATE && isIDFIRST_lazy_if(s,UTF)) {
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(*p))
- croak("Missing $ on loop variable");
+ if (isIDFIRST_lazy_if(p,UTF)) {
+ 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);
@@ -3409,7 +4179,7 @@ yylex(void)
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);
@@ -3504,7 +4274,7 @@ yylex(void)
UNI(OP_HEX);
case KEY_if:
- yylval.ival = PL_curcop->cop_line;
+ yylval.ival = CopLINE(PL_curcop);
OPERATOR(IF);
case KEY_index:
@@ -3536,6 +4306,7 @@ yylex(void)
UNI(OP_LCFIRST);
case KEY_local:
+ yylval.ival = 0;
OPERATOR(LOCAL);
case KEY_length:
@@ -3570,8 +4341,8 @@ yylex(void)
TERM(sublex_start());
case KEY_map:
- LOP(OP_MAPSTART,XREF);
-
+ LOP(OP_MAPSTART, XREF);
+
case KEY_mkdir:
LOP(OP_MKDIR,XTERM);
@@ -3587,11 +4358,14 @@ yylex(void)
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(*s)) {
+ if (isIDFIRST_lazy_if(s,UTF)) {
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];
@@ -3600,6 +4374,7 @@ yylex(void)
yyerror(tmpbuf);
}
}
+ yylval.ival = 1;
OPERATOR(MY);
case KEY_next:
@@ -3618,17 +4393,21 @@ yylex(void)
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);
- if (isIDFIRST(*s)) {
+ if (isIDFIRST_lazy_if(s,UTF)) {
char *t;
- for (d = s; isALNUM(*d); d++) ;
+ for (d = s; isALNUM_lazy_if(d,UTF); 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_PRECEDENCE))
+ Perl_warner(aTHX_ WARN_PRECEDENCE,
+ "Precedence problem: open %.*s should be open(%.*s)",
+ d-s,s, d-s,s);
}
LOP(OP_OPEN,XTERM);
@@ -3676,7 +4455,7 @@ yylex(void)
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;
@@ -3686,40 +4465,52 @@ yylex(void)
UNI(OP_QUOTEMETA);
case KEY_qw:
- s = scan_str(s);
+ s = scan_str(s,FALSE,FALSE);
if (!s)
missingterm((char*)0);
- if (PL_dowarn && SvLEN(PL_lex_stuff)) {
+ force_next(')');
+ if (SvCUR(PL_lex_stuff)) {
+ OP *words = Nullop;
+ int warned = 0;
d = SvPV_force(PL_lex_stuff, len);
- for (; len; --len, ++d) {
- if (*d == ',') {
- warn("Possible attempt to separate words with commas");
- break;
- }
- if (*d == '#') {
- warn("Possible attempt to put comments in qw() list");
- break;
+ while (len) {
+ for (; isSPACE(*d) && len; --len, ++d) ;
+ if (len) {
+ char *b = d;
+ if (!warned && ckWARN(WARN_QW)) {
+ for (; !isSPACE(*d) && len; --len, ++d) {
+ if (*d == ',') {
+ Perl_warner(aTHX_ WARN_QW,
+ "Possible attempt to separate words with commas");
+ ++warned;
+ }
+ else if (*d == '#') {
+ Perl_warner(aTHX_ WARN_QW,
+ "Possible attempt to put comments in qw() list");
+ ++warned;
+ }
+ }
+ }
+ else {
+ for (; !isSPACE(*d) && len; --len, ++d) ;
+ }
+ words = append_elem(OP_LIST, words,
+ newSVOP(OP_CONST, 0, newSVpvn(b, d-b)));
}
}
+ if (words) {
+ PL_nextval[PL_nexttoke].opval = words;
+ force_next(THING);
+ }
}
- force_next(')');
- PL_nextval[PL_nexttoke].opval = (OP*)newSVOP(OP_CONST, 0, tokeq(PL_lex_stuff));
+ if (PL_lex_stuff)
+ SvREFCNT_dec(PL_lex_stuff);
PL_lex_stuff = Nullsv;
- force_next(THING);
- force_next(',');
- PL_nextval[PL_nexttoke].opval = (OP*)newSVOP(OP_CONST, 0, newSVpv(" ",1));
- force_next(THING);
- force_next('(');
- yylval.ival = OP_SPLIT;
- CLINE;
PL_expect = XTERM;
- PL_bufptr = s;
- PL_last_lop = PL_oldbufptr;
- PL_last_lop_op = OP_SPLIT;
- return FUNC;
+ TOKEN('(');
case KEY_qq:
- s = scan_str(s);
+ s = scan_str(s,FALSE,FALSE);
if (!s)
missingterm((char*)0);
yylval.ival = OP_STRINGIFY;
@@ -3732,7 +4523,7 @@ yylex(void)
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;
@@ -3743,12 +4534,18 @@ yylex(void)
OLDLOP(OP_RETURN);
case KEY_require:
- *PL_tokenbuf = '\0';
- s = force_word(s,WORD,TRUE,TRUE,FALSE);
- if (isIDFIRST(*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_if(PL_tokenbuf,UTF))
+ gv_stashpvn(PL_tokenbuf, strlen(PL_tokenbuf), TRUE);
+ else if (*s == '<')
+ yyerror("<> should be quotes");
+ }
UNI(OP_REQUIRE);
case KEY_reset:
@@ -3894,7 +4691,7 @@ yylex(void)
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);
@@ -3918,7 +4715,6 @@ yylex(void)
UNI(OP_STAT);
case KEY_study:
- PL_sawstudy++;
UNI(OP_STUDY);
case KEY_substr:
@@ -3927,73 +4723,97 @@ yylex(void)
case KEY_format:
case KEY_sub:
really_sub:
- s = skipspace(s);
-
- if (isIDFIRST(*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_if(s,UTF) || *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;
- }
-
- if (*SvPV(PL_subname,n_a) == '?') {
- sv_setpv(PL_subname,"__ANON__");
- TOKEN(ANONSUB);
+ (void) force_word(PL_oldbufptr + tboffset, WORD,
+ FALSE, TRUE, TRUE);
+ if (key == KEY_my)
+ TOKEN(MYSUB);
+ TOKEN(SUB);
}
- PREBLOCK(SUB);
case KEY_system:
set_csh();
@@ -4052,11 +4872,11 @@ yylex(void)
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:
@@ -4072,10 +4892,11 @@ yylex(void)
LOP(OP_UTIME,XTERM);
case KEY_umask:
- if (PL_dowarn) {
+ if (ckWARN(WARN_UMASK)) {
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_UMASK,
+ "umask: argument is missing initial 0");
}
UNI(OP_UMASK);
@@ -4086,9 +4907,9 @@ yylex(void)
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);
}
@@ -4104,11 +4925,10 @@ yylex(void)
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:
@@ -4156,7 +4976,7 @@ yylex(void)
}
I32
-keyword(register char *d, I32 len)
+Perl_keyword(pTHX_ register char *d, I32 len)
{
switch (*d) {
case '_':
@@ -4196,6 +5016,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) {
@@ -4279,7 +5100,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;
@@ -4500,8 +5321,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;
@@ -4775,22 +5595,26 @@ 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;
- if (PL_dowarn && *s == ' ' && s[1] == '(') { /* XXX gotta be a better way */
- int level = 1;
- for (w = s+2; *w && level; w++) {
- if (*w == '(')
- ++level;
- else if (*w == ')')
- --level;
- }
- if (*w)
- for (; *w && isSPACE(*w); w++) ;
- if (!*w || !strchr(";|})]oaiuw!=", *w)) /* an advisory hack only... */
- warn("%s (...) interpreted as function",name);
+ if (*s == ' ' && s[1] == '(') { /* XXX gotta be a better way */
+ dTHR; /* only for ckWARN */
+ if (ckWARN(WARN_SYNTAX)) {
+ int level = 1;
+ for (w = s+2; *w && level; w++) {
+ if (*w == '(')
+ ++level;
+ else if (*w == ')')
+ --level;
+ }
+ if (*w)
+ for (; *w && isSPACE(*w); w++) ;
+ if (!*w || !strchr(";|})]oaiuw!=", *w)) /* an advisory hack only... */
+ Perl_warner(aTHX_ WARN_SYNTAX,
+ "%s (...) interpreted as function",name);
+ }
}
while (s < PL_bufend && isSPACE(*s))
s++;
@@ -4798,104 +5622,128 @@ checkcomma(register char *s, char *name, char *what)
s++;
while (s < PL_bufend && isSPACE(*s))
s++;
- if (isIDFIRST(*s)) {
+ if (isIDFIRST_lazy_if(s,UTF)) {
w = s++;
- while (isALNUM(*s))
+ while (isALNUM_lazy_if(s,UTF))
s++;
while (s < PL_bufend && isSPACE(*s))
s++;
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;
- char buf[128];
-
- if (!table) {
- yyerror("%^H is not defined");
- return sv;
+ const char *why1, *why2, *why3;
+
+ if (!table || !(PL_hints & HINT_LOCALIZE_HH)) {
+ SV *msg;
+
+ why1 = "%^H is not consistent";
+ why2 = strEQ(key,"charnames")
+ ? " (missing \"use charnames ...\"?)"
+ : "";
+ why3 = "";
+ report:
+ msg = Perl_newSVpvf(aTHX_ "constant(%s): %s%s%s",
+ (type ? type: "undef"), why1, why2, why3);
+ yyerror(SvPVX(msg));
+ SvREFCNT_dec(msg);
+ return sv;
}
cvp = hv_fetch(table, key, strlen(key), FALSE);
if (!cvp || !SvOK(*cvp)) {
- sprintf(buf,"$^H{%s} is not defined", key);
- yyerror(buf);
- return sv;
+ why1 = "$^H{";
+ why2 = key;
+ why3 = "} is not defined";
+ goto report;
}
sv_2mortal(sv); /* Parent created it permanently */
cv = *cvp;
- if (!pv)
- pv = sv_2mortal(newSVpv(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)) {
- sprintf(buf,"Call to &{$^H{%s}} did not return a defined value", key);
- yyerror(buf);
+ why1 = "Call to &{$^H{";
+ why2 = key;
+ why3 = "}} did not return a defined value";
+ sv = res;
+ goto report;
}
- return SvREFCNT_inc(res);
-}
+ 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);
- if (isALNUM(*s))
+ Perl_croak(aTHX_ ident_too_long);
+ if (isALNUM(*s)) /* UTF handled below */
*d++ = *s++;
- else if (*s == '\'' && allow_package && isIDFIRST(s[1])) {
+ else if (*s == '\'' && allow_package && isIDFIRST_lazy_if(s+1,UTF)) {
*d++ = ':';
*d++ = ':';
s++;
@@ -4904,6 +5752,16 @@ scan_word(register char *s, char *dest, STRLEN destlen, int allow_package, STRLE
*d++ = *s++;
*d++ = *s++;
}
+ else if (UTF && *(U8*)s >= 0xc0 && isALNUM_utf8((U8*)s)) {
+ char *t = s + UTF8SKIP(s);
+ while (*t & 0x80 && is_utf8_mark((U8*)t))
+ t += UTF8SKIP(t);
+ if (d + (t - s) > e)
+ Perl_croak(aTHX_ ident_too_long);
+ Copy(s, d, t - s, char);
+ d += t - s;
+ s = t;
+ }
else {
*d = '\0';
*slp = d - dest;
@@ -4913,15 +5771,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;
@@ -4929,17 +5785,17 @@ 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);
- if (isALNUM(*s))
+ Perl_croak(aTHX_ ident_too_long);
+ if (isALNUM(*s)) /* UTF handled below */
*d++ = *s++;
- else if (*s == '\'' && isIDFIRST(s[1])) {
+ else if (*s == '\'' && isIDFIRST_lazy_if(s+1,UTF)) {
*d++ = ':';
*d++ = ':';
s++;
@@ -4948,6 +5804,16 @@ scan_ident(register char *s, register char *send, char *dest, STRLEN destlen, I3
*d++ = *s++;
*d++ = *s++;
}
+ else if (UTF && *(U8*)s >= 0xc0 && isALNUM_utf8((U8*)s)) {
+ char *t = s + UTF8SKIP(s);
+ while (*t & 0x80 && is_utf8_mark((U8*)t))
+ t += UTF8SKIP(t);
+ if (d + (t - s) > e)
+ Perl_croak(aTHX_ ident_too_long);
+ Copy(s, d, t - s, char);
+ d += t - s;
+ s = t;
+ }
else
break;
}
@@ -4960,12 +5826,9 @@ scan_ident(register char *s, register char *send, char *dest, STRLEN destlen, I3
return s;
}
if (*s == '$' && s[1] &&
- (isALNUM(s[1]) || strchr("${", s[1]) || strnEQ(s+1,"::",2)) )
+ (isALNUM_lazy_if(s+1,UTF) || strchr("${", s[1]) || strnEQ(s+1,"::",2)) )
{
- if (isDIGIT(s[1]) && PL_lex_state == LEX_INTERPNORMAL)
- deprecate("\"$$<digit>\" to mean \"${$}<digit>\"");
- else
- return s;
+ return s;
}
if (*s == '{') {
bracket = s;
@@ -4976,7 +5839,7 @@ scan_ident(register char *s, register char *send, char *dest, STRLEN destlen, I3
if (s < send)
*d = *s++;
d[1] = '\0';
- if (*d == '^' && *s && (isUPPER(*s) || strchr("[\\]^_?", *s))) {
+ if (*d == '^' && *s && isCONTROLVAR(*s)) {
*d = toCTRL(*s);
s++;
}
@@ -4990,23 +5853,52 @@ scan_ident(register char *s, register char *send, char *dest, STRLEN destlen, I3
}
}
}
- if (isIDFIRST(*d)) {
+ if (isIDFIRST_lazy_if(d,UTF)) {
d++;
- while (isALNUM(*s) || *s == ':')
- *d++ = *s++;
+ if (UTF) {
+ e = s;
+ while ((e < send && isALNUM_lazy_if(e,UTF)) || *e == ':') {
+ e += UTF8SKIP(e);
+ while (e < send && *e & 0x80 && is_utf8_mark((U8*)e))
+ e += UTF8SKIP(e);
+ }
+ Copy(s, d, e - s, char);
+ d += e - s;
+ s = e;
+ }
+ else {
+ while ((isALNUM(*s) || *s == ':') && d < e)
+ *d++ = *s++;
+ if (d >= e)
+ Perl_croak(aTHX_ ident_too_long);
+ }
*d = '\0';
while (s < send && (*s == ' ' || *s == '\t')) s++;
if ((*s == '[' || (*s == '{' && strNE(dest, "sub")))) {
- if (PL_dowarn && keyword(dest, d - dest)) {
- char *brack = *s == '[' ? "[...]" : "{...}";
- warn("Ambiguous use of %c{%s%s} resolved to %c%s%s",
+ dTHR; /* only for ckWARN */
+ if (ckWARN(WARN_AMBIGUOUS) && keyword(dest, d - dest)) {
+ 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;
}
+ }
+ /* Handle extended ${^Foo} variables
+ * 1999-02-27 mjd-perl-patch@plover.com */
+ else if (!isALNUM(*d) && !isPRINT(*d) /* isCTRL(d) */
+ && isALNUM(*s))
+ {
+ d++;
+ while (isALNUM(*s) && d < e) {
+ *d++ = *s++;
+ }
+ if (d >= e)
+ Perl_croak(aTHX_ ident_too_long);
+ *d = '\0';
}
if (*s == '}') {
s++;
@@ -5014,10 +5906,16 @@ scan_ident(register char *s, register char *send, char *dest, STRLEN destlen, I3
PL_lex_state = LEX_INTERPEND;
if (funny == '#')
funny = '@';
- if (PL_dowarn && PL_lex_state == LEX_NORMAL &&
- (keyword(dest, d - dest) || perl_get_cv(dest, FALSE)))
- warn("Ambiguous use of %c{%s} resolved to %c%s",
- funny, dest, funny, dest);
+ if (PL_lex_state == LEX_NORMAL) {
+ dTHR; /* only for ckWARN */
+ if (ckWARN(WARN_AMBIGUOUS) &&
+ (keyword(dest, d - dest) || get_cv(dest, FALSE)))
+ {
+ Perl_warner(aTHX_ WARN_AMBIGUOUS,
+ "Ambiguous use of %c{%s} resolved to %c%s",
+ funny, dest, funny, dest);
+ }
+ }
}
else {
s = bracket; /* let the parser handle it */
@@ -5029,7 +5927,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;
@@ -5048,17 +5947,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);
@@ -5080,7 +5979,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;
@@ -5089,20 +5988,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);
@@ -5110,7 +6009,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 */
@@ -5128,17 +6027,17 @@ scan_subst(char *start)
if (es) {
SV *repl;
- PL_super_bufptr = s;
- PL_super_bufend = PL_bufend;
+ PL_sublex_info.super_bufptr = s;
+ PL_sublex_info.super_bufend = PL_bufend;
PL_multi_end = 0;
pm->op_pmflags |= PMf_EVAL;
- repl = newSVpv("",0);
+ repl = newSVpvn("",0);
while (es-- > 0)
sv_catpv(repl, es ? "eval " : "do ");
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;
}
@@ -5150,28 +6049,30 @@ scan_subst(char *start)
}
STATIC char *
-scan_trans(char *start)
+S_scan_trans(pTHX_ char *start)
{
register char* s;
OP *o;
short *tbl;
I32 squash;
- I32 Delete;
+ I32 del;
I32 complement;
+ I32 utf8;
+ I32 count = 0;
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);
@@ -5179,23 +6080,48 @@ 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");
}
- New(803,tbl,256,short);
- o = newPVOP(OP_TRANS, 0, (char*)tbl);
+ if (UTF) {
+ o = newSVOP(OP_TRANS, 0, 0);
+ utf8 = OPpTRANS_FROM_UTF|OPpTRANS_TO_UTF;
+ }
+ else {
+ New(803,tbl,256,short);
+ o = newPVOP(OP_TRANS, 0, (char*)tbl);
+ utf8 = 0;
+ }
- complement = Delete = squash = 0;
- while (*s == 'c' || *s == 'd' || *s == 's') {
+ complement = del = squash = 0;
+ while (strchr("cdsCU", *s)) {
if (*s == 'c')
complement = OPpTRANS_COMPLEMENT;
else if (*s == 'd')
- Delete = OPpTRANS_DELETE;
- else
+ del = OPpTRANS_DELETE;
+ else if (*s == 's')
squash = OPpTRANS_SQUASH;
+ else {
+ switch (count++) {
+ case 0:
+ if (*s == 'C')
+ utf8 &= ~OPpTRANS_FROM_UTF;
+ else
+ utf8 |= OPpTRANS_FROM_UTF;
+ break;
+ case 1:
+ if (*s == 'C')
+ utf8 &= ~OPpTRANS_TO_UTF;
+ else
+ utf8 |= OPpTRANS_TO_UTF;
+ break;
+ default:
+ Perl_croak(aTHX_ "Too many /C and /U options");
+ }
+ }
s++;
}
- o->op_private = Delete|squash|complement;
+ o->op_private = del|squash|complement|utf8;
PL_lex_op = o;
yylval.ival = OP_TRANS;
@@ -5203,7 +6129,7 @@ scan_trans(char *start)
}
STATIC char *
-scan_heredoc(register char *s)
+S_scan_heredoc(pTHX_ register char *s)
{
dTHR;
SV *herewas;
@@ -5235,15 +6161,15 @@ scan_heredoc(register char *s)
s++, term = '\'';
else
term = '"';
- if (!isALNUM(*s))
+ if (!isALNUM_lazy_if(s,UTF))
deprecate("bare << to mean <<\"\"");
- for (; isALNUM(*s); s++) {
+ for (; isALNUM_lazy_if(s,UTF); s++) {
if (d < e)
*d++ = *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;
@@ -5273,9 +6199,9 @@ scan_heredoc(register char *s)
#endif
d = "\n";
if (outer || !(d=ninstr(s,PL_bufend,d,d+1)))
- herewas = newSVpv(s,PL_bufend-s);
+ herewas = newSVpvn(s,PL_bufend-s);
else
- s--, herewas = newSVpv(s,d-s);
+ s--, herewas = newSVpvn(s,d-s);
s += SvCUR(herewas);
tmpstr = NEWSV(87,79);
@@ -5290,12 +6216,12 @@ 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) {
- char *bufptr = PL_super_bufptr;
- char *bufend = PL_super_bufend;
+ char *bufptr = PL_sublex_info.super_bufptr;
+ char *bufend = PL_sublex_info.super_bufend;
char *olds = s - SvCUR(herewas);
s = strchr(bufptr, '\n');
if (!s)
@@ -5304,10 +6230,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);
@@ -5324,15 +6250,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);
@@ -5344,10 +6270,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) {
@@ -5369,8 +6295,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;
@@ -5385,7 +6310,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);
@@ -5413,25 +6338,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++;
@@ -5445,7 +6374,7 @@ scan_inputsymbol(char *start)
if (*d == '$' && d[1]) d++;
/* allow <Pkg'VALUE> or <Pkg::VALUE> */
- while (*d && (isALNUM(*d) || *d == '\'' || *d == ':'))
+ while (*d && (isALNUM_lazy_if(d,UTF) || *d == '\'' || *d == ':'))
d++;
/* If we've tried to read what we allow filehandles to look like, and
@@ -5457,9 +6386,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 {
@@ -5482,16 +6411,16 @@ scan_inputsymbol(char *start)
if ((tmp = pad_findmy(d)) != NOT_IN_PAD) {
OP *o = newOP(OP_PADSV, 0);
o->op_targ = tmp;
- PL_lex_op = (OP*)newUNOP(OP_READLINE, 0, newUNOP(OP_RV2GV, 0, o));
+ PL_lex_op = (OP*)newUNOP(OP_READLINE, 0, o);
}
else {
GV *gv = gv_fetchpv(d+1,TRUE, SVt_PV);
PL_lex_op = (OP*)newUNOP(OP_READLINE, 0,
- newUNOP(OP_RV2GV, 0,
newUNOP(OP_RV2SV, 0,
- newGVOP(OP_GV, 0, gv))));
+ newGVOP(OP_GV, 0, gv)));
}
- /* we created the ops in lex_op, so make yylval.ival a null op */
+ PL_lex_op->op_flags |= OPf_SPECIAL;
+ /* we created the ops in PL_lex_op, so make yylval.ival a null op */
yylval.ival = OP_NULL;
}
@@ -5510,6 +6439,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.
@@ -5527,6 +6458,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 <FOO>, <>, <$fh>, or <*.c>
In most of these cases (all but <>, patterns and transliterate)
@@ -5549,7 +6481,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 */
@@ -5558,6 +6490,7 @@ scan_str(char *start)
register char term; /* terminating character */
register char *to; /* current position in the sv's data */
I32 brackets = 1; /* bracket nesting level */
+ bool has_utf = FALSE; /* is there any utf8 content? */
/* skip space before the delimiter */
if (isSPACE(*s))
@@ -5568,8 +6501,11 @@ scan_str(char *start)
/* after skipping whitespace, the next character is the terminator */
term = *s;
+ if ((term & 0x80) && UTF)
+ has_utf = TRUE;
+
/* 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 */
@@ -5585,22 +6521,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
@@ -5610,6 +6548,8 @@ scan_str(char *start)
have found the terminator */
else if (*s == term)
break;
+ else if (!has_utf && (*s & 0x80) && UTF)
+ has_utf = TRUE;
*to = *s;
}
}
@@ -5623,10 +6563,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++;
@@ -5636,6 +6577,8 @@ scan_str(char *start)
break;
else if (*s == PL_multi_open)
brackets++;
+ else if (!has_utf && (*s & 0x80) && UTF)
+ has_utf = TRUE;
*to = *s;
}
}
@@ -5647,7 +6590,8 @@ scan_str(char *start)
* this next chunk reads more into the buffer if we're not done yet
*/
- if (s < PL_bufend) break; /* handle case where we are done yet :-) */
+ if (s < PL_bufend)
+ break; /* handle case where we are done yet :-) */
#ifndef PERL_STRICT_CR
if (to - SvPVX(sv) >= 2) {
@@ -5671,29 +6615,32 @@ 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) {
SV *sv = NEWSV(88,0);
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 */
PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr);
}
/* 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);
+ if (has_utf)
+ SvUTF8_on(sv);
+ PL_multi_end = CopLINE(PL_curcop);
s++;
/* if we allocated too much space, give some back */
@@ -5721,7 +6668,7 @@ scan_str(char *start)
Read a number in any of the formats that Perl accepts:
- 0(x[0-7A-F]+)|([0-7]+)
+ 0(x[0-7A-F]+)|([0-7]+)|(b[01])
[\d_]+(\.[\d_]*)?[Ee](\d+)
Underbars (_) are allowed in decimal numbers. If -w is on,
@@ -5736,15 +6683,14 @@ 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? */
+ 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";
@@ -5752,42 +6698,63 @@ 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.
- */
+ 0.13 disguise, or a hexadecimal number, or a binary number. */
case '0':
{
/* variables:
u holds the "number so far"
- shift the power of 2 of the base (hex == 4, octal == 3)
+ shift the power of 2 of the base
+ (hex == 4, octal == 3, binary == 1)
overflowed was the number more than we can hold?
Shift is used when we add a digit. It also serves as an "are
- we in octal or hex?" indicator to disallow hex characters when
- in octal mode.
+ 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') {
shift = 4;
s += 2;
+ } else if (s[1] == 'b') {
+ shift = 1;
+ 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;
- /* read the rest of the octal number */
+ 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) {
@@ -5802,13 +6769,18 @@ scan_num(char *start)
/* 8 and 9 are not octal */
case '8': case '9':
- if (shift != 4)
- yyerror("Illegal octal digit");
+ if (shift == 3)
+ yyerror(Perl_form(aTHX_ "Illegal octal digit '%c'", *s));
/* FALL THROUGH */
/* octal digits */
- case '0': case '1': case '2': case '3': case '4':
+ case '2': case '3': case '4':
case '5': case '6': case '7':
+ if (shift == 1)
+ yyerror(Perl_form(aTHX_ "Illegal binary digit '%c'", *s));
+ /* FALL THROUGH */
+
+ case '0': case '1':
b = *s++ & 15; /* ASCII digit -> value of digit */
goto digit;
@@ -5825,14 +6797,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" : "octal");
- 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;
}
}
@@ -5842,8 +6833,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;
@@ -5865,22 +6873,26 @@ scan_num(char *start)
if -w is on
*/
if (*s == '_') {
- if (PL_dowarn && lastub && s - lastub != 3)
- warn("Misplaced _ in number");
+ dTHR; /* only for ckWARN */
+ if (ckWARN(WARN_SYNTAX) && lastub && s - lastub != 3)
+ 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++;
}
}
/* final misplaced underbar check */
- if (PL_dowarn && lastub && s - lastub != 3)
- warn("Misplaced _ in number");
+ if (lastub && s - lastub != 3) {
+ dTHR;
+ if (ckWARN(WARN_SYNTAX))
+ Perl_warner(aTHX_ WARN_SYNTAX, "Misplaced _ in number");
+ }
/* read a decimal portion if there is one. avoid
3..5 being interpreted as the number 3. followed
@@ -5896,10 +6908,15 @@ 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;
}
+ if (*s == '.' && isDIGIT(s[1])) {
+ /* oops, it's really a v-string, but without the "v" */
+ s = start - 1;
+ goto vstring;
+ }
}
/* read exponent part, if present */
@@ -5917,7 +6934,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++;
}
}
@@ -5927,9 +6944,17 @@ 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);
+
+ /* unfortunately this monster needs to be on one line or
+ makedepend will be confused. */
+#if (defined(USE_64_BIT_INT) && (!defined(HAS_STRTOLL)|| !defined(HAS_STRTOULL))) || (!defined(USE_64_BIT_INT) && (!defined(HAS_STRTOL) || !defined(HAS_STRTOUL)))
+
+ /*
+ No working strto[u]l[l]. Since atoi() doesn't do range checks,
+ we need to do this the hard way.
+ */
+
+ value = Atof(PL_tokenbuf);
/*
See if we can make do with an integer value without loss of
@@ -5941,31 +6966,130 @@ scan_num(char *start)
Note: if floatit is true, then we don't need to do the
conversion at all.
*/
- tryiv = I_V(value);
- if (!floatit && (double)tryiv == value)
- sv_setiv(sv, tryiv);
- else
+ {
+ UV tryuv = U_V(value);
+ if (!floatit && (NV)tryuv == value) {
+ if (tryuv <= IV_MAX)
+ sv_setiv(sv, (IV)tryuv);
+ else
+ sv_setuv(sv, tryuv);
+ }
+ else
+ sv_setnv(sv, value);
+ }
+#else
+ /*
+ strtol/strtoll sets errno to ERANGE if the number is too big
+ for an integer. We try to do an integer conversion first
+ if no characters indicating "float" have been found.
+ */
+
+ if (!floatit) {
+ IV iv;
+ UV uv;
+ errno = 0;
+ if (*PL_tokenbuf == '-')
+ iv = Strtol(PL_tokenbuf, (char**)NULL, 10);
+ else
+ uv = Strtoul(PL_tokenbuf, (char**)NULL, 10);
+ if (errno)
+ floatit = TRUE; /* probably just too large */
+ else if (*PL_tokenbuf == '-')
+ sv_setiv(sv, iv);
+ else
+ sv_setuv(sv, uv);
+ }
+ if (floatit) {
+ value = Atof(PL_tokenbuf);
sv_setnv(sv, value);
- if ( floatit ? (PL_hints & HINT_NEW_FLOAT) : (PL_hints & HINT_NEW_INTEGER) )
+ }
+#endif
+ 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 v-string */
+ case 'v':
+vstring:
+ {
+ char *pos = s;
+ pos++;
+ while (isDIGIT(*pos) || *pos == '_')
+ pos++;
+ if (!isALPHA(*pos)) {
+ UV rev;
+ U8 tmpbuf[UTF8_MAXLEN];
+ U8 *tmpend;
+ bool utf8 = FALSE;
+ s++; /* get past 'v' */
+
+ sv = NEWSV(92,5);
+ sv_setpvn(sv, "", 0);
+
+ for (;;) {
+ if (*s == '0' && isDIGIT(s[1]))
+ yyerror("Octal number in vector unsupported");
+ rev = 0;
+ {
+ /* this is atoi() that tolerates underscores */
+ char *end = pos;
+ UV mult = 1;
+ while (--end >= s) {
+ UV orev;
+ if (*end == '_')
+ continue;
+ orev = rev;
+ rev += (*end - '0') * mult;
+ mult *= 10;
+ if (orev > rev && ckWARN_d(WARN_OVERFLOW))
+ Perl_warner(aTHX_ WARN_OVERFLOW,
+ "Integer overflow in decimal number");
+ }
+ }
+ tmpend = uv_to_utf8(tmpbuf, rev);
+ utf8 = utf8 || rev > 127;
+ sv_catpvn(sv, (const char*)tmpbuf, tmpend - tmpbuf);
+ if (*pos == '.' && isDIGIT(pos[1]))
+ s = ++pos;
+ else {
+ s = pos;
+ break;
+ }
+ while (isDIGIT(*pos) || *pos == '_')
+ pos++;
+ }
+
+ SvPOK_on(sv);
+ SvREADONLY_on(sv);
+ if (utf8) {
+ SvUTF8_on(sv);
+ sv_utf8_downgrade(sv, TRUE);
+ }
+ }
+ }
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;
register char *t;
- SV *stuff = newSVpv("",0);
+ SV *stuff = newSVpvn("",0);
bool needargs = FALSE;
while (!needargs) {
@@ -5996,6 +7120,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) {
@@ -6034,7 +7166,7 @@ scan_formline(register char *s)
}
STATIC void
-set_csh(void)
+S_set_csh(pTHX)
{
#ifdef CSH
if (!PL_cshlen)
@@ -6043,7 +7175,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;
@@ -6053,11 +7185,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);
- SAVESPTR(PL_comppad);
+ SAVECOMPPAD();
SAVESPTR(PL_comppad_name);
SAVESPTR(PL_compcv);
SAVEI32(PL_comppad_name_fill);
@@ -6076,9 +7207,9 @@ 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, newSVpv("@_", 2));
+ av_store(PL_comppad_name, 0, newSVpvn("@_", 2));
PL_curpad[0] = (SV*)newAV();
SvPADMY_on(PL_curpad[0]); /* XXX Needed? */
#endif /* USE_THREADS */
@@ -6100,18 +7231,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;
@@ -6137,7 +7267,12 @@ yyerror(char *s)
}
else if (yychar > 255)
where = "next token ???";
+#ifdef USE_PURE_BISON
+/* GNU Bison sets the value -2 */
+ else if (yychar == -2) {
+#else
else if ((yychar & 127) == 127) {
+#endif
if (PL_lex_state == LEX_NORMAL ||
(PL_lex_state == LEX_KNOWNEXT && PL_lex_defer == LEX_NORMAL))
where = "at end of line";
@@ -6147,39 +7282,63 @@ yyerror(char *s)
where = "within string";
}
else {
- SV *where_sv = sv_2mortal(newSVpv("next char ", 0));
+ 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) {
+ if (PL_in_eval && SvCUR(ERRSV))
+ Perl_croak(aTHX_ "%_%s has too many errors.\n",
+ ERRSV, CopFILE(PL_curcop));
+ else
+ 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;
+}
OpenPOWER on IntegriCloud