This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
parts/apicheck.pl: make macro public in X+M flagged functions
[perl5.git] / cpan / Digest-MD5 / MD5.xs
index ac36b05..a48d951 100644 (file)
@@ -43,6 +43,51 @@ extern "C" {
 }
 #endif
 
+#ifndef PERL_UNUSED_VAR
+# define PERL_UNUSED_VAR(x) ((void)x)
+#endif
+
+#ifndef PERL_MAGIC_ext
+# define PERL_MAGIC_ext '~'
+#endif
+
+#ifndef Newxz
+# define Newxz(v,n,t) Newz(0,v,n,t)
+#endif
+
+#ifndef SvMAGIC_set
+# define SvMAGIC_set(sv, mg) (SvMAGIC(sv) = (mg))
+#endif
+
+#ifndef sv_magicext
+# define sv_magicext(sv, obj, type, vtbl, name, namlen) \
+    THX_sv_magicext(aTHX_ sv, obj, type, vtbl, name, namlen)
+static MAGIC *THX_sv_magicext(pTHX_ SV *sv, SV *obj, int type,
+    MGVTBL const *vtbl, char const *name, I32 namlen)
+{
+    MAGIC *mg;
+    if (obj || namlen)
+       /* exceeded intended usage of this reserve implementation */
+       return NULL;
+    Newxz(mg, 1, MAGIC);
+    mg->mg_virtual = (MGVTBL*)vtbl;
+    mg->mg_type = type;
+    mg->mg_ptr = (char *)name;
+    mg->mg_len = -1;
+    (void) SvUPGRADE(sv, SVt_PVMG);
+    mg->mg_moremagic = SvMAGIC(sv);
+    SvMAGIC_set(sv, mg);
+    SvMAGICAL_off(sv);
+    mg_magical(sv);
+    return mg;
+}
+#endif
+
+#if PERL_VERSION < 8
+# undef SvPVbyte
+# define SvPVbyte(sv, lp) (sv_utf8_downgrade((sv), 0), SvPV((sv), (lp)))
+#endif
+
 /* Perl does not guarantee that U32 is exactly 32 bits.  Some system
  * has no integral type with exactly 32 bits.  For instance, A Cray has
  * short, int and long all at 64 bits so we need to apply this macro
@@ -89,7 +134,7 @@ static void u2s(U32 u, U8* s)
                         ((U32)(*(s+3)) << 24))
 #endif
 
-/* This stucture keeps the current state of algorithm.
+/* This structure keeps the current state of algorithm.
  */
 typedef struct {
   U32 A, B, C, D;  /* current digest */
@@ -98,7 +143,7 @@ typedef struct {
   U8 buffer[128];  /* collect complete 64 byte blocks */
 } MD5_CTX;
 
-#ifdef USE_ITHREADS
+#if defined(USE_ITHREADS) && defined(MGf_DUP)
 STATIC int dup_md5_ctx(pTHX_ MAGIC *mg, CLONE_PARAMS *params)
 {
     MD5_CTX *new_ctx;
@@ -110,26 +155,29 @@ STATIC int dup_md5_ctx(pTHX_ MAGIC *mg, CLONE_PARAMS *params)
 }
 #endif
 
-STATIC MGVTBL vtbl_md5 = {
+#if defined(MGf_DUP) && defined(USE_ITHREADS)
+STATIC const MGVTBL vtbl_md5 = {
     NULL, /* get */
     NULL, /* set */
     NULL, /* len */
     NULL, /* clear */
     NULL, /* free */
-#ifdef MGf_COPY
     NULL, /* copy */
-#endif
-#ifdef MGf_DUP
-# ifdef USE_ITHREADS
-    dup_md5_ctx,
-# else
-    NULL, /* dup */
-# endif
-#endif
-#ifdef MGf_LOCAL
+    dup_md5_ctx, /* dup */
     NULL /* local */
-#endif
 };
+#else
+/* declare as 5 member, not normal 8 to save image space*/
+STATIC const struct {
+       int (*svt_get)(SV* sv, MAGIC* mg);
+       int (*svt_set)(SV* sv, MAGIC* mg);
+       U32 (*svt_len)(SV* sv, MAGIC* mg);
+       int (*svt_clear)(SV* sv, MAGIC* mg);
+       int (*svt_free)(SV* sv, MAGIC* mg);
+} vtbl_md5 = {
+       NULL, NULL, NULL, NULL, NULL
+};
+#endif
 
 
 /* Padding is added at the end of the message in order to fill a
@@ -458,7 +506,8 @@ static MD5_CTX* get_md5_ctx(pTHX_ SV* sv)
        croak("Not a reference to a Digest::MD5 object");
 
     for (mg = SvMAGIC(SvRV(sv)); mg; mg = mg->mg_moremagic) {
-       if (mg->mg_type == PERL_MAGIC_ext && mg->mg_virtual == &vtbl_md5) {
+       if (mg->mg_type == PERL_MAGIC_ext
+           && mg->mg_virtual == (const MGVTBL * const)&vtbl_md5) {
            return (MD5_CTX *)mg->mg_ptr;
        }
     }
@@ -480,9 +529,9 @@ static SV * new_md5_ctx(pTHX_ MD5_CTX *context, const char *klass)
 #ifdef USE_ITHREADS
     mg =
 #endif
-       sv_magicext(sv, NULL, PERL_MAGIC_ext, &vtbl_md5, (void *)context, 0);
+       sv_magicext(sv, NULL, PERL_MAGIC_ext, (const MGVTBL * const)&vtbl_md5, (const char *)context, 0);
 
-#ifdef USE_ITHREADS
+#if defined(USE_ITHREADS) && defined(MGf_DUP)
     mg->mg_flags |= MGf_DUP;
 #endif
 
@@ -555,7 +604,7 @@ static SV* make_mortal_sv(pTHX_ const unsigned char *src, int type)
        len = 22;
        break;
     default:
-       croak("Bad convertion type (%d)", type);
+       croak("Bad conversion type (%d)", type);
        break;
     }
     return sv_2mortal(newSVpv(ret,len));
@@ -686,6 +735,45 @@ digest(context)
         XSRETURN(1);
 
 void
+context(ctx, ...)
+       MD5_CTX* ctx
+    PREINIT:
+       char out[16];
+        U32 w;
+    PPCODE:
+       if (items > 2) {
+           STRLEN len;
+           unsigned long blocks = SvUV(ST(1));
+           unsigned char *buf = (unsigned char *)(SvPV(ST(2), len));
+           ctx->A = buf[ 0] | (buf[ 1]<<8) | (buf[ 2]<<16) | (buf[ 3]<<24);
+           ctx->B = buf[ 4] | (buf[ 5]<<8) | (buf[ 6]<<16) | (buf[ 7]<<24);
+           ctx->C = buf[ 8] | (buf[ 9]<<8) | (buf[10]<<16) | (buf[11]<<24);
+           ctx->D = buf[12] | (buf[13]<<8) | (buf[14]<<16) | (buf[15]<<24);
+           ctx->bytes_low = blocks << 6;
+           ctx->bytes_high = blocks >> 26;
+           if (items == 4) {
+               buf = (unsigned char *)(SvPV(ST(3), len));
+               MD5Update(ctx, buf, len);
+           }
+           XSRETURN(1); /* ctx */
+       } else if (items != 1) {
+           XSRETURN(0);
+       }
+
+        w=ctx->A; out[ 0]=w; out[ 1]=(w>>8); out[ 2]=(w>>16); out[ 3]=(w>>24);
+        w=ctx->B; out[ 4]=w; out[ 5]=(w>>8); out[ 6]=(w>>16); out[ 7]=(w>>24);
+        w=ctx->C; out[ 8]=w; out[ 9]=(w>>8); out[10]=(w>>16); out[11]=(w>>24);
+        w=ctx->D; out[12]=w; out[13]=(w>>8); out[14]=(w>>16); out[15]=(w>>24);
+
+       EXTEND(SP, 3);
+       ST(0) = sv_2mortal(newSVuv(ctx->bytes_high << 26 |
+                                  ctx->bytes_low >> 6));
+       ST(1) = sv_2mortal(newSVpv(out, 16));
+       ST(2) = sv_2mortal(newSVpv((char *)ctx->buffer,
+                                  ctx->bytes_low & 0x3F));
+       XSRETURN(3);
+
+void
 md5(...)
     ALIAS:
        Digest::MD5::md5        = F_BIN
@@ -700,12 +788,14 @@ md5(...)
     PPCODE:
        MD5Init(&ctx);
 
-       if (PL_dowarn & G_WARN_ON) {
+       if ((PL_dowarn & G_WARN_ON) || ckWARN(WARN_SYNTAX)) {
             const char *msg = 0;
            if (items == 1) {
                if (SvROK(ST(0))) {
                     SV* sv = SvRV(ST(0));
-                   if (SvOBJECT(sv) && strEQ(HvNAME(SvSTASH(sv)), "Digest::MD5"))
+                    char *name;
+                   if (SvOBJECT(sv) && (name = HvNAME(SvSTASH(sv)))
+                                     && strEQ(name, "Digest::MD5"))
                        msg = "probably called as method";
                    else
                        msg = "called with reference argument";
@@ -718,7 +808,9 @@ md5(...)
                }
                else if (SvROK(ST(0))) {
                    SV* sv = SvRV(ST(0));
-                   if (SvOBJECT(sv) && strEQ(HvNAME(SvSTASH(sv)), "Digest::MD5"))
+                    char *name;
+                   if (SvOBJECT(sv) && (name = HvNAME(SvSTASH(sv)))
+                                     && strEQ(name, "Digest::MD5"))
                        msg = "probably called as method";
                }
            }