+2009-04-26 Bruno Haible <bruno@clisp.org>
+
+ Simplify calling convention of u*_conv_to_encoding.
+ * lib/uniconv.h (u8_conv_to_encoding, u16_conv_to_encoding,
+ u32_conv_to_encoding): Expect a resultbuf argument and return the
+ result directly as a pointer.
+ * lib/uniconv/u8-conv-to-enc.c (u8_conv_to_encoding): Likewise.
+ * lib/uniconv/u-conv-to-enc.h (FUNC): Likewise. Preserve errno while
+ freeing scaled_offsets if mem_iconveha failed.
+ * lib/unicase/u-casexfrm.h (FUNC): Update.
+ * lib/uninorm/u-normxfrm.h (FUNC): Update.
+ * lib/vasnprintf.c (VASNPRINTF): Update.
+ * tests/uniconv/test-u8-conv-to-enc.c (main): Update.
+ * tests/uniconv/test-u16-conv-to-enc.c (main): Update.
+ * tests/uniconv/test-u32-conv-to-enc.c (main): Update.
+ * NEWS: Mention the change.
+
2009-04-26 Bruno Haible <bruno@clisp.org>
Avoid test failures on AIX and OSF/1.
Date Modules Changes
-2009-04-24 maintainer-makefile
+2009-04-26 modules/uniconv/u8-conv-to-enc
+ modules/uniconv/u16-conv-to-enc
+ modules/uniconv/u32-conv-to-enc
+ The calling convention of the functions
+ u*_conv_to_encoding is changed.
+
+2009-04-24 maintainer-makefile
The maint.mk file was copied from
coreutils, and the old
coverage/gettext/indent rules were
char convsbuf[2048];
char *convs;
size_t convs_length;
- int ret;
char *result;
/* Casefold and normalize the Unicode string. */
return NULL;
/* Convert it to locale encoding. */
- convs = convsbuf;
convs_length = sizeof (convsbuf) - 1;
- ret = U_CONV_TO_ENCODING (locale_charset (),
- iconveh_error,
- foldeds, foldeds_length,
- NULL,
- &convs, &convs_length);
- if (ret < 0)
+ convs = U_CONV_TO_ENCODING (locale_charset (),
+ iconveh_error,
+ foldeds, foldeds_length,
+ NULL,
+ convsbuf, &convs_length);
+ if (convs == NULL)
{
if (foldeds != foldedsbuf)
{
array is filled with offsets into the result, i.e. the character starting
at SRC[i] corresponds to the character starting at (*RESULTP)[OFFSETS[i]],
and other offsets are set to (size_t)(-1).
- *RESULTP and *LENGTHP should initially be a scratch buffer and its size,
- or *RESULTP can initially be NULL.
+ RESULTBUF and *LENGTHP should initially be a scratch buffer and its size,
+ or RESULTBUF can be NULL.
May erase the contents of the memory at *RESULTP.
- Return value: 0 if successful, otherwise -1 and errno set.
- If successful: The resulting string is stored in *RESULTP and its length
- in *LENGTHP. *RESULTP is set to a freshly allocated memory block, or is
- unchanged if no dynamic memory allocation was necessary.
- Particular errno values: EINVAL, EILSEQ, ENOMEM. */
-extern int
+ If successful: The resulting string (non-NULL) is returned and its length
+ stored in *LENGTHP. The resulting string is RESULTBUF if no dynamic memory
+ allocation was necessary, or a freshly allocated memory block otherwise.
+ In case of error: NULL is returned and errno is set. Particular errno
+ values: EINVAL, EILSEQ, ENOMEM. */
+extern char *
u8_conv_to_encoding (const char *tocode,
enum iconv_ilseq_handler handler,
const uint8_t *src, size_t srclen,
size_t *offsets,
- char **resultp, size_t *lengthp);
-extern int
+ char *resultbuf, size_t *lengthp);
+extern char *
u16_conv_to_encoding (const char *tocode,
enum iconv_ilseq_handler handler,
const uint16_t *src, size_t srclen,
size_t *offsets,
- char **resultp, size_t *lengthp);
-extern int
+ char *resultbuf, size_t *lengthp);
+extern char *
u32_conv_to_encoding (const char *tocode,
enum iconv_ilseq_handler handler,
const uint32_t *src, size_t srclen,
size_t *offsets,
- char **resultp, size_t *lengthp);
+ char *resultbuf, size_t *lengthp);
/* Converts a NUL terminated string from a given encoding.
The result is malloc allocated, or NULL (with errno set) in case of error.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
-int
+char *
FUNC (const char *tocode,
enum iconv_ilseq_handler handler,
const UNIT *src, size_t srclen,
size_t *offsets,
- char **resultp, size_t *lengthp)
+ char *resultbuf, size_t *lengthp)
{
#if HAVE_UTF_NAME
size_t *scaled_offsets;
+ char *result;
+ size_t length;
int retval;
if (offsets != NULL && srclen > 0)
if (scaled_offsets == NULL)
{
errno = ENOMEM;
- return -1;
+ return NULL;
}
}
else
scaled_offsets = NULL;
+ result = resultbuf;
+ length = *lengthp;
retval = mem_iconveha ((const char *) src, srclen * sizeof (UNIT),
UTF_NAME, tocode,
handler == iconveh_question_mark, handler,
- scaled_offsets, resultp, lengthp);
+ scaled_offsets, &result, &length);
+ if (retval < 0)
+ {
+ int saved_errno = errno;
+ free (scaled_offsets);
+ errno = saved_errno;
+ return NULL;
+ }
if (offsets != NULL)
{
- if (retval >= 0)
- {
- /* Convert scaled_offsets[srclen * sizeof (UNIT)] to
- offsets[srclen]. */
- size_t i;
+ /* Convert scaled_offsets[srclen * sizeof (UNIT)] to
+ offsets[srclen]. */
+ size_t i;
- for (i = 0; i < srclen; i++)
- offsets[i] = scaled_offsets[i * sizeof (UNIT)];
- }
+ for (i = 0; i < srclen; i++)
+ offsets[i] = scaled_offsets[i * sizeof (UNIT)];
free (scaled_offsets);
}
- return retval;
+
+ if (result == NULL) /* when (resultbuf == NULL && length == 0) */
+ {
+ result = (char *) malloc (1);
+ if (result == NULL)
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+ }
+ *lengthp = length;
+ return result;
#else
uint8_t tmpbuf[4096];
size_t tmpbufsize = SIZEOF (tmpbuf);
uint8_t *utf8_src;
size_t utf8_srclen;
size_t *scaled_offsets;
- int retval;
+ char *result;
utf8_src = U_TO_U8 (src, srclen, tmpbuf, &tmpbufsize);
if (utf8_src == NULL)
- return -1;
+ return NULL;
utf8_srclen = tmpbufsize;
if (offsets != NULL && utf8_srclen > 0)
if (utf8_src != tmpbuf)
free (utf8_src);
errno = ENOMEM;
- return -1;
+ return NULL;
}
}
else
scaled_offsets = NULL;
- retval = u8_conv_to_encoding (tocode, handler, utf8_src, utf8_srclen,
- scaled_offsets, resultp, lengthp);
- if (retval < 0)
+ result = u8_conv_to_encoding (tocode, handler, utf8_src, utf8_srclen,
+ scaled_offsets, resultbuf, lengthp);
+ if (result == NULL)
{
int saved_errno = errno;
free (scaled_offsets);
if (utf8_src != tmpbuf)
free (utf8_src);
errno = saved_errno;
- return -1;
+ return NULL;
}
if (offsets != NULL)
{
}
if (utf8_src != tmpbuf)
free (utf8_src);
- return retval;
+ return result;
#endif
}
#include "striconveha.h"
#include "unistr.h"
-int
+char *
u8_conv_to_encoding (const char *tocode,
enum iconv_ilseq_handler handler,
const uint8_t *src, size_t srclen,
size_t *offsets,
- char **resultp, size_t *lengthp)
+ char *resultbuf, size_t *lengthp)
{
- char *result;
-
if (STRCASEEQ (tocode, "UTF-8", 'U','T','F','-','8',0,0,0,0))
{
+ char *result;
+
/* Conversion from UTF-8 to UTF-8. No need to go through iconv(). */
#if CONFIG_UNICODE_SAFETY
if (u8_check (src, srclen))
{
errno = EILSEQ;
- return -1;
+ return NULL;
}
#endif
/* Memory allocation. */
- if ((*resultp != NULL && *lengthp >= srclen) || srclen == 0)
- result = *resultp;
+ if (resultbuf != NULL && *lengthp >= srclen)
+ result = resultbuf;
else
{
- result = (char *) malloc (srclen);
+ result = (char *) malloc (srclen > 0 ? srclen : 1);
if (result == NULL)
{
errno = ENOMEM;
- return -1;
+ return NULL;
}
}
memcpy (result, (const char *) src, srclen);
- *resultp = result;
*lengthp = srclen;
- return 0;
+ return result;
}
else
- return mem_iconveha ((const char *) src, srclen,
- "UTF-8", tocode,
- handler == iconveh_question_mark, handler,
- offsets, resultp, lengthp);
+ {
+ char *result = resultbuf;
+ size_t length = *lengthp;
+ int retval =
+ mem_iconveha ((const char *) src, srclen,
+ "UTF-8", tocode,
+ handler == iconveh_question_mark, handler,
+ offsets, &result, &length);
+
+ if (retval < 0)
+ return NULL;
+
+ if (result == NULL) /* when (resultbuf == NULL && length == 0) */
+ {
+ result = (char *) malloc (1);
+ if (result == NULL)
+ {
+ errno = ENOMEM;
+ return NULL;
+ }
+ }
+ *lengthp = length;
+ return result;
+ }
}
char convsbuf[2048];
char *convs;
size_t convs_length;
- int ret;
char *result;
/* Normalize the Unicode string. */
return NULL;
/* Convert it to locale encoding. */
- convs = convsbuf;
convs_length = sizeof (convsbuf) - 1;
- ret = U_CONV_TO_ENCODING (locale_charset (),
- iconveh_error,
- norms, norms_length,
- NULL,
- &convs, &convs_length);
- if (ret < 0)
+ convs = U_CONV_TO_ENCODING (locale_charset (),
+ iconveh_error,
+ norms, norms_length,
+ NULL,
+ convsbuf, &convs_length);
+ if (convs == NULL)
{
if (norms != normsbuf)
{
size_t converted_len = allocated - length;
# if DCHAR_IS_TCHAR
/* Convert from UTF-8 to locale encoding. */
- if (u8_conv_to_encoding (locale_charset (),
- iconveh_question_mark,
- arg, arg_end - arg, NULL,
- &converted, &converted_len)
- < 0)
+ converted =
+ u8_conv_to_encoding (locale_charset (),
+ iconveh_question_mark,
+ arg, arg_end - arg, NULL,
+ converted, &converted_len);
# else
/* Convert from UTF-8 to UTF-16/UTF-32. */
converted =
U8_TO_DCHAR (arg, arg_end - arg,
converted, &converted_len);
- if (converted == NULL)
# endif
+ if (converted == NULL)
{
int saved_errno = errno;
if (!(result == resultbuf || result == NULL))
size_t converted_len = allocated - length;
# if DCHAR_IS_TCHAR
/* Convert from UTF-16 to locale encoding. */
- if (u16_conv_to_encoding (locale_charset (),
- iconveh_question_mark,
- arg, arg_end - arg, NULL,
- &converted, &converted_len)
- < 0)
+ converted =
+ u16_conv_to_encoding (locale_charset (),
+ iconveh_question_mark,
+ arg, arg_end - arg, NULL,
+ converted, &converted_len);
# else
/* Convert from UTF-16 to UTF-8/UTF-32. */
converted =
U16_TO_DCHAR (arg, arg_end - arg,
converted, &converted_len);
- if (converted == NULL)
# endif
+ if (converted == NULL)
{
int saved_errno = errno;
if (!(result == resultbuf || result == NULL))
size_t converted_len = allocated - length;
# if DCHAR_IS_TCHAR
/* Convert from UTF-32 to locale encoding. */
- if (u32_conv_to_encoding (locale_charset (),
- iconveh_question_mark,
- arg, arg_end - arg, NULL,
- &converted, &converted_len)
- < 0)
+ converted =
+ u32_conv_to_encoding (locale_charset (),
+ iconveh_question_mark,
+ arg, arg_end - arg, NULL,
+ converted, &converted_len);
# else
/* Convert from UTF-32 to UTF-8/UTF-16. */
converted =
U32_TO_DCHAR (arg, arg_end - arg,
converted, &converted_len);
- if (converted == NULL)
# endif
+ if (converted == NULL)
{
int saved_errno = errno;
if (!(result == resultbuf || result == NULL))
/* Test of conversion from UTF-16 to legacy encodings.
- Copyright (C) 2007-2008 Free Software Foundation, Inc.
+ Copyright (C) 2007-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
for (o = 0; o < 2; o++)
{
size_t *offsets = (o ? new_offsets (SIZEOF (input)) : NULL);
- char *result = NULL;
- size_t length = 0;
- int retval = u16_conv_to_encoding ("ISO-8859-1", handler,
- input, SIZEOF (input),
- offsets,
- &result, &length);
- ASSERT (retval == 0);
- ASSERT (length == strlen (expected));
+ size_t length;
+ char *result = u16_conv_to_encoding ("ISO-8859-1", handler,
+ input, SIZEOF (input),
+ offsets,
+ NULL, &length);
ASSERT (result != NULL);
+ ASSERT (length == strlen (expected));
ASSERT (memcmp (result, expected, length) == 0);
if (o)
{
for (o = 0; o < 2; o++)
{
size_t *offsets = (o ? new_offsets (SIZEOF (input)) : NULL);
- char *result = NULL;
- size_t length = 0;
- int retval = u16_conv_to_encoding ("ISO-8859-1", handler,
- input, SIZEOF (input),
- offsets,
- &result, &length);
+ size_t length = 0xdead;
+ char *result = u16_conv_to_encoding ("ISO-8859-1", handler,
+ input, SIZEOF (input),
+ offsets,
+ NULL, &length);
switch (handler)
{
case iconveh_error:
- ASSERT (retval == -1 && errno == EILSEQ);
ASSERT (result == NULL);
- ASSERT (length == 0);
+ ASSERT (errno == EILSEQ);
+ ASSERT (length == 0xdead);
break;
case iconveh_question_mark:
{
static const char expected[] = "Rafa? Maszkowski";
static const char expected_translit[] = "Rafal Maszkowski";
- ASSERT (retval == 0);
- ASSERT (length == strlen (expected));
ASSERT (result != NULL);
+ ASSERT (length == strlen (expected));
ASSERT (memcmp (result, expected, length) == 0
|| memcmp (result, expected_translit, length) == 0);
if (o)
case iconveh_escape_sequence:
{
static const char expected[] = "Rafa\\u0142 Maszkowski";
- ASSERT (retval == 0);
- ASSERT (length == strlen (expected));
ASSERT (result != NULL);
+ ASSERT (length == strlen (expected));
ASSERT (memcmp (result, expected, length) == 0);
if (o)
{
for (o = 0; o < 2; o++)
{
size_t *offsets = (o ? new_offsets (SIZEOF (input)) : NULL);
- char *result = NULL;
- size_t length = 0;
- int retval = u16_conv_to_encoding ("ISO-8859-1", handler,
- input, SIZEOF (input),
- offsets,
- &result, &length);
- ASSERT (retval == 0);
+ size_t length;
+ char *result = u16_conv_to_encoding ("ISO-8859-1", handler,
+ input, SIZEOF (input),
+ offsets,
+ NULL, &length);
+ ASSERT (result != NULL);
ASSERT (length == strlen (""));
- /* result may be == NULL or != NULL. */
if (o)
{
ASSERT (offsets[0] == 0);
/* Test of conversion from UTF-32 to legacy encodings.
- Copyright (C) 2007-2008 Free Software Foundation, Inc.
+ Copyright (C) 2007-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
for (o = 0; o < 2; o++)
{
size_t *offsets = (o ? new_offsets (SIZEOF (input)) : NULL);
- char *result = NULL;
- size_t length = 0;
- int retval = u32_conv_to_encoding ("ISO-8859-1", handler,
- input, SIZEOF (input),
- offsets,
- &result, &length);
- ASSERT (retval == 0);
- ASSERT (length == strlen (expected));
+ size_t length;
+ char *result = u32_conv_to_encoding ("ISO-8859-1", handler,
+ input, SIZEOF (input),
+ offsets,
+ NULL, &length);
ASSERT (result != NULL);
+ ASSERT (length == strlen (expected));
ASSERT (memcmp (result, expected, length) == 0);
if (o)
{
for (o = 0; o < 2; o++)
{
size_t *offsets = (o ? new_offsets (SIZEOF (input)) : NULL);
- char *result = NULL;
- size_t length = 0;
- int retval = u32_conv_to_encoding ("ISO-8859-1", handler,
- input, SIZEOF (input),
- offsets,
- &result, &length);
+ size_t length = 0xdead;
+ char *result = u32_conv_to_encoding ("ISO-8859-1", handler,
+ input, SIZEOF (input),
+ offsets,
+ NULL, &length);
switch (handler)
{
case iconveh_error:
- ASSERT (retval == -1 && errno == EILSEQ);
ASSERT (result == NULL);
- ASSERT (length == 0);
+ ASSERT (errno == EILSEQ);
+ ASSERT (length == 0xdead);
break;
case iconveh_question_mark:
{
static const char expected[] = "Rafa? Maszkowski";
static const char expected_translit[] = "Rafal Maszkowski";
- ASSERT (retval == 0);
- ASSERT (length == strlen (expected));
ASSERT (result != NULL);
+ ASSERT (length == strlen (expected));
ASSERT (memcmp (result, expected, length) == 0
|| memcmp (result, expected_translit, length) == 0);
if (o)
case iconveh_escape_sequence:
{
static const char expected[] = "Rafa\\u0142 Maszkowski";
- ASSERT (retval == 0);
- ASSERT (length == strlen (expected));
ASSERT (result != NULL);
+ ASSERT (length == strlen (expected));
ASSERT (memcmp (result, expected, length) == 0);
if (o)
{
/* Test of conversion from UTF-8 to legacy encodings.
- Copyright (C) 2007-2008 Free Software Foundation, Inc.
+ Copyright (C) 2007-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
for (o = 0; o < 2; o++)
{
size_t *offsets = (o ? new_offsets (u8_strlen (input)) : NULL);
- char *result = NULL;
- size_t length = 0;
- int retval = u8_conv_to_encoding ("ISO-8859-1", handler,
- input, u8_strlen (input),
- offsets,
- &result, &length);
- ASSERT (retval == 0);
- ASSERT (length == strlen (expected));
+ size_t length;
+ char *result = u8_conv_to_encoding ("ISO-8859-1", handler,
+ input, u8_strlen (input),
+ offsets,
+ NULL, &length);
ASSERT (result != NULL);
+ ASSERT (length == strlen (expected));
ASSERT (memcmp (result, expected, length) == 0);
if (o)
{
for (o = 0; o < 2; o++)
{
size_t *offsets = (o ? new_offsets (u8_strlen (input)) : NULL);
- char *result = NULL;
- size_t length = 0;
- int retval = u8_conv_to_encoding ("ISO-8859-1", handler,
- input, u8_strlen (input),
- offsets,
- &result, &length);
+ size_t length = 0xdead;
+ char *result = u8_conv_to_encoding ("ISO-8859-1", handler,
+ input, u8_strlen (input),
+ offsets,
+ NULL, &length);
switch (handler)
{
case iconveh_error:
- ASSERT (retval == -1 && errno == EILSEQ);
ASSERT (result == NULL);
- ASSERT (length == 0);
+ ASSERT (errno == EILSEQ);
+ ASSERT (length == 0xdead);
break;
case iconveh_question_mark:
{
static const char expected[] = "Rafa? Maszkowski";
static const char expected_translit[] = "Rafal Maszkowski";
- ASSERT (retval == 0);
- ASSERT (length == strlen (expected));
ASSERT (result != NULL);
+ ASSERT (length == strlen (expected));
ASSERT (memcmp (result, expected, length) == 0
|| memcmp (result, expected_translit, length) == 0);
if (o)
case iconveh_escape_sequence:
{
static const char expected[] = "Rafa\\u0142 Maszkowski";
- ASSERT (retval == 0);
- ASSERT (length == strlen (expected));
ASSERT (result != NULL);
+ ASSERT (length == strlen (expected));
ASSERT (memcmp (result, expected, length) == 0);
if (o)
{
for (o = 0; o < 2; o++)
{
size_t *offsets = (o ? new_offsets (u8_strlen (input)) : NULL);
- char *result = NULL;
- size_t length = 0;
- int retval = u8_conv_to_encoding ("ISO-8859-1", handler,
- input, u8_strlen (input),
- offsets,
- &result, &length);
- ASSERT (retval == 0);
+ size_t length;
+ char *result = u8_conv_to_encoding ("ISO-8859-1", handler,
+ input, u8_strlen (input),
+ offsets,
+ NULL, &length);
+ ASSERT (result != NULL);
ASSERT (length == strlen (""));
- /* result may be == NULL or != NULL. */
if (o)
{
ASSERT (offsets[0] == 0);