Re: [ID 20010810.011] 'use v2b' not allowed with strict
Rafael Garcia-Suarez [Mon, 13 Aug 2001 22:51:59 +0000 (00:51 +0200)]
Message-ID: <20010813225159.C6681@rafael>
       (Applied with several tweaks.)

p4raw-id: //depot/perl@11966

embed.h
embed.pl
proto.h
toke.c

diff --git a/embed.h b/embed.h
index 47ae070..ebdac34 100644 (file)
--- a/embed.h
+++ b/embed.h
 #if defined(PERL_IN_TOKE_C) || defined(PERL_DECL_PROT)
 #define check_uni()            S_check_uni(aTHX)
 #define force_next(a)          S_force_next(aTHX_ a)
-#define force_version(a)       S_force_version(aTHX_ a)
+#define force_version(a,b)     S_force_version(aTHX_ a,b)
 #define force_word(a,b,c,d,e)  S_force_word(aTHX_ a,b,c,d,e)
 #define tokeq(a)               S_tokeq(aTHX_ a)
 #define pending_ident()                S_pending_ident(aTHX)
index c303c01..fa0a639 100755 (executable)
--- a/embed.pl
+++ b/embed.pl
@@ -2260,7 +2260,7 @@ s |SV*    |gv_share       |SV *sv
 #if defined(PERL_IN_TOKE_C) || defined(PERL_DECL_PROT)
 s      |void   |check_uni
 s      |void   |force_next     |I32 type
-s      |char*  |force_version  |char *start
+s      |char*  |force_version  |char *start|int guessing
 s      |char*  |force_word     |char *start|int token|int check_keyword \
                                |int allow_pack|int allow_tick
 s      |SV*    |tokeq          |SV *sv
diff --git a/proto.h b/proto.h
index 769145a..f44ecdc 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -1248,7 +1248,7 @@ STATIC SV*        S_gv_share(pTHX_ SV *sv);
 #if defined(PERL_IN_TOKE_C) || defined(PERL_DECL_PROT)
 STATIC void    S_check_uni(pTHX);
 STATIC void    S_force_next(pTHX_ I32 type);
-STATIC char*   S_force_version(pTHX_ char *start);
+STATIC char*   S_force_version(pTHX_ char *start, int guessing);
 STATIC char*   S_force_word(pTHX_ char *start, int token, int check_keyword, int allow_pack, int allow_tick);
 STATIC SV*     S_tokeq(pTHX_ SV *sv);
 STATIC int     S_pending_ident(pTHX);
diff --git a/toke.c b/toke.c
index 1d0dc7c..f0c0071 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -864,10 +864,13 @@ Perl_str_to_version(pTHX_ SV *sv)
 /*
  * S_force_version
  * Forces the next token to be a version number.
+ * If the next token appears to be an invalid version number, (e.g. "v2b"),
+ * and if "guessing" is TRUE, then no new token is created (and the caller
+ * must use an alternative parsing method).
  */
 
 STATIC char *
-S_force_version(pTHX_ char *s)
+S_force_version(pTHX_ char *s, int guessing)
 {
     OP *version = Nullop;
     char *d;
@@ -878,7 +881,8 @@ S_force_version(pTHX_ char *s)
     if (*d == 'v')
        d++;
     if (isDIGIT(*d)) {
-        for (; isDIGIT(*d) || *d == '_' || *d == '.'; d++);
+       while (isDIGIT(*d) || *d == '_' || *d == '.')
+           d++;
         if (*d == ';' || isSPACE(*d) || *d == '}' || !*d) {
            SV *ver;
             s = scan_num(s, &yylval);
@@ -890,13 +894,15 @@ S_force_version(pTHX_ char *s)
                SvNOK_on(ver);          /* hint that it is a version */
            }
         }
+       else if (guessing)
+           return s;
     }
 
     /* NOTE: The parser sees the package name and the VERSION swapped */
     PL_nextval[PL_nexttoke].opval = version;
     force_next(WORD);
 
-    return (s);
+    return s;
 }
 
 /*
@@ -4534,7 +4540,7 @@ Perl_yylex(pTHX)
            if (PL_expect != XSTATE)
                yyerror("\"no\" not allowed in expression");
            s = force_word(s,WORD,FALSE,TRUE,FALSE);
-           s = force_version(s);
+           s = force_version(s, FALSE);
            yylval.ival = 0;
            OPERATOR(USE);
 
@@ -4686,10 +4692,12 @@ Perl_yylex(pTHX)
 
        case KEY_require:
            s = skipspace(s);
-           if (isDIGIT(*s) || (*s == 'v' && isDIGIT(s[1]))) {
-               s = force_version(s);
+           if (isDIGIT(*s)) {
+               s = force_version(s, FALSE);
            }
-           else {
+           else if (*s != 'v' || !isDIGIT(s[1])
+                   || (s = force_version(s, TRUE), *s == 'v'))
+           {
                *PL_tokenbuf = '\0';
                s = force_word(s,WORD,TRUE,TRUE,FALSE);
                if (isIDFIRST_lazy_if(PL_tokenbuf,UTF))
@@ -5049,15 +5057,19 @@ Perl_yylex(pTHX)
                yyerror("\"use\" not allowed in expression");
            s = skipspace(s);
            if (isDIGIT(*s) || (*s == 'v' && isDIGIT(s[1]))) {
-               s = force_version(s);
+               s = force_version(s, TRUE);
                if (*s == ';' || (s = skipspace(s), *s == ';')) {
                    PL_nextval[PL_nexttoke].opval = Nullop;
                    force_next(WORD);
                }
+               else if (*s == 'v') {
+                   s = force_word(s,WORD,FALSE,TRUE,FALSE);
+                   s = force_version(s, FALSE);
+               }
            }
            else {
                s = force_word(s,WORD,FALSE,TRUE,FALSE);
-               s = force_version(s);
+               s = force_version(s, FALSE);
            }
            yylval.ival = 1;
            OPERATOR(USE);