Fix bug in DynaLoader, which has been passing a filename in dynamic
[p5sagit/p5-mst-13.2.git] / op.c
diff --git a/op.c b/op.c
index 3c44f96..366897b 100644 (file)
--- a/op.c
+++ b/op.c
@@ -224,7 +224,7 @@ S_no_bareword_allowed(pTHX_ const OP *o)
        return;         /* various ok barewords are hidden in extra OP_NULL */
     qerror(Perl_mess(aTHX_
                     "Bareword \"%"SVf"\" not allowed while \"strict subs\" in use",
-                    cSVOPo_sv));
+                    (void*)cSVOPo_sv));
 }
 
 /* "register" allocation */
@@ -250,9 +250,13 @@ Perl_allocmy(pTHX_ char *name)
            p = strchr(name, '\0');
            /* The next block assumes the buffer is at least 205 chars
               long.  At present, it's always at least 256 chars. */
-           if (p-name > 200) {
-               strcpy(name+200, "...");
-               p = name+199;
+           if (p - name > 200) {
+#ifdef HAS_STRLCPY
+               strlcpy(name + 200, "...", 4);
+#else
+               strcpy(name + 200, "...");
+#endif
+               p = name + 199;
            }
            else {
                p[1] = '\0';
@@ -4830,9 +4834,9 @@ Perl_cv_ckproto_len(pTHX_ const CV *cv, const GV *gv, const char *p,
            gv_efullname3(name = sv_newmortal(), gv, NULL);
        sv_setpv(msg, "Prototype mismatch:");
        if (name)
-           Perl_sv_catpvf(aTHX_ msg, " sub %"SVf, name);
+           Perl_sv_catpvf(aTHX_ msg, " sub %"SVf, (void*)name);
        if (SvPOK(cv))
-           Perl_sv_catpvf(aTHX_ msg, " (%"SVf")", (const SV *)cv);
+           Perl_sv_catpvf(aTHX_ msg, " (%"SVf")", (void*)cv);
        else
            sv_catpvs(msg, ": none");
        sv_catpvs(msg, " vs ");
@@ -4840,7 +4844,7 @@ Perl_cv_ckproto_len(pTHX_ const CV *cv, const GV *gv, const char *p,
            Perl_sv_catpvf(aTHX_ msg, "(%.*s)", (int) len, p);
        else
            sv_catpvs(msg, "none");
-       Perl_warner(aTHX_ packWARN(WARN_PROTOTYPE), "%"SVf, msg);
+       Perl_warner(aTHX_ packWARN(WARN_PROTOTYPE), "%"SVf, (void*)msg);
     }
 }
 
@@ -5251,7 +5255,7 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
                else {
                    /* force display of errors found but not reported */
                    sv_catpv(ERRSV, not_safe);
-                   Perl_croak(aTHX_ "%"SVf, ERRSV);
+                   Perl_croak(aTHX_ "%"SVf, (void*)ERRSV);
                }
            }
        }
@@ -5425,15 +5429,10 @@ Perl_newCONSTSUB(pTHX_ HV *stash, const char *name, SV *sv)
     /* file becomes the CvFILE. For an XS, it's supposed to be static storage,
        and so doesn't get free()d.  (It's expected to be from the C pre-
        processor __FILE__ directive). But we need a dynamically allocated one,
-       and we need it to get freed.  So we cheat, and take advantage of the
-       fact that the first 0 bytes of any string always look the same.  */
-    cv = newXS(name, const_sv_xsub, file);
+       and we need it to get freed.  */
+    cv = newXS_flags(name, const_sv_xsub, file, "", XS_DYNAMIC_FILENAME);
     CvXSUBANY(cv).any_ptr = sv;
     CvCONST_on(cv);
-    /* prototype is "".  But this gets free()d.  :-)  */
-    sv_usepvn_flags((SV*)cv, file, len, SV_HAS_TRAILING_NUL); 
-    /* This gives us a prototype of "", rather than the file name.  */
-    SvCUR_set(cv, 0);
 
 #ifdef USE_ITHREADS
     if (stash)
@@ -5444,10 +5443,55 @@ Perl_newCONSTSUB(pTHX_ HV *stash, const char *name, SV *sv)
     return cv;
 }
 
