* "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"
* 1999-02-27 mjd-perl-patch@plover.com */
#define isCONTROLVAR(x) (isUPPER(x) || strchr("[\\]^_?", (x)))
-/* The following are arranged oddly so that the guard on the switch statement
+/* LEX_* are values for PL_lex_state, the state of the lexer.
+ * They are arranged oddly so that the guard on the switch statement
* can get by with a single comparison (if the compiler is smart enough).
*/
#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))
+/*
+ * 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
+ * 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)
#define AOPERATOR(retval) return ao((PL_expect = XTERM,PL_bufptr = s,(int)retval))
/* 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
S_ao(pTHX_ 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
S_no_op(pTHX_ char *what, char *s)
{
char *oldbp = PL_bufptr;
bool is_first = (PL_oldbufptr == PL_linestart);
- 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");
if (t < PL_bufptr && isSPACE(*t))
Perl_warn(aTHX_ "\t(Do you need to predeclare %.*s?)\n",
t - PL_oldoldbufptr, PL_oldoldbufptr);
-
}
- else if (s <= oldbp)
- Perl_warn(aTHX_ "\t(Missing operator before end of line?)\n");
else
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
S_missingterm(pTHX_ char *s)
{
Perl_croak(aTHX_ "Can't find string terminator %c%s%c anywhere before EOF",q,s,q);
}
+/*
+ * Perl_deprecate
+ */
+
void
Perl_deprecate(pTHX_ char *s)
{
Perl_warner(aTHX_ WARN_DEPRECATED, "Use of %s is deprecated", s);
}
+/*
+ * depcom
+ * Deprecate a comma-less variable list.
+ */
+
STATIC void
S_depcom(pTHX)
{
deprecate("comma-less variable list");
}
+/*
+ * experimental text filters for win32 carriage-returns, utf16-to-utf8 and
+ * utf16-to-utf8-reversed.
+ */
+
#ifdef WIN32
STATIC I32
return count;
}
+/*
+ * Perl_lex_start
+ * Initialize variables. Uses the Perl save_stack to save its state (for
+ * recursive calls to the parser).
+ */
+
void
Perl_lex_start(pTHX_ SV *line)
{
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));
PL_rsfp = 0;
}
+/*
+ * Perl_lex_end
+ * Finalizer for lexing operations. Must be called when the parser is
+ * done with the lexer.
+ */
+
void
Perl_lex_end(pTHX)
{
PL_doextract = FALSE;
}
+/*
+ * S_incline
+ * This subroutine has nothing to do with tilting, whether at windmills
+ * or pinball tables. Its name is short for "increment line". It
+ * increments the current line number in PL_curcop->cop_line and checks
+ * 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
S_incline(pTHX_ char *s)
{
PL_curcop->cop_line = atoi(n)-1;
}
+/*
+ * S_skipspace
+ * Called to gobble the appropriate amount and type of whitespace.
+ * Skips comments as well.
+ */
+
STATIC char *
S_skipspace(pTHX_ register char *s)
{
}
for (;;) {
STRLEN prevlen;
+ SSize_t oldprevlen, oldoldprevlen;
+ SSize_t oldloplen, oldunilen;
while (s < PL_bufend && isSPACE(*s)) {
if (*s++ == '\n' && PL_in_eval && !PL_rsfp)
incline(s);
}
+
+ /* comment */
if (s < PL_bufend && *s == '#') {
while (s < PL_bufend && *s != '\n')
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)" :
}
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())
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);
}
}
+/*
+ * 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
S_check_uni(pTHX)
{
}
}
+/* 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
#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
S_lop(pTHX_ 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
S_force_next(pTHX_ 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 *
S_force_word(pTHX_ register char *start, int token, int check_keyword, int allow_pack, int allow_initial_tick)
{
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
S_force_ident(pTHX_ register char *s, int kind)
{
}
}
+/*
+ * S_force_version
+ * Forces the next token to be a version number.
+ */
+
STATIC char *
S_force_version(pTHX_ 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 *
S_tokeq(pTHX_ 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
S_sublex_start(pTHX)
{
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
S_sublex_push(pTHX)
{
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);
return '(';
}
+/*
+ * S_sublex_done
+ * Restores lexer state after a S_sublex_push.
+ */
+
STATIC I32
S_sublex_done(pTHX)
{
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;
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 */
d = (char*)uv_to_utf8((U8*)d,
scan_hex(s + 1, e - s - 1, &len));
s = e + 1;
-
}
else {
UV uv = (UV)scan_hex(s, 2, &len);
}
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++;
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
S_intuit_more(pTHX_ 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;
return TRUE;
}
+/*
+ * S_intuit_method
+ *
+ * Does all the checking to disambiguate
+ * foo bar
+ * between foo(bar) and bar->foo. Returns 0 if not a method, otherwise
+ * FUNCMETH (bar->foo(args)) or METHOD (bar->foo args).
+ *
+ * First argument is the stuff after the first token, e.g. "bar".
+ *
+ * Not a method if bar is a filehandle.
+ * Not a method if foo is a subroutine prototyped to take a filehandle.
+ * Not a method if it's really "Foo $bar"
+ * Method if it's "foo $bar"
+ * Not a method if it's really "print foo $bar"
+ * Method if it's really "foo package::" (interpreted as package->foo)
+ * Not a method if bar is known to be a subroutne ("sub bar; foo bar")
+ * Not a method if bar is a filehandle or package, but is quotd with
+ * =>
+ */
+
STATIC int
S_intuit_method(pTHX_ 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;
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*
S_incl_perldb(pTHX)
{
#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;
|| (*t == '=' && t[1] == '>')))
OPERATOR(HASHBRACK);
if (PL_expect == XREF)
- PL_expect = XSTATE; /* was XTERM, trying XSTATE */
+ PL_expect = XTERM;
else {
PL_lex_brackstack[PL_lex_brackets-1] = XSTATE;
PL_expect = XSTATE;
}
if (s[1] == '#' && (isIDFIRST_lazy(s+2) || strchr("{$:+-", s[2]))) {
- if (PL_expect == XOPERATOR)
- no_op("Array length", PL_bufptr);
PL_tokenbuf[0] = '@';
- s = scan_ident(s + 1, PL_bufend, PL_tokenbuf + 1, sizeof PL_tokenbuf - 1,
- FALSE);
+ s = scan_ident(s + 1, PL_bufend, PL_tokenbuf + 1,
+ sizeof PL_tokenbuf - 1, FALSE);
+ if (PL_expect == XOPERATOR)
+ no_op("Array length", s);
if (!PL_tokenbuf[1])
PREREF(DOLSHARP);
PL_expect = XOPERATOR;
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");
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:
TERM(sublex_start());
case KEY_map:
- LOP(OP_MAPSTART, XREF);
-
+ LOP(OP_MAPSTART, *s == '(' ? XTERM : XREF);
+
case KEY_mkdir:
LOP(OP_MKDIR,XTERM);
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;
+
+ s = scan_str(s,FALSE,FALSE);
+ if (!s) {
+ if (PL_lex_stuff)
+ SvREFCNT_dec(PL_lex_stuff);
+ PL_lex_stuff = Nullsv;
+ Perl_croak(aTHX_ "Prototype not terminated");
+ }
+ /* strip spaces */
+ d = SvPVX(PL_lex_stuff);
+ tmp = 0;
+ for (p = d; *p; ++p) {
+ if (!isSPACE(*p))
+ d[tmp++] = *p;
+ }
+ d[tmp] = '\0';
+ SvCUR(PL_lex_stuff) = tmp;
+ have_proto = TRUE;
+
+ s = skipspace(s);
+ }
+ else
+ have_proto = FALSE;
- /* Look for a prototype */
- if (*s == '(') {
- char *p;
+ if (*s == ':' && s[1] != ':')
+ PL_expect = attrful;
- s = scan_str(s);
- if (!s) {
- if (PL_lex_stuff)
- SvREFCNT_dec(PL_lex_stuff);
+ if (have_proto) {
+ PL_nextval[PL_nexttoke].opval =
+ (OP*)newSVOP(OP_CONST, 0, PL_lex_stuff);
PL_lex_stuff = Nullsv;
- Perl_croak(aTHX_ "Prototype not terminated");
- }
- /* strip spaces */
- d = SvPVX(PL_lex_stuff);
- tmp = 0;
- for (p = d; *p; ++p) {
- if (!isSPACE(*p))
- d[tmp++] = *p;
+ force_next(THING);
}
- d[tmp] = '\0';
- SvCUR(PL_lex_stuff) = tmp;
-
- PL_nexttoke++;
- PL_nextval[1] = PL_nextval[0];
- PL_nexttype[1] = PL_nexttype[0];
- PL_nextval[0].opval = (OP*)newSVOP(OP_CONST, 0, PL_lex_stuff);
- PL_nexttype[0] = THING;
- if (PL_nexttoke == 1) {
- PL_lex_defer = PL_lex_state;
- PL_lex_expect = PL_expect;
- PL_lex_state = LEX_KNOWNEXT;
+ if (!have_name) {
+ sv_setpv(PL_subname,"__ANON__");
+ TOKEN(ANONSUB);
}
- PL_lex_stuff = Nullsv;
- }
-
- if (*SvPV(PL_subname,n_a) == '?') {
- sv_setpv(PL_subname,"__ANON__");
- TOKEN(ANONSUB);
+ (void) force_word(PL_oldbufptr + tboffset, WORD,
+ FALSE, TRUE, TRUE);
+ if (key == KEY_my)
+ TOKEN(MYSUB);
+ TOKEN(SUB);
}
- PREBLOCK(SUB);
case KEY_system:
set_csh();
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";
when in octal mode.
*/
dTHR;
- UV u;
+ 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') {
s += 2;
}
/* check for a decimal in disguise */
- else if (s[1] == '.')
+ else if (s[1] == '.' || s[1] == 'e' || s[1] == 'E')
goto decimal;
/* so it must be octal */
else
shift = 3;
- u = 0;
+
+ base = bases[shift];
+ Base = Bases[shift];
+ max = maxima[shift];
/* read the rest of the number */
for (;;) {
- UV n, b; /* n is used in the overflow test, b is the digit we're adding on */
+ /* x is used in the overflow test,
+ b is the digit we're adding on. */
+ UV x, b;
switch (*s) {
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 */
*/
digit:
- n = u << shift; /* make room for the digit */
- if (!overflowed && (n >> shift) != u
- && !(PL_hints & HINT_NEW_BINARY))
- {
- if (ckWARN_d(WARN_UNSAFE))
- Perl_warner(aTHX_ WARN_UNSAFE,
- "Integer overflow in %s number",
- (shift == 4) ? "hex"
- : ((shift == 3) ? "octal" : "binary"));
- overflowed = TRUE;
+ if (!overflowed) {
+ x = u << shift; /* make room for the digit */
+
+ if ((x >> shift) != u
+ && !(PL_hints & HINT_NEW_BINARY)) {
+ dTHR;
+ overflowed = TRUE;
+ n = (NV) u;
+ if (ckWARN_d(WARN_OVERFLOW))
+ Perl_warner(aTHX_ WARN_OVERFLOW,
+ "Integer overflow in %s number",
+ base);
+ } else
+ u = x | b; /* add the digit to the end */
+ }
+ if (overflowed) {
+ n *= nvshift[shift];
+ /* If an NV has not enough bits in its
+ * mantissa to represent an UV this summing of
+ * small low-order numbers is a waste of time
+ * (because the NV cannot preserve the
+ * low-order bits anyway): we could just
+ * remember when did we overflow and in the
+ * end just multiply n by the right
+ * amount. */
+ n += (NV) b;
}
- u = n | b; /* add the digit to the end */
break;
}
}
*/
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;
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;
#include "XSUB.h"
#endif
+/*
+ * restore_rsfp
+ * Restore a source filter.
+ */
+
static void
restore_rsfp(pTHXo_ void *f)
{
PL_rsfp = fp;
}
+/*
+ * restore_expect
+ * Restores the state of PL_expect when the lexing that begun with a
+ * start_lex() call has ended.
+ */
+
static void
restore_expect(pTHXo_ void *e)
{
PL_expect = (expectation)((char *)e - PL_tokenbuf);
}
+/*
+ * restore_lex_expect
+ * Restores the state of PL_lex_expect when the lexing that begun with a
+ * start_lex() call has ended.
+ */
+
static void
restore_lex_expect(pTHXo_ void *e)
{
/* a safe way to store a small integer in a pointer */
PL_lex_expect = (expectation)((char *)e - PL_tokenbuf);
}
-