diff options
author | John Peacock <jpeacock@rowman.com> | 2003-07-08 18:05:38 -0700 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2003-07-09 06:58:39 +0000 |
commit | f333445c29f1556015c4df0c417df8e1a742d36d (patch) | |
tree | 7e58fc16146315ff89d4c7c5d04390faa867f397 /toke.c | |
parent | 9a33f774ee40a20ac08cacf3360fea9af2b7ff5d (diff) | |
download | perl-f333445c29f1556015c4df0c417df8e1a742d36d.tar.gz |
Re: [REPATCH] was Re: [perl #16010] v-strings left of a => don't get quoted.
Message-ID: <3F0BCCD2.1020009@rowman.com>
p4raw-id: //depot/perl@20084
Diffstat (limited to 'toke.c')
-rw-r--r-- | toke.c | 87 |
1 files changed, 87 insertions, 0 deletions
@@ -7958,3 +7958,90 @@ utf16rev_textfilter(pTHX_ int idx, SV *sv, int maxlen) } #endif +/* +Returns a pointer to the next character after the parsed +vstring, as well as updating the passed in sv. + +Function must be called like + + sv = NEWSV(92,5); + s = scan_vstring(s,sv); + +The sv should already be large enough to store the vstring +passed in, for performance reasons. + +*/ + +char * +Perl_scan_vstring(pTHX_ char *s, SV *sv) +{ + char *pos = s; + char *start = s; + if (*pos == 'v') pos++; /* get past 'v' */ + while (isDIGIT(*pos) || *pos == '_') + pos++; + if ( *pos != '.') { + /* this may not be a v-string if followed by => */ + start = pos; + if (isSPACE(*start)) + start = skipspace(start); + if ( *start == '=' && start[1] == '>' ) + { + /* return string not v-string */ + sv_setpvn(sv,(char *)s,pos-s); + return pos; + } + } + + if (!isALPHA(*pos)) { + UV rev; + U8 tmpbuf[UTF8_MAXLEN+1]; + U8 *tmpend; + + if (*s == 'v') s++; /* get past 'v' */ + + sv_setpvn(sv, "", 0); + + for (;;) { + 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_ packWARN(WARN_OVERFLOW), + "Integer overflow in decimal number"); + } + } +#ifdef EBCDIC + if (rev > 0x7FFFFFFF) + Perl_croak(aTHX_ "In EBCDIC the v-string components cannot exceed 2147483647"); +#endif + /* 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); + sv_magic(sv,NULL,PERL_MAGIC_vstring,(const char*)start, pos-start); + SvRMAGICAL_on(sv); + } + return s; +} + |