v-strings as Objects Step 1
John Peacock [Thu, 15 Nov 2001 12:41:04 +0000 (07:41 -0500)]
Message-ID: <3BF3FE30.70D7EDCA@rowman.com>

p4raw-id: //depot/perl@13028

embed.h
embed.pl
global.sym
pod/perlapi.pod
proto.h
toke.c
util.c

diff --git a/embed.h b/embed.h
index a3d430e..f8c8abb 100644 (file)
--- a/embed.h
+++ b/embed.h
 #define newUNOP                        Perl_newUNOP
 #define newWHILEOP             Perl_newWHILEOP
 #define new_stackinfo          Perl_new_stackinfo
+#define new_vstring            Perl_new_vstring
 #define nextargv               Perl_nextargv
 #define ninstr                 Perl_ninstr
 #define oopsCV                 Perl_oopsCV
 #define newUNOP(a,b,c)         Perl_newUNOP(aTHX_ a,b,c)
 #define newWHILEOP(a,b,c,d,e,f,g)      Perl_newWHILEOP(aTHX_ a,b,c,d,e,f,g)
 #define new_stackinfo(a,b)     Perl_new_stackinfo(aTHX_ a,b)
+#define new_vstring(a,b)       Perl_new_vstring(aTHX_ a,b)
 #define nextargv(a)            Perl_nextargv(aTHX_ a)
 #define ninstr(a,b,c,d)                Perl_ninstr(aTHX_ a,b,c,d)
 #define oopsCV(a)              Perl_oopsCV(aTHX_ a)
index 25b3946..de6df26 100755 (executable)
--- a/embed.pl
+++ b/embed.pl
@@ -1573,6 +1573,7 @@ Ap        |OP*    |newWHILEOP     |I32 flags|I32 debuggable|LOOP* loop \
                                |I32 whileline|OP* expr|OP* block|OP* cont
 
 Ap     |PERL_SI*|new_stackinfo|I32 stitems|I32 cxitems
+Apd    |char*  |new_vstring    |char *vstr|SV *sv
 p      |PerlIO*|nextargv       |GV* gv
 Ap     |char*  |ninstr         |const char* big|const char* bigend \
                                |const char* little|const char* lend
index 1130326..5d0372f 100644 (file)
@@ -302,6 +302,7 @@ Perl_newSVsv
 Perl_newUNOP
 Perl_newWHILEOP
 Perl_new_stackinfo
+Perl_new_vstring
 Perl_ninstr
 Perl_op_free
 Perl_pad_sv
index fb6d0a6..ef4ab30 100644 (file)
@@ -794,7 +794,7 @@ Found in file cop.h
 =item HEf_SVKEY
 
 This flag, used in the length slot of hash entries and magic structures,
-specifies the structure contains a C<SV*> pointer where a C<char*> pointer
+specifies the structure contains an C<SV*> pointer where a C<char*> pointer
 is to be expected. (For information only--not to be used).
 
 =for hackers
@@ -958,7 +958,7 @@ Found in file hv.c
 Returns the SV which corresponds to the specified key in the hash.  The
 C<klen> is the length of the key.  If C<lval> is set then the fetch will be
 part of a store.  Check that the return value is non-null before
-dereferencing it to a C<SV*>.
+dereferencing it to an C<SV*>.
 
 See L<perlguts/"Understanding the Magic of Tied Hashes and Arrays"> for more
 information on how to use this function on tied hashes.
@@ -1553,6 +1553,24 @@ memory is zeroed with C<memzero>.
 =for hackers
 Found in file handy.h
 
+=item new_vstring
+
+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 = new_vstring(s,sv);
+
+The sv must already be large enough to store the vstring
+passed in.
+
+       char*   new_vstring(char *vstr, SV *sv)
+
+=for hackers
+Found in file util.c
+
 =item Nullav
 
 Null AV pointer.
@@ -2220,7 +2238,7 @@ Found in file sv.h
 
 =item SvIOK_notUV
 
-Returns a boolean indicating whether the SV contains an signed integer.
+Returns a boolean indicating whether the SV contains a signed integer.
 
        void    SvIOK_notUV(SV* sv)
 
@@ -2282,22 +2300,22 @@ version which guarantees to evaluate sv only once.
 =for hackers
 Found in file sv.h
 
-=item SvIVx
+=item SvIVX
 
-Coerces the given SV to an integer and returns it. Guarantees to evaluate
-sv only once. Use the more efficient C<SvIV> otherwise.
+Returns the raw value in the SV's IV slot, without checks or conversions.
+Only use when you are sure SvIOK is true. See also C<SvIV()>.
 
-       IV      SvIVx(SV* sv)
+       IV      SvIVX(SV* sv)
 
 =for hackers
 Found in file sv.h
 
-=item SvIVX
+=item SvIVx
 
-Returns the raw value in the SV's IV slot, without checks or conversions.
-Only use when you are sure SvIOK is true. See also C<SvIV()>.
+Coerces the given SV to an integer and returns it. Guarantees to evaluate
+sv only once. Use the more efficient C<SvIV> otherwise.
 
