This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
mktables: Add comment
[perl5.git] / toke.c
diff --git a/toke.c b/toke.c
index 2f395d4..8fb6164 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -595,31 +595,30 @@ S_missingterm(pTHX_ char *s)
     Perl_croak(aTHX_ "Can't find string terminator %c%s%c anywhere before EOF",q,s,q);
 }
 
+#include "feature.h"
+
 /*
  * Check whether the named feature is enabled.
  */
 bool
-Perl_feature_is_enabled(pTHX_ const char *const name, STRLEN namelen,
-                             bool negate)
+Perl_feature_is_enabled(pTHX_ const char *const name, STRLEN namelen)
 {
     dVAR;
     char he_name[8 + MAX_FEATURE_LEN] = "feature_";
 
     PERL_ARGS_ASSERT_FEATURE_IS_ENABLED;
 
+    assert(CURRENT_FEATURE_BUNDLE == FEATURE_BUNDLE_CUSTOM);
+
     if (namelen > MAX_FEATURE_LEN)
        return FALSE;
-    if (negate) he_name[8] = 'n', he_name[9] = 'o';
-    memcpy(&he_name[8 + 2*negate], name, namelen);
+    memcpy(&he_name[8], name, namelen);
 
     return
-       (
-           cop_hints_fetch_pvn(
-               PL_curcop, he_name, 8 + 2*negate + namelen, 0, 0
-           )
-           != &PL_sv_placeholder
-       )
-       != negate;
+       cop_hints_fetch_pvn(
+           PL_curcop, he_name, 8 + namelen, 0,
+           REFCOUNTED_HE_EXISTS
+       );
 }
 
 /*
@@ -2193,11 +2192,13 @@ S_force_version(pTHX_ char *s, int guessing)
         if (*d == ';' || isSPACE(*d) || *d == '{' || *d == '}' || !*d) {
            SV *ver;
 #ifdef USE_LOCALE_NUMERIC
-           char *loc = setlocale(LC_NUMERIC, "C");
+           char *loc = savepv(setlocale(LC_NUMERIC, NULL));
+           setlocale(LC_NUMERIC, "C");
 #endif
             s = scan_num(s, &pl_yylval);
 #ifdef USE_LOCALE_NUMERIC
            setlocale(LC_NUMERIC, loc);
+           Safefree(loc);
 #endif
             version = pl_yylval.opval;
            ver = cSVOPx(version)->op_sv;
@@ -6238,6 +6239,7 @@ Perl_yylex(pTHX)
                    if (*t == '}' || *t == ']') {
                        t++;
                        PL_bufptr = PEEKSPACE(PL_bufptr); /* XXX can realloc */
+       /* diag_listed_as: Scalar value @%s[%s] better written as $%s[%s] */
                        Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
                            "Scalar value %.*s better written as $%.*s",
                            (int)(t-PL_bufptr), PL_bufptr,
