#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
* LOOPX : loop exiting command (goto, last, dump, etc)
* FTST : file test operator
* FUN0 : zero-argument function
- * FUN1 : not used
+ * FUN1 : not used, except for not, which isn't a UNIOP
* BOop : bitwise or or xor
* BAop : bitwise and
* SHop : shift operator
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");
SAVEI32(PL_lex_state);
SAVESPTR(PL_lex_inpat);
SAVEI32(PL_lex_inwhat);
- SAVEI16(PL_curcop->cop_line);
+ SAVECOPLINE(PL_curcop);
SAVEPPTR(PL_bufptr);
SAVEPPTR(PL_bufend);
SAVEPPTR(PL_oldbufptr);
SAVESPTR(PL_linestr);
SAVEPPTR(PL_lex_brackstack);
SAVEPPTR(PL_lex_casestack);
- SAVEDESTRUCTOR(restore_rsfp, PL_rsfp);
+ SAVEDESTRUCTOR_X(restore_rsfp, PL_rsfp);
SAVESPTR(PL_lex_stuff);
SAVEI32(PL_lex_defer);
+ SAVEI32(PL_sublex_info.sub_inwhat);
SAVESPTR(PL_lex_repl);
- SAVEDESTRUCTOR(restore_expect, PL_tokenbuf + PL_expect); /* encode as pointer */
- SAVEDESTRUCTOR(restore_lex_expect, PL_tokenbuf + PL_expect);
+ SAVEDESTRUCTOR_X(restore_expect, PL_tokenbuf + PL_expect); /* encode as pointer */
+ SAVEDESTRUCTOR_X(restore_lex_expect, PL_tokenbuf + PL_expect);
PL_lex_state = LEX_NORMAL;
PL_lex_defer = 0;
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));
* 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
+ * 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.
char ch;
int sawline = 0;
- PL_curcop->cop_line++;
+ CopLINE_inc(PL_curcop);
if (*s++ != '#')
return;
while (*s == ' ' || *s == '\t') s++;
ch = *t;
*t = '\0';
if (t - s > 0)
- PL_curcop->cop_filegv = gv_fetchfile(s);
+ CopFILE_set(PL_curcop, s);
else
- PL_curcop->cop_filegv = gv_fetchfile(PL_origfilename);
+ CopFILE_set(PL_curcop, PL_origfilename);
*t = ch;
- PL_curcop->cop_line = atoi(n)-1;
+ CopLINE_set(PL_curcop, atoi(n)-1);
}
/*
}
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 */
}
/* 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,
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);
}
}
}
* 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)
SAVEI32(PL_lex_state);
SAVESPTR(PL_lex_inpat);
SAVEI32(PL_lex_inwhat);
- SAVEI16(PL_curcop->cop_line);
+ SAVECOPLINE(PL_curcop);
SAVEPPTR(PL_bufptr);
SAVEPPTR(PL_oldbufptr);
SAVEPPTR(PL_oldoldbufptr);
*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)
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 & (PL_lex_repl ?
OPpTRANS_FROM_UTF : OPpTRANS_TO_UTF))
: UTF;
- char *leaveit = /* set of acceptably-backslashed characters */
+ const char *leaveit = /* set of acceptably-backslashed characters */
PL_lex_inpat
? "\\.^$@AGZdDwWsSbBpPXC+*?|()-nrtfeaxcz0123456789[{]} \t\n\r\f\v#"
: "";
/* \132 indicates an octal constant */
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
- *d++ = scan_oct(s, 3, &len);
+ *d++ = (char)scan_oct(s, 3, &len);
s += len;
continue;
}
/* note: utf always shorter than hex */
d = (char*)uv_to_utf8((U8*)d,
- scan_hex(s + 1, e - s - 1, &len));
+ (UV)scan_hex(s + 1, e - s - 1, &len));
s = e + 1;
}
else {
}
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++;
* store private buffers and state information.
*
* The supplied datasv parameter is upgraded to a PVIO type
- * and the IoDIRP field is used to store the function pointer.
+ * and the IoDIRP field is used to store the function pointer,
+ * and IOf_FAKE_DIRP is enabled on datasv to mark this as such.
* Note that IoTOP_NAME, IoFMT_NAME, IoBOTTOM_NAME, if set for
* private use must be set using malloc'd pointers.
*/
SV *
Perl_filter_add(pTHX_ filter_t funcp, SV *datasv)
{
- if (!funcp){ /* temporary handy debugging hack to be deleted */
- PL_filter_debug = atoi((char*)datasv);
- return NULL;
- }
+ if (!funcp)
+ return Nullsv;
+
if (!PL_rsfp_filters)
PL_rsfp_filters = newAV();
if (!datasv)
if (!SvUPGRADE(datasv, SVt_PVIO))
Perl_die(aTHX_ "Can't upgrade filter_add data to SVt_PVIO");
IoDIRP(datasv) = (DIR*)funcp; /* stash funcp into spare field */
-#ifdef DEBUGGING
- if (PL_filter_debug) {
- STRLEN n_a;
- Perl_warn(aTHX_ "filter_add func %p (%s)", funcp, SvPV(datasv, n_a));
- }
-#endif /* DEBUGGING */
+ 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);
void
Perl_filter_del(pTHX_ filter_t funcp)
{
-#ifdef DEBUGGING
- if (PL_filter_debug)
- Perl_warn(aTHX_ "filter_del func %p", funcp);
-#endif /* DEBUGGING */
+ 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){
- IoDIRP(FILTER_DATA(AvFILLp(PL_rsfp_filters))) = NULL;
+ 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;
if (idx > AvFILLp(PL_rsfp_filters)){ /* Any more filters? */
/* Provide a default input filter to make life easy. */
/* Note that we append to the line. This is handy. */
-#ifdef DEBUGGING
- if (PL_filter_debug)
- Perl_warn(aTHX_ "filter_read %d: from rsfp\n", idx);
-#endif /* DEBUGGING */
+ DEBUG_P(PerlIO_printf(Perl_debug_log,
+ "filter_read %d: from rsfp\n", idx));
if (maxlen) {
/* Want a block */
int len ;
}
/* Skip this filter slot if filter has been deleted */
if ( (datasv = FILTER_DATA(idx)) == &PL_sv_undef){
-#ifdef DEBUGGING
- if (PL_filter_debug)
- Perl_warn(aTHX_ "filter_read %d: skipped (filter deleted)\n", idx);
-#endif /* DEBUGGING */
+ DEBUG_P(PerlIO_printf(Perl_debug_log,
+ "filter_read %d: skipped (filter deleted)\n",
+ idx));
return FILTER_READ(idx+1, buf_sv, maxlen); /* recurse */
}
/* Get function pointer hidden within datasv */
funcp = (filter_t)IoDIRP(datasv);
-#ifdef DEBUGGING
- if (PL_filter_debug) {
- STRLEN n_a;
- Perl_warn(aTHX_ "filter_read %d: via function %p (%s)\n",
- idx, funcp, SvPV(datasv,n_a));
- }
-#endif /* DEBUGGING */
+ DEBUG_P(PerlIO_printf(Perl_debug_log,
+ "filter_read %d: via function %p (%s)\n",
+ idx, funcp, SvPV_nolen(datasv)));
/* Call function. The function is expected to */
/* call "FILTER_READ(idx+1, buf_sv)" first. */
/* Return: <0:error, =0:eof, >0:not eof */
#ifdef DEBUGGING
static char* exp_name[] =
- { "OPERATOR", "TERM", "REF", "STATE", "BLOCK", "TERMBLOCK" };
+ { "OPERATOR", "TERM", "REF", "STATE", "BLOCK", "ATTRBLOCK",
+ "ATTRTERM", "TERMBLOCK"
+ };
#endif
/*
if it's a legal name, the OP is a PADANY.
*/
if (PL_in_my) {
- if (strchr(PL_tokenbuf,':'))
- yyerror(Perl_form(aTHX_ PL_no_myglob,PL_tokenbuf));
+ if (PL_in_my == KEY_our) { /* "our" is merely analogous to "my" */
+ tmp = pad_allocmy(PL_tokenbuf);
+ }
+ else {
+ if (strchr(PL_tokenbuf,':'))
+ yyerror(Perl_form(aTHX_ PL_no_myglob,PL_tokenbuf));
- yylval.opval = newOP(OP_PADANY, 0);
- yylval.opval->op_targ = pad_allocmy(PL_tokenbuf);
- return PRIVATEREF;
+ yylval.opval = newOP(OP_PADANY, 0);
+ yylval.opval->op_targ = pad_allocmy(PL_tokenbuf);
+ return PRIVATEREF;
+ }
}
/*
}
#endif /* USE_THREADS */
if ((tmp = pad_findmy(PL_tokenbuf)) != NOT_IN_PAD) {
+ /* might be an "our" variable" */
+ if (SvFLAGS(AvARRAY(PL_comppad_name)[tmp]) & SVpad_OUR) {
+ /* build ops for a bareword */
+ yylval.opval = (OP*)newSVOP(OP_CONST, 0, newSVpv(PL_tokenbuf+1, 0));
+ yylval.opval->op_private = OPpCONST_ENTERED;
+ gv_fetchpv(PL_tokenbuf+1,
+ (PL_in_eval
+ ? (GV_ADDMULTI | GV_ADDINEVAL | GV_ADDOUR)
+ : GV_ADDOUR
+ ),
+ ((PL_tokenbuf[0] == '$') ? SVt_PV
+ : (PL_tokenbuf[0] == '@') ? SVt_PVAV
+ : SVt_PVHV));
+ return WORD;
+ }
+
/* if it's a sort block and they're naming $a or $b */
if (PL_last_lop_op == OP_SORT &&
PL_tokenbuf[0] == '$' &&
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];
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:
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;
}
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 */
*/
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);
}
* 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++;
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 ')':
}
}
/* 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;
}
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('{');
s--;
if (PL_expect == XOPERATOR) {
if (ckWARN(WARN_SEMICOLON) && isIDFIRST_lazy(s) && PL_bufptr == PL_linestart) {
- PL_curcop->cop_line--;
+ CopLINE_dec(PL_curcop);
Perl_warner(aTHX_ WARN_SEMICOLON, PL_warn_nosemi);
- PL_curcop->cop_line++;
+ CopLINE_inc(PL_curcop);
}
BAop(OP_BIT_AND);
}
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)
if (PL_expect == XOPERATOR) {
if (PL_bufptr == PL_linestart) {
- PL_curcop->cop_line--;
+ CopLINE_dec(PL_curcop);
Perl_warner(aTHX_ WARN_SEMICOLON, PL_warn_nosemi);
- PL_curcop->cop_line++;
+ CopLINE_inc(PL_curcop);
}
else
no_op("Bareword",s);
if (PL_oldoldbufptr &&
PL_oldoldbufptr < PL_bufptr &&
- (PL_oldoldbufptr == PL_last_lop || PL_oldoldbufptr == PL_last_uni) &&
+ (PL_oldoldbufptr == PL_last_lop
+ || PL_oldoldbufptr == PL_last_uni) &&
/* NO SKIPSPACE BEFORE HERE! */
(PL_expect == XREF ||
((PL_opargs[PL_last_lop_op] >> OASHIFT)& 7) == OA_FILEREF))
case KEY___FILE__:
yylval.opval = (OP*)newSVOP(OP_CONST, 0,
- newSVsv(GvSV(PL_curcop->cop_filegv)));
+ newSVsv(CopFILESV(PL_curcop)));
TERM(THING);
case KEY___LINE__:
- yylval.opval = (OP*)newSVOP(OP_CONST, 0,
- Perl_newSVpvf(aTHX_ "%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__:
case KEY_DESTROY:
case KEY_BEGIN:
case KEY_END:
+ case KEY_STOP:
case KEY_INIT:
if (PL_expect == XSTATE) {
s = PL_bufptr;
case KEY_crypt:
#ifdef FCRYPT
- if (!PL_cryptseen++)
+ if (!PL_cryptseen) {
+ PL_cryptseen = TRUE;
init_des();
+ }
#endif
LOP(OP_CRYPT,XTERM);
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);
PREBLOCK(ELSE);
case KEY_elsif:
- yylval.ival = PL_curcop->cop_line;
+ yylval.ival = CopLINE(PL_curcop);
OPERATOR(ELSIF);
case KEY_eq:
case KEY_for:
case KEY_foreach:
- yylval.ival = PL_curcop->cop_line;
+ yylval.ival = CopLINE(PL_curcop);
s = skipspace(s);
if (PL_expect == XSTATE && isIDFIRST_lazy(s)) {
char *p = s;
if ((PL_bufend - p) >= 3 &&
strnEQ(p, "my", 2) && isSPACE(*(p + 2)))
p += 2;
+ else if ((PL_bufend - p) >= 4 &&
+ strnEQ(p, "our", 3) && isSPACE(*(p + 3)))
+ p += 3;
p = skipspace(p);
- if (isIDFIRST_lazy(p))
+ if (isIDFIRST_lazy(p)) {
+ p = scan_ident(p, PL_bufend,
+ PL_tokenbuf, sizeof PL_tokenbuf, TRUE);
+ p = skipspace(p);
+ }
+ if (*p != '$')
Perl_croak(aTHX_ "Missing $ on loop variable");
}
OPERATOR(FOR);
UNI(OP_HEX);
case KEY_if:
- yylval.ival = PL_curcop->cop_line;
+ yylval.ival = CopLINE(PL_curcop);
OPERATOR(IF);
case KEY_index:
UNI(OP_LCFIRST);
case KEY_local:
+ yylval.ival = 0;
OPERATOR(LOCAL);
case KEY_length:
case KEY_msgsnd:
LOP(OP_MSGSND,XTERM);
+ case KEY_our:
case KEY_my:
- PL_in_my = TRUE;
+ PL_in_my = tmp;
s = skipspace(s);
if (isIDFIRST_lazy(s)) {
s = scan_word(s, PL_tokenbuf, sizeof PL_tokenbuf, TRUE, &len);
+ if (len == 3 && strnEQ(PL_tokenbuf, "sub", 3))
+ goto really_sub;
PL_in_my_stash = gv_stashpv(PL_tokenbuf, FALSE);
if (!PL_in_my_stash) {
char tmpbuf[1024];
yyerror(tmpbuf);
}
}
+ yylval.ival = 1;
OPERATOR(MY);
case KEY_next:
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);
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;
UNI(OP_STAT);
case KEY_study:
- PL_sawstudy++;
UNI(OP_STUDY);
case KEY_substr:
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);
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:
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);
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:
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;
break;
}
break;
+ case 'S':
+ if (strEQ(d,"STOP")) return KEY_STOP;
+ break;
case 's':
switch (d[1]) {
case 0: return KEY_s;
if (*w)
for (; *w && isSPACE(*w); w++) ;
if (!*w || !strchr(";|})]oaiuw!=", *w)) /* an advisory hack only... */
- Perl_warner(aTHX_ WARN_SYNTAX, "%s (...) interpreted as function",name);
+ Perl_warner(aTHX_ WARN_SYNTAX,
+ "%s (...) interpreted as function",name);
}
}
while (s < PL_bufend && isSPACE(*s))
}
}
+/* 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)
+S_new_constant(pTHX_ char *s, STRLEN len, const char *key, SV *sv, SV *pv,
+ const char *type)
{
dSP;
HV *table = GvHV(PL_hintgv); /* ^H */
- BINOP myop;
SV *res;
- bool oldcatch = CATCH_GET;
SV **cvp;
SV *cv, *typesv;
-
+ const char *why, *why1, *why2;
+
+ if (!(PL_hints & HINT_LOCALIZE_HH)) {
+ SV *msg;
+
+ why = "%^H is not localized";
+ report_short:
+ why1 = why2 = "";
+ report:
+ msg = Perl_newSVpvf(aTHX_ "constant(%s): %s%s%s",
+ (type ? type: "undef"), why1, why2, why);
+ yyerror(SvPVX(msg));
+ SvREFCNT_dec(msg);
+ return sv;
+ }
if (!table) {
- yyerror("%^H is not defined");
- return sv;
+ why = "%^H is not defined";
+ goto report_short;
}
cvp = hv_fetch(table, key, strlen(key), FALSE);
if (!cvp || !SvOK(*cvp)) {
- char buf[128];
- sprintf(buf,"$^H{%s} is not defined", key);
- yyerror(buf);
- return sv;
+ why = "} is not defined";
+ why1 = "$^H{";
+ why2 = key;
+ goto report;
}
sv_2mortal(sv); /* Parent created it permanently */
cv = *cvp;
- if (!pv)
- pv = sv_2mortal(newSVpvn(s, len));
- if (type)
- typesv = sv_2mortal(newSVpv(type, 0));
+ if (!pv && s)
+ pv = sv_2mortal(newSVpvn(s, len));
+ if (type && pv)
+ typesv = sv_2mortal(newSVpv(type, 0));
else
- typesv = &PL_sv_undef;
- CATCH_SET(TRUE);
- Zero(&myop, 1, BINOP);
- myop.op_last = (OP *) &myop;
- myop.op_next = Nullop;
- myop.op_flags = OPf_WANT_SCALAR | OPf_STACKED;
-
+ typesv = &PL_sv_undef;
+
PUSHSTACKi(PERLSI_OVERLOAD);
- ENTER;
- SAVEOP();
- PL_op = (OP *) &myop;
- if (PERLDB_SUB && PL_curstash != PL_debstash)
- PL_op->op_private |= OPpENTERSUB_DB;
- PUTBACK;
- 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 */
+ (void)POPs;
+ res = SvREFCNT_inc(sv);
+ }
+ else {
+ res = POPs;
+ (void)SvREFCNT_inc(res);
+ }
+
+ PUTBACK ;
+ FREETMPS ;
+ LEAVE ;
POPSTACK;
-
+
if (!SvOK(res)) {
- char buf[128];
- sprintf(buf,"Call to &{$^H{%s}} did not return a defined value", key);
- yyerror(buf);
- }
- return SvREFCNT_inc(res);
+ why = "}} did not return a defined value";
+ why1 = "Call to &{$^H{";
+ why2 = key;
+ sv = res;
+ goto report;
+ }
+
+ return res;
}
-
+
STATIC char *
S_scan_word(pTHX_ register char *s, char *dest, STRLEN destlen, int allow_package, STRLEN *slp)
{
if ((*s == '[' || (*s == '{' && strNE(dest, "sub")))) {
dTHR; /* only for ckWARN */
if (ckWARN(WARN_AMBIGUOUS) && keyword(dest, d - dest)) {
- char *brack = *s == '[' ? "[...]" : "{...}";
+ const char *brack = *s == '[' ? "[...]" : "{...}";
Perl_warner(aTHX_ WARN_AMBIGUOUS,
"Ambiguous use of %c{%s%s} resolved to %c%s%s",
funny, dest, brack, funny, dest, brack);
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);
}
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) {
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);
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);
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) {
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;
}
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);
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 */
/* after skipping whitespace, the next character is the terminator */
term = *s;
/* mark where we are */
- PL_multi_start = PL_curcop->cop_line;
+ PL_multi_start = CopLINE(PL_curcop);
PL_multi_open = term;
/* find corresponding closing delimiter */
(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
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++;
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_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 */
/* at this point, we have successfully read the delimited string */
- PL_multi_end = PL_curcop->cop_line;
+ if (keep_delims)
+ sv_catpvn(sv, s, 1);
+ PL_multi_end = CopLINE(PL_curcop);
s++;
/* if we allocated too much space, give some back */
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";
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
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) && n > 4294967295.0)
- Perl_warner(aTHX_ WARN_UNSAFE,
+ if (ckWARN(WARN_PORTABLE) && n > 4294967295.0)
+ Perl_warner(aTHX_ WARN_PORTABLE,
"%s number > %s non-portable",
Base, max);
sv_setnv(sv, n);
}
else {
-#if UV_SIZEOF > 4
+#if UVSIZE > 4
dTHR;
- if (ckWARN(WARN_UNSAFE) && u > 0xffffffff)
- Perl_warner(aTHX_ WARN_UNSAFE,
+ if (ckWARN(WARN_PORTABLE) && u > 0xffffffff)
+ Perl_warner(aTHX_ WARN_PORTABLE,
"%s number > %s non-portable",
Base, max);
#endif
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;
}
PL_comppad_name_fill = 0;
PL_min_intro_pending = 0;
PL_padix = 0;
- PL_subline = PL_curcop->cop_line;
+ PL_subline = CopLINE(PL_curcop);
#ifdef USE_THREADS
av_store(PL_comppad_name, 0, newSVpvn("@_", 2));
PL_curpad[0] = (SV*)newAV();
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));
- Perl_sv_catpvf(aTHX_ msg, " at %_ line %ld, ",
- GvSV(PL_curcop->cop_filegv), (long)PL_curcop->cop_line);
+ Perl_sv_catpvf(aTHX_ msg, " at %_ line %"IVdf", ",
+ CopFILESV(PL_curcop), (IV)CopLINE(PL_curcop));
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);
+ 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 & EVAL_WARNONLY)
Perl_warn(aTHX_ "%_", msg);
- else if (PL_in_eval)
- sv_catsv(ERRSV, msg);
else
- PerlIO_write(PerlIO_stderr(), SvPVX(msg), SvCUR(msg));
- if (++PL_error_count >= 10)
- Perl_croak(aTHX_ "%_ has too many errors.\n", GvSV(PL_curcop->cop_filegv));
+ qerror(msg);
+ if (PL_error_count >= 10)
+ Perl_croak(aTHX_ "%_ has too many errors.\n", CopFILESV(PL_curcop));
PL_in_my = 0;
PL_in_my_stash = Nullhv;
return 0;
#ifdef PERL_OBJECT
-#define NO_XSLOCKS
#include "XSUB.h"
#endif