prototype("CORE::recv")
[p5sagit/p5-mst-13.2.git] / sv.c
diff --git a/sv.c b/sv.c
index 75b35a8..5778adb 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -1430,12 +1430,12 @@ S_not_a_number(pTHX_ SV *sv)
 {
     char tmpbuf[64];
     char *d = tmpbuf;
-    char *s;
     char *limit = tmpbuf + sizeof(tmpbuf) - 8;
                   /* each *s can expand to 4 chars + "...\0",
                      i.e. need room for 8 chars */
 
-    for (s = SvPVX(sv); *s && d < limit; s++) {
+    char *s, *end;
+    for (s = SvPVX(sv), end = s + SvCUR(sv); s < end && d < limit; s++) {
        int ch = *s & 0xFF;
        if (ch & 128 && !isPRINT_LC(ch)) {
            *d++ = 'M';
@@ -1458,6 +1458,10 @@ S_not_a_number(pTHX_ SV *sv)
            *d++ = '\\';
            *d++ = '\\';
        }
+       else if (ch == '\0') {
+           *d++ = '\\';
+           *d++ = '0';
+       }
        else if (isPRINT_LC(ch))
            *d++ = ch;
        else {
@@ -1465,7 +1469,7 @@ S_not_a_number(pTHX_ SV *sv)
            *d++ = toCTRL(ch);
        }
     }
-    if (*s) {
+    if (s < end) {
        *d++ = '.';
        *d++ = '.';
        *d++ = '.';
@@ -2966,8 +2970,12 @@ Perl_sv_utf8_upgrade(pTHX_ register SV *sv)
     if (!sv)
        return 0;
 
-    if (!SvPOK(sv))
-       (void) SvPV_nolen(sv);
+    if (!SvPOK(sv)) {
+       STRLEN len = 0;
+       (void) sv_2pv(sv,&len);
+       if (!SvPOK(sv))
+            return len;
+    }
 
     if (SvUTF8(sv))
        return SvCUR(sv);
@@ -3817,8 +3825,9 @@ Perl_sv_chop(pTHX_ register SV *sv, register char *ptr)   /* like set but assuming
 =for apidoc sv_catpvn
 
 Concatenates the string onto the end of the string which is in the SV.  The
-C<len> indicates number of bytes to copy.  Handles 'get' magic, but not
-'set' magic.  See C<sv_catpvn_mg>.
+C<len> indicates number of bytes to copy.  If the SV has the UTF8
+status set, then the bytes appended should be valid UTF8.
+Handles 'get' magic, but not 'set' magic.  See C<sv_catpvn_mg>.
 
 =cut
 */
@@ -3916,10 +3925,10 @@ Perl_sv_catsv_mg(pTHX_ SV *dsv, register SV *ssv)
 =for apidoc sv_catpv
 
 Concatenates the string onto the end of the string which is in the SV.
-Handles 'get' magic, but not 'set' magic.  See C<sv_catpv_mg>.
+If the SV has the UTF8 status set, then the bytes appended should be
+valid UTF8.  Handles 'get' magic, but not 'set' magic.  See C<sv_catpv_mg>.
 
-=cut
-*/
+=cut */
 
 void
 Perl_sv_catpv(pTHX_ register SV *sv, register const char *ptr)
@@ -6760,12 +6769,15 @@ Perl_sv_catpvf_mg_nocontext(SV *sv, const char* pat, ...)
 /*
 =for apidoc sv_catpvf
 
-Processes its arguments like C<sprintf> and appends the formatted output
-to an SV.  Handles 'get' magic, but not 'set' magic.  C<SvSETMAGIC()> must
-typically be called after calling this function to handle 'set' magic.
+Processes its arguments like C<sprintf> and appends the formatted
+output to an SV.  If the appended data contains "wide" characters
+(including, but not limited to, SVs with a UTF-8 PV formatted with %s,
+and characters >255 formatted with %c), the original SV might get
+upgraded to UTF-8.  Handles 'get' magic, but not 'set' magic.
+C<SvSETMAGIC()> must typically be called after calling this function
+to handle 'set' magic.
 
-=cut
-*/
+=cut */
 
 void
 Perl_sv_catpvf(pTHX_ SV *sv, const char* pat, ...)
@@ -7672,8 +7684,8 @@ Perl_gp_dup(pTHX_ GP *gp)
 MAGIC *
 Perl_mg_dup(pTHX_ MAGIC *mg)
 {
-    MAGIC *mgret = (MAGIC*)NULL;
-    MAGIC *mgprev;
+    MAGIC *mgprev = (MAGIC*)NULL;
+    MAGIC *mgret;
     if (!mg)
        return (MAGIC*)NULL;
     /* look for it in the table first */
@@ -7684,10 +7696,10 @@ Perl_mg_dup(pTHX_ MAGIC *mg)
     for (; mg; mg = mg->mg_moremagic) {
        MAGIC *nmg;
        Newz(0, nmg, 1, MAGIC);
-       if (!mgret)
-           mgret = nmg;
-       else
+       if (mgprev)
            mgprev->mg_moremagic = nmg;
+       else
+           mgret = nmg;
        nmg->mg_virtual = mg->mg_virtual;       /* XXX copy dynamic vtable? */
        nmg->mg_private = mg->mg_private;
        nmg->mg_type    = mg->mg_type;
@@ -8523,6 +8535,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl)
            TOPIV(nss,ix) = iv;
             break;
        case SAVEt_FREESV:
+       case SAVEt_MORTALIZESV:
            sv = (SV*)POPPTR(ss,ix);
            TOPPTR(nss,ix) = sv_dup_inc(sv);
            break;