@@ -7680,6 +7682,7 @@ Perl_yylex(pTHX)
                if ( *t && strchr("|&*+-=!?:.", *t) && ckWARN_d(WARN_PRECEDENCE)
                    /* [perl #16184] */
                    && !(t[0] == '=' && t[1] == '>')
+                   && !(t[0] == ':' && t[1] == ':')
                    && !keyword(s, d-s, 0)
                ) {
                    int parms_len = (int)(d-s);
@@ -8608,7 +8611,7 @@ S_new_constant(pTHX_ const char *s, STRLEN len, const char *key, STRLEN keylen,
               SV *sv, SV *pv, const char *type, STRLEN typelen)
 {
     dVAR; dSP;
-    HV * const table = GvHV(PL_hintgv);                 /* ^H */
+    HV * table = GvHV(PL_hintgv);               /* ^H */
     SV *res;
     SV **cvp;
     SV *cv, *typesv;
@@ -8616,43 +8619,57 @@ S_new_constant(pTHX_ const char *s, STRLEN len, const char *key, STRLEN keylen,
 
     PERL_ARGS_ASSERT_NEW_CONSTANT;
 
-    if (!table || !(PL_hints & HINT_LOCALIZE_HH)) {
+    /* charnames doesn't work well if there have been errors found */
+    if (PL_error_count > 0 && strEQ(key,"charnames"))
+       return &PL_sv_undef;
+
+    if (!table
+       || ! (PL_hints & HINT_LOCALIZE_HH)
+       || ! (cvp = hv_fetch(table, key, keylen, FALSE))
+       || ! SvOK(*cvp))
+    {
        SV *msg;
        
-       why2 = (const char *)
-           (strEQ(key,"charnames")
-            ? "(possibly a missing \"use charnames ...\")"
-            : "");
-       msg = Perl_newSVpvf(aTHX_ "Constant(%s) unknown: %s",
-                           (type ? type: "undef"), why2);
-
-       /* This is convoluted and evil ("goto considered harmful")
-        * but I do not understand the intricacies of all the different
-        * failure modes of %^H in here.  The goal here is to make
-        * the most probable error message user-friendly. --jhi */
-
-       goto msgdone;
-
+       /* Here haven't found what we're looking for.  If it is charnames,
+        * perhaps it needs to be loaded.  Try doing that before giving up */
+       if (strEQ(key,"charnames")) {
+           Perl_load_module(aTHX_
+                           0,
+                           newSVpvs("_charnames"),
+                            /* version parameter; no need to specify it, as if
+                             * we get too early a version, will fail anyway,
+                             * not being able to find '_charnames' */
+                           NULL,
+                           newSVpvs(":full"),
+                           newSVpvs(":short"),
+                           NULL);
+           SPAGAIN;
+           table = GvHV(PL_hintgv);
+           if (table
+               && (PL_hints & HINT_LOCALIZE_HH)
+               && (cvp = hv_fetch(table, key, keylen, FALSE))
+               && SvOK(*cvp))
+           {
+               goto now_ok;
+           }
+       }
+       if (!table || !(PL_hints & HINT_LOCALIZE_HH)) {
+           msg = Perl_newSVpvf(aTHX_
+                           "Constant(%s) unknown", (type ? type: "undef"));
+       }
+       else {
+       why1 = "$^H{";
+       why2 = key;
+       why3 = "} is not defined";
     report:
        msg = Perl_newSVpvf(aTHX_ "Constant(%s): %s%s%s",
                            (type ? type: "undef"), why1, why2, why3);
-    msgdone:
+       }
        yyerror(SvPVX_const(msg));
        SvREFCNT_dec(msg);
        return sv;
     }
-
-    /* charnames doesn't work well if there have been errors found */
-    if (PL_error_count > 0 && strEQ(key,"charnames"))
-       return &PL_sv_undef;
-
-    cvp = hv_fetch(table, key, keylen, FALSE);
-    if (!cvp || !SvOK(*cvp)) {
-       why1 = "$^H{";
-       why2 = key;
-       why3 = "} is not defined";
-       goto report;
-    }
+now_ok:
     sv_2mortal(sv);                    /* Parent created it permanently */
     cv = *cvp;
     if (!pv && s)
@@ -8982,7 +8999,7 @@ S_pmflag(pTHX_ const char* const valid_flags, U32 * pmfl, char** s, char* charse
                    goto deprecate;
                }
                Perl_ck_warner_d(aTHX_ packWARN(WARN_AMBIGUOUS),
-                   "Ambiguous use of 's//le...' resolved as 's// le...'; Rewrite as 's//el' if you meant 'use locale rules and evaluate rhs as an expression'.  In Perl 5.16, it will be resolved the other way");
+                   "Ambiguous use of 's//le...' resolved as 's// le...'; Rewrite as 's//el' if you meant 'use locale rules and evaluate rhs as an expression'.  In Perl 5.18, it will be resolved the other way");
                return FALSE;
            }
            if (*charset) {
@@ -10807,6 +10824,7 @@ S_swallow_bom(pTHX_ U8 *s)
        if (s[1] == 0xFE) {
            /* UTF-16 little-endian? (or UTF-32LE?) */
            if (s[2] == 0 && s[3] == 0)  /* UTF-32 little-endian */
+               /* diag_listed_as: Unsupported script encoding %s */
                Perl_croak(aTHX_ "Unsupported script encoding UTF-32LE");
 #ifndef PERL_NO_UTF16_FILTER
            if (DEBUG_p_TEST || DEBUG_T_TEST) PerlIO_printf(Perl_debug_log, "UTF-16LE script encoding (BOM)\n");
@@ -10815,6 +10833,7 @@ S_swallow_bom(pTHX_ U8 *s)
                s = add_utf16_textfilter(s, TRUE);
            }
 #else
+           /* diag_listed_as: Unsupported script encoding %s */
            Perl_croak(aTHX_ "Unsupported script encoding UTF-16LE");
 #endif
        }
@@ -10828,6 +10847,7 @@ S_swallow_bom(pTHX_ U8 *s)
                s = add_utf16_textfilter(s, FALSE);
            }
 #else
+           /* diag_listed_as: Unsupported script encoding %s */
            Perl_croak(aTHX_ "Unsupported script encoding UTF-16BE");
 #endif
        }
@@ -10843,6 +10863,7 @@ S_swallow_bom(pTHX_ U8 *s)
             if (s[1] == 0) {
                  if (s[2] == 0xFE && s[3] == 0xFF) {
                       /* UTF-32 big-endian */
+                      /* diag_listed_as: Unsupported script encoding %s */
                       Perl_croak(aTHX_ "Unsupported script encoding UTF-32BE");
                  }
             }
@@ -10854,6 +10875,7 @@ S_swallow_bom(pTHX_ U8 *s)
                  if (DEBUG_p_TEST || DEBUG_T_TEST) PerlIO_printf(Perl_debug_log, "UTF-16BE script encoding (no BOM)\n");
                  s = add_utf16_textfilter(s, FALSE);
 #else
+                 /* diag_listed_as: Unsupported script encoding %s */
                  Perl_croak(aTHX_ "Unsupported script encoding UTF-16BE");
 #endif
             }
@@ -10876,6 +10898,7 @@ S_swallow_bom(pTHX_ U8 *s)
              if (DEBUG_p_TEST || DEBUG_T_TEST) PerlIO_printf(Perl_debug_log, "UTF-16LE script encoding (no BOM)\n");
              s = add_utf16_textfilter(s, TRUE);
 #else
+             /* diag_listed_as: Unsupported script encoding %s */
              Perl_croak(aTHX_ "Unsupported script encoding UTF-16LE");
 #endif
         }
@@ -11092,6 +11115,7 @@ Perl_scan_vstring(pTHX_ const char *s, const char *const e, SV *sv)
                    rev += (*end - '0') * mult;
                    mult *= 10;
                    if (orev > rev)
+                       /* diag_listed_as: Integer overflow in %s number */
                        Perl_ck_warner_d(aTHX_ packWARN(WARN_OVERFLOW),
                                         "Integer overflow in decimal number");
                }