* "It all comes from here, the stench and the peril." --Frodo
*/
-/* toke.c
- *
- * This file is the tokenizer for Perl. It's closely linked to the
+/*
+ * 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.
/*
* Convenience functions to return different tokens and prime the
- * tokenizer for the next token. They all take an argument.
+ * lexer for the next token. They all take an argument.
*
* TOKEN : generic token (used for '(', DOLSHARP, etc)
* OPERATOR : generic operator
* BAop : bitwise and
* SHop : shift operator
* PWop : power operator
- * PMop : matching operator
+ * PMop : pattern-matching operator
* Aop : addition-level operator
* Mop : multiplication-level operator
* Eop : equality-testing operator
char *oldbp = PL_bufptr;
bool is_first = (PL_oldbufptr == PL_linestart);
- assert(s >= oldbp);
- PL_bufptr = s;
+ if (!s)
+ s = oldbp;
+ else {
+ assert(s >= oldbp);
+ PL_bufptr = s;
+ }
yywarn(Perl_form(aTHX_ "%s found where operator expected", what));
if (is_first)
Perl_warn(aTHX_ "\t(Missing semicolon on previous line?)\n");
/*
* Perl_deprecate
- * Warns that something is deprecated. Duh.
*/
void
/*
* depcom
- * Deprecate a comma-less variable list. Called from three places
- * in the tokenizer.
+ * Deprecate a comma-less variable list.
*/
STATIC void
}
/*
- * text filters for win32 carriage-returns, utf16-to-utf8 and
- * utf16-to-utf8-reversed, whatever that is.
+ * experimental text filters for win32 carriage-returns, utf16-to-utf8 and
+ * utf16-to-utf8-reversed.
*/
#ifdef WIN32
/*
* Perl_lex_start
- * Initialize variables. Called by perl.c. It uses the Perl stack
- * to save its state (for recursive calls to the parser).
+ * Initialize variables. Uses the Perl save_stack to save its state (for
+ * recursive calls to the parser).
*/
void
SAVEDESTRUCTOR(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);
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));
/*
* Perl_lex_end
- * Tidy up. Called from pp_ctl.c in the sv_compile_2op(), doeval(),
- * and pp_leaveeval() subroutines.
+ * Finalizer for lexing operations. Must be called when the parser is
+ * done with the lexer.
*/
void
* or pinball tables. Its name is short for "increment line". It
* increments the current line number in PL_curcop->cop_line and checks
* to see whether the line starts with a comment of the form
- * # line 500
- * If so, it sets the current line number to the number in the comment.
+ * # line 500 "foo.pm"
+ * If so, it sets the current line number and file to the values in the comment.
*/
STATIC void
}
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);
* of the buffer, we're not reading from a source filter, and
* we're in normal lexing mode
*/
- if (s < PL_bufend || !PL_rsfp || PL_lex_state != LEX_NORMAL)
+ if (s < PL_bufend || !PL_rsfp || PL_sublex_info.sub_inwhat ||
+ PL_lex_state == LEX_FORMLINE)
return s;
/* try to recharge the buffer */
- if ((s = filter_gets(PL_linestr, PL_rsfp, (prevlen = SvCUR(PL_linestr)))) == Nullch) {
- /* end of file. Add on the -p or -n magic */
+ 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)" :
sv_setpv(PL_linestr,";");
/* reset variables for next time we lex */
- PL_oldoldbufptr = PL_oldbufptr = PL_bufptr = s = PL_linestart = SvPVX(PL_linestr);
+ 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,
}
/* 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,
/*
* S_force_next
- * When the tokenizer realizes it knows the next token (for instance,
+ * 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 make the current token be the next one. It will also set
- * PL_nextval, and possibly PL_expect to ensure the lexer handles the
- * token correctly.
+ * 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
* it calls S_force_word to stick the next word into the PL_next lookahead.
*
* Arguments:
- * char *start : start of the buffer
+ * char *start : buffer position (must be within PL_linestr)
* int token : PL_next will be this type of bare word (e.g., METHOD,WORD)
* int check_keyword : if true, Perl checks to make sure the word isn't
* a keyword (do this if the word is a label, e.g. goto FOO)
* int allow_pack : if true, : characters will also be allowed (require,
* use, etc. do this)
- * int allow_initial_tick : used by the "sub" tokenizer only.
+ * int allow_initial_tick : used by the "sub" lexer only.
*/
STATIC char *
/*
* S_force_ident
- * Called when the tokenizer wants $foo *foo &foo etc, but the program
+ * 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 (through the gv_fetchpv
- * call).
+ * Creates the symbol if it didn't already exist (via gv_fetchpv()).
*/
STATIC 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_bufend = SvPVX(PL_linestr);
PL_bufend += SvCUR(PL_linestr);
PL_expect = XOPERATOR;
+ PL_sublex_info.sub_inwhat = 0;
return ')';
}
}
? (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))
+ ? (PL_sublex_info.sub_op->op_private & (PL_lex_repl ?
+ OPpTRANS_FROM_UTF : OPpTRANS_TO_UTF))
: UTF;
- /* leaveit is the set of acceptably-backslashed characters */
- char *leaveit =
+ char *leaveit = /* set of acceptably-backslashed characters */
PL_lex_inpat
? "\\.^$@AGZdDwWsSbBpPXC+*?|()-nrtfeaxcz0123456789[{]} \t\n\r\f\v#"
: "";
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 */
}
continue;
+ /* \N{latin small letter a} is a named character */
+ case 'N':
+ ++s;
+ if (*s == '{') {
+ char* e = strchr(s, '}');
+ HV *hv;
+ SV **svp;
+ SV *res, *cv;
+ STRLEN len;
+ char *str;
+ char *why = Nullch;
+
+ if (!e) {
+ yyerror("Missing right brace on \\N{}");
+ e = s - 1;
+ goto cont_scan;
+ }
+ res = newSVpvn(s + 1, e - s - 1);
+ res = new_constant( Nullch, 0, "charnames",
+ res, Nullsv, "\\N{...}" );
+ str = SvPV(res,len);
+ if (len > e - s + 4) {
+ char *odest = SvPVX(sv);
+
+ SvGROW(sv, (SvCUR(sv) + len - (e - s + 4)));
+ d = SvPVX(sv) + (d - odest);
+ }
+ Copy(str, d, len, char);
+ d += len;
+ SvREFCNT_dec(res);
+ cont_scan:
+ s = e + 1;
+ }
+ else
+ yyerror("Missing braces on \\N{}");
+ continue;
+
/* \c is a control character */
case 'c':
s++;
/* S_intuit_more
* Returns TRUE if there's more to the expression (e.g., a subscript),
* FALSE otherwise.
- * This is the one truly awful dwimmer necessary to conflate C and sed.
*
* It deals with "$foo[3]" and /$foo[3]/ and /$foo[0123456789$]+/
*
* anything else returns TRUE
*/
+/* This is the one truly awful dwimmer necessary to conflate C and sed. */
+
STATIC int
S_intuit_more(pTHX_ register char *s)
{
#ifdef DEBUGGING
static char* exp_name[] =
- { "OPERATOR", "TERM", "REF", "STATE", "BLOCK", "TERMBLOCK" };
+ { "OPERATOR", "TERM", "REF", "STATE", "BLOCK", "ATTRBLOCK",
+ "ATTRTERM", "TERMBLOCK"
+ };
#endif
/*
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];
* 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
goto just_a_word;
}
s++;
+ switch (PL_expect) {
+ OP *attrs;
+ case XOPERATOR:
+ if (!PL_in_my || PL_lex_state != LEX_NORMAL)
+ break;
+ PL_bufptr = s; /* update in case we back off */
+ goto grabattrs;
+ case XATTRBLOCK:
+ PL_expect = XBLOCK;
+ goto grabattrs;
+ case XATTRTERM:
+ PL_expect = XTERMBLOCK;
+ grabattrs:
+ s = skipspace(s);
+ attrs = Nullop;
+ while (isIDFIRST_lazy(s)) {
+ d = scan_word(s, PL_tokenbuf, sizeof PL_tokenbuf, FALSE, &len);
+ if (*d == '(') {
+ d = scan_str(d,TRUE,TRUE);
+ if (!d) {
+ if (PL_lex_stuff) {
+ SvREFCNT_dec(PL_lex_stuff);
+ PL_lex_stuff = Nullsv;
+ }
+ /* MUST advance bufptr here to avoid bogus
+ "at end of line" context messages from yyerror().
+ */
+ PL_bufptr = s + len;
+ yyerror("Unterminated attribute parameter in attribute list");
+ if (attrs)
+ op_free(attrs);
+ return 0; /* EOF indicator */
+ }
+ }
+ if (PL_lex_stuff) {
+ SV *sv = newSVpvn(s, len);
+ sv_catsv(sv, PL_lex_stuff);
+ attrs = append_elem(OP_LIST, attrs,
+ newSVOP(OP_CONST, 0, sv));
+ SvREFCNT_dec(PL_lex_stuff);
+ PL_lex_stuff = Nullsv;
+ }
+ else {
+ attrs = append_elem(OP_LIST, attrs,
+ newSVOP(OP_CONST, 0,
+ newSVpvn(s, len)));
+ }
+ s = skipspace(d);
+ while (*s == ',')
+ s = skipspace(s+1);
+ }
+ tmp = (PL_expect == XOPERATOR ? '=' : '{'); /*'}' for vi */
+ if (*s != ';' && *s != tmp) {
+ char q = ((*s == '\'') ? '"' : '\'');
+ /* If here for an expression, and parsed no attrs, back off. */
+ if (tmp == '=' && !attrs) {
+ s = PL_bufptr;
+ break;
+ }
+ /* MUST advance bufptr here to avoid bogus "at end of line"
+ context messages from yyerror().
+ */
+ PL_bufptr = s;
+ if (!*s)
+ yyerror("Unterminated attribute list");
+ else
+ yyerror(Perl_form(aTHX_ "Invalid separator character %c%c%c in attribute list",
+ q, *s, q));
+ if (attrs)
+ op_free(attrs);
+ OPERATOR(':');
+ }
+ if (attrs) {
+ PL_nextval[PL_nexttoke].opval = attrs;
+ force_next(THING);
+ }
+ TOKEN(COLONATTR);
+ }
OPERATOR(':');
case '(':
s++;
}
}
/* 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;
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;
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;
TERM(sublex_start());
case '`':
- s = scan_str(s);
+ s = scan_str(s,FALSE,FALSE);
if (PL_expect == XOPERATOR)
no_op("Backticks",s);
if (!s)
TERM(THING);
case KEY___LINE__:
- yylval.opval = (OP*)newSVOP(OP_CONST, 0,
- Perl_newSVpvf(aTHX_ "%ld", (long)PL_curcop->cop_line));
+#ifdef IV_IS_QUAD
+ yylval.opval = (OP*)newSVOP(OP_CONST, 0,
+ Perl_newSVpvf(aTHX_ "%" PERL_PRId64, (IV)PL_curcop->cop_line));
+#else
+ yylval.opval = (OP*)newSVOP(OP_CONST, 0,
+ Perl_newSVpvf(aTHX_ "%ld", (long)PL_curcop->cop_line));
+#endif
TERM(THING);
case KEY___PACKAGE__:
if (ckWARN(WARN_OCTAL)) {
for (d = s; d < PL_bufend && (isSPACE(*d) || *d == '('); d++) ;
if (*d != '0' && isDIGIT(*d))
- yywarn("chmod: mode argument is missing initial 0");
+ Perl_warner(aTHX_ WARN_OCTAL,
+ "chmod: mode argument is missing initial 0");
}
LOP(OP_CHMOD,XTERM);
UNI(OP_LCFIRST);
case KEY_local:
+ yylval.ival = 0;
OPERATOR(LOCAL);
case KEY_length:
s = skipspace(s);
if (isIDFIRST_lazy(s)) {
s = scan_word(s, PL_tokenbuf, sizeof PL_tokenbuf, TRUE, &len);
+ if (len == 3 && strnEQ(PL_tokenbuf, "sub", 3))
+ goto really_sub;
PL_in_my_stash = gv_stashpv(PL_tokenbuf, FALSE);
if (!PL_in_my_stash) {
char tmpbuf[1024];
yyerror(tmpbuf);
}
}
+ yylval.ival = 1;
OPERATOR(MY);
case KEY_next:
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;
UNI(OP_QUOTEMETA);
case KEY_qw:
- s = scan_str(s);
+ s = scan_str(s,FALSE,FALSE);
if (!s)
missingterm((char*)0);
force_next(')');
TOKEN('(');
case KEY_qq:
- s = scan_str(s);
+ s = scan_str(s,FALSE,FALSE);
if (!s)
missingterm((char*)0);
yylval.ival = OP_STRINGIFY;
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;
case KEY_format:
case KEY_sub:
really_sub:
- s = skipspace(s);
-
- if (isIDFIRST_lazy(s) || *s == '\'' || *s == ':') {
+ {
char tmpbuf[sizeof PL_tokenbuf];
- PL_expect = XBLOCK;
- d = scan_word(s, tmpbuf, sizeof tmpbuf, TRUE, &len);
- if (strchr(tmpbuf, ':'))
- sv_setpv(PL_subname, tmpbuf);
+ SSize_t tboffset;
+ expectation attrful;
+ bool have_name, have_proto;
+ int key = tmp;
+
+ s = skipspace(s);
+
+ if (isIDFIRST_lazy(s) || *s == '\'' ||
+ (*s == ':' && s[1] == ':'))
+ {
+ PL_expect = XBLOCK;
+ attrful = XATTRBLOCK;
+ /* remember buffer pos'n for later force_word */
+ tboffset = s - PL_oldbufptr;
+ d = scan_word(s, tmpbuf, sizeof tmpbuf, TRUE, &len);
+ if (strchr(tmpbuf, ':'))
+ sv_setpv(PL_subname, tmpbuf);
+ else {
+ sv_setsv(PL_subname,PL_curstname);
+ sv_catpvn(PL_subname,"::",2);
+ sv_catpvn(PL_subname,tmpbuf,len);
+ }
+ s = skipspace(d);
+ have_name = TRUE;
+ }
else {
- sv_setsv(PL_subname,PL_curstname);
- sv_catpvn(PL_subname,"::",2);
- sv_catpvn(PL_subname,tmpbuf,len);
+ if (key == KEY_my)
+ Perl_croak(aTHX_ "Missing name in \"my sub\"");
+ PL_expect = XTERMBLOCK;
+ attrful = XATTRTERM;
+ sv_setpv(PL_subname,"?");
+ have_name = FALSE;
}
- s = force_word(s,WORD,FALSE,TRUE,TRUE);
- s = skipspace(s);
- }
- else {
- PL_expect = XTERMBLOCK;
- sv_setpv(PL_subname,"?");
- }
- if (tmp == KEY_format) {
- s = skipspace(s);
- if (*s == '=')
- PL_lex_formbrack = PL_lex_brackets + 1;
- OPERATOR(FORMAT);
- }
+ if (key == KEY_format) {
+ if (*s == '=')
+ PL_lex_formbrack = PL_lex_brackets + 1;
+ if (have_name)
+ (void) force_word(PL_oldbufptr + tboffset, WORD,
+ FALSE, TRUE, TRUE);
+ OPERATOR(FORMAT);
+ }
- /* Look for a prototype */
- if (*s == '(') {
- char *p;
+ /* Look for a prototype */
+ if (*s == '(') {
+ char *p;
+
+ s = scan_str(s,FALSE,FALSE);
+ if (!s) {
+ if (PL_lex_stuff)
+ SvREFCNT_dec(PL_lex_stuff);
+ PL_lex_stuff = Nullsv;
+ Perl_croak(aTHX_ "Prototype not terminated");
+ }
+ /* strip spaces */
+ d = SvPVX(PL_lex_stuff);
+ tmp = 0;
+ for (p = d; *p; ++p) {
+ if (!isSPACE(*p))
+ d[tmp++] = *p;
+ }
+ d[tmp] = '\0';
+ SvCUR(PL_lex_stuff) = tmp;
+ have_proto = TRUE;
- s = scan_str(s);
- if (!s) {
- if (PL_lex_stuff)
- SvREFCNT_dec(PL_lex_stuff);
- PL_lex_stuff = Nullsv;
- Perl_croak(aTHX_ "Prototype not terminated");
+ s = skipspace(s);
}
- /* strip spaces */
- d = SvPVX(PL_lex_stuff);
- tmp = 0;
- for (p = d; *p; ++p) {
- if (!isSPACE(*p))
- d[tmp++] = *p;
+ else
+ have_proto = FALSE;
+
+ if (*s == ':' && s[1] != ':')
+ PL_expect = attrful;
+
+ if (have_proto) {
+ PL_nextval[PL_nexttoke].opval =
+ (OP*)newSVOP(OP_CONST, 0, PL_lex_stuff);
+ PL_lex_stuff = Nullsv;
+ force_next(THING);
}
- d[tmp] = '\0';
- SvCUR(PL_lex_stuff) = tmp;
-
- PL_nexttoke++;
- PL_nextval[1] = PL_nextval[0];
- PL_nexttype[1] = PL_nexttype[0];
- PL_nextval[0].opval = (OP*)newSVOP(OP_CONST, 0, PL_lex_stuff);
- PL_nexttype[0] = THING;
- if (PL_nexttoke == 1) {
- PL_lex_defer = PL_lex_state;
- PL_lex_expect = PL_expect;
- PL_lex_state = LEX_KNOWNEXT;
+ if (!have_name) {
+ sv_setpv(PL_subname,"__ANON__");
+ TOKEN(ANONSUB);
}
- PL_lex_stuff = Nullsv;
+ (void) force_word(PL_oldbufptr + tboffset, WORD,
+ FALSE, TRUE, TRUE);
+ if (key == KEY_my)
+ TOKEN(MYSUB);
+ TOKEN(SUB);
}
- if (*SvPV(PL_subname,n_a) == '?') {
- sv_setpv(PL_subname,"__ANON__");
- TOKEN(ANONSUB);
- }
- PREBLOCK(SUB);
-
case KEY_system:
set_csh();
LOP(OP_SYSTEM,XREF);
case KEY_umask:
if (ckWARN(WARN_OCTAL)) {
for (d = s; d < PL_bufend && (isSPACE(*d) || *d == '('); d++) ;
- if (*d != '0' && isDIGIT(*d))
- yywarn("umask: argument is missing initial 0");
+ if (*d != '0' && isDIGIT(*d))
+ Perl_warner(aTHX_ WARN_OCTAL,
+ "umask: argument is missing initial 0");
}
UNI(OP_UMASK);
}
}
+/* 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 *
S_new_constant(pTHX_ char *s, STRLEN len, char *key, SV *sv, SV *pv, char *type)
{
dSP;
HV *table = GvHV(PL_hintgv); /* ^H */
- BINOP myop;
SV *res;
- bool oldcatch = CATCH_GET;
SV **cvp;
SV *cv, *typesv;
-
+ char *why, *why1, *why2;
+
+ if (!(PL_hints & HINT_LOCALIZE_HH)) {
+ SV *msg;
+
+ why = "%^H is not localized";
+ report_short:
+ why1 = why2 = "";
+ report:
+ msg = Perl_newSVpvf(aTHX_ "constant(%s): %s%s%s",
+ (type ? type: "undef"), why1, why2, why);
+ yyerror(SvPVX(msg));
+ SvREFCNT_dec(msg);
+ return sv;
+ }
if (!table) {
- yyerror("%^H is not defined");
- return sv;
+ why = "%^H is not defined";
+ goto report_short;
}
cvp = hv_fetch(table, key, strlen(key), FALSE);
if (!cvp || !SvOK(*cvp)) {
- char buf[128];
- sprintf(buf,"$^H{%s} is not defined", key);
- yyerror(buf);
- return sv;
+ why = "} is not defined";
+ why1 = "$^H{";
+ why2 = key;
+ goto report;
}
sv_2mortal(sv); /* Parent created it permanently */
cv = *cvp;
- if (!pv)
- pv = sv_2mortal(newSVpvn(s, len));
- if (type)
- typesv = sv_2mortal(newSVpv(type, 0));
+ if (!pv && s)
+ pv = sv_2mortal(newSVpvn(s, len));
+ if (type && pv)
+ typesv = sv_2mortal(newSVpv(type, 0));
else
- typesv = &PL_sv_undef;
- CATCH_SET(TRUE);
- Zero(&myop, 1, BINOP);
- myop.op_last = (OP *) &myop;
- myop.op_next = Nullop;
- myop.op_flags = OPf_WANT_SCALAR | OPf_STACKED;
-
+ typesv = &PL_sv_undef;
+
PUSHSTACKi(PERLSI_OVERLOAD);
- ENTER;
- SAVEOP();
- PL_op = (OP *) &myop;
- if (PERLDB_SUB && PL_curstash != PL_debstash)
- PL_op->op_private |= OPpENTERSUB_DB;
- PUTBACK;
- Perl_pp_pushmark(aTHX);
-
+ 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 = Perl_pp_entersub(aTHX))
- CALLRUNOPS(aTHX);
- 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 */
+ POPs ;
+ res = SvREFCNT_inc(sv);
+ }
+ else {
+ res = POPs;
+ SvREFCNT_inc(res);
+ }
+
+ PUTBACK ;
+ FREETMPS ;
+ LEAVE ;
POPSTACK;
-
+
if (!SvOK(res)) {
- char buf[128];
- sprintf(buf,"Call to &{$^H{%s}} did not return a defined value", key);
- yyerror(buf);
- }
- return SvREFCNT_inc(res);
+ why = "}} did not return a defined value";
+ why1 = "Call to &{$^H{";
+ why2 = key;
+ sv = res;
+ goto report;
+ }
+
+ return res;
}
-
+
STATIC char *
S_scan_word(pTHX_ register char *s, char *dest, STRLEN destlen, int allow_package, STRLEN *slp)
{
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);
yylval.ival = OP_NULL;
- s = scan_str(start);
+ s = scan_str(start,FALSE,FALSE);
if (!s) {
if (PL_lex_stuff)
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);
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);
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);
if (d - PL_tokenbuf != len) {
yylval.ival = OP_GLOB;
set_csh();
- s = scan_str(start);
+ s = scan_str(start,FALSE,FALSE);
if (!s)
Perl_croak(aTHX_ "Glob not terminated");
return s;
/* 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.
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)
*/
STATIC char *
-S_scan_str(pTHX_ char *start)
+S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims)
{
dTHR;
SV *sv; /* scalar value: string */
(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++) {
PL_curcop->cop_line++;
/* handle quoted delimiters */
if (*s == '\\' && s+1 < PL_bufend && term != '\\') {
- if (s[1] == term)
+ if (!keep_quoted && s[1] == term)
s++;
/* any other quotes are simply copied straight through */
else
PL_curcop->cop_line++;
/* backslashes can escape the open or closing characters */
if (*s == '\\' && s+1 < PL_bufend) {
- if ((s[1] == PL_multi_open) || (s[1] == PL_multi_close))
+ if (!keep_quoted &&
+ ((s[1] == PL_multi_open) || (s[1] == PL_multi_close)))
s++;
else
*to++ = *s++;
/* at this point, we have successfully read the delimited string */
+ if (keep_delims)
+ sv_catpvn(sv, s, 1);
PL_multi_end = PL_curcop->cop_line;
s++;
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 */
+ IV tryiv; /* used to see if it can be an IV */
NV value; /* number read, as a double */
SV *sv; /* place to put the converted number */
- I32 floatit; /* boolean: int or float? */
+ bool floatit; /* boolean: int or float? */
char *lastub = 0; /* position of last underbar */
static char number_too_long[] = "Number too long";
static char *maxima[5] = { "",
"0b11111111111111111111111111111111",
"",
- "0b37777777777",
+ "037777777777",
"0xffffffff" };
char *base, *Base, *max;
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
/* read the rest of the number */
for (;;) {
/* x is used in the overflow test,
- b is the digit we're adding on */
+ b is the digit we're adding on. */
UV x, b;
switch (*s) {
case '8': case '9':
if (shift == 3)
yyerror(Perl_form(aTHX_ "Illegal octal digit '%c'", *s));
- else
- if (shift == 1)
- yyerror(Perl_form(aTHX_ "Illegal binary digit '%c'", *s));
/* FALL THROUGH */
/* octal digits */
dTHR;
overflowed = TRUE;
n = (NV) u;
- if (ckWARN_d(WARN_UNSAFE))
- Perl_warner(aTHX_ ((shift == 3) ?
- WARN_OCTAL : WARN_UNSAFE),
+ if (ckWARN_d(WARN_OVERFLOW))
+ Perl_warner(aTHX_ WARN_OVERFLOW,
"Integer overflow in %s number",
base);
} else
sv = NEWSV(92,0);
if (overflowed) {
dTHR;
- if (ckWARN(WARN_UNSAFE) && (double) n > 4294967295.0)
- Perl_warner(aTHX_ WARN_UNSAFE,
+ if (ckWARN(WARN_PORTABLE) && n > 4294967295.0)
+ Perl_warner(aTHX_ WARN_PORTABLE,
"%s number > %s non-portable",
Base, max);
sv_setnv(sv, n);
}
else {
+#if UVSIZE > 4
dTHR;
- if (ckWARN(WARN_UNSAFE) && u > 4294967295)
- Perl_warner(aTHX_ WARN_UNSAFE,
+ 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)
+ if (PL_hints & HINT_NEW_BINARY)
sv = new_constant(start, s - start, "binary", sv, Nullsv, NULL);
}
break;
sv_setiv(sv, tryiv);
else
sv_setnv(sv, value);
- if ( floatit ? (PL_hints & HINT_NEW_FLOAT) : (PL_hints & HINT_NEW_INTEGER) )
+ if ( floatit ? (PL_hints & HINT_NEW_FLOAT) :
+ (PL_hints & HINT_NEW_INTEGER) )
sv = new_constant(PL_tokenbuf, d - PL_tokenbuf,
- (floatit ? "float" : "integer"), sv, Nullsv, NULL);
+ (floatit ? "float" : "integer"),
+ sv, Nullsv, NULL);
break;
}
Perl_yywarn(pTHX_ char *s)
{
dTHR;
- --PL_error_count;
PL_in_eval |= EVAL_WARNONLY;
yyerror(s);
PL_in_eval &= ~EVAL_WARNONLY;
where = SvPVX(where_sv);
}
msg = sv_2mortal(newSVpv(s, 0));
+#ifdef IV_IS_QUAD
+ Perl_sv_catpvf(aTHX_ msg, " at %_ line %" PERL_PRId64 ", ",
+ GvSV(PL_curcop->cop_filegv), (IV)PL_curcop->cop_line);
+#else
Perl_sv_catpvf(aTHX_ msg, " at %_ line %ld, ",
- GvSV(PL_curcop->cop_filegv), (long)PL_curcop->cop_line);
+ GvSV(PL_curcop->cop_filegv), (long)PL_curcop->cop_line);
+#endif
if (context)
Perl_sv_catpvf(aTHX_ msg, "near \"%.*s\"\n", contlen, context);
else
Perl_sv_catpvf(aTHX_ msg, "%s\n", where);
if (PL_multi_start < PL_multi_end && (U32)(PL_curcop->cop_line - PL_multi_end) <= 1) {
- Perl_sv_catpvf(aTHX_ msg,
- " (Might be a runaway multi-line %c%c string starting on line %ld)\n",
- (int)PL_multi_open,(int)PL_multi_close,(long)PL_multi_start);
+#ifdef IV_IS_QUAD
+ Perl_sv_catpvf(aTHX_ msg,
+ " (Might be a runaway multi-line %c%c string starting on line %" PERL_\
+PRId64 ")\n",
+ (int)PL_multi_open,(int)PL_multi_close,(IV)PL_multi_start);
+#else
+ Perl_sv_catpvf(aTHX_ msg,
+ " (Might be a runaway multi-line %c%c string starting on line %ld)\n",
+ (int)PL_multi_open,(int)PL_multi_close,(long)PL_multi_start);
+#endif
PL_multi_end = 0;
}
if (PL_in_eval & EVAL_WARNONLY)
Perl_warn(aTHX_ "%_", msg);
- else if (PL_in_eval)
- sv_catsv(ERRSV, msg);
else
- PerlIO_write(PerlIO_stderr(), SvPVX(msg), SvCUR(msg));
- if (++PL_error_count >= 10)
+ qerror(msg);
+ if (PL_error_count >= 10)
Perl_croak(aTHX_ "%_ has too many errors.\n", GvSV(PL_curcop->cop_filegv));
PL_in_my = 0;
PL_in_my_stash = Nullhv;