Missing semi-colon
[p5sagit/p5-mst-13.2.git] / ext / MIME / Base64 / Base64.xs
index e421836..14c8bea 100644 (file)
@@ -1,6 +1,6 @@
-/* $Id: Base64.xs,v 1.32 2003/01/05 07:49:07 gisle Exp $
+/* $Id: Base64.xs,v 1.41 2004/01/08 14:07:26 gisle Exp $
 
-Copyright 1997-2003 Gisle Aas
+Copyright 1997-2004 Gisle Aas
 
 This library is free software; you can redistribute it and/or
 modify it under the same terms as Perl itself.
@@ -35,11 +35,24 @@ extern "C" {
 }
 #endif
 
-#include "patchlevel.h"
+#ifndef PATCHLEVEL
+#    include <patchlevel.h>
+#    if !(defined(PERL_VERSION) || (SUBVERSION > 0 && defined(PATCHLEVEL)))
+#        include <could_not_find_Perl_patchlevel.h>
+#    endif
+#endif
+
 #if PATCHLEVEL <= 4 && !defined(PL_dowarn)
    #define PL_dowarn dowarn
 #endif
 
+#ifdef G_WARN_ON
+   #define DOWARN (PL_dowarn & G_WARN_ON)
+#else
+   #define DOWARN PL_dowarn
+#endif
+
+
 #define MAX_LINE  76 /* size of encoded lines */
 
 static char basis_64[] =
@@ -146,7 +159,7 @@ encode_base64(sv,...)
                chunk = 0;
            }
            c1 = *str++;
-           c2 = *str++;
+           c2 = len > 1 ? *str++ : '\0';
            *r++ = basis_64[c1>>2];
            *r++ = basis_64[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)];
            if (len > 2) {
@@ -203,7 +216,7 @@ decode_base64(sv)
 
                if (str == end) {
                    if (i < 4) {
-                       if (i && PL_dowarn)
+                       if (i && DOWARN)
                            warn("Premature end of base64 data");
                        if (i < 2) goto thats_it;
                        if (i == 2) c[2] = EQ;
@@ -214,7 +227,7 @@ decode_base64(sv)
             } while (i < 4);
        
            if (c[0] == EQ || c[1] == EQ) {
-               if (PL_dowarn) warn("Premature padding of base64 data");
+               if (DOWARN) warn("Premature padding of base64 data");
                break;
             }
            /* printf("c0=%d,c1=%d,c2=%d,c3=%d\n", c[0],c[1],c[2],c[3]);*/
@@ -240,7 +253,7 @@ decode_base64(sv)
 
 MODULE = MIME::Base64          PACKAGE = MIME::QuotedPrint
 
-#define qp_isplain(c) ((c) == '\t' || ((c) >= ' ' && (c) <= '~') && (c) != '=')
+#define qp_isplain(c) ((c) == '\t' || (((c) >= ' ' && (c) <= '~') && (c) != '='))
 
 SV*
 encode_qp(sv,...)
@@ -285,7 +298,7 @@ encode_qp(sv,...)
            while (p < end && qp_isplain(*p)) {
                p++;
            }
-           if (*p == '\n' || p == end) {
+           if (p == end || *p == '\n') {
                /* whitespace at end of line must be encoded */
                while (p > p_beg && (*(p - 1) == '\t' || *(p - 1) == ' '))
                    p--;
@@ -295,9 +308,9 @@ encode_qp(sv,...)
            if (p_len) {
                /* output plain text (with line breaks) */
                if (eol_len) {
-                   STRLEN max_last_line = (*p == '\n' || p == end)
+                   STRLEN max_last_line = (p == end || *p == '\n')
                                              ? MAX_LINE         /* .......\n */
-                                             : (*(p + 1) == '\n' || (p + 1) == end)
+                                             : ((p + 1) == end || *(p + 1) == '\n')
                                                ? MAX_LINE - 3   /* ....=XX\n */
                                                : MAX_LINE - 4;  /* ...=XX=\n */
                    while (p_len + linelen > max_last_line) {
@@ -318,13 +331,17 @@ encode_qp(sv,...)
                }
            }
 
-           if (*p == '\n') {
+           if (p == end) {
+               break;
+            }
+           else if (*p == '\n' && eol_len) {
                sv_catpvn(RETVAL, eol, eol_len);
                p++;
                linelen = 0;
            }
-           else if (p < end) {
+           else {
                /* output escaped char (with line breaks) */
+               assert(p < end);
                if (eol_len && linelen > MAX_LINE - 4) {
                    sv_catpvn(RETVAL, "=", 1);
                    sv_catpvn(RETVAL, eol, eol_len);
@@ -334,10 +351,6 @@ encode_qp(sv,...)
                p++;
                linelen += 3;
            }
-           else {
-               assert(p == end);
-               break;
-           }
 
            /* optimize reallocs a bit */
            if (SvLEN(RETVAL) > 80 && SvLEN(RETVAL) - SvCUR(RETVAL) < 3) {
@@ -356,7 +369,7 @@ decode_qp(sv)
 
         PREINIT:
        STRLEN len;
-       char *str = (unsigned char*)SvPVbyte(sv, len);
+       char *str = SvPVbyte(sv, len);
        char const* end = str + len;
        char *r;
        char *whitespace = 0;
@@ -385,25 +398,38 @@ decode_qp(sv)
                    }
                    whitespace = 0;
                 }
-               if (*str == '=' && (str + 2) < end && isxdigit(str[1]) && isxdigit(str[2])) {
-                   char buf[3];
-                    str++;
-                   buf[0] = *str++;
-                   buf[1] = *str++;
-                   buf[2] = '\0';
-                   *r++ = (char)strtol(buf, 0, 16);
-               }
-               else if (*str == '=' && (str + 1) < end && str[1] == '\n') {
-                   str += 2;
+               if (*str == '=') {
+                   if ((str + 2) < end && isXDIGIT(str[1]) && isXDIGIT(str[2])) {
+                       char buf[3];
+                        str++;
+                       buf[0] = *str++;
+                       buf[1] = *str++;
+                       buf[2] = '\0';
+                       *r++ = (char)strtol(buf, 0, 16);
+                   }
+                   else {
+                       /* look for soft line break */
+                       char *p = str + 1;
+                       while (p < end && (*p == ' ' || *p == '\t'))
+                           p++;
+                       if (p < end && *p == '\n')
+                           str = p + 1;
+                       else if ((p + 1) < end && *p == '\r' && *(p + 1) == '\n')
+                           str = p + 2;
+                       else
+                           *r++ = *str++; /* give up */
+                   }
                }
-               else if (*str == '=' && (str + 2) < end && str[1] == '\r' && str[2] == '\n') {
-                   str += 3;
+               else {
+                   *r++ = *str++;
                }
-               else {
-                   *r++ = *str++;
-                }
            }
        }
+       if (whitespace) {
+           while (whitespace < str) {
+               *r++ = *whitespace++;
+           }
+        }
        *r = '\0';
        SvCUR_set(RETVAL, r - SvPVX(RETVAL));