Try to make including patchlevel.h a bit more
[p5sagit/p5-mst-13.2.git] / ext / Digest / MD5 / MD5.xs
index 12642ae..b1f2a04 100644 (file)
@@ -1,3 +1,5 @@
+/* $Id: MD5.xs,v 1.35 2003/01/05 00:54:17 gisle Exp $ */
+
 /* 
  * This library is free software; you can redistribute it and/or
  * modify it under the same terms as Perl itself.
@@ -7,7 +9,7 @@
  *  Copyright 1991-1992 RSA Data Security, Inc.
  *
  * This code is derived from Neil Winton's MD5-1.7 Perl module, which in
- * turn is derived from the reference implementation in RFC 1231 which
+ * turn is derived from the reference implementation in RFC 1321 which
  * comes with this message:
  *
  * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
@@ -42,8 +44,32 @@ extern "C" {
 }
 #endif
 
-/* Define this to turn on verbose debugging prints */
-#undef MD5_DEBUG
+#include <patchlevel.h>
+#ifndef PERL_VERSION
+#    include <could_not_find_Perl_patchlevel.h>
+#endif
+#if PATCHLEVEL <= 4 && !defined(PL_dowarn)
+   #define PL_dowarn dowarn
+#endif
+
+#ifdef SvPVbyte
+   #if PERL_REVISION == 5 && PERL_VERSION < 7
+       /* SvPVbyte does not work in perl-5.6.1, borrowed version for 5.7.3 */
+       #undef SvPVbyte
+       #define SvPVbyte(sv, lp) \
+         ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \
+          ? ((lp = SvCUR(sv)), SvPVX(sv)) : my_sv_2pvbyte(aTHX_ sv, &lp))
+
+       static char *
+       my_sv_2pvbyte(pTHX_ register SV *sv, STRLEN *lp)
+       {
+          sv_utf8_downgrade(sv,0);
+           return SvPV(sv,*lp);
+       }
+   #endif
+#else
+   #define SvPVbyte SvPV
+#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
@@ -79,10 +105,10 @@ extern "C" {
 #ifndef BYTESWAP
 static void u2s(U32 u, U8* s)
 {
-    *s++ = u         & 0xFF;
-    *s++ = (u >>  8) & 0xFF;
-    *s++ = (u >> 16) & 0xFF;
-    *s   = (u >> 24) & 0xFF;
+    *s++ = (U8)(u         & 0xFF);
+    *s++ = (U8)((u >>  8) & 0xFF);
+    *s++ = (U8)((u >> 16) & 0xFF);
+    *s   = (U8)((u >> 24) & 0xFF);
 }
 
 #define s2u(s,u) ((u) =  (U32)(*s)            |  \
@@ -136,7 +162,7 @@ static unsigned char PADDING[64] = {
 
 /* F, G, H and I are basic MD5 functions.
  */
-#define F(x, y, z) (((x) & ((y) ^ (z)) ^ (z)))
+#define F(x, y, z) ((((x) & ((y) ^ (z))) ^ (z)))
 #define G(x, y, z) F(z, x, y)
 #define H(x, y, z) ((x) ^ (y) ^ (z))
 #define I(x, y, z) ((y) ^ ((x) | (~z)))
@@ -539,6 +565,22 @@ new(xclass)
        XSRETURN(1);
 
 void
+clone(self)
+       SV* self
+    PREINIT:
+       MD5_CTX* cont = get_md5_ctx(self);
+       char *myname = sv_reftype(SvRV(self),TRUE);
+       MD5_CTX* context;
+    PPCODE:
+       STRLEN my_na;
+       New(55, context, 1, MD5_CTX);
+       ST(0) = sv_newmortal();
+       sv_setref_pv(ST(0), myname , (void*)context);
+       SvREADONLY_on(SvRV(ST(0)));
+       memcpy(context,cont,sizeof(MD5_CTX));
+       XSRETURN(1);
+
+void
 DESTROY(context)
        MD5_CTX* context
     CODE:
@@ -618,6 +660,31 @@ md5(...)
        unsigned char digeststr[16];
     PPCODE:
        MD5Init(&ctx);
+
+       if (PL_dowarn) {
+            char *msg = 0;
+           if (items == 1) {
+               if (SvROK(ST(0))) {
+                    SV* sv = SvRV(ST(0));
+                   if (SvOBJECT(sv) && strEQ(HvNAME(SvSTASH(sv)), "Digest::MD5"))
+                       msg = "probably called as method";
+                   else
+                       msg = "called with reference argument";
+               }
+           }
+           else if (items > 1) {
+               data = (unsigned char *)SvPVbyte(ST(0), len);
+               if (len == 11 && memEQ("Digest::MD5", data, 11)) {
+                   msg = "probably called as class method";
+               }
+           }
+           if (msg) {
+               char *f = (ix == F_BIN) ? "md5" :
+                          (ix == F_HEX) ? "md5_hex" : "md5_base64";
+               warn("&Digest::MD5::%s function %s", f, msg);
+           }
+       }
+
        for (i = 0; i < items; i++) {
            data = (unsigned char *)(SvPVbyte(ST(i), len));
            MD5Update(&ctx, data, len);