+
+ /* if it starts with a v, it could be a version number */
+ case 'v':
+vstring:
+ {
+ char *pos = s;
+ pos++;
+ while (isDIGIT(*pos) || *pos == '_')
+ pos++;
+ if (!isALPHA(*pos)) {
+ UV rev;
+ U8 tmpbuf[UTF8_MAXLEN];
+ U8 *tmpend;
+ bool utf8 = FALSE;
+ 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");
+ }
+ }
+ tmpend = uv_to_utf8(tmpbuf, rev);
+ utf8 = utf8 || rev > 127;
+ sv_catpvn(sv, (const char*)tmpbuf, tmpend - tmpbuf);
+ if (*pos == '.' && isDIGIT(pos[1]))
+ s = ++pos;
+ else {
+ s = pos;
+ break;
+ }
+ while (isDIGIT(*pos) || *pos == '_')
+ pos++;
+ }
+
+ SvPOK_on(sv);
+ SvREADONLY_on(sv);
+ if (utf8) {
+ SvUTF8_on(sv);
+ sv_utf8_downgrade(sv, TRUE);
+ }
+ }
+ }
+ break;