-       IV      SvIVX(SV* sv)
+       IV      SvIVx(SV* sv)
 
 =for hackers
 Found in file sv.h
@@ -2397,22 +2415,22 @@ which guarantees to evaluate sv only once.
 =for hackers
 Found in file sv.h
 
-=item SvNVX
+=item SvNVx
 
-Returns the raw value in the SV's NV slot, without checks or conversions.
-Only use when you are sure SvNOK is true. See also C<SvNV()>.
+Coerces the given SV to a double and returns it. Guarantees to evaluate
+sv only once. Use the more efficient C<SvNV> otherwise.
 
-       NV      SvNVX(SV* sv)
+       NV      SvNVx(SV* sv)
 
 =for hackers
 Found in file sv.h
 
-=item SvNVx
+=item SvNVX
 
-Coerces the given SV to a double and returns it. Guarantees to evaluate
-sv only once. Use the more efficient C<SvNV> otherwise.
+Returns the raw value in the SV's NV slot, without checks or conversions.
+Only use when you are sure SvNOK is true. See also C<SvNV()>.
 
-       NV      SvNVx(SV* sv)
+       NV      SvNVX(SV* sv)
 
 =for hackers
 Found in file sv.h
@@ -4521,7 +4539,7 @@ Found in file XSUB.h
 
 =item XSRETURN_NV
 
-Return an double from an XSUB immediately.  Uses C<XST_mNV>.
+Return a double from an XSUB immediately.  Uses C<XST_mNV>.
 
        void    XSRETURN_NV(NV nv)
 
diff --git a/proto.h b/proto.h
index 80b2c2c..01d30a4 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -561,6 +561,7 @@ PERL_CALLCONV OP*   Perl_newUNOP(pTHX_ I32 type, I32 flags, OP* first);
 PERL_CALLCONV OP*      Perl_newWHILEOP(pTHX_ I32 flags, I32 debuggable, LOOP* loop, I32 whileline, OP* expr, OP* block, OP* cont);
 
 PERL_CALLCONV PERL_SI* Perl_new_stackinfo(pTHX_ I32 stitems, I32 cxitems);
+PERL_CALLCONV char*    Perl_new_vstring(pTHX_ char *vstr, SV *sv);
 PERL_CALLCONV PerlIO*  Perl_nextargv(pTHX_ GV* gv);
 PERL_CALLCONV char*    Perl_ninstr(pTHX_ const char* big, const char* bigend, const char* little, const char* lend);
 PERL_CALLCONV OP*      Perl_oopsCV(pTHX_ OP* o);
diff --git a/toke.c b/toke.c
index 64ef174..d9e7248 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -7222,7 +7222,7 @@ Perl_scan_num(pTHX_ char *start, YYSTYPE* lvalp)
            }
            if (*s == '.' && isDIGIT(s[1])) {
                /* oops, it's really a v-string, but without the "v" */
-               s = start - 1;
+               s = start;
                goto vstring;
            }
        }
@@ -7316,58 +7316,8 @@ Perl_scan_num(pTHX_ char *start, YYSTYPE* lvalp)
     /* if it starts with a v, it could be a v-string */
     case 'v':
 vstring:
-       {
-           char *pos = s;
-           pos++;
-           while (isDIGIT(*pos) || *pos == '_')
-               pos++;
-           if (!isALPHA(*pos)) {
-               UV rev;
-               U8 tmpbuf[UTF8_MAXLEN+1];
-               U8 *tmpend;
-               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");
-                       }
-                   }
-                   /* 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);
-               SvREADONLY_on(sv);
-           }
-       }
+               sv = NEWSV(92,5); /* preallocate storage space */
+               s = new_vstring(s,sv);
        break;
     }
 
diff --git a/util.c b/util.c
index 5224a55..4f3e092 100644 (file)
--- a/util.c
+++ b/util.c
@@ -3884,3 +3884,76 @@ Perl_getcwd_sv(pTHX_ register SV *sv)
 #endif
 }
 
+/*
+=for apidoc new_vstring
+
+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 = new_vstring(s,sv);
+
+The sv must already be large enough to store the vstring
+passed in.
+
+=cut
+*/
+
+char *
+Perl_new_vstring(pTHX_ char *s, SV *sv)
+{
+    char *pos = s;
+    if (*pos == 'v') pos++;  /* get past 'v' */
+    while (isDIGIT(*pos) || *pos == '_')
+    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;
+           if ( *(s-1) == '_') {
+               mult = 10;
+           }
+           while (--end >= s) {
+               UV orev;
+               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");
+           }
+           }
+           /* 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 == '.' || *pos == '_') && isDIGIT(pos[1]))
+           s = ++pos;
+           else {
+           s = pos;
+           break;
+           }
+           while (isDIGIT(*pos) )
+           pos++;
+       }
+       SvPOK_on(sv);
+       SvREADONLY_on(sv);
+    }
+    return s;
+}
+
+