New shiny models
[p5sagit/p5-mst-13.2.git] / toke.c
diff --git a/toke.c b/toke.c
index b3688bb..5c24cca 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -1275,7 +1275,7 @@ S_force_word(pTHX_ register char *start, int token, int check_keyword, int allow
        (allow_initial_tick && *s == '\'') )
     {
        s = scan_word(s, PL_tokenbuf, sizeof PL_tokenbuf, allow_pack, &len);
-       if (check_keyword && keyword(PL_tokenbuf, len))
+       if (check_keyword && keyword(PL_tokenbuf, len, 0))
            return start;
        start_force(PL_curforce);
        if (PL_madskills)
@@ -1791,9 +1791,10 @@ S_scan_const(pTHX_ char *start)
 #endif
 
     const char * const leaveit = /* set of acceptably-backslashed characters */
-       PL_lex_inpat
-           ? "\\.^$@AGZdDwWsSbBpPXC+*?|()-nrtfeaxcz0123456789[{]} \t\n\r\f\v#"
-           : "";
+       (const char *)
+       (PL_lex_inpat
+        ? "\\.^$@AGZdDwWsSbBpPXC+*?|()-Nnrktfeaxcz0123456789[{]} \t\n\r\f\v#"
+        : "");
 
     if (PL_lex_inwhat == OP_TRANS && PL_sublex_info.sub_op) {
        /* If we are doing a trans and we know we want UTF8 set expectation */
@@ -2178,6 +2179,7 @@ S_scan_const(pTHX_ char *start)
                    SV *res;
                    STRLEN len;
                    const char *str;
+                   SV *type;
 
                    if (!e) {
                        yyerror("Missing right brace on \\N{}");
@@ -2191,12 +2193,17 @@ S_scan_const(pTHX_ char *start)
                        s += 3;
                        len = e - s;
                        uv = grok_hex(s, &len, &flags, NULL);
+                       if ( e > s && len != (STRLEN)(e - s) ) {
+                           uv = 0xFFFD;
+                       }
                        s = e + 1;
                        goto NUM_ESCAPE_INSERT;
                    }
                    res = newSVpvn(s + 1, e - s - 1);
+                   type = newSVpvn(s - 2,e - s + 3);
                    res = new_constant( NULL, 0, "charnames",
-                                       res, NULL, "\\N{...}" );
+                                       res, NULL, SvPVX(type) );
+                   SvREFCNT_dec(type);         
                    if (has_utf8)
                        sv_utf8_upgrade(res);
                    str = SvPV_const(res,len);
@@ -2352,13 +2359,15 @@ S_scan_const(pTHX_ char *start)
     /* return the substring (via yylval) only if we parsed anything */
     if (s > PL_bufptr) {
        if ( PL_hints & ( PL_lex_inpat ? HINT_NEW_RE : HINT_NEW_STRING ) )
-           sv = new_constant(start, s - start, (PL_lex_inpat ? "qr" : "q"),
+           sv = new_constant(start, s - start,
+                             (const char *)(PL_lex_inpat ? "qr" : "q"),
                              sv, NULL,
-                             ( PL_lex_inwhat == OP_TRANS
-                               ? "tr"
-                               : ( (PL_lex_inwhat == OP_SUBST && !PL_lex_inpat)
-                                   ? "s"
-                                   : "qq")));
+                             (const char *)
+                             (( PL_lex_inwhat == OP_TRANS
+                                ? "tr"
+                                : ( (PL_lex_inwhat == OP_SUBST && !PL_lex_inpat)
+                                    ? "s"
+                                    : "qq"))));
        yylval.opval = (OP*)newSVOP(OP_CONST, 0, sv);
     } else
        SvREFCNT_dec(sv);
@@ -2473,7 +2482,7 @@ S_intuit_more(pTHX_ register char *s)
                if (s[1]) {
                    if (strchr("wds]",s[1]))
                        weight += 100;
-                   else if (seen['\''] || seen['"'])
+                   else if (seen[(U8)'\''] || seen[(U8)'"'])
                        weight += 1;
                    else if (strchr("rnftbxcav",s[1]))
                        weight += 40;
@@ -2505,7 +2514,7 @@ S_intuit_more(pTHX_ register char *s)
                    while (isALPHA(*s))
                        *d++ = *s++;
                    *d = '\0';
-                   if (keyword(tmpbuf, d - tmpbuf))
+                   if (keyword(tmpbuf, d - tmpbuf, 0))
                        weight -= 150;
                }
                if (un_char == last_un_char + 1)
@@ -2584,14 +2593,14 @@ S_intuit_method(pTHX_ char *start, GV *gv, CV *cv)
        len = start - SvPVX(PL_linestr);
 #endif
        s = PEEKSPACE(s);
-#ifdef PERLMAD
+#ifdef PERL_MAD
        start = SvPVX(PL_linestr) + len;
 #endif
        PL_bufptr = start;
        PL_expect = XREF;
        return *s == '(' ? FUNCMETH : METHOD;
     }