+CV *
+Perl_newXS_flags(pTHX_ const char *name, XSUBADDR_t subaddr,
+                const char *const filename, const char *const proto,
+                U32 flags)
+{
+    CV *cv = newXS(name, subaddr, filename);
+
+    if (flags & XS_DYNAMIC_FILENAME) {
+       /* We need to "make arrangements" (ie cheat) to ensure that the
+          filename lasts as long as the PVCV we just created, but also doesn't
+          leak  */
+       STRLEN filename_len = strlen(filename);
+       STRLEN proto_and_file_len = filename_len;
+       char *proto_and_file;
+       STRLEN proto_len;
+
+       if (proto) {
+           proto_len = strlen(proto);
+           proto_and_file_len += proto_len;
+
+           Newx(proto_and_file, proto_and_file_len + 1, char);
+           Copy(proto, proto_and_file, proto_len, char);
+           Copy(filename, proto_and_file + proto_len, filename_len + 1, char);
+       } else {
+           proto_len = 0;
+           proto_and_file = savepvn(filename, filename_len);
+       }
+
+       /* This gets free()d.  :-)  */
+       sv_usepvn_flags((SV*)cv, proto_and_file, proto_and_file_len,
+                       SV_HAS_TRAILING_NUL);
+       if (proto) {
+           /* This gives us the correct prototype, rather than one with the
+              file name appended.  */
+           SvCUR_set(cv, proto_len);
+       } else {
+           SvPOK_off(cv);
+       }
+    } else {
+       sv_setpv((SV *)cv, proto);
+    }
+    return cv;
+}
+
 /*
 =for apidoc U||newXS
 
-Used by C<xsubpp> to hook up XSUBs as Perl subs.
+Used by C<xsubpp> to hook up XSUBs as Perl subs.  I<filename> needs to be
+static storage, as it is used directly as CvFILE(), without a copy being made.
 
 =cut
 */
@@ -5593,7 +5637,7 @@ Perl_newFORM(pTHX_ I32 floor, OP *o, OP *block)
                CopLINE_set(PL_curcop, PL_copline);
            Perl_warner(aTHX_ packWARN(WARN_REDEFINE),
                        o ? "Format %"SVf" redefined"
-                       : "Format STDOUT redefined" ,cSVOPo->op_sv);
+                       : "Format STDOUT redefined", (void*)cSVOPo->op_sv);
            CopLINE_set(PL_curcop, oldline);
        }
        SvREFCNT_dec(cv);
@@ -6099,8 +6143,8 @@ Perl_ck_rvconst(pTHX_ register OP *o)
            }
            if (badthing)
                Perl_croak(aTHX_
-         "Can't use bareword (\"%"SVf"\") as %s ref while \"strict refs\" in use",
-                     kidsv, badthing);
+                          "Can't use bareword (\"%"SVf"\") as %s ref while \"strict refs\" in use",
+                          (void*)kidsv, badthing);
        }
        /*
         * This is a little tricky.  We only want to add the symbol if we
@@ -6258,7 +6302,7 @@ Perl_ck_fun(pTHX_ OP *o)
                    if (ckWARN2(WARN_DEPRECATED, WARN_SYNTAX))
                        Perl_warner(aTHX_ packWARN2(WARN_DEPRECATED, WARN_SYNTAX),
                            "Array @%"SVf" missing the @ in argument %"IVdf" of %s()",
-                           ((SVOP*)kid)->op_sv, (IV)numargs, PL_op_desc[type]);
+                           (void*)((SVOP*)kid)->op_sv, (IV)numargs, PL_op_desc[type]);
 #ifdef PERL_MAD
                    op_getmad(kid,newop,'K');
 #else
@@ -6281,7 +6325,7 @@ Perl_ck_fun(pTHX_ OP *o)
                    if (ckWARN2(WARN_DEPRECATED, WARN_SYNTAX))
                        Perl_warner(aTHX_ packWARN2(WARN_DEPRECATED, WARN_SYNTAX),
                            "Hash %%%"SVf" missing the %% in argument %"IVdf" of %s()",
-                           ((SVOP*)kid)->op_sv, (IV)numargs, PL_op_desc[type]);
+                           (void*)((SVOP*)kid)->op_sv, (IV)numargs, PL_op_desc[type]);
 #ifdef PERL_MAD
                    op_getmad(kid,newop,'K');
 #else
@@ -7453,7 +7497,7 @@ Perl_ck_subr(pTHX_ OP *o)
            default:
              oops:
                Perl_croak(aTHX_ "Malformed prototype for %s: %"SVf,
-                          gv_ename(namegv), cv);
+                          gv_ename(namegv), (void*)cv);
            }
        }
        else
@@ -7724,7 +7768,7 @@ Perl_peep(pTHX_ register OP *o)
                    gv_efullname3(sv, gv, NULL);
                    Perl_warner(aTHX_ packWARN(WARN_PROTOTYPE),
                                "%"SVf"() called too early to check prototype",
-                               sv);
+                               (void*)sv);
                }
            }
            else if (o->op_next->op_type == OP_READLINE