summaryrefslogtreecommitdiff
path: root/lgl
diff options
context:
space:
mode:
authorSimon Josefsson <simon@josefsson.org>2007-03-05 11:23:38 +0000
committerSimon Josefsson <simon@josefsson.org>2007-03-05 11:23:38 +0000
commitc1c8d2fe18e19f109db0730c39197931a21d8f1f (patch)
treef9229e84d865a8bba6fdbf19509ea113f4f85f30 /lgl
parent9d39932d4ddeab2de8a08c2a22f9e8050bddca5a (diff)
downloadgnutls-c1c8d2fe18e19f109db0730c39197931a21d8f1f.tar.gz
Updaet.
Diffstat (limited to 'lgl')
-rw-r--r--lgl/m4/gnulib-comp.m42
-rw-r--r--lgl/m4/time_r.m43
-rw-r--r--lgl/m4/vasnprintf.m430
-rw-r--r--lgl/m4/vasprintf.m424
-rw-r--r--lgl/time_.h2
-rw-r--r--lgl/vasnprintf.c499
-rw-r--r--lgl/vasnprintf.h6
-rw-r--r--lgl/vasprintf.h10
8 files changed, 553 insertions, 23 deletions
diff --git a/lgl/m4/gnulib-comp.m4 b/lgl/m4/gnulib-comp.m4
index 362af5989e..5442a06ee5 100644
--- a/lgl/m4/gnulib-comp.m4
+++ b/lgl/m4/gnulib-comp.m4
@@ -69,7 +69,7 @@ AC_DEFUN([lgl_INIT],
gl_GC_SHA1
gl_MODULE_INDICATOR([gc-sha1])
dnl you must add AM_GNU_GETTEXT([external]) or similar to configure.ac.
- AM_GNU_GETTEXT_VERSION([0.15])
+ AM_GNU_GETTEXT_VERSION([0.16.1])
gl_MD2
gl_FUNC_MEMMEM
gl_STRING_MODULE_INDICATOR([memmem])
diff --git a/lgl/m4/time_r.m4 b/lgl/m4/time_r.m4
index a4e016f819..dbb6396607 100644
--- a/lgl/m4/time_r.m4
+++ b/lgl/m4/time_r.m4
@@ -9,7 +9,10 @@ dnl Written by Paul Eggert.
AC_DEFUN([gl_TIME_R],
[
+ dnl Persuade glibc and Solaris <time.h> to declare localtime_r.
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+
+ AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS])
AC_REQUIRE([AC_C_RESTRICT])
AC_CACHE_CHECK([whether localtime_r is compatible with its POSIX signature],
diff --git a/lgl/m4/vasnprintf.m4 b/lgl/m4/vasnprintf.m4
index 72c9a13e2f..e7b51dc413 100644
--- a/lgl/m4/vasnprintf.m4
+++ b/lgl/m4/vasnprintf.m4
@@ -1,5 +1,5 @@
-# vasnprintf.m4 serial 7
-dnl Copyright (C) 2002-2004, 2006 Free Software Foundation, Inc.
+# vasnprintf.m4 serial 8
+dnl Copyright (C) 2002-2004, 2006-2007 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
@@ -7,18 +7,28 @@ dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_VASNPRINTF],
[
AC_REQUIRE([gl_EOVERFLOW])
- AC_REPLACE_FUNCS(vasnprintf)
+ AC_CHECK_FUNCS([vasnprintf])
if test $ac_cv_func_vasnprintf = no; then
- AC_LIBOBJ(printf-args)
- AC_LIBOBJ(printf-parse)
- AC_LIBOBJ(asnprintf)
- gl_PREREQ_PRINTF_ARGS
- gl_PREREQ_PRINTF_PARSE
- gl_PREREQ_VASNPRINTF
- gl_PREREQ_ASNPRINTF
+ gl_REPLACE_VASNPRINTF
fi
])
+AC_DEFUN([gl_REPLACE_VASNPRINTF],
+[
+ AC_LIBOBJ([vasnprintf])
+ AC_LIBOBJ([printf-args])
+ AC_LIBOBJ([printf-parse])
+ AC_LIBOBJ([asnprintf])
+ if test $ac_cv_func_vasnprintf = yes; then
+ AC_DEFINE([REPLACE_VASNPRINTF], 1,
+ [Define if vasnprintf exists but is overridden by gnulib.])
+ fi
+ gl_PREREQ_PRINTF_ARGS
+ gl_PREREQ_PRINTF_PARSE
+ gl_PREREQ_VASNPRINTF
+ gl_PREREQ_ASNPRINTF
+])
+
# Prequisites of lib/printf-args.h, lib/printf-args.c.
AC_DEFUN([gl_PREREQ_PRINTF_ARGS],
[
diff --git a/lgl/m4/vasprintf.m4 b/lgl/m4/vasprintf.m4
index 18ca6327b5..0f4c12374f 100644
--- a/lgl/m4/vasprintf.m4
+++ b/lgl/m4/vasprintf.m4
@@ -1,20 +1,30 @@
-# vasprintf.m4 serial 2
-dnl Copyright (C) 2002-2003, 2006 Free Software Foundation, Inc.
+# vasprintf.m4 serial 3
+dnl Copyright (C) 2002-2003, 2006-2007 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_VASPRINTF],
[
- AC_REPLACE_FUNCS(vasprintf)
+ AC_CHECK_FUNCS([vasprintf])
if test $ac_cv_func_vasprintf = no; then
- AC_LIBOBJ(asprintf)
- gl_PREREQ_VASPRINTF_H
- gl_PREREQ_VASPRINTF
- gl_PREREQ_ASPRINTF
+ gl_REPLACE_VASPRINTF
fi
])
+AC_DEFUN([gl_REPLACE_VASPRINTF],
+[
+ AC_LIBOBJ([vasprintf])
+ AC_LIBOBJ([asprintf])
+ if test $ac_cv_func_vasprintf = yes; then
+ AC_DEFINE([REPLACE_VASPRINTF], 1,
+ [Define if vasprintf exists but is overridden by gnulib.])
+ fi
+ gl_PREREQ_VASPRINTF_H
+ gl_PREREQ_VASPRINTF
+ gl_PREREQ_ASPRINTF
+])
+
# Prerequisites of lib/vasprintf.h.
AC_DEFUN([gl_PREREQ_VASPRINTF_H],
[
diff --git a/lgl/time_.h b/lgl/time_.h
index b4709bf85f..7b0c6014cd 100644
--- a/lgl/time_.h
+++ b/lgl/time_.h
@@ -86,7 +86,7 @@ char *strptime (char const *restrict __buf, char const *restrict __format,
time_t timegm (struct tm *__tm);
#endif
-/* Encourage applications to avoid unsafe functions that can overrrun
+/* Encourage applications to avoid unsafe functions that can overrun
buffers when given outlandish struct tm values. Portable
applications should use strftime (or even sprintf) instead. */
# if GNULIB_PORTCHECK
diff --git a/lgl/vasnprintf.c b/lgl/vasnprintf.c
index 8e5c8c39f5..15b426b875 100644
--- a/lgl/vasnprintf.c
+++ b/lgl/vasnprintf.c
@@ -49,6 +49,15 @@
/* Checked size_t computations. */
#include "xsize.h"
+#if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL
+# include "isnan.h"
+# include "isnanl.h"
+# if HAVE_LONG_DOUBLE
+# include "printf-frexp.h"
+# include "printf-frexpl.h"
+# endif
+#endif
+
#if HAVE_WCHAR_T
# if HAVE_WCSLEN
# define local_wcslen wcslen
@@ -257,6 +266,474 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar
abort ();
}
}
+#if NEED_PRINTF_DIRECTIVE_A && !defined IN_LIBINTL
+ else if (dp->conversion == 'a' || dp->conversion == 'A')
+ {
+ arg_type type = a.arg[dp->arg_index].type;
+ int flags = dp->flags;
+ int has_width;
+ size_t width;
+ int has_precision;
+ size_t precision;
+ size_t tmp_length;
+ CHAR_T tmpbuf[700];
+ CHAR_T *tmp;
+ CHAR_T *pad_ptr;
+ CHAR_T *p;
+
+ has_width = 0;
+ width = 0;
+ if (dp->width_start != dp->width_end)
+ {
+ if (dp->width_arg_index != ARG_NONE)
+ {
+ int arg;
+
+ if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
+ abort ();
+ arg = a.arg[dp->width_arg_index].a.a_int;
+ if (arg < 0)
+ {
+ /* "A negative field width is taken as a '-' flag
+ followed by a positive field width." */
+ flags |= FLAG_LEFT;
+ width = (unsigned int) (-arg);
+ }
+ else
+ width = arg;
+ }
+ else
+ {
+ const CHAR_T *digitp = dp->width_start;
+
+ do
+ width = xsum (xtimes (width, 10), *digitp++ - '0');
+ while (digitp != dp->width_end);
+ }
+ has_width = 1;
+ }
+
+ has_precision = 0;
+ precision = 0;
+ if (dp->precision_start != dp->precision_end)
+ {
+ if (dp->precision_arg_index != ARG_NONE)
+ {
+ int arg;
+
+ if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
+ abort ();
+ arg = a.arg[dp->precision_arg_index].a.a_int;
+ /* "A negative precision is taken as if the precision
+ were omitted." */
+ if (arg >= 0)
+ {
+ precision = arg;
+ has_precision = 1;
+ }
+ }
+ else
+ {
+ const CHAR_T *digitp = dp->precision_start + 1;
+
+ precision = 0;
+ while (digitp != dp->precision_end)
+ precision = xsum (xtimes (precision, 10), *digitp++ - '0');
+ has_precision = 1;
+ }
+ }
+
+ /* Allocate a temporary buffer of sufficient size. */
+# if HAVE_LONG_DOUBLE
+ if (type == TYPE_LONGDOUBLE)
+ tmp_length =
+ (unsigned int) ((LDBL_DIG + 1)
+ * 0.831 /* decimal -> hexadecimal */
+ )
+ + 1; /* turn floor into ceil */
+ else
+# endif
+ tmp_length =
+ (unsigned int) ((DBL_DIG + 1)
+ * 0.831 /* decimal -> hexadecimal */
+ )
+ + 1; /* turn floor into ceil */
+ if (tmp_length < precision)
+ tmp_length = precision;
+ /* Account for sign, decimal point etc. */
+ tmp_length = xsum (tmp_length, 12);
+
+ if (tmp_length < width)
+ tmp_length = width;
+
+ tmp_length = xsum (tmp_length, 1); /* account for trailing NUL */
+
+ if (tmp_length <= sizeof (tmpbuf) / sizeof (CHAR_T))
+ tmp = tmpbuf;
+ else
+ {
+ size_t tmp_memsize = xtimes (tmp_length, sizeof (CHAR_T));
+
+ if (size_overflow_p (tmp_memsize))
+ /* Overflow, would lead to out of memory. */
+ goto out_of_memory;
+ tmp = (CHAR_T *) malloc (tmp_memsize);
+ if (tmp == NULL)
+ /* Out of memory. */
+ goto out_of_memory;
+ }
+
+ pad_ptr = NULL;
+ p = tmp;
+# if HAVE_LONG_DOUBLE
+ if (type == TYPE_LONGDOUBLE)
+ {
+ long double arg = a.arg[dp->arg_index].a.a_longdouble;
+
+ if (isnanl (arg))
+ {
+ if (dp->conversion == 'A')
+ {
+ *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
+ }
+ else
+ {
+ *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
+ }
+ }
+ else
+ {
+ int sign = 0;
+
+ if (arg < 0.0L)
+ {
+ sign = -1;
+ arg = -arg;
+ }
+ else if (arg == 0.0L)
+ {
+ /* Distinguish 0.0L and -0.0L. */
+ static long double plus_zero = 0.0L;
+ long double arg_mem = arg;
+ if (memcmp (&plus_zero, &arg_mem, sizeof (long double)) != 0)
+ {
+ sign = -1;
+ arg = -arg;
+ }
+ }
+
+ if (sign < 0)
+ *p++ = '-';
+ else if (flags & FLAG_SHOWSIGN)
+ *p++ = '+';
+ else if (flags & FLAG_SPACE)
+ *p++ = ' ';
+
+ if (arg > 0.0L && arg + arg == arg)
+ {
+ if (dp->conversion == 'A')
+ {
+ *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
+ }
+ else
+ {
+ *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
+ }
+ }
+ else
+ {
+ int exponent;
+ long double mantissa;
+
+ if (arg > 0.0L)
+ mantissa = printf_frexpl (arg, &exponent);
+ else
+ {
+ exponent = 0;
+ mantissa = 0.0L;
+ }
+
+ if (has_precision
+ && precision < (unsigned int) ((LDBL_DIG + 1) * 0.831) + 1)
+ {
+ /* Round the mantissa. */
+ long double tail = mantissa;
+ size_t q;
+
+ for (q = precision; ; q--)
+ {
+ int digit = (int) tail;
+ tail -= digit;
+ if (q == 0)
+ {
+ if (digit & 1 ? tail >= 0.5L : tail > 0.5L)
+ tail = 1 - tail;
+ else
+ tail = - tail;
+ break;
+ }
+ tail *= 16.0L;
+ }
+ if (tail != 0.0L)
+ for (q = precision; q > 0; q--)
+ tail *= 0.0625L;
+ mantissa += tail;
+ }
+
+ *p++ = '0';
+ *p++ = dp->conversion - 'A' + 'X';
+ pad_ptr = p;
+ {
+ int digit;
+
+ digit = (int) mantissa;
+ mantissa -= digit;
+ *p++ = '0' + digit;
+ if ((flags & FLAG_ALT)
+ || mantissa > 0.0L || precision > 0)
+ {
+ *p++ = '.';
+ /* This loop terminates because we assume
+ that FLT_RADIX is a power of 2. */
+ while (mantissa > 0.0L)
+ {
+ mantissa *= 16.0L;
+ digit = (int) mantissa;
+ mantissa -= digit;
+ *p++ = digit
+ + (digit < 10
+ ? '0'
+ : dp->conversion - 10);
+ if (precision > 0)
+ precision--;
+ }
+ while (precision > 0)
+ {
+ *p++ = '0';
+ precision--;
+ }
+ }
+ }
+ *p++ = dp->conversion - 'A' + 'P';
+# if WIDE_CHAR_VERSION
+ {
+ static const wchar_t decimal_format[] =
+ { '%', '+', 'd', '\0' };
+ SNPRINTF (p, 6 + 1, decimal_format, exponent);
+ }
+# else
+ sprintf (p, "%+d", exponent);
+# endif
+ while (*p != '\0')
+ p++;
+ }
+ }
+ }
+ else
+# endif
+ {
+ double arg = a.arg[dp->arg_index].a.a_double;
+
+ if (isnan (arg))
+ {
+ if (dp->conversion == 'A')
+ {
+ *p++ = 'N'; *p++ = 'A'; *p++ = 'N';
+ }
+ else
+ {
+ *p++ = 'n'; *p++ = 'a'; *p++ = 'n';
+ }
+ }
+ else
+ {
+ int sign = 0;
+
+ if (arg < 0.0)
+ {
+ sign = -1;
+ arg = -arg;
+ }
+ else if (arg == 0.0)
+ {
+ /* Distinguish 0.0 and -0.0. */
+ static double plus_zero = 0.0;
+ double arg_mem = arg;
+ if (memcmp (&plus_zero, &arg_mem, sizeof (double)) != 0)
+ {
+ sign = -1;
+ arg = -arg;
+ }
+ }
+
+ if (sign < 0)
+ *p++ = '-';
+ else if (flags & FLAG_SHOWSIGN)
+ *p++ = '+';
+ else if (flags & FLAG_SPACE)
+ *p++ = ' ';
+
+ if (arg > 0.0 && arg + arg == arg)
+ {
+ if (dp->conversion == 'A')
+ {
+ *p++ = 'I'; *p++ = 'N'; *p++ = 'F';
+ }
+ else
+ {
+ *p++ = 'i'; *p++ = 'n'; *p++ = 'f';
+ }
+ }
+ else
+ {
+ int exponent;
+ double mantissa;
+
+ if (arg > 0.0)
+ mantissa = printf_frexp (arg, &exponent);
+ else
+ {
+ exponent = 0;
+ mantissa = 0.0;
+ }
+
+ if (has_precision
+ && precision < (unsigned int) ((DBL_DIG + 1) * 0.831) + 1)
+ {
+ /* Round the mantissa. */
+ double tail = mantissa;
+ size_t q;
+
+ for (q = precision; ; q--)
+ {
+ int digit = (int) tail;
+ tail -= digit;
+ if (q == 0)
+ {
+ if (digit & 1 ? tail >= 0.5 : tail > 0.5)
+ tail = 1 - tail;
+ else
+ tail = - tail;
+ break;
+ }
+ tail *= 16.0;
+ }
+ if (tail != 0.0)
+ for (q = precision; q > 0; q--)
+ tail *= 0.0625;
+ mantissa += tail;
+ }
+
+ *p++ = '0';
+ *p++ = dp->conversion - 'A' + 'X';
+ pad_ptr = p;
+ {
+ int digit;
+
+ digit = (int) mantissa;
+ mantissa -= digit;
+ *p++ = '0' + digit;
+ if ((flags & FLAG_ALT)
+ || mantissa > 0.0 || precision > 0)
+ {
+ *p++ = '.';
+ /* This loop terminates because we assume
+ that FLT_RADIX is a power of 2. */
+ while (mantissa > 0.0)
+ {
+ mantissa *= 16.0;
+ digit = (int) mantissa;
+ mantissa -= digit;
+ *p++ = digit
+ + (digit < 10
+ ? '0'
+ : dp->conversion - 10);
+ if (precision > 0)
+ precision--;
+ }
+ while (precision > 0)
+ {
+ *p++ = '0';
+ precision--;
+ }
+ }
+ }
+ *p++ = dp->conversion - 'A' + 'P';
+# if WIDE_CHAR_VERSION
+ {
+ static const wchar_t decimal_format[] =
+ { '%', '+', 'd', '\0' };
+ SNPRINTF (p, 6 + 1, decimal_format, exponent);
+ }
+# else
+ sprintf (p, "%+d", exponent);
+# endif
+ while (*p != '\0')
+ p++;
+ }
+ }
+ }
+ /* The generated string now extends from tmp to p, with the
+ zero padding insertion point being at pad_ptr. */
+ if (has_width && p - tmp < width)
+ {
+ size_t pad = width - (p - tmp);
+ CHAR_T *end = p + pad;
+
+ if (flags & FLAG_LEFT)
+ {
+ /* Pad with spaces on the right. */
+ for (; pad > 0; pad--)
+ *p++ = ' ';
+ }
+ else if ((flags & FLAG_ZERO) && pad_ptr != NULL)
+ {
+ /* Pad with zeroes. */
+ CHAR_T *q = end;
+
+ while (p > pad_ptr)
+ *--q = *--p;
+ for (; pad > 0; pad--)
+ *p++ = '0';
+ }
+ else
+ {
+ /* Pad with spaces on the left. */
+ CHAR_T *q = end;
+
+ while (p > tmp)
+ *--q = *--p;
+ for (; pad > 0; pad--)
+ *p++ = ' ';
+ }
+
+ p = end;
+ }
+
+ {
+ size_t count = p - tmp;
+
+ if (count >= tmp_length)
+ /* tmp_length was incorrectly calculated - fix the
+ code above! */
+ abort ();
+
+ /* Make room for the result. */
+ if (count >= allocated - length)
+ {
+ size_t n = xsum (length, count);
+
+ ENSURE_ALLOCATION (n);
+ }
+
+ /* Append the result. */
+ memcpy (result + length, tmp, count * sizeof (CHAR_T));
+ if (tmp != tmpbuf)
+ free (tmp);
+ length += count;
+ }
+ }
+#endif
else
{
arg_type type = a.arg[dp->arg_index].type;
@@ -430,12 +907,32 @@ VASNPRINTF (CHAR_T *resultbuf, size_t *lengthp, const CHAR_T *format, va_list ar
break;
case 'e': case 'E': case 'g': case 'G':
- case 'a': case 'A':
tmp_length =
12; /* sign, decimal point, exponent etc. */
tmp_length = xsum (tmp_length, precision);
break;
+ case 'a': case 'A':
+# if HAVE_LONG_DOUBLE
+ if (type == TYPE_LONGDOUBLE)
+ tmp_length =
+ (unsigned int) (LDBL_DIG
+ * 0.831 /* decimal -> hexadecimal */
+ )
+ + 1; /* turn floor into ceil */
+ else
+# endif
+ tmp_length =
+ (unsigned int) (DBL_DIG
+ * 0.831 /* decimal -> hexadecimal */
+ )
+ + 1; /* turn floor into ceil */
+ if (tmp_length < precision)
+ tmp_length = precision;
+ /* Account for sign, decimal point etc. */
+ tmp_length = xsum (tmp_length, 12);
+ break;
+
case 'c':
# if HAVE_WINT_T && !WIDE_CHAR_VERSION
if (type == TYPE_WIDE_CHAR)
diff --git a/lgl/vasnprintf.h b/lgl/vasnprintf.h
index 3ed5714471..f2a035b61a 100644
--- a/lgl/vasnprintf.h
+++ b/lgl/vasnprintf.h
@@ -1,5 +1,5 @@
/* vsprintf with automatic memory allocation.
- Copyright (C) 2002-2004 Free Software Foundation, Inc.
+ Copyright (C) 2002-2004, 2007 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
@@ -65,6 +65,10 @@ extern "C" {
free (output);
}
*/
+#if REPLACE_VASNPRINTF
+# define asnprintf rpl_asnprintf
+# define vasnprintf rpl_vasnprintf
+#endif
extern char * asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
__attribute__ ((__format__ (__printf__, 3, 4)));
extern char * vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
diff --git a/lgl/vasprintf.h b/lgl/vasprintf.h
index b7a7ac87f9..37e7e47e62 100644
--- a/lgl/vasprintf.h
+++ b/lgl/vasprintf.h
@@ -1,5 +1,5 @@
/* vsprintf with automatic memory allocation.
- Copyright (C) 2002-2003 Free Software Foundation, Inc.
+ Copyright (C) 2002-2003, 2007 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
@@ -23,7 +23,9 @@
/* Get asprintf(), vasprintf() declarations. */
#include <stdio.h>
-#else
+#endif
+
+#if !HAVE_VASPRINTF || REPLACE_VASPRINTF
/* Get va_list. */
#include <stdarg.h>
@@ -49,6 +51,10 @@ extern "C" {
If the memory allocation succeeds, store the address of the string in
*RESULT and return the number of resulting bytes, excluding the trailing
NUL. Upon memory allocation error, or some other error, return -1. */
+#if REPLACE_VASPRINTF
+# define asprintf rpl_asprintf
+# define vasprintf rpl_vasprintf
+#endif
extern int asprintf (char **result, const char *format, ...)
__attribute__ ((__format__ (__printf__, 2, 3)));
extern int vasprintf (char **result, const char *format, va_list args)