-    if (!keyword(tmpbuf, len)) {
+    if (!keyword(tmpbuf, len, 0)) {
        if (len > 2 && tmpbuf[len - 2] == ':' && tmpbuf[len - 1] == ':') {
            len -= 2;
            tmpbuf[len] = '\0';
@@ -3095,6 +3104,13 @@ Perl_yylex(pTHX)
     STRLEN len;
     bool bof = FALSE;
 
+    /* orig_keyword, gvp, and gv are initialized here because
+     * jump to the label just_a_word_zero can bypass their
+     * initialization later. */
+    I32 orig_keyword = 0;
+    GV *gv = NULL;
+    GV **gvp = NULL;
+
     DEBUG_T( {
        SV* tmp = newSVpvs("");
        PerlIO_printf(Perl_debug_log, "### %"IVdf":LEX_%s/X%s %s\n",
@@ -3432,9 +3448,10 @@ Perl_yylex(pTHX)
            PL_last_uni = 0;
            PL_last_lop = 0;
            if (PL_lex_brackets) {
-               yyerror(PL_lex_formbrack
-                   ? "Format not terminated"
-                   : "Missing right curly or square bracket");
+               yyerror((const char *)
+                       (PL_lex_formbrack
+                        ? "Format not terminated"
+                        : "Missing right curly or square bracket"));
            }
             DEBUG_T( { PerlIO_printf(Perl_debug_log,
                         "### Tokener got EOF\n");
@@ -3534,8 +3551,10 @@ Perl_yylex(pTHX)
                    if (PL_madskills)
                        PL_faketokens = 1;
 #endif
-                   sv_setpv(PL_linestr,PL_minus_p
-                            ? ";}continue{print;}" : ";}");
+                   sv_setpv(PL_linestr,
+                            (const char *)
+                            (PL_minus_p
+                             ? ";}continue{print;}" : ";}"));
                    PL_oldoldbufptr = PL_oldbufptr = s = PL_linestart = SvPVX(PL_linestr);
                    PL_bufend = SvPVX(PL_linestr) + SvCUR(PL_linestr);
                    PL_last_lop = PL_last_uni = NULL;
@@ -4097,7 +4116,7 @@ Perl_yylex(pTHX)
                I32 tmp;
                SV *sv;
                d = scan_word(s, PL_tokenbuf, sizeof PL_tokenbuf, FALSE, &len);
-               if (isLOWER(*s) && (tmp = keyword(PL_tokenbuf, len))) {
+               if (isLOWER(*s) && (tmp = keyword(PL_tokenbuf, len, 0))) {
                    if (tmp < 0) tmp = -tmp;
                    switch (tmp) {
                    case KEY_or:
@@ -4206,10 +4225,11 @@ Perl_yylex(pTHX)
                       context messages from yyerror().
                    */
                    PL_bufptr = s;
-                   yyerror( *s
-                            ? Perl_form(aTHX_ "Invalid separator character "
-                                        "%c%c%c in attribute list", q, *s, q)
-                            : "Unterminated attribute list" );
+                   yyerror( (const char *)
+                            (*s
+                             ? Perl_form(aTHX_ "Invalid separator character "
+                                         "%c%c%c in attribute list", q, *s, q)
+                             : "Unterminated attribute list" ) );
                    if (attrs)
                        op_free(attrs);
                    OPERATOR(':');
@@ -4742,7 +4762,7 @@ Perl_yylex(pTHX)
                    char tmpbuf[sizeof PL_tokenbuf];
                    int t2;
                    scan_word(s, tmpbuf, sizeof tmpbuf, TRUE, &len);
-                   if ((t2 = keyword(tmpbuf, len))) {
+                   if ((t2 = keyword(tmpbuf, len, 0))) {
                        /* binary operators exclude handle interpretations */
                        switch (t2) {
                        case -KEY_x:
@@ -5015,9 +5035,10 @@ Perl_yylex(pTHX)
 
       keylookup: {
        I32 tmp;
-       I32 orig_keyword = 0;
-       GV *gv = NULL;
-       GV **gvp = NULL;
+
+       orig_keyword = 0;
+       gv = NULL;
+       gvp = NULL;
 
        PL_bufptr = s;
        s = scan_word(s, PL_tokenbuf, sizeof PL_tokenbuf, FALSE, &len);
@@ -5046,7 +5067,7 @@ Perl_yylex(pTHX)
        }
 
        /* Check for keywords */
-       tmp = keyword(PL_tokenbuf, len);
+       tmp = keyword(PL_tokenbuf, len, 0);
 
        /* Is this a word before a => operator? */
        if (*d == '=' && d[1] == '>') {
@@ -5394,8 +5415,10 @@ Perl_yylex(pTHX)
                        while (*proto == ';')
                            proto++;
                        if (*proto == '&' && *s == '{') {
-                           sv_setpv(PL_subname, PL_curstash ?
-                                       "__ANON__" : "__ANON__::__ANON__");
+                           sv_setpv(PL_subname,
+                                    (const char *)
+                                    (PL_curstash ?
+                                     "__ANON__" : "__ANON__::__ANON__"));
                            PREBLOCK(LSTOPSUB);
                        }
                    }
@@ -5428,7 +5451,7 @@ Perl_yylex(pTHX)
                        STRLEN tmplen;
                        d = s;
                        d = scan_word(d, tmpbuf, sizeof tmpbuf, TRUE, &tmplen);
-                       if (!keyword(tmpbuf,tmplen))
+                       if (!keyword(tmpbuf, tmplen, 0))
                            probable_sub = 1;
                        else {
                            while (d < PL_bufend && isSPACE(*d))
@@ -5628,7 +5651,7 @@ Perl_yylex(pTHX)
                s += 2;
                d = s;
                s = scan_word(s, PL_tokenbuf, sizeof PL_tokenbuf, FALSE, &len);
-               if (!(tmp = keyword(PL_tokenbuf, len)))
+               if (!(tmp = keyword(PL_tokenbuf, len, 0)))
                    Perl_croak(aTHX_ "CORE::%s is not a keyword", PL_tokenbuf);
                if (tmp < 0)
                    tmp = -tmp;
@@ -6623,7 +6646,8 @@ Perl_yylex(pTHX)
 #endif
                if (!have_name) {
                    sv_setpv(PL_subname,
-                       PL_curstash ? "__ANON__" : "__ANON__::__ANON__");
+                            (const char *)
+                            (PL_curstash ? "__ANON__" : "__ANON__::__ANON__"));
                    TOKEN(ANONSUB);
                }
 #ifndef PERL_MAD
@@ -6929,7 +6953,7 @@ S_pending_ident(pTHX)
  */
 
 I32
-Perl_keyword (pTHX_ const char *name, I32 len)
+Perl_keyword (pTHX_ const char *name, I32 len, bool all_keywords)
 {
     dVAR;
   switch (len)
@@ -7201,7 +7225,7 @@ Perl_keyword (pTHX_ const char *name, I32 len)
             case 'r':
               if (name[2] == 'r')
               {                                   /* err        */
-                return (FEATURE_IS_ENABLED("err") ? -KEY_err : 0);
+                return (all_keywords || FEATURE_IS_ENABLED("err") ? -KEY_err : 0);
               }
 
               goto unknown;
@@ -7340,7 +7364,7 @@ Perl_keyword (pTHX_ const char *name, I32 len)
             case 'a':
               if (name[2] == 'y')
               {                                   /* say        */
-                return (FEATURE_IS_ENABLED("say") ? -KEY_say : 0);
+                return (all_keywords || FEATURE_IS_ENABLED("say") ? -KEY_say : 0);
               }
 
               goto unknown;
@@ -7864,7 +7888,7 @@ Perl_keyword (pTHX_ const char *name, I32 len)
               if (name[2] == 'e' &&
                   name[3] == 'n')
               {                                   /* when       */
-                return (FEATURE_IS_ENABLED("switch") ? KEY_when : 0);
+                return (all_keywords || FEATURE_IS_ENABLED("switch") ? KEY_when : 0);
               }
 
               goto unknown;
@@ -7947,7 +7971,7 @@ Perl_keyword (pTHX_ const char *name, I32 len)
                   name[3] == 'a' &&
                   name[4] == 'k')
               {                                   /* break      */
-                return (FEATURE_IS_ENABLED("switch") ? -KEY_break : 0);
+                return (all_keywords || FEATURE_IS_ENABLED("switch") ? -KEY_break : 0);
               }
 
               goto unknown;
@@ -8075,7 +8099,7 @@ Perl_keyword (pTHX_ const char *name, I32 len)
               name[3] == 'e' &&
               name[4] == 'n')
           {                                       /* given      */
-            return (FEATURE_IS_ENABLED("switch") ? KEY_given : 0);
+            return (all_keywords || FEATURE_IS_ENABLED("switch") ? KEY_given : 0);
           }
 
           goto unknown;
@@ -8243,7 +8267,7 @@ Perl_keyword (pTHX_ const char *name, I32 len)
                   if (name[3] == 't' &&
                       name[4] == 'e')
                   {                               /* state      */
-                    return (FEATURE_IS_ENABLED("state") ? KEY_state : 0);
+                    return (all_keywords || FEATURE_IS_ENABLED("state") ? KEY_state : 0);
                   }
 
                   goto unknown;
@@ -8911,7 +8935,7 @@ Perl_keyword (pTHX_ const char *name, I32 len)
                         name[5] == 'l' &&
                         name[6] == 't')
                     {                             /* default    */
-                      return (FEATURE_IS_ENABLED("switch") ? KEY_default : 0);
+                      return (all_keywords || FEATURE_IS_ENABLED("switch") ? KEY_default : 0);
                     }
 
                     goto unknown;
@@ -10344,7 +10368,7 @@ S_checkcomma(pTHX_ const char *s, const char *name, const char *what)
            s++;
        if (*s == ',') {
            GV* gv;
-           if (keyword(w, s - w))
+           if (keyword(w, s - w, 0))
                return;
 
            gv = gv_fetchpvn_flags(w, s - w, 0, SVt_PVCV);
@@ -10374,9 +10398,10 @@ S_new_constant(pTHX_ const char *s, STRLEN len, const char *key, SV *sv, SV *pv,
     if (!table || !(PL_hints & HINT_LOCALIZE_HH)) {
        SV *msg;
        
-       why2 = strEQ(key,"charnames")
-              ? "(possibly a missing \"use charnames ...\")"
-              : "";
+       why2 = (const char *)
+           (strEQ(key,"charnames")
+            ? "(possibly a missing \"use charnames ...\")"
+            : "");
        msg = Perl_newSVpvf(aTHX_ "Constant(%s) unknown: %s",
                            (type ? type: "undef"), why2);
 
@@ -10603,8 +10628,10 @@ S_scan_ident(pTHX_ register char *s, register const char *send, char *dest, STRL
            while (s < send && SPACE_OR_TAB(*s))
                s++;
            if ((*s == '[' || (*s == '{' && strNE(dest, "sub")))) {
-               if (ckWARN(WARN_AMBIGUOUS) && keyword(dest, d - dest)) {
-                   const char * const brack = (*s == '[') ? "[...]" : "{...}";
+               if (ckWARN(WARN_AMBIGUOUS) && keyword(dest, d - dest, 0)) {
+                   const char * const brack =
+                       (const char *)
+                       ((*s == '[') ? "[...]" : "{...}");
                    Perl_warner(aTHX_ packWARN(WARN_AMBIGUOUS),
                        "Ambiguous use of %c{%s%s} resolved to %c%s%s",
                        funny, dest, brack, funny, dest, brack);
@@ -10635,7 +10662,7 @@ S_scan_ident(pTHX_ register char *s, register const char *send, char *dest, STRL
            }
            if (PL_lex_state == LEX_NORMAL) {
                if (ckWARN(WARN_AMBIGUOUS) &&
-                   (keyword(dest, d - dest) || get_cv(dest, FALSE)))
+                   (keyword(dest, d - dest, 0) || get_cv(dest, FALSE)))
                {
                    if (funny == '#')
                        funny = '@';
@@ -10681,7 +10708,8 @@ S_scan_pat(pTHX_ char *start, I32 type)
     dVAR;
     PMOP *pm;
     char *s = scan_str(start,!!PL_madskills,FALSE);
-    const char * const valid_flags = (type == OP_QR) ? "iomsx" : "iogcmsx";
+    const char * const valid_flags =
+       (const char *)((type == OP_QR) ? "iomsx" : "iogcmsx");
 #ifdef PERL_MAD
     char *modstart;
 #endif
@@ -10689,9 +10717,11 @@ S_scan_pat(pTHX_ char *start, I32 type)
 
     if (!s) {
        const char * const delimiter = skipspace(start);
-       Perl_croak(aTHX_ *delimiter == '?'
-                  ? "Search pattern not terminated or ternary operator parsed as search pattern"
-                  : "Search pattern not terminated" );
+       Perl_croak(aTHX_
+                  (const char *)
+                  (*delimiter == '?'
+                   ? "Search pattern not terminated or ternary operator parsed as search pattern"
+                   : "Search pattern not terminated" ));
     }
 
     pm = (PMOP*)newPMOP(type, 0);
@@ -10806,7 +10836,7 @@ S_scan_subst(pTHX_ char *start)
        PL_multi_end = 0;
        pm->op_pmflags |= PMf_EVAL;
        while (es-- > 0)
-           sv_catpv(repl, es ? "eval " : "do ");
+           sv_catpv(repl, (const char *)(es ? "eval " : "do "));
        sv_catpvs(repl, "{");
        sv_catsv(repl, PL_lex_repl);
        if (strchr(SvPVX(PL_lex_repl), '#'))
@@ -11004,7 +11034,7 @@ S_scan_heredoc(pTHX_ register char *s)
 #ifdef PERL_MAD
     found_newline = 0;
 #endif
-    if ( outer || !(found_newline = memchr(s, '\n', PL_bufend - s)) ) {
+    if ( outer || !(found_newline = (char*)memchr((void*)s, '\n', PL_bufend - s)) ) {
         herewas = newSVpvn(s,PL_bufend-s);
     }
     else {
@@ -11390,7 +11420,7 @@ S_scan_str(pTHX_ char *start, int keep_quoted, int keep_delims)
 {
     dVAR;
     SV *sv;                            /* scalar value: string */
-    char *tmps;                                /* temp string, used for delimiter matching */
+    const char *tmps;                  /* temp string, used for delimiter matching */
     register char *s = start;          /* current position in the buffer */
     register char term;                        /* terminating character */
     register char *to;                 /* current position in the sv's data */
@@ -12100,7 +12130,9 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
 
        if ( floatit ? (PL_hints & HINT_NEW_FLOAT) :
                       (PL_hints & HINT_NEW_INTEGER) )
-           sv = new_constant(PL_tokenbuf, d - PL_tokenbuf,
+           sv = new_constant(PL_tokenbuf,
+                             d - PL_tokenbuf,
+                             (const char *)
                              (floatit ? "float" : "integer"),
                              sv, NULL, NULL);
        break;