libxml2-utils.c local_string_to_utf8() function could easily be reused
in other places. This commit extracts it with a new parameter to allow
giving the encoding of the input string and publishes it in
guestfs-utils.h as guestfs_int_string_to_utf8()
---
common/utils/guestfs-utils.h | 1 +
common/utils/libxml2-utils.c | 57 +--------------------------------------
common/utils/utils.c | 64 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 66 insertions(+), 56 deletions(-)
diff --git a/common/utils/guestfs-utils.h b/common/utils/guestfs-utils.h
index 90e7c3dd9..68e704a2c 100644
--- a/common/utils/guestfs-utils.h
+++ b/common/utils/guestfs-utils.h
@@ -70,6 +70,7 @@ extern int guestfs_int_is_fifo (int64_t mode);
extern int guestfs_int_is_lnk (int64_t mode);
extern int guestfs_int_is_sock (int64_t mode);
extern char *guestfs_int_full_path (const char *dir, const char *name);
+extern char * guestfs_int_string_to_utf8 (/* const */ char *input, const char
*encoding);
/* Not all language bindings know how to deal with Pointer arguments.
* Those that don't will use this macro which complains noisily and
diff --git a/common/utils/libxml2-utils.c b/common/utils/libxml2-utils.c
index 8a05aa5b1..f83bb177e 100644
--- a/common/utils/libxml2-utils.c
+++ b/common/utils/libxml2-utils.c
@@ -31,7 +31,6 @@
#include <errno.h>
#include <locale.h>
#include <langinfo.h>
-#include <iconv.h>
#include <libxml/uri.h>
@@ -120,59 +119,5 @@ guestfs_int_parse_nonstandard_uri (const char *arg)
static char *
local_string_to_utf8 (/* const */ char *input)
{
- iconv_t ic;
- size_t len, inlen, outlen, outalloc, r, prev;
- int err;
- char *out, *inp, *outp;
-
- /* Convert from input locale to UTF-8. */
- ic = iconv_open ("UTF-8", nl_langinfo (CODESET));
- if (ic == (iconv_t) -1)
- return NULL;
-
- len = strlen (input);
- outalloc = len; /* Initial guess. */
-
- again:
- inlen = len;
- outlen = outalloc;
- out = malloc (outlen + 1);
- if (out == NULL) {
- err = errno;
- iconv_close (ic);
- errno = err;
- return NULL;
- }
- inp = input;
- outp = out;
-
- r = iconv (ic, (ICONV_CONST char **) &inp, &inlen, &outp, &outlen);
- if (r == (size_t) -1) {
- if (errno == E2BIG) {
- err = errno;
- prev = outalloc;
- /* Try again with a larger output buffer. */
- free (out);
- outalloc *= 2;
- if (outalloc < prev) {
- iconv_close (ic);
- errno = err;
- return NULL;
- }
- goto again;
- }
- else {
- /* Else some other conversion failure, eg. EILSEQ, EINVAL. */
- err = errno;
- iconv_close (ic);
- free (out);
- errno = err;
- return NULL;
- }
- }
-
- *outp = '\0';
- iconv_close (ic);
-
- return out;
+ return guestfs_int_string_to_utf8 (input, nl_langinfo (CODESET));
}
diff --git a/common/utils/utils.c b/common/utils/utils.c
index 22af62b0f..faef7c089 100644
--- a/common/utils/utils.c
+++ b/common/utils/utils.c
@@ -35,6 +35,7 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <libintl.h>
+#include <iconv.h>
/* NB: MUST NOT require linking to gnulib, because that will break the
* Python 'sdist' which includes a copy of this file. It's OK to
@@ -733,3 +734,66 @@ guestfs_int_full_path (const char *dir, const char *name)
return path;
}
+
+/* Would be const, but the interface to iconv is not const-correct on
+ * all platforms. The input string is not touched.
+ */
+char *
+guestfs_int_string_to_utf8 (/* const */ char *input, const char *encoding)
+{
+ iconv_t ic;
+ size_t len, inlen, outlen, outalloc, r, prev;
+ int err;
+ char *out, *inp, *outp;
+
+ /* Convert from input encoding to UTF-8. */
+ ic = iconv_open ("UTF-8", encoding);
+ if (ic == (iconv_t) -1)
+ return NULL;
+
+ len = strlen (input);
+ outalloc = len; /* Initial guess. */
+
+ again:
+ inlen = len;
+ outlen = outalloc;
+ out = malloc (outlen + 1);
+ if (out == NULL) {
+ err = errno;
+ iconv_close (ic);
+ errno = err;
+ return NULL;
+ }
+ inp = input;
+ outp = out;
+
+ r = iconv (ic, (ICONV_CONST char **) &inp, &inlen, &outp, &outlen);
+ if (r == (size_t) -1) {
+ if (errno == E2BIG) {
+ err = errno;
+ prev = outalloc;
+ /* Try again with a larger output buffer. */
+ free (out);
+ outalloc *= 2;
+ if (outalloc < prev) {
+ iconv_close (ic);
+ errno = err;
+ return NULL;
+ }
+ goto again;
+ }
+ else {
+ /* Else some other conversion failure, eg. EILSEQ, EINVAL. */
+ err = errno;
+ iconv_close (ic);
+ free (out);
+ errno = err;
+ return NULL;
+ }
+ }
+
+ *outp = '\0';
+ iconv_close (ic);
+
+ return out;
+}
--
2.16.1