summaryrefslogtreecommitdiff
path: root/source4/lib/charset
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/charset')
-rw-r--r--source4/lib/charset/charcnv.c97
-rw-r--r--source4/lib/charset/charset.h2
-rw-r--r--source4/lib/charset/tests/iconv.c4
-rw-r--r--source4/lib/charset/util_unistr.c38
4 files changed, 77 insertions, 64 deletions
diff --git a/source4/lib/charset/charcnv.c b/source4/lib/charset/charcnv.c
index bbc40e3e3b..83bd11563f 100644
--- a/source4/lib/charset/charcnv.c
+++ b/source4/lib/charset/charcnv.c
@@ -4,6 +4,7 @@
Copyright (C) Igor Vergeichik <iverg@mail.ru> 2001
Copyright (C) Andrew Tridgell 2001
Copyright (C) Simo Sorce 2001
+ Copyright (C) Jelmer Vernooij 2007
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
@@ -167,9 +168,10 @@ static smb_iconv_t get_conv_handle(struct smb_iconv_convenience *ic,
* @param destlen maximal length allowed for string
* @returns the number of bytes occupied in the destination
**/
-_PUBLIC_ ssize_t convert_string(charset_t from, charset_t to,
- void const *src, size_t srclen,
- void *dest, size_t destlen)
+_PUBLIC_ ssize_t convert_string(struct smb_iconv_convenience *ic,
+ charset_t from, charset_t to,
+ void const *src, size_t srclen,
+ void *dest, size_t destlen)
{
size_t i_len, o_len;
size_t retval;
@@ -180,7 +182,7 @@ _PUBLIC_ ssize_t convert_string(charset_t from, charset_t to,
if (srclen == (size_t)-1)
srclen = strlen(inbuf)+1;
- descriptor = get_conv_handle(global_smb_iconv_convenience, from, to);
+ descriptor = get_conv_handle(ic, from, to);
if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
/* conversion not supported, use as is */
@@ -202,12 +204,12 @@ _PUBLIC_ ssize_t convert_string(charset_t from, charset_t to,
reason="No more room";
if (from == CH_UNIX) {
DEBUG(0,("E2BIG: convert_string(%s,%s): srclen=%d destlen=%d - '%s'\n",
- charset_name(global_smb_iconv_convenience, from), charset_name(global_smb_iconv_convenience, to),
+ charset_name(ic, from), charset_name(ic, to),
(int)srclen, (int)destlen,
(const char *)src));
} else {
DEBUG(0,("E2BIG: convert_string(%s,%s): srclen=%d destlen=%d\n",
- charset_name(global_smb_iconv_convenience, from), charset_name(global_smb_iconv_convenience, to),
+ charset_name(ic, from), charset_name(ic, to),
(int)srclen, (int)destlen));
}
return -1;
@@ -288,8 +290,11 @@ convert:
* @returns Size in bytes of the converted string; or -1 in case of error.
**/
-_PUBLIC_ ssize_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_t to,
- void const *src, size_t srclen, void **dest)
+_PUBLIC_ ssize_t convert_string_talloc(TALLOC_CTX *ctx,
+ struct smb_iconv_convenience *ic,
+ charset_t from, charset_t to,
+ void const *src, size_t srclen,
+ void **dest)
{
smb_iconv_t descriptor;
@@ -298,13 +303,13 @@ _PUBLIC_ ssize_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_
if (src == NULL || srclen == (size_t)-1 || srclen == 0)
return (size_t)-1;
- descriptor = get_conv_handle(global_smb_iconv_convenience, from, to);
+ descriptor = get_conv_handle(ic, from, to);
if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) {
/* conversion not supported, return -1*/
DEBUG(3, ("convert_string_talloc: conversion from %s to %s not supported!\n",
- charset_name(global_smb_iconv_convenience, from),
- charset_name(global_smb_iconv_convenience, to)));
+ charset_name(ic, from),
+ charset_name(ic, to)));
return -1;
}
@@ -325,7 +330,8 @@ _PUBLIC_ ssize_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_
* @param dest_len the maximum length in bytes allowed in the
* destination. If @p dest_len is -1 then no maximum is used.
**/
-static ssize_t push_ascii(void *dest, const char *src, size_t dest_len, int flags)
+static ssize_t push_ascii(struct smb_iconv_convenience *ic,
+ void *dest, const char *src, size_t dest_len, int flags)
{
size_t src_len;
ssize_t ret;
@@ -335,7 +341,7 @@ static ssize_t push_ascii(void *dest, const char *src, size_t dest_len, int flag
if (tmpbuf == NULL) {
return -1;
}
- ret = push_ascii(dest, tmpbuf, dest_len, flags & ~STR_UPPER);
+ ret = push_ascii(ic, dest, tmpbuf, dest_len, flags & ~STR_UPPER);
talloc_free(tmpbuf);
return ret;
}
@@ -345,7 +351,7 @@ static ssize_t push_ascii(void *dest, const char *src, size_t dest_len, int flag
if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII))
src_len++;
- return convert_string(CH_UNIX, CH_DOS, src, src_len, dest, dest_len);
+ return convert_string(ic, CH_UNIX, CH_DOS, src, src_len, dest, dest_len);
}
/**
@@ -357,11 +363,11 @@ static ssize_t push_ascii(void *dest, const char *src, size_t dest_len, int flag
* @returns The number of bytes occupied by the string in the destination
* or -1 in case of error.
**/
-_PUBLIC_ ssize_t push_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
+_PUBLIC_ ssize_t push_ascii_talloc(TALLOC_CTX *ctx, struct smb_iconv_convenience *ic, char **dest, const char *src)
{
size_t src_len = strlen(src)+1;
*dest = NULL;
- return convert_string_talloc(ctx, CH_UNIX, CH_DOS, src, src_len, (void **)dest);
+ return convert_string_talloc(ctx, ic, CH_UNIX, CH_DOS, src, src_len, (void **)dest);
}
@@ -380,7 +386,7 @@ _PUBLIC_ ssize_t push_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src
* @param src_len is the length of the source area in bytes.
* @returns the number of bytes occupied by the string in @p src.
**/
-static ssize_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
+static ssize_t pull_ascii(struct smb_iconv_convenience *ic, char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
{
size_t ret;
@@ -395,7 +401,7 @@ static ssize_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t s
}
}
- ret = convert_string(CH_DOS, CH_UNIX, src, src_len, dest, dest_len);
+ ret = convert_string(ic, CH_DOS, CH_UNIX, src, src_len, dest, dest_len);
if (dest_len)
dest[MIN(ret, dest_len-1)] = 0;
@@ -419,7 +425,8 @@ static ssize_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t s
* @param dest_len is the maximum length allowed in the
* destination. If dest_len is -1 then no maxiumum is used.
**/
-static ssize_t push_ucs2(void *dest, const char *src, size_t dest_len, int flags)
+static ssize_t push_ucs2(struct smb_iconv_convenience *ic,
+ void *dest, const char *src, size_t dest_len, int flags)
{
size_t len=0;
size_t src_len = strlen(src);
@@ -430,7 +437,7 @@ static ssize_t push_ucs2(void *dest, const char *src, size_t dest_len, int flags
if (tmpbuf == NULL) {
return -1;
}
- ret = push_ucs2(dest, tmpbuf, dest_len, flags & ~STR_UPPER);
+ ret = push_ucs2(ic, dest, tmpbuf, dest_len, flags & ~STR_UPPER);
talloc_free(tmpbuf);
return ret;
}
@@ -448,7 +455,7 @@ static ssize_t push_ucs2(void *dest, const char *src, size_t dest_len, int flags
/* ucs2 is always a multiple of 2 bytes */
dest_len &= ~1;
- ret = convert_string(CH_UNIX, CH_UTF16, src, src_len, dest, dest_len);
+ ret = convert_string(ic, CH_UNIX, CH_UTF16, src, src_len, dest, dest_len);
if (ret == (size_t)-1) {
return 0;
}
@@ -468,11 +475,11 @@ static ssize_t push_ucs2(void *dest, const char *src, size_t dest_len, int flags
* @returns The number of bytes occupied by the string in the destination
* or -1 in case of error.
**/
-_PUBLIC_ ssize_t push_ucs2_talloc(TALLOC_CTX *ctx, void **dest, const char *src)
+_PUBLIC_ ssize_t push_ucs2_talloc(TALLOC_CTX *ctx, struct smb_iconv_convenience *ic, void **dest, const char *src)
{
size_t src_len = strlen(src)+1;
*dest = NULL;
- return convert_string_talloc(ctx, CH_UNIX, CH_UTF16, src, src_len, dest);
+ return convert_string_talloc(ctx, ic, CH_UNIX, CH_UTF16, src, src_len, dest);
}
@@ -484,11 +491,11 @@ _PUBLIC_ ssize_t push_ucs2_talloc(TALLOC_CTX *ctx, void **dest, const char *src)
* @returns The number of bytes occupied by the string in the destination
**/
-_PUBLIC_ ssize_t push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
+_PUBLIC_ ssize_t push_utf8_talloc(TALLOC_CTX *ctx, struct smb_iconv_convenience *ic, char **dest, const char *src)
{
size_t src_len = strlen(src)+1;
*dest = NULL;
- return convert_string_talloc(ctx, CH_UNIX, CH_UTF8, src, src_len, (void **)dest);
+ return convert_string_talloc(ctx, ic, CH_UNIX, CH_UTF8, src, src_len, (void **)dest);
}
/**
@@ -502,7 +509,7 @@ _PUBLIC_ ssize_t push_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
The resulting string in "dest" is always null terminated.
**/
-static size_t pull_ucs2(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
+static size_t pull_ucs2(struct smb_iconv_convenience *ic, char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
{
size_t ret;
@@ -524,7 +531,7 @@ static size_t pull_ucs2(char *dest, const void *src, size_t dest_len, size_t src
if (src_len != (size_t)-1)
src_len &= ~1;
- ret = convert_string(CH_UTF16, CH_UNIX, src, src_len, dest, dest_len);
+ ret = convert_string(ic, CH_UTF16, CH_UNIX, src, src_len, dest, dest_len);
if (dest_len)
dest[MIN(ret, dest_len-1)] = 0;
@@ -539,11 +546,11 @@ static size_t pull_ucs2(char *dest, const void *src, size_t dest_len, size_t src
* @returns The number of bytes occupied by the string in the destination
**/
-_PUBLIC_ ssize_t pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
+_PUBLIC_ ssize_t pull_ascii_talloc(TALLOC_CTX *ctx, struct smb_iconv_convenience *ic, char **dest, const char *src)
{
size_t src_len = strlen(src)+1;
*dest = NULL;
- return convert_string_talloc(ctx, CH_DOS, CH_UNIX, src, src_len, (void **)dest);
+ return convert_string_talloc(ctx, ic, CH_DOS, CH_UNIX, src, src_len, (void **)dest);
}
/**
@@ -554,11 +561,11 @@ _PUBLIC_ ssize_t pull_ascii_talloc(TALLOC_CTX *ctx, char **dest, const char *src
* @returns The number of bytes occupied by the string in the destination
**/
-_PUBLIC_ ssize_t pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const void *src)
+_PUBLIC_ ssize_t pull_ucs2_talloc(TALLOC_CTX *ctx, struct smb_iconv_convenience *ic, char **dest, const void *src)
{
size_t src_len = utf16_len(src);
*dest = NULL;
- return convert_string_talloc(ctx, CH_UTF16, CH_UNIX, src, src_len, (void **)dest);
+ return convert_string_talloc(ctx, ic, CH_UTF16, CH_UNIX, src, src_len, (void **)dest);
}
/**
@@ -569,11 +576,11 @@ _PUBLIC_ ssize_t pull_ucs2_talloc(TALLOC_CTX *ctx, char **dest, const void *src)
* @returns The number of bytes occupied by the string in the destination
**/
-_PUBLIC_ ssize_t pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
+_PUBLIC_ ssize_t pull_utf8_talloc(TALLOC_CTX *ctx, struct smb_iconv_convenience *ic, char **dest, const char *src)
{
size_t src_len = strlen(src)+1;
*dest = NULL;
- return convert_string_talloc(ctx, CH_UTF8, CH_UNIX, src, src_len, (void **)dest);
+ return convert_string_talloc(ctx, ic, CH_UTF8, CH_UNIX, src, src_len, (void **)dest);
}
/**
@@ -590,12 +597,13 @@ _PUBLIC_ ssize_t pull_utf8_talloc(TALLOC_CTX *ctx, char **dest, const char *src)
is -1 then no maxiumum is used.
**/
-_PUBLIC_ ssize_t push_string(void *dest, const char *src, size_t dest_len, int flags)
+_PUBLIC_ ssize_t push_string(struct smb_iconv_convenience *ic,
+ void *dest, const char *src, size_t dest_len, int flags)
{
if (flags & STR_ASCII) {
- return push_ascii(dest, src, dest_len, flags);
+ return push_ascii(ic, dest, src, dest_len, flags);
} else if (flags & STR_UNICODE) {
- return push_ucs2(dest, src, dest_len, flags);
+ return push_ucs2(ic, dest, src, dest_len, flags);
} else {
smb_panic("push_string requires either STR_ASCII or STR_UNICODE flag to be set");
return -1;
@@ -617,12 +625,13 @@ _PUBLIC_ ssize_t push_string(void *dest, const char *src, size_t dest_len, int f
The resulting string in "dest" is always null terminated.
**/
-_PUBLIC_ ssize_t pull_string(char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
+_PUBLIC_ ssize_t pull_string(struct smb_iconv_convenience *ic,
+ char *dest, const void *src, size_t dest_len, size_t src_len, int flags)
{
if (flags & STR_ASCII) {
- return pull_ascii(dest, src, dest_len, src_len, flags);
+ return pull_ascii(ic, dest, src, dest_len, src_len, flags);
} else if (flags & STR_UNICODE) {
- return pull_ucs2(dest, src, dest_len, src_len, flags);
+ return pull_ucs2(ic, dest, src, dest_len, src_len, flags);
} else {
smb_panic("pull_string requires either STR_ASCII or STR_UNICODE flag to be set");
return -1;
@@ -639,7 +648,8 @@ _PUBLIC_ ssize_t pull_string(char *dest, const void *src, size_t dest_len, size_
return INVALID_CODEPOINT if the next character cannot be converted
*/
-_PUBLIC_ codepoint_t next_codepoint(const char *str, size_t *size)
+_PUBLIC_ codepoint_t next_codepoint(struct smb_iconv_convenience *ic,
+ const char *str, size_t *size)
{
/* it cannot occupy more than 4 bytes in UTF16 format */
uint8_t buf[4];
@@ -660,7 +670,7 @@ _PUBLIC_ codepoint_t next_codepoint(const char *str, size_t *size)
ilen_orig = strnlen(str, 5);
ilen = ilen_orig;
- descriptor = get_conv_handle(global_smb_iconv_convenience, CH_UNIX, CH_UTF16);
+ descriptor = get_conv_handle(ic, CH_UNIX, CH_UTF16);
if (descriptor == (smb_iconv_t)-1) {
*size = 1;
return INVALID_CODEPOINT;
@@ -711,7 +721,8 @@ _PUBLIC_ codepoint_t next_codepoint(const char *str, size_t *size)
return the number of bytes occupied by the CH_UNIX character, or
-1 on failure
*/
-_PUBLIC_ ssize_t push_codepoint(char *str, codepoint_t c)
+_PUBLIC_ ssize_t push_codepoint(struct smb_iconv_convenience *ic,
+ char *str, codepoint_t c)
{
smb_iconv_t descriptor;
uint8_t buf[4];
@@ -723,7 +734,7 @@ _PUBLIC_ ssize_t push_codepoint(char *str, codepoint_t c)
return 1;
}
- descriptor = get_conv_handle(global_smb_iconv_convenience,
+ descriptor = get_conv_handle(ic,
CH_UTF16, CH_UNIX);
if (descriptor == (smb_iconv_t)-1) {
return -1;
diff --git a/source4/lib/charset/charset.h b/source4/lib/charset/charset.h
index 96762af85a..b1bb18a7c8 100644
--- a/source4/lib/charset/charset.h
+++ b/source4/lib/charset/charset.h
@@ -71,6 +71,8 @@ typedef struct smb_iconv_s {
#define STR_LEN_NOTERM 256 /* the length field is the unterminated length */
struct loadparm_context;
+struct smb_iconv_convenience;
+extern struct smb_iconv_convenience *global_smb_iconv_convenience;
#include "lib/charset/charset_proto.h"
diff --git a/source4/lib/charset/tests/iconv.c b/source4/lib/charset/tests/iconv.c
index bc5ae62dae..ca13dc503a 100644
--- a/source4/lib/charset/tests/iconv.c
+++ b/source4/lib/charset/tests/iconv.c
@@ -288,7 +288,7 @@ static bool test_codepoint(struct torture_context *tctx, unsigned int codepoint)
size_t size, size2;
codepoint_t c;
- size = push_codepoint((char *)buf, codepoint);
+ size = push_codepoint(global_smb_iconv_convenience, (char *)buf, codepoint);
torture_assert(tctx, size != -1 || (codepoint >= 0xd800 && codepoint <= 0x10000),
"Invalid Codepoint range");
@@ -299,7 +299,7 @@ static bool test_codepoint(struct torture_context *tctx, unsigned int codepoint)
buf[size+2] = random();
buf[size+3] = random();
- c = next_codepoint((char *)buf, &size2);
+ c = next_codepoint(global_smb_iconv_convenience, (char *)buf, &size2);
torture_assert(tctx, c == codepoint,
talloc_asprintf(tctx,
diff --git a/source4/lib/charset/util_unistr.c b/source4/lib/charset/util_unistr.c
index e9cca090cc..67a790c250 100644
--- a/source4/lib/charset/util_unistr.c
+++ b/source4/lib/charset/util_unistr.c
@@ -129,8 +129,8 @@ _PUBLIC_ int strcasecmp_m(const char *s1, const char *s2)
if (s2 == NULL) return 1;
while (*s1 && *s2) {
- c1 = next_codepoint(s1, &size1);
- c2 = next_codepoint(s2, &size2);
+ c1 = next_codepoint(global_smb_iconv_convenience, s1, &size1);
+ c2 = next_codepoint(global_smb_iconv_convenience, s2, &size2);
s1 += size1;
s2 += size2;
@@ -215,8 +215,8 @@ _PUBLIC_ int strncasecmp_m(const char *s1, const char *s2, size_t n)
while (*s1 && *s2 && n) {
n--;
- c1 = next_codepoint(s1, &size1);
- c2 = next_codepoint(s2, &size2);
+ c1 = next_codepoint(global_smb_iconv_convenience, s1, &size1);
+ c2 = next_codepoint(global_smb_iconv_convenience, s2, &size2);
s1 += size1;
s2 += size2;
@@ -275,7 +275,7 @@ _PUBLIC_ void string_replace_w(char *s, char oldc, char newc)
{
while (s && *s) {
size_t size;
- codepoint_t c = next_codepoint(s, &size);
+ codepoint_t c = next_codepoint(global_smb_iconv_convenience, s, &size);
if (c == oldc) {
*s = newc;
}
@@ -353,7 +353,7 @@ _PUBLIC_ size_t strlen_m(const char *s)
while (*s) {
size_t c_size;
- codepoint_t c = next_codepoint(s, &c_size);
+ codepoint_t c = next_codepoint(global_smb_iconv_convenience, s, &c_size);
if (c < 0x10000) {
count += 1;
} else {
@@ -391,7 +391,7 @@ _PUBLIC_ char *strchr_m(const char *s, char c)
while (*s) {
size_t size;
- codepoint_t c2 = next_codepoint(s, &size);
+ codepoint_t c2 = next_codepoint(global_smb_iconv_convenience, s, &size);
if (c2 == c) {
return discard_const_p(char, s);
}
@@ -416,7 +416,7 @@ _PUBLIC_ char *strrchr_m(const char *s, char c)
while (*s) {
size_t size;
- codepoint_t c2 = next_codepoint(s, &size);
+ codepoint_t c2 = next_codepoint(global_smb_iconv_convenience, s, &size);
if (c2 == c) {
ret = discard_const_p(char, s);
}
@@ -436,7 +436,7 @@ _PUBLIC_ bool strhaslower(const char *string)
codepoint_t s;
codepoint_t t;
- s = next_codepoint(string, &c_size);
+ s = next_codepoint(global_smb_iconv_convenience, string, &c_size);
string += c_size;
t = toupper_w(s);
@@ -459,7 +459,7 @@ _PUBLIC_ bool strhasupper(const char *string)
codepoint_t s;
codepoint_t t;
- s = next_codepoint(string, &c_size);
+ s = next_codepoint(global_smb_iconv_convenience, string, &c_size);
string += c_size;
t = tolower_w(s);
@@ -489,12 +489,12 @@ _PUBLIC_ char *strlower_talloc(TALLOC_CTX *ctx, const char *src)
while (*src) {
size_t c_size;
- codepoint_t c = next_codepoint(src, &c_size);
+ codepoint_t c = next_codepoint(global_smb_iconv_convenience, src, &c_size);
src += c_size;
c = tolower_w(c);
- c_size = push_codepoint(dest+size, c);
+ c_size = push_codepoint(global_smb_iconv_convenience, dest+size, c);
if (c_size == -1) {
talloc_free(dest);
return NULL;
@@ -533,12 +533,12 @@ _PUBLIC_ char *strupper_talloc(TALLOC_CTX *ctx, const char *src)
while (*src) {
size_t c_size;
- codepoint_t c = next_codepoint(src, &c_size);
+ codepoint_t c = next_codepoint(global_smb_iconv_convenience, src, &c_size);
src += c_size;
c = toupper_w(c);
- c_size = push_codepoint(dest+size, c);
+ c_size = push_codepoint(global_smb_iconv_convenience, dest+size, c);
if (c_size == -1) {
talloc_free(dest);
return NULL;
@@ -579,8 +579,8 @@ _PUBLIC_ void strlower_m(char *s)
while (*s) {
size_t c_size, c_size2;
- codepoint_t c = next_codepoint(s, &c_size);
- c_size2 = push_codepoint(d, tolower_w(c));
+ codepoint_t c = next_codepoint(global_smb_iconv_convenience, s, &c_size);
+ c_size2 = push_codepoint(global_smb_iconv_convenience, d, tolower_w(c));
if (c_size2 > c_size) {
DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strlower_m\n",
c, tolower_w(c), (int)c_size, (int)c_size2));
@@ -615,8 +615,8 @@ _PUBLIC_ void strupper_m(char *s)
while (*s) {
size_t c_size, c_size2;
- codepoint_t c = next_codepoint(s, &c_size);
- c_size2 = push_codepoint(d, toupper_w(c));
+ codepoint_t c = next_codepoint(global_smb_iconv_convenience, s, &c_size);
+ c_size2 = push_codepoint(global_smb_iconv_convenience, d, toupper_w(c));
if (c_size2 > c_size) {
DEBUG(0,("FATAL: codepoint 0x%x (0x%x) expanded from %d to %d bytes in strupper_m\n",
c, toupper_w(c), (int)c_size, (int)c_size2));
@@ -638,7 +638,7 @@ _PUBLIC_ size_t count_chars_w(const char *s, char c)
while (*s) {
size_t size;
- codepoint_t c2 = next_codepoint(s, &size);
+ codepoint_t c2 = next_codepoint(global_smb_iconv_convenience, s, &size);
if (c2 == c) count++;
s += size;
}