]> git.deb.at Git - pkg/abook.git/blobdiff - intl/printf.c
Autotools update to autoconf-2.68 / automake-1.11 / gettextize 0.18.1.
[pkg/abook.git] / intl / printf.c
index 878646c2de5e675b6cfb1aea36cba360dcf08bd7..b7cdc5d82a0f7a865886db4305c6d9d9f70aed67 100644 (file)
@@ -1,5 +1,5 @@
 /* Formatted output to strings, using POSIX/XSI format strings with positions.
-   Copyright (C) 2003 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2006-2007, 2009 Free Software Foundation, Inc.
    Written by Bruno Haible <bruno@clisp.org>, 2003.
 
    This program is free software; you can redistribute it and/or modify it
@@ -14,7 +14,7 @@
 
    You should have received a copy of the GNU Library General Public
    License along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
    USA.  */
 
 #ifdef HAVE_CONFIG_H
@@ -47,13 +47,22 @@ char *alloca ();
 
 #if !HAVE_POSIX_PRINTF
 
+#include <errno.h>
+#include <limits.h>
 #include <stdlib.h>
 #include <string.h>
 
+/* Some systems, like OSF/1 4.0 and Woe32, don't have EOVERFLOW.  */
+#ifndef EOVERFLOW
+# define EOVERFLOW E2BIG
+#endif
+
 /* When building a DLL, we must export some functions.  Note that because
    the functions are only defined for binary backward compatibility, we
    don't need to use __declspec(dllimport) in any case.  */
-#if defined _MSC_VER && BUILDING_DLL
+#if HAVE_VISIBILITY && BUILDING_DLL
+# define DLL_EXPORTED __attribute__((__visibility__("default")))
+#elif defined _MSC_VER && BUILDING_DLL
 # define DLL_EXPORTED __declspec(dllexport)
 #else
 # define DLL_EXPORTED
@@ -61,6 +70,14 @@ char *alloca ();
 
 #define STATIC static
 
+/* This needs to be consistent with libgnuintl.h.in.  */
+#if defined __NetBSD__ || defined __BEOS__ || defined __CYGWIN__ || defined __MINGW32__
+/* Don't break __attribute__((format(printf,M,N))).
+   This redefinition is only possible because the libc in NetBSD, Cygwin,
+   mingw does not have a function __printf__.  */
+# define libintl_printf __printf__
+#endif
+
 /* Define auxiliary functions declared in "printf-args.h".  */
 #include "printf-args.c"
 
@@ -87,11 +104,17 @@ libintl_vfprintf (FILE *stream, const char *format, va_list args)
       char *result = libintl_vasnprintf (NULL, &length, format, args);
       int retval = -1;
       if (result != NULL)
-       {
-         if (fwrite (result, 1, length, stream) == length)
-           retval = length;
-         free (result);
-       }
+        {
+          size_t written = fwrite (result, 1, length, stream);
+          free (result);
+          if (written == length)
+            {
+              if (length > INT_MAX)
+                errno = EOVERFLOW;
+              else
+                retval = length;
+            }
+        }
       return retval;
     }
 }
@@ -140,12 +163,17 @@ libintl_vsprintf (char *resultbuf, const char *format, va_list args)
       size_t length = (size_t) ~0 / (4 * sizeof (char));
       char *result = libintl_vasnprintf (resultbuf, &length, format, args);
       if (result != resultbuf)
-       {
-         free (result);
-         return -1;
-       }
+        {
+          free (result);
+          return -1;
+        }
+      if (length > INT_MAX)
+        {
+          errno = EOVERFLOW;
+          return -1;
+        }
       else
-       return length;
+        return length;
     }
 }
 
@@ -183,19 +211,23 @@ libintl_vsnprintf (char *resultbuf, size_t length, const char *format, va_list a
       size_t maxlength = length;
       char *result = libintl_vasnprintf (resultbuf, &length, format, args);
       if (result != resultbuf)
-       {
-         if (maxlength > 0)
-           {
-             if (length < maxlength)
-               abort ();
-             memcpy (resultbuf, result, maxlength - 1);
-             resultbuf[maxlength - 1] = '\0';
-           }
-         free (result);
-         return -1;
-       }
+        {
+          if (maxlength > 0)
+            {
+              size_t pruned_length =
+                (length < maxlength ? length : maxlength - 1);
+              memcpy (resultbuf, result, pruned_length);
+              resultbuf[pruned_length] = '\0';
+            }
+          free (result);
+        }
+      if (length > INT_MAX)
+        {
+          errno = EOVERFLOW;
+          return -1;
+        }
       else
-       return length;
+        return length;
     }
 }
 
@@ -224,6 +256,12 @@ libintl_vasprintf (char **resultp, const char *format, va_list args)
   char *result = libintl_vasnprintf (NULL, &length, format, args);
   if (result == NULL)
     return -1;
+  if (length > INT_MAX)
+    {
+      free (result);
+      errno = EOVERFLOW;
+      return -1;
+    }
   *resultp = result;
   return length;
 }
@@ -249,7 +287,12 @@ libintl_asprintf (char **resultp, const char *format, ...)
 
 #define WIDE_CHAR_VERSION 1
 
+#include "wprintf-parse.h"
 /* Define auxiliary functions declared in "wprintf-parse.h".  */
+#define CHAR_T wchar_t
+#define DIRECTIVE wchar_t_directive
+#define DIRECTIVES wchar_t_directives
+#define PRINTF_PARSE wprintf_parse
 #include "printf-parse.c"
 
 /* Define functions declared in "vasnprintf.h".  */
@@ -280,15 +323,20 @@ libintl_vfwprintf (FILE *stream, const wchar_t *format, va_list args)
       wchar_t *result = libintl_vasnwprintf (NULL, &length, format, args);
       int retval = -1;
       if (result != NULL)
-       {
-         size_t i;
-         for (i = 0; i < length; i++)
-           if (fputwc (result[i], stream) == WEOF)
-             break;
-         if (i == length)
-           retval = length;
-         free (result);
-       }
+        {
+          size_t i;
+          for (i = 0; i < length; i++)
+            if (fputwc (result[i], stream) == WEOF)
+              break;
+          free (result);
+          if (i == length)
+            {
+              if (length > INT_MAX)
+                errno = EOVERFLOW;
+              else
+                retval = length;
+            }
+        }
       return retval;
     }
 }
@@ -337,19 +385,29 @@ libintl_vswprintf (wchar_t *resultbuf, size_t length, const wchar_t *format, va_
       size_t maxlength = length;
       wchar_t *result = libintl_vasnwprintf (resultbuf, &length, format, args);
       if (result != resultbuf)
-       {
-         if (maxlength > 0)
-           {
-             if (length < maxlength)
-               abort ();
-             memcpy (resultbuf, result, (maxlength - 1) * sizeof (wchar_t));
-             resultbuf[maxlength - 1] = 0;
-           }
-         free (result);
-         return -1;
-       }
+        {
+          if (maxlength > 0)
+            {
+              size_t pruned_length =
+                (length < maxlength ? length : maxlength - 1);
+              memcpy (resultbuf, result, pruned_length * sizeof (wchar_t));
+              resultbuf[pruned_length] = 0;
+            }
+          free (result);
+          /* Unlike vsnprintf, which has to return the number of character that
+             would have been produced if the resultbuf had been sufficiently
+             large, the vswprintf function has to return a negative value if
+             the resultbuf was not sufficiently large.  */
+          if (length >= maxlength)
+            return -1;
+        }
+      if (length > INT_MAX)
+        {
+          errno = EOVERFLOW;
+          return -1;
+        }
       else
-       return length;
+        return length;
     }
 }