/* toke.c
*
- * Copyright (c) 1991-2001, Larry Wall
+ * Copyright (c) 1991-2002, Larry Wall
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
#define yylval PL_yylval
static char ident_too_long[] = "Identifier too long";
+static char c_without_g[] = "Use of /c modifier is meaningless without /g";
+static char c_in_subst[] = "Use of /c modifier is meaningless in s///";
static void restore_rsfp(pTHX_ void *f);
#ifndef PERL_NO_UTF16_FILTER
Perl_deprecate(pTHX_ char *s)
{
if (ckWARN(WARN_DEPRECATED))
- Perl_warner(aTHX_ WARN_DEPRECATED, "Use of %s is deprecated", s);
+ Perl_warner(aTHX_ packWARN(WARN_DEPRECATED), "Use of %s is deprecated", s);
+}
+
+void
+Perl_deprecate_old(pTHX_ char *s)
+{
+ /* This function should NOT be called for any new deprecated warnings */
+ /* Use Perl_deprecate instead */
+ /* */
+ /* It is here to maintain backward compatibility with the pre-5.8 */
+ /* warnings category hierarchy. The "deprecated" category used to */
+ /* live under the "syntax" category. It is now a top-level category */
+ /* in its own right. */
+
+ if (ckWARN2(WARN_DEPRECATED, WARN_SYNTAX))
+ Perl_warner(aTHX_ packWARN2(WARN_DEPRECATED, WARN_SYNTAX),
+ "Use of %s is deprecated", s);
}
/*
STATIC void
S_depcom(pTHX)
{
- deprecate("comma-less variable list");
+ deprecate_old("comma-less variable list");
}
/*
ch = *t;
*t = '\0';
if (t - s > 0) {
-#ifdef USE_ITHREADS
- Safefree(CopFILE(PL_curcop));
-#else
- SvREFCNT_dec(CopFILEGV(PL_curcop));
-#endif
+ CopFILE_free(PL_curcop);
CopFILE_set(PL_curcop, s);
}
*t = ch;
sv_upgrade(sv, SVt_PVMG);
sv_setpvn(sv,PL_bufptr,PL_bufend-PL_bufptr);
+ (void)SvIOK_on(sv);
+ SvIVX(sv) = 0;
av_store(CopFILEAV(PL_curcop),(I32)CopLINE(PL_curcop),sv);
}
}
if (ckWARN_d(WARN_AMBIGUOUS)){
char ch = *s;
*s = '\0';
- Perl_warner(aTHX_ WARN_AMBIGUOUS,
+ Perl_warner(aTHX_ packWARN(WARN_AMBIGUOUS),
"Warning: Use of \"%s\" without parens is ambiguous",
PL_last_uni);
*s = ch;
}
}
-/* workaround to replace the UNI() macro with a function. Only the
- * hints/uts.sh file mentions this. Other comments elsewhere in the
- * source indicate Microport Unix might need it too.
- */
-
-#ifdef CRIPPLED_CC
-
-#undef UNI
-#define UNI(f) return uni(f,s)
-
-STATIC int
-S_uni(pTHX_ I32 f, char *s)
-{
- yylval.ival = f;
- PL_expect = XTERM;
- PL_bufptr = s;
- PL_last_uni = PL_oldbufptr;
- PL_last_lop_op = f;
- if (*s == '(')
- return FUNC1;
- s = skipspace(s);
- if (*s == '(')
- return FUNC1;
- else
- return UNIOP;
-}
-
-#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.
isDIGIT(*s) && *s != '0' && !isDIGIT(s[1]))
{
if (ckWARN(WARN_SYNTAX))
- Perl_warner(aTHX_ WARN_SYNTAX, "\\%c better written as $%c", *s, *s);
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX), "\\%c better written as $%c", *s, *s);
*--s = '$';
break;
}
/* FALL THROUGH */
default:
{
- if (ckWARN(WARN_MISC) && isALNUM(*s))
- Perl_warner(aTHX_ WARN_MISC,
+ if (ckWARN(WARN_MISC) &&
+ isALNUM(*s) &&
+ *s != '_')
+ Perl_warner(aTHX_ packWARN(WARN_MISC),
"Unrecognized escape \\%c passed through",
*s);
/* default action is to copy the quoted character */
}
continue;
- /* \N{latin small letter a} is a named character */
+ /* \N{LATIN SMALL LETTER A} is a named character */
case 'N':
++s;
if (*s == '{') {
if (has_utf8)
sv_utf8_upgrade(res);
str = SvPV(res,len);
+#ifdef EBCDIC_NEVER_MIND
+ /* charnames uses pack U and that has been
+ * recently changed to do the below uni->native
+ * mapping, so this would be redundant (and wrong,
+ * the code point would be doubly converted).
+ * But leave this in just in case the pack U change
+ * gets revoked, but the semantics is still
+ * desireable for charnames. --jhi */
+ {
+ UV uv = utf8_to_uvchr((U8*)str, 0);
+
+ if (uv < 0x100) {
+ U8 tmpbuf[UTF8_MAXLEN+1], *d;
+
+ d = uvchr_to_utf8(tmpbuf, UNI_TO_NATIVE(uv));
+ sv_setpvn(res, (char *)tmpbuf, d - tmpbuf);
+ str = SvPV(res, len);
+ }
+ }
+#endif
if (!has_utf8 && SvUTF8(res)) {
char *ostart = SvPVX(sv);
SvCUR_set(sv, d - ostart);
d = SvPVX(sv) + SvCUR(sv);
has_utf8 = TRUE;
}
- if (len > e - s + 4) {
+ if (len > e - s + 4) { /* I _guess_ 4 is \N{} --jhi */
char *odest = SvPVX(sv);
SvGROW(sv, (SvLEN(sv) + len - (e - s + 4)));
SvPOK_on(sv);
if (PL_encoding && !has_utf8) {
- Perl_sv_recode_to_utf8(aTHX_ sv);
+ sv_recode_to_utf8(sv, PL_encoding);
has_utf8 = TRUE;
}
if (has_utf8) {
IoANY(datasv) = (void *)funcp; /* stash funcp into spare field */
IoFLAGS(datasv) |= IOf_FAKE_DIRP;
DEBUG_P(PerlIO_printf(Perl_debug_log, "filter_add func %p (%s)\n",
- funcp, SvPV_nolen(datasv)));
+ (void*)funcp, SvPV_nolen(datasv)));
av_unshift(PL_rsfp_filters, 1);
av_store(PL_rsfp_filters, 0, datasv) ;
return(datasv);
Perl_filter_del(pTHX_ filter_t funcp)
{
SV *datasv;
- DEBUG_P(PerlIO_printf(Perl_debug_log, "filter_del func %p", funcp));
+ DEBUG_P(PerlIO_printf(Perl_debug_log, "filter_del func %p", (void*)funcp));
if (!PL_rsfp_filters || AvFILLp(PL_rsfp_filters)<0)
return;
/* if filter is on top of stack (usual case) just pop it off */
funcp = (filter_t)IoANY(datasv);
DEBUG_P(PerlIO_printf(Perl_debug_log,
"filter_read %d: via function %p (%s)\n",
- idx, funcp, SvPV_nolen(datasv)));
+ idx, (void*)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 */
bool bof = FALSE;
/* check if there's an identifier for us to look at */
- if (PL_pending_ident)
+ if (PL_pending_ident)
return S_pending_ident(aTHX);
/* no identifier pending identification */
if (PL_minus_F) {
if (strchr("/'\"", *PL_splitstr)
&& strchr(PL_splitstr + 1, *PL_splitstr))
- Perl_sv_catpvf(aTHX_ PL_linestr, "@F=split(%s);", PL_splitstr);
+ Perl_sv_catpvf(aTHX_ PL_linestr, "our @F=split(%s);", PL_splitstr);
else {
char delim;
s = "'~#\200\1'"; /* surely one char is unused...*/
sv_upgrade(sv, SVt_PVMG);
sv_setsv(sv,PL_linestr);
+ (void)SvIOK_on(sv);
+ SvIVX(sv) = 0;
av_store(CopFILEAV(PL_curcop),(I32)CopLINE(PL_curcop),sv);
}
goto retry;
}
}
if (PL_doextract) {
- if (*s == '#' && s[1] == '!' && instr(s,"perl"))
- PL_doextract = FALSE;
-
/* Incest with pod. */
if (*s == '=' && strnEQ(s, "=cut", 4)) {
sv_setpv(PL_linestr, "");
sv_upgrade(sv, SVt_PVMG);
sv_setsv(sv,PL_linestr);
+ (void)SvIOK_on(sv);
+ SvIVX(sv) = 0;
av_store(CopFILEAV(PL_curcop),(I32)CopLINE(PL_curcop),sv);
}
PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr);
* at least, set argv[0] to the basename of the Perl
* interpreter. So, having found "#!", we'll set it right.
*/
- SV *x = GvSV(gv_fetchpv("\030", TRUE, SVt_PV));
+ SV *x = GvSV(gv_fetchpv("\030", TRUE, SVt_PV)); /* $^X */
assert(SvPOK(x) || SvGMAGICAL(x));
if (sv_eq(x, CopFILESV(PL_curcop))) {
sv_setpvn(x, ipath, ipathend - ipath);
while (SPACE_OR_TAB(*d)) d++;
if (*d++ == '-') {
+ bool switches_done = PL_doswitches;
do {
if (*d == 'M' || *d == 'm') {
char *m = d;
(void)gv_fetchfile(PL_origfilename);
goto retry;
}
+ if (PL_doswitches && !switches_done) {
+ int argc = PL_origargc;
+ char **argv = PL_origargv;
+ do {
+ argc--,argv++;
+ } while (argc && argv[0][0] == '-' && argv[0][1]);
+ init_argv_symbols(argc,argv);
+ }
}
}
}
PL_lex_stuff = Nullsv;
}
else {
+ /* NOTE: any CV attrs applied here need to be part of
+ the CVf_BUILTIN_ATTRS define in cv.h! */
if (!PL_in_my && len == 6 && strnEQ(s, "lvalue", len))
CvLVALUE_on(PL_compcv);
else if (!PL_in_my && len == 6 && strnEQ(s, "locked", len))
else if (!PL_in_my && len == 6 && strnEQ(s, "method", len))
CvMETHOD_on(PL_compcv);
#ifdef USE_ITHREADS
- else if (PL_in_my == KEY_our && len == 6 && strnEQ(s, "unique", len))
+ else if (PL_in_my == KEY_our && len == 6 &&
+ strnEQ(s, "unique", len))
GvUNIQUE_on(cGVOPx_gv(yylval.opval));
#endif
/* After we've set the flags, it could be argued that
we don't need to do the attributes.pm-based setting
process, and shouldn't bother appending recognized
- flags. To experiment with that, uncomment the
- following "else": */
+ flags. To experiment with that, uncomment the
+ following "else". (Note that's already been
+ uncommented. That keeps the above-applied built-in
+ attributes from being intercepted (and possibly
+ rejected) by a package's attribute routines, but is
+ justified by the performance win for the common case
+ of applying only built-in attributes.) */
else
attrs = append_elem(OP_LIST, attrs,
newSVOP(OP_CONST, 0,
&& isIDFIRST_lazy_if(s,UTF) && PL_bufptr == PL_linestart)
{
CopLINE_dec(PL_curcop);
- Perl_warner(aTHX_ WARN_SEMICOLON, PL_warn_nosemi);
+ Perl_warner(aTHX_ packWARN(WARN_SEMICOLON), PL_warn_nosemi);
CopLINE_inc(PL_curcop);
}
BAop(OP_BIT_AND);
if (tmp == '~')
PMop(OP_MATCH);
if (ckWARN(WARN_SYNTAX) && tmp && isSPACE(*s) && strchr("+-*/%.^&|<",tmp))
- Perl_warner(aTHX_ WARN_SYNTAX, "Reversed %c= operator",(int)tmp);
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX), "Reversed %c= operator",(int)tmp);
s--;
if (PL_expect == XSTATE && isALPHA(tmp) &&
(s == PL_linestart+1 || s[-2] == '\n') )
PL_bufptr = skipspace(PL_bufptr);
while (t < PL_bufend && *t != ']')
t++;
- Perl_warner(aTHX_ WARN_SYNTAX,
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
"Multidimensional syntax %.*s not supported",
(t - PL_bufptr) + 1, PL_bufptr);
}
t = scan_word(t, tmpbuf, sizeof tmpbuf, TRUE, &len);
for (; isSPACE(*t); t++) ;
if (*t == ';' && get_cv(tmpbuf, FALSE))
- Perl_warner(aTHX_ WARN_SYNTAX,
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
"You need to quote \"%s\"", tmpbuf);
}
}
if (*t == '}' || *t == ']') {
t++;
PL_bufptr = skipspace(PL_bufptr);
- Perl_warner(aTHX_ WARN_SYNTAX,
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
"Scalar value %.*s better written as $%.*s",
t-PL_bufptr, PL_bufptr, t-PL_bufptr-1, PL_bufptr+1);
}
case '\\':
s++;
if (ckWARN(WARN_SYNTAX) && PL_lex_inwhat && isDIGIT(*s))
- Perl_warner(aTHX_ WARN_SYNTAX,"Can't use \\%c to mean $%c in expression",
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX),"Can't use \\%c to mean $%c in expression",
*s, *s);
if (PL_expect == XOPERATOR)
no_op("Backslash",s);
}
else { /* no override */
tmp = -tmp;
+ if (tmp == KEY_dump && ckWARN(WARN_MISC)) {
+ Perl_warner(aTHX_ packWARN(WARN_MISC),
+ "dump() better written as CORE::dump()");
+ }
gv = Nullgv;
gvp = 0;
if (ckWARN(WARN_AMBIGUOUS) && hgv
&& tmp != KEY_x && tmp != KEY_CORE) /* never ambiguous */
- Perl_warner(aTHX_ WARN_AMBIGUOUS,
+ Perl_warner(aTHX_ packWARN(WARN_AMBIGUOUS),
"Ambiguous call resolved as CORE::%s(), %s",
GvENAME(hgv), "qualify as such or use &");
}
if (PL_expect == XOPERATOR) {
if (PL_bufptr == PL_linestart) {
CopLINE_dec(PL_curcop);
- Perl_warner(aTHX_ WARN_SEMICOLON, PL_warn_nosemi);
+ Perl_warner(aTHX_ packWARN(WARN_SEMICOLON), PL_warn_nosemi);
CopLINE_inc(PL_curcop);
}
else
PL_tokenbuf[len - 2] == ':' && PL_tokenbuf[len - 1] == ':')
{
if (ckWARN(WARN_BAREWORD) && ! gv_fetchpv(PL_tokenbuf, FALSE, SVt_PVHV))
- Perl_warner(aTHX_ WARN_BAREWORD,
+ Perl_warner(aTHX_ packWARN(WARN_BAREWORD),
"Bareword \"%s\" refers to nonexistent package",
PL_tokenbuf);
len -= 2;
if (gv && GvCVu(gv)) {
CV* cv;
if (lastchar == '-' && ckWARN_d(WARN_AMBIGUOUS))
- Perl_warner(aTHX_ WARN_AMBIGUOUS,
+ Perl_warner(aTHX_ packWARN(WARN_AMBIGUOUS),
"Ambiguous use of -%s resolved as -&%s()",
PL_tokenbuf, PL_tokenbuf);
/* Check for a constant sub */
if (strEQ(proto, "$"))
OPERATOR(UNIOPSUB);
if (*proto == '&' && *s == '{') {
- sv_setpv(PL_subname,"__ANON__");
+ sv_setpv(PL_subname, PL_curstash ?
+ "__ANON__" : "__ANON__::__ANON__");
PREBLOCK(LSTOPSUB);
}
}
if (lastchar != '-') {
for (d = PL_tokenbuf; *d && isLOWER(*d); d++) ;
if (!*d && strNE(PL_tokenbuf,"main"))
- Perl_warner(aTHX_ WARN_RESERVED, PL_warn_reserved,
+ Perl_warner(aTHX_ packWARN(WARN_RESERVED), PL_warn_reserved,
PL_tokenbuf);
}
}
safe_bareword:
if (lastchar && strchr("*%&", lastchar) && ckWARN_d(WARN_AMBIGUOUS)) {
- Perl_warner(aTHX_ WARN_AMBIGUOUS,
+ Perl_warner(aTHX_ packWARN(WARN_AMBIGUOUS),
"Operator or semicolon missing before %c%s",
lastchar, PL_tokenbuf);
- Perl_warner(aTHX_ WARN_AMBIGUOUS,
+ Perl_warner(aTHX_ packWARN(WARN_AMBIGUOUS),
"Ambiguous use of %c resolved as operator %c",
lastchar, lastchar);
}
for (d = s; isALNUM_lazy_if(d,UTF); d++) ;
t = skipspace(d);
if (strchr("|&*+-=!?:.", *t) && ckWARN_d(WARN_PRECEDENCE))
- Perl_warner(aTHX_ WARN_PRECEDENCE,
+ Perl_warner(aTHX_ packWARN(WARN_PRECEDENCE),
"Precedence problem: open %.*s should be open(%.*s)",
d-s,s, d-s,s);
}
if (!warned && ckWARN(WARN_QW)) {
for (; !isSPACE(*d) && len; --len, ++d) {
if (*d == ',') {
- Perl_warner(aTHX_ WARN_QW,
+ Perl_warner(aTHX_ packWARN(WARN_QW),
"Possible attempt to separate words with commas");
++warned;
}
else if (*d == '#') {
- Perl_warner(aTHX_ WARN_QW,
+ Perl_warner(aTHX_ packWARN(WARN_QW),
"Possible attempt to put comments in qw() list");
++warned;
}
char tmpbuf[sizeof PL_tokenbuf];
SSize_t tboffset = 0;
expectation attrful;
- bool have_name, have_proto;
+ bool have_name, have_proto, bad_proto;
int key = tmp;
s = skipspace(s);
s = scan_str(s,FALSE,FALSE);
if (!s)
Perl_croak(aTHX_ "Prototype not terminated");
- /* strip spaces */
+ /* strip spaces and check for bad characters */
d = SvPVX(PL_lex_stuff);
tmp = 0;
+ bad_proto = FALSE;
for (p = d; *p; ++p) {
- if (!isSPACE(*p))
+ if (!isSPACE(*p)) {
d[tmp++] = *p;
+ if (!strchr("$@%*;[]&\\", *p))
+ bad_proto = TRUE;
+ }
}
d[tmp] = '\0';
+ if (bad_proto && ckWARN(WARN_SYNTAX))
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
+ "Illegal character in prototype for %s : %s",
+ SvPVX(PL_subname), d);
SvCUR(PL_lex_stuff) = tmp;
have_proto = TRUE;
force_next(THING);
}
if (!have_name) {
- sv_setpv(PL_subname,"__ANON__");
+ sv_setpv(PL_subname,
+ PL_curstash ? "__ANON__" : "__ANON__::__ANON__");
TOKEN(ANONSUB);
}
(void) force_word(PL_oldbufptr + tboffset, WORD,
gv_fetchpv(SvPVX(sym),
(PL_in_eval
? (GV_ADDMULTI | GV_ADDINEVAL)
- : TRUE
+ : GV_ADDMULTI
),
((PL_tokenbuf[0] == '$') ? SVt_PV
: (PL_tokenbuf[0] == '@') ? SVt_PVAV
&& ckWARN(WARN_AMBIGUOUS))
{
/* Downgraded from fatal to warning 20000522 mjd */
- Perl_warner(aTHX_ WARN_AMBIGUOUS,
+ Perl_warner(aTHX_ packWARN(WARN_AMBIGUOUS),
"Possible unintended interpolation of %s in string",
PL_tokenbuf);
}
if (*w)
for (; *w && isSPACE(*w); w++) ;
if (!*w || !strchr(";|})]oaiuw!=", *w)) /* an advisory hack only... */
- Perl_warner(aTHX_ WARN_SYNTAX,
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
"%s (...) interpreted as function",name);
}
}
if ((*s == '[' || (*s == '{' && strNE(dest, "sub")))) {
if (ckWARN(WARN_AMBIGUOUS) && keyword(dest, d - dest)) {
const char *brack = *s == '[' ? "[...]" : "{...}";
- Perl_warner(aTHX_ WARN_AMBIGUOUS,
+ Perl_warner(aTHX_ packWARN(WARN_AMBIGUOUS),
"Ambiguous use of %c{%s%s} resolved to %c%s%s",
funny, dest, brack, funny, dest, brack);
}
if (ckWARN(WARN_AMBIGUOUS) &&
(keyword(dest, d - dest) || get_cv(dest, FALSE)))
{
- Perl_warner(aTHX_ WARN_AMBIGUOUS,
+ Perl_warner(aTHX_ packWARN(WARN_AMBIGUOUS),
"Ambiguous use of %c{%s} resolved to %c%s",
funny, dest, funny, dest);
}
while (*s && strchr("iogcmsx", *s))
pmflag(&pm->op_pmflags,*s++);
}
+ /* issue a warning if /c is specified,but /g is not */
+ if (ckWARN(WARN_REGEXP) &&
+ (pm->op_pmflags & PMf_CONTINUE) && !(pm->op_pmflags & PMf_GLOBAL))
+ {
+ Perl_warner(aTHX_ packWARN(WARN_REGEXP), c_without_g);
+ }
+
pm->op_pmpermflags = pm->op_pmflags;
PL_lex_op = (OP*)pm;
break;
}
+ /* /c is not meaningful with s/// */
+ if (ckWARN(WARN_REGEXP) && (pm->op_pmflags & PMf_CONTINUE))
+ {
+ Perl_warner(aTHX_ packWARN(WARN_REGEXP), c_in_subst);
+ }
+
if (es) {
SV *repl;
PL_sublex_info.super_bufptr = s;
else
term = '"';
if (!isALNUM_lazy_if(s,UTF))
- deprecate("bare << to mean <<\"\"");
+ deprecate_old("bare << to mean <<\"\"");
for (; isALNUM_lazy_if(s,UTF); s++) {
if (d < e)
*d++ = *s;
sv_upgrade(sv, SVt_PVMG);
sv_setsv(sv,PL_linestr);
+ (void)SvIOK_on(sv);
+ SvIVX(sv) = 0;
av_store(CopFILEAV(PL_curcop), (I32)CopLINE(PL_curcop),sv);
}
if (*s == term && memEQ(s,PL_tokenbuf,len)) {
return s;
}
else {
+ bool readline_overriden = FALSE;
+ GV *gv_readline = Nullgv;
+ GV **gvp;
/* we're in a filehandle read situation */
d = PL_tokenbuf;
if (!len)
(void)strcpy(d,"ARGV");
+ /* Check whether readline() is overriden */
+ if (((gv_readline = gv_fetchpv("readline", FALSE, SVt_PVCV))
+ && GvCVu(gv_readline) && GvIMPORTED_CV(gv_readline))
+ ||
+ ((gvp = (GV**)hv_fetch(PL_globalstash, "readline", 8, FALSE))
+ && (gv_readline = *gvp) != (GV*)&PL_sv_undef
+ && GvCVu(gv_readline) && GvIMPORTED_CV(gv_readline)))
+ readline_overriden = TRUE;
+
/* if <$fh>, create the ops to turn the variable into a
filehandle
*/
else {
OP *o = newOP(OP_PADSV, 0);
o->op_targ = tmp;
- PL_lex_op = (OP*)newUNOP(OP_READLINE, 0, o);
+ PL_lex_op = readline_overriden
+ ? (OP*)newUNOP(OP_ENTERSUB, OPf_STACKED,
+ append_elem(OP_LIST, o,
+ newCVREF(0, newGVOP(OP_GV,0,gv_readline))))
+ : (OP*)newUNOP(OP_READLINE, 0, o);
}
}
else {
gv = gv_fetchpv(d,
(PL_in_eval
? (GV_ADDMULTI | GV_ADDINEVAL)
- : TRUE),
+ : GV_ADDMULTI),
SVt_PV);
- PL_lex_op = (OP*)newUNOP(OP_READLINE, 0,
- newUNOP(OP_RV2SV, 0,
- newGVOP(OP_GV, 0, gv)));
- }
- PL_lex_op->op_flags |= OPf_SPECIAL;
+ PL_lex_op = readline_overriden
+ ? (OP*)newUNOP(OP_ENTERSUB, OPf_STACKED,
+ append_elem(OP_LIST,
+ newUNOP(OP_RV2SV, 0, newGVOP(OP_GV, 0, gv)),
+ newCVREF(0, newGVOP(OP_GV, 0, gv_readline))))
+ : (OP*)newUNOP(OP_READLINE, 0,
+ newUNOP(OP_RV2SV, 0,
+ newGVOP(OP_GV, 0, gv)));
+ }
+ if (!readline_overriden)
+ PL_lex_op->op_flags |= OPf_SPECIAL;
/* we created the ops in PL_lex_op, so make yylval.ival a null op */
yylval.ival = OP_NULL;
}
(<Foo::BAR> or <FOO>) so build a simple readline OP */
else {
GV *gv = gv_fetchpv(d,TRUE, SVt_PVIO);
- PL_lex_op = (OP*)newUNOP(OP_READLINE, 0, newGVOP(OP_GV, 0, gv));
+ PL_lex_op = readline_overriden
+ ? (OP*)newUNOP(OP_ENTERSUB, OPf_STACKED,
+ append_elem(OP_LIST,
+ newGVOP(OP_GV, 0, gv),
+ newCVREF(0, newGVOP(OP_GV, 0, gv_readline))))
+ : (OP*)newUNOP(OP_READLINE, 0, newGVOP(OP_GV, 0, gv));
yylval.ival = OP_NULL;
}
}
sv_upgrade(sv, SVt_PVMG);
sv_setsv(sv,PL_linestr);
+ (void)SvIOK_on(sv);
+ SvIVX(sv) = 0;
av_store(CopFILEAV(PL_curcop), (I32)CopLINE(PL_curcop), sv);
}
if (*s == '_') {
if (ckWARN(WARN_SYNTAX))
- Perl_warner(aTHX_ WARN_SYNTAX,
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
"Misplaced _ in number");
lastub = s++;
}
/* _ are ignored -- but warned about if consecutive */
case '_':
if (ckWARN(WARN_SYNTAX) && lastub && s == lastub + 1)
- Perl_warner(aTHX_ WARN_SYNTAX,
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
"Misplaced _ in number");
lastub = s++;
break;
overflowed = TRUE;
n = (NV) u;
if (ckWARN_d(WARN_OVERFLOW))
- Perl_warner(aTHX_ WARN_OVERFLOW,
+ Perl_warner(aTHX_ packWARN(WARN_OVERFLOW),
"Integer overflow in %s number",
base);
} else
/* final misplaced underbar check */
if (s[-1] == '_') {
if (ckWARN(WARN_SYNTAX))
- Perl_warner(aTHX_ WARN_SYNTAX, "Misplaced _ in number");
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX), "Misplaced _ in number");
}
sv = NEWSV(92,0);
if (overflowed) {
if (ckWARN(WARN_PORTABLE) && n > 4294967295.0)
- Perl_warner(aTHX_ WARN_PORTABLE,
+ Perl_warner(aTHX_ packWARN(WARN_PORTABLE),
"%s number > %s non-portable",
Base, max);
sv_setnv(sv, n);
else {
#if UVSIZE > 4
if (ckWARN(WARN_PORTABLE) && u > 0xffffffff)
- Perl_warner(aTHX_ WARN_PORTABLE,
+ Perl_warner(aTHX_ packWARN(WARN_PORTABLE),
"%s number > %s non-portable",
Base, max);
#endif
*/
if (*s == '_') {
if (ckWARN(WARN_SYNTAX) && lastub && s == lastub + 1)
- Perl_warner(aTHX_ WARN_SYNTAX,
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
"Misplaced _ in number");
lastub = s++;
}
/* final misplaced underbar check */
if (lastub && s == lastub + 1) {
if (ckWARN(WARN_SYNTAX))
- Perl_warner(aTHX_ WARN_SYNTAX, "Misplaced _ in number");
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX), "Misplaced _ in number");
}
/* read a decimal portion if there is one. avoid
if (*s == '_') {
if (ckWARN(WARN_SYNTAX))
- Perl_warner(aTHX_ WARN_SYNTAX,
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
"Misplaced _ in number");
lastub = s;
}
Perl_croak(aTHX_ number_too_long);
if (*s == '_') {
if (ckWARN(WARN_SYNTAX) && lastub && s == lastub + 1)
- Perl_warner(aTHX_ WARN_SYNTAX,
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
"Misplaced _ in number");
lastub = s;
}
/* fractional part ending in underbar? */
if (s[-1] == '_') {
if (ckWARN(WARN_SYNTAX))
- Perl_warner(aTHX_ WARN_SYNTAX,
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
"Misplaced _ in number");
}
if (*s == '.' && isDIGIT(s[1])) {
/* oops, it's really a v-string, but without the "v" */
- s = start - 1;
+ s = start;
goto vstring;
}
}
/* stray preinitial _ */
if (*s == '_') {
if (ckWARN(WARN_SYNTAX))
- Perl_warner(aTHX_ WARN_SYNTAX,
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
"Misplaced _ in number");
lastub = s++;
}
/* stray initial _ */
if (*s == '_') {
if (ckWARN(WARN_SYNTAX))
- Perl_warner(aTHX_ WARN_SYNTAX,
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
"Misplaced _ in number");
lastub = s++;
}
if (ckWARN(WARN_SYNTAX) &&
((lastub && s == lastub + 1) ||
(!isDIGIT(s[1]) && s[1] != '_')))
- Perl_warner(aTHX_ WARN_SYNTAX,
+ Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
"Misplaced _ in number");
lastub = s++;
}
/* if it starts with a v, it could be a v-string */
case 'v':
vstring:
- {
- char *pos = s;
- pos++;
- while (isDIGIT(*pos) || *pos == '_')
- pos++;
- if (!isALPHA(*pos)) {
- UV rev;
- U8 tmpbuf[UTF8_MAXLEN+1];
- U8 *tmpend;
- s++; /* get past 'v' */
-
- sv = NEWSV(92,5);
- sv_setpvn(sv, "", 0);
-
- for (;;) {
- if (*s == '0' && isDIGIT(s[1]))
- yyerror("Octal number in vector unsupported");
- rev = 0;
- {
- /* this is atoi() that tolerates underscores */
- char *end = pos;
- UV mult = 1;
- while (--end >= s) {
- UV orev;
- if (*end == '_')
- continue;
- orev = rev;
- rev += (*end - '0') * mult;
- mult *= 10;
- if (orev > rev && ckWARN_d(WARN_OVERFLOW))
- Perl_warner(aTHX_ WARN_OVERFLOW,
- "Integer overflow in decimal number");
- }
- }
- /* Append native character for the rev point */
- tmpend = uvchr_to_utf8(tmpbuf, rev);
- sv_catpvn(sv, (const char*)tmpbuf, tmpend - tmpbuf);
- if (!UNI_IS_INVARIANT(NATIVE_TO_UNI(rev)))
- SvUTF8_on(sv);
- if (*pos == '.' && isDIGIT(pos[1]))
- s = ++pos;
- else {
- s = pos;
- break;
- }
- while (isDIGIT(*pos) || *pos == '_')
- pos++;
- }
- SvPOK_on(sv);
- SvREADONLY_on(sv);
- }
- }
+ sv = NEWSV(92,5); /* preallocate storage space */
+ s = new_vstring(s,sv);
break;
}
}
msg = sv_2mortal(newSVpv(s, 0));
Perl_sv_catpvf(aTHX_ msg, " at %s line %"IVdf", ",
- CopFILE(PL_curcop), (IV)CopLINE(PL_curcop));
+ OutCopFILE(PL_curcop), (IV)CopLINE(PL_curcop));
if (context)
Perl_sv_catpvf(aTHX_ msg, "near \"%.*s\"\n", contlen, context);
else
if (PL_error_count >= 10) {
if (PL_in_eval && SvCUR(ERRSV))
Perl_croak(aTHX_ "%"SVf"%s has too many errors.\n",
- ERRSV, CopFILE(PL_curcop));
+ ERRSV, OutCopFILE(PL_curcop));
else
Perl_croak(aTHX_ "%s has too many errors.\n",
- CopFILE(PL_curcop));
+ OutCopFILE(PL_curcop));
}
PL_in_my = 0;
PL_in_my_stash = Nullhv;