PERFORCE change 146565 for review
Konrad Jankowski
konrad at FreeBSD.org
Sun Aug 3 21:41:35 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=146565
Change 146565 by konrad at vspredator on 2008/08/03 21:41:32
Finally, only the relevant deltas.
Affected files ...
.. //depot/projects/soc2008/konrad_collation/libc/locale/collate.h#6 edit
.. //depot/projects/soc2008/konrad_collation/libc/locale/collcmp.c#6 edit
.. //depot/projects/soc2008/konrad_collation/libc/locale/setlocale.c#6 edit
.. //depot/projects/soc2008/konrad_collation/libc/string/strcoll.c#6 edit
.. //depot/projects/soc2008/konrad_collation/libc/string/strxfrm.c#6 edit
.. //depot/projects/soc2008/konrad_collation/libc/string/wcscoll.c#6 edit
.. //depot/projects/soc2008/konrad_collation/libc/string/wcsxfrm.c#6 edit
Differences ...
==== //depot/projects/soc2008/konrad_collation/libc/locale/collate.h#6 (text+ko) ====
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: src/lib/libc/locale/collate.h,v 1.15 2005/02/27 20:31:13 ru Exp $
+ * $FreeBSD: src/lib/libc/locale/collate.h,v 1.14 2002/08/30 20:26:02 ache Exp $
*/
#ifndef _COLLATE_H_
@@ -33,34 +33,91 @@
#include <sys/cdefs.h>
#include <sys/types.h>
#include <limits.h>
+#include "setlocale.h" /* for ENCODING_LEN */
+
+#undef COLL_WEIGHTS_MAX
+#define COLL_WEIGHTS_MAX 4
#define STR_LEN 10
#define TABLE_SIZE 100
-#define COLLATE_VERSION "1.0\n"
-#define COLLATE_VERSION1_2 "1.2\n"
+#define COLLATE_VERSION "1.0\n"
+#define COLLATE_VERSION1_1 "1.1\n"
+#define COLLATE_VERSION1_1A "1.1A\n"
+#define COLLATE_VERSION1_2 "1.2\n"
+#define COLLATE_VERSION1_3 "1.3\n"
+/* see discussion in string/FreeBSD/strxfrm for this value */
+#define COLLATE_MAX_PRIORITY ((1 << 24) - 1)
+
+#define DIRECTIVE_UNDEF 0x00
+#define DIRECTIVE_FORWARD 0x01
+#define DIRECTIVE_BACKWARD 0x02
+#define DIRECTIVE_POSITION 0x04
+
+#define DIRECTIVE_DIRECTION_MASK (DIRECTIVE_FORWARD | DIRECTIVE_BACKWARD)
+
+#define COLLATE_SUBST_DUP 0x0001
+
+#define IGNORE_EQUIV_CLASS 1
+
+struct __collate_st_info {
+ __uint8_t directive[COLL_WEIGHTS_MAX];
+ __uint8_t flags;
+#if _BYTE_ORDER == _LITTLE_ENDIAN
+ unsigned int directive_count:4;
+ unsigned int chain_max_len:4;
+#else
+ unsigned int chain_max_len:4;
+ unsigned int directive_count:4;
+#endif
+ __int32_t undef_pri[COLL_WEIGHTS_MAX];
+ __int32_t subst_count[COLL_WEIGHTS_MAX];
+ __int32_t chain_count;
+ __int32_t large_pri_count;
+};
struct __collate_st_char_pri {
- int prim, sec;
+ __int32_t pri[COLL_WEIGHTS_MAX];
};
struct __collate_st_chain_pri {
- u_char str[STR_LEN];
- int prim, sec;
+ wchar_t str[STR_LEN];
+ __int32_t pri[COLL_WEIGHTS_MAX];
+};
+struct __collate_st_large_char_pri {
+ __int32_t val;
+ struct __collate_st_char_pri pri;
+};
+struct __collate_st_subst {
+ __int32_t val;
+ wchar_t str[STR_LEN];
+};
+
+struct __locale_st_collate {
+ char __encoding[ENCODING_LEN + 1];
+ struct __collate_st_info __info;
+ struct __collate_st_subst *__substitute_table[COLL_WEIGHTS_MAX];
+ struct __collate_st_chain_pri *__chain_pri_table;
+ struct __collate_st_large_char_pri *__large_char_pri_table;
+ struct __collate_st_char_pri __char_pri_table[UCHAR_MAX + 1];
};
extern int __collate_load_error;
extern int __collate_substitute_nontrivial;
-#define __collate_substitute_table (*__collate_substitute_table_ptr)
-extern u_char __collate_substitute_table[UCHAR_MAX + 1][STR_LEN];
-#define __collate_char_pri_table (*__collate_char_pri_table_ptr)
-extern struct __collate_st_char_pri __collate_char_pri_table[UCHAR_MAX + 1];
-extern struct __collate_st_chain_pri *__collate_chain_pri_table;
+extern struct __locale_st_collate *__collate_data;
__BEGIN_DECLS
-u_char *__collate_strdup(u_char *);
-u_char *__collate_substitute(const u_char *);
+wchar_t *__collate_mbstowcs(const char *);
+wchar_t *__collate_wcsdup(const wchar_t *);
+wchar_t *__collate_substitute(const wchar_t *, int);
int __collate_load_tables(const char *);
-void __collate_lookup(const u_char *, int *, int *, int *);
-int __collate_range_cmp(int, int);
+void __collate_lookup(const wchar_t *, int *, int *, int *);
+void __collate_lookup_which(const wchar_t *, int *, int *, int);
+void __collate_xfrm(const wchar_t *, wchar_t **);
+int __collate_range_cmp(wchar_t, wchar_t);
+size_t __collate_collating_symbol(wchar_t *, size_t, const char *, size_t,
+ mbstate_t *);
+int __collate_equiv_class(const char *, size_t, mbstate_t *);
+size_t __collate_equiv_match(int, wchar_t *, size_t, wchar_t, const char *,
+ size_t, mbstate_t *, size_t *);
#ifdef COLLATE_DEBUG
void __collate_print_tables(void);
#endif
==== //depot/projects/soc2008/konrad_collation/libc/locale/collcmp.c#6 (text+ko) ====
@@ -28,17 +28,18 @@
__FBSDID("$FreeBSD: src/lib/libc/locale/collcmp.c,v 1.18 2005/02/27 14:54:23 phantom Exp $");
#include <string.h>
+#include <wchar.h>
#include "collate.h"
/*
* Compare two characters using collate
*/
-int __collate_range_cmp(int c1, int c2)
+int __collate_range_cmp(wchar_t c1, wchar_t c2)
{
- static char s1[2], s2[2];
+ static wchar_t s1[2], s2[2];
s1[0] = c1;
s2[0] = c2;
- return (strcoll(s1, s2));
+ return (wcscoll(s1, s2));
}
==== //depot/projects/soc2008/konrad_collation/libc/locale/setlocale.c#6 (text+ko) ====
@@ -46,6 +46,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <wchar.h>
#include "collate.h"
#include "lmonetary.h" /* for __monetary_load_locale() */
#include "lnumeric.h" /* for __numeric_load_locale() */
@@ -105,6 +106,10 @@
int i, j, len, saverr;
const char *env, *r;
+#ifdef LOCALE_DEBUG
+ fprintf(stderr, "setlocale: %s: %s\n", categories[category],
+ locale ? locale : "NULL");
+#endif
if (category < LC_ALL || category >= _LC_LAST) {
errno = EINVAL;
return (NULL);
@@ -191,11 +196,16 @@
for (i = 1; i < _LC_LAST; ++i) {
(void)strcpy(saved_categories[i], current_categories[i]);
- if (loadlocale(i) == NULL) {
+ if ((r = loadlocale(i)) == NULL) {
saverr = errno;
for (j = 1; j < i; j++) {
(void)strcpy(new_categories[j],
saved_categories[j]);
+#ifdef LOCALE_DEBUG
+ fprintf(stderr, "setlocale: resetting "
+ "locale to %s\n",
+ saved_categories[j]);
+#endif
if (loadlocale(j) == NULL) {
(void)strcpy(new_categories[j], "C");
(void)loadlocale(j);
@@ -204,6 +214,9 @@
errno = saverr;
return (NULL);
}
+#ifdef LOCALE_DEBUG
+ fprintf(stderr, "setlocale: loadlocale returned %s\n", r);
+#endif
}
return (currentlocale());
}
@@ -236,6 +249,10 @@
int (*func)(const char *);
int saved_errno;
+#ifdef LOCALE_DEBUG
+ fprintf(stderr, "loadlocale: %s->%s (was %s)\n",
+ categories[category], new, old);
+#endif
if ((new[0] == '.' &&
(new[1] == '\0' || (new[1] == '.' && new[2] == '\0'))) ||
strchr(new, '/') != NULL) {
@@ -280,6 +297,9 @@
(void)strcpy(old, new);
return (old);
}
+#ifdef LOCALE_DEBUG
+ fprintf(stderr, "loadlocale: returning NULL\n");
+#endif
return (NULL);
}
@@ -327,6 +347,9 @@
} else
_PathLocale = _PATH_LOCALE;
}
+#ifdef LOCALE_DEBUG
+ fprintf(stderr, "__detect_path_locale: %s\n", _PathLocale);
+#endif
return (0);
}
==== //depot/projects/soc2008/konrad_collation/libc/string/strcoll.c#6 (text+ko) ====
@@ -30,57 +30,31 @@
#include <stdlib.h>
#include <string.h>
+#include <wchar.h>
+#include <errno.h>
#include "collate.h"
int
-strcoll(s, s2)
- const char *s, *s2;
+strcoll(const char *s, const char *s2)
{
- int len, len2, prim, prim2, sec, sec2, ret, ret2;
- const char *t, *t2;
- char *tt, *tt2;
+ int ret;
+ const wchar_t *t = NULL, *t2 = NULL;
+ int sverrno;
- if (__collate_load_error)
+ if (__collate_load_error || (t = __collate_mbstowcs(s)) == NULL ||
+ (t2 = __collate_mbstowcs(s2)) == NULL) {
+ sverrno = errno;
+ free((void *)t);
+ free((void *)t2);
+ errno = sverrno;
return strcmp(s, s2);
+ }
- len = len2 = 1;
- ret = ret2 = 0;
- if (__collate_substitute_nontrivial) {
- t = tt = __collate_substitute(s);
- t2 = tt2 = __collate_substitute(s2);
- } else {
- tt = tt2 = NULL;
- t = s;
- t2 = s2;
- }
- while(*t && *t2) {
- prim = prim2 = 0;
- while(*t && !prim) {
- __collate_lookup(t, &len, &prim, &sec);
- t += len;
- }
- while(*t2 && !prim2) {
- __collate_lookup(t2, &len2, &prim2, &sec2);
- t2 += len2;
- }
- if(!prim || !prim2)
- break;
- if(prim != prim2) {
- ret = prim - prim2;
- goto end;
- }
- if(!ret2)
- ret2 = sec - sec2;
- }
- if(!*t && *t2)
- ret = -(int)((u_char)*t2);
- else if(*t && !*t2)
- ret = (u_char)*t;
- else if(!*t && !*t2)
- ret = ret2;
- end:
- free(tt);
- free(tt2);
+ ret = wcscoll(t, t2);
+ sverrno = errno;
+ free((void *)t);
+ free((void *)t2);
+ errno = sverrno;
return ret;
}
==== //depot/projects/soc2008/konrad_collation/libc/string/strxfrm.c#6 (text+ko) ====
@@ -30,22 +30,53 @@
#include <stdlib.h>
#include <string.h>
+#include <wchar.h>
+#include <errno.h>
#include "collate.h"
+/*
+ * In the non-POSIX case, we transform each character into a string of
+ * characters representing the character's priority. Since char is usually
+ * signed, we are limited by 7 bits per byte. To avoid zero, we need to add
+ * XFRM_OFFSET, so we can't use a full 7 bits. For simplicity, we choose 6
+ * bits per byte. We choose 4 bytes per character as a good compromise
+ * between maximum coverage and minimum size. This gives 24 bits, or 16M
+ * priorities. So we choose COLLATE_MAX_PRIORITY to be (2^24 - 1). This
+ * this can be increased if more is needed.
+ */
+
+#define XFRM_BYTES 4
+#define XFRM_OFFSET ('0') /* make all printable characters */
+#define XFRM_SHIFT 6
+#define XFRM_MASK ((1 << XFRM_SHIFT) - 1)
+
+static void
+xfrm(unsigned char *p, int pri)
+{
+
+ p[3] = (pri & XFRM_MASK) + XFRM_OFFSET;
+ pri >>= XFRM_SHIFT;
+ p[2] = (pri & XFRM_MASK) + XFRM_OFFSET;
+ pri >>= XFRM_SHIFT;
+ p[1] = (pri & XFRM_MASK) + XFRM_OFFSET;
+ pri >>= XFRM_SHIFT;
+ p[0] = (pri & XFRM_MASK) + XFRM_OFFSET;
+}
+
size_t
strxfrm(char * __restrict dest, const char * __restrict src, size_t len)
{
- int prim, sec, l;
size_t slen;
- char *s, *ss;
+ wchar_t *wcs, *xf[2];
+ int sverrno;
- if (!*src) {
+ if (!*src && dest) {
if (len > 0)
*dest = '\0';
return 0;
}
- if (__collate_load_error) {
+ if (__collate_load_error || (wcs = __collate_mbstowcs(src)) == NULL) {
slen = strlen(src);
if (len > 0) {
if (slen < len)
@@ -58,26 +89,57 @@
return slen;
}
- slen = 0;
- prim = sec = 0;
- ss = s = __collate_substitute(src);
- while (*s) {
- while (*s && !prim) {
- __collate_lookup(s, &l, &prim, &sec);
- s += l;
+ __collate_xfrm(wcs, xf);
+
+ slen = wcslen(xf[0]) * XFRM_BYTES;
+ if (xf[1])
+ slen += (wcslen(xf[1]) + 1) * XFRM_BYTES;
+ if (len > 0) {
+ wchar_t *w = xf[0];
+ int b = 0;
+ unsigned char buf[XFRM_BYTES];
+ unsigned char *bp;
+ while (len > 1) {
+ if (!b) {
+ if (!*w)
+ break;
+ xfrm(bp = buf, *w++);
+ b = XFRM_BYTES;
+ }
+ *dest++ = *(char *)bp++;
+ b--;
+ len--;
}
- if (prim) {
- if (len > 1) {
- *dest++ = (char)prim;
+ if ((w = xf[1]) != NULL) {
+ xfrm(bp = buf, 0);
+ b = XFRM_BYTES;
+ while (len > 1) {
+ if (!b)
+ break;
+ *dest++ = *(char *)bp++;
+ b--;
+ len--;
+ }
+ b = 0;
+ while (len > 1) {
+ if (!b) {
+ if (!*w)
+ break;
+ xfrm(bp = buf, *w++);
+ b = XFRM_BYTES;
+ }
+ *dest++ = *(char *)bp++;
+ b--;
len--;
}
- slen++;
- prim = 0;
}
- }
- free(ss);
- if (len > 0)
- *dest = '\0';
+ *dest = 0;
+ }
+ sverrno = errno;
+ free(wcs);
+ free(xf[0]);
+ free(xf[1]);
+ errno = sverrno;
return slen;
}
==== //depot/projects/soc2008/konrad_collation/libc/string/wcscoll.c#6 (text+ko) ====
@@ -27,72 +27,220 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/lib/libc/string/wcscoll.c,v 1.3 2004/04/07 09:47:56 tjr Exp $");
+
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include "collate.h"
-static char *__mbsdup(const wchar_t *);
+#define NOTFORWARD (DIRECTIVE_BACKWARD | DIRECTIVE_POSITION)
-/*
- * Placeholder implementation of wcscoll(). Attempts to use the single-byte
- * collation ordering where possible, and falls back on wcscmp() in locales
- * with extended character sets.
- */
int
wcscoll(const wchar_t *ws1, const wchar_t *ws2)
{
- char *mbs1, *mbs2;
- int diff, sverrno;
+ int sverrno;
+ int len, len2, prim, prim2, sec, sec2, ret, ret2;
+ const wchar_t *t, *t2;
+ wchar_t *tt = NULL, *tt2 = NULL;
+ wchar_t *tr = NULL, *tr2 = NULL;
+ struct __collate_st_info *info;
- if (__collate_load_error || MB_CUR_MAX > 1)
+ if (__collate_load_error)
/*
- * Locale has no special collating order, could not be
- * loaded, or has an extended character set; do a fast binary
- * comparison.
+ * Locale has no special collating order or could not be
+ * loaded, do a fast binary comparison.
*/
return (wcscmp(ws1, ws2));
- if ((mbs1 = __mbsdup(ws1)) == NULL || (mbs2 = __mbsdup(ws2)) == NULL) {
- /*
- * Out of memory or illegal wide chars; fall back to wcscmp()
- * but leave errno indicating the error. Callers that don't
- * check for error will get a reasonable but often slightly
- * incorrect result.
- */
- sverrno = errno;
- free(mbs1);
- errno = sverrno;
- return (wcscmp(ws1, ws2));
+ info = &__collate_data->__info;
+ len = len2 = 1;
+ ret = ret2 = 0;
+
+ if ((info->directive[0] & NOTFORWARD) ||
+ (info->directive[1] & NOTFORWARD) ||
+ (!(info->flags && COLLATE_SUBST_DUP) &&
+ (info->subst_count[0] > 0 || info->subst_count[1] > 0))) {
+ int direc, pass;
+ for(pass = 0; pass < info->directive_count; pass++) {
+ direc = info->directive[pass];
+ if (pass == 0 || !(info->flags & COLLATE_SUBST_DUP)) {
+ free(tt);
+ tt = __collate_substitute(ws1, pass);
+ free(tt2);
+ tt2 = tt ? __collate_substitute(ws2, pass) :
+ NULL;
+ }
+ if (direc & DIRECTIVE_BACKWARD) {
+ wchar_t *bp, *fp, c;
+ tr = __collate_wcsdup(tt ? tt : ws1);
+ bp = tr;
+ fp = tr + wcslen(tr) - 1;
+ while(bp < fp) {
+ c = *bp;
+ *bp++ = *fp;
+ *fp-- = c;
+ }
+ tr2 = __collate_wcsdup(tt2 ? tt2 : ws2);
+ bp = tr2;
+ fp = tr2 + wcslen(tr2) - 1;
+ while(bp < fp) {
+ c = *bp;
+ *bp++ = *fp;
+ *fp-- = c;
+ }
+ t = (const wchar_t *)tr;
+ t2 = (const wchar_t *)tr2;
+ } else if (tt) {
+ t = (const wchar_t *)tt;
+ t2 = (const wchar_t *)tt2;
+ } else {
+ t = (const wchar_t *)ws1;
+ t2 = (const wchar_t *)ws2;
+ }
+ if(direc & DIRECTIVE_POSITION) {
+ while(*t && *t2) {
+ prim = prim2 = 0;
+ __collate_lookup_which(t, &len,
+ &prim, pass);
+ if (prim <= 0) {
+ if (prim < 0) {
+ errno = EINVAL;
+ ret = -1;
+ goto end;
+ }
+ prim = COLLATE_MAX_PRIORITY;
+ }
+ __collate_lookup_which(t2, &len2,
+ &prim2, pass);
+ if (prim2 <= 0) {
+ if (prim2 < 0) {
+ errno = EINVAL;
+ ret = -1;
+ goto end;
+ }
+ prim2 = COLLATE_MAX_PRIORITY;
+ }
+ if(prim != prim2) {
+ ret = prim - prim2;
+ goto end;
+ }
+ t += len;
+ t2 += len2;
+ }
+ } else {
+ while(*t && *t2) {
+ prim = prim2 = 0;
+ while(*t) {
+ __collate_lookup_which(t, &len,
+ &prim, pass);
+ if(prim > 0)
+ break;
+ if (prim < 0) {
+ errno = EINVAL;
+ ret = -1;
+ goto end;
+ }
+ t += len;
+ }
+ while(*t2) {
+ __collate_lookup_which(t2,
+ &len2, &prim2, pass);
+ if(prim2 > 0)
+ break;
+ if (prim2 < 0) {
+ errno = EINVAL;
+ ret = -1;
+ goto end;
+ }
+ t2 += len2;
+ }
+ if(!prim || !prim2)
+ break;
+ if(prim != prim2) {
+ ret = prim - prim2;
+ goto end;
+ }
+ t += len;
+ t2 += len2;
+ }
+ }
+ if(!*t) {
+ if(*t2) {
+ ret = -(int)*t2;
+ goto end;
+ }
+ } else {
+ ret = *t;
+ goto end;
+ }
+ }
+ ret = 0;
+ goto end;
}
- diff = strcoll(mbs1, mbs2);
+ /*
+ * Optimized common case: order_start forward;forward and duplicate
+ * (or no) substitute tables.
+ */
+ tt = __collate_substitute(ws1, 0);
+ if (tt == NULL) {
+ tt2 = NULL;
+ t = (const wchar_t *)ws1;
+ t2 = (const wchar_t *)ws2;
+ } else {
+ tt2 = __collate_substitute(ws2, 0);
+ t = (const wchar_t *)tt;
+ t2 = (const wchar_t *)tt2;
+ }
+ while(*t && *t2) {
+ prim = prim2 = 0;
+ while(*t) {
+ __collate_lookup(t, &len, &prim, &sec);
+ if (prim > 0)
+ break;
+ if (prim < 0) {
+ errno = EINVAL;
+ ret = -1;
+ goto end;
+ }
+ t += len;
+ }
+ while(*t2) {
+ __collate_lookup(t2, &len2, &prim2, &sec2);
+ if (prim2 > 0)
+ break;
+ if (prim2 < 0) {
+ errno = EINVAL;
+ ret = -1;
+ goto end;
+ }
+ t2 += len2;
+ }
+ if(!prim || !prim2)
+ break;
+ if(prim != prim2) {
+ ret = prim - prim2;
+ goto end;
+ }
+ if(!ret2)
+ ret2 = sec - sec2;
+ t += len;
+ t2 += len2;
+ }
+ if(!*t && *t2)
+ ret = -(int)*t2;
+ else if(*t && !*t2)
+ ret = *t;
+ else if(!*t && !*t2)
+ ret = ret2;
+ end:
sverrno = errno;
- free(mbs1);
- free(mbs2);
+ free(tt);
+ free(tt2);
+ free(tr);
+ free(tr2);
errno = sverrno;
- return (diff);
-}
-
-static char *
-__mbsdup(const wchar_t *ws)
-{
- static const mbstate_t initial;
- mbstate_t st;
- const wchar_t *wcp;
- size_t len;
- char *mbs;
-
- wcp = ws;
- st = initial;
- if ((len = wcsrtombs(NULL, &wcp, 0, &st)) == (size_t)-1)
- return (NULL);
- if ((mbs = malloc(len + 1)) == NULL)
- return (NULL);
- st = initial;
- wcsrtombs(mbs, &ws, len + 1, &st);
-
- return (mbs);
+ return ret;
}
==== //depot/projects/soc2008/konrad_collation/libc/string/wcsxfrm.c#6 (text+ko) ====
@@ -34,20 +34,17 @@
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
+#include <errno.h>
#include "collate.h"
-static char *__mbsdup(const wchar_t *);
+#define WCS_XFRM_OFFSET 1
-/*
- * Placeholder wcsxfrm() implementation. See wcscoll.c for a description of
- * the logic used.
- */
size_t
wcsxfrm(wchar_t * __restrict dest, const wchar_t * __restrict src, size_t len)
{
- int prim, sec, l;
size_t slen;
- char *mbsrc, *s, *ss;
+ wchar_t *xf[2];
+ int sverrno;
if (*src == L'\0') {
if (len != 0)
@@ -55,7 +52,7 @@
return (0);
}
- if (__collate_load_error || MB_CUR_MAX > 1) {
+ if (__collate_load_error) {
slen = wcslen(src);
if (len > 0) {
if (slen < len)
@@ -68,49 +65,35 @@
return (slen);
}
- mbsrc = __mbsdup(src);
- slen = 0;
- prim = sec = 0;
- ss = s = __collate_substitute(mbsrc);
- while (*s != '\0') {
- while (*s != '\0' && prim == 0) {
- __collate_lookup(s, &l, &prim, &sec);
- s += l;
+ __collate_xfrm(src, xf);
+
+ slen = wcslen(xf[0]);
+ if (xf[1])
+ slen += wcslen(xf[1]) + 1;
+ if (len > 0) {
+ wchar_t *w = xf[0];
+ while (len > 1) {
+ if (!*w)
+ break;
+ *dest++ = *w++ + WCS_XFRM_OFFSET;
+ len--;
}
- if (prim != 0) {
- if (len > 1) {
- *dest++ = (wchar_t)prim;
+ if ((w = xf[1]) != NULL) {
+ if (len > 1)
+ *dest++ = WCS_XFRM_OFFSET;
+ while (len > 1) {
+ if (!*w)
+ break;
+ *dest++ = *w++ + WCS_XFRM_OFFSET;
len--;
}
- slen++;
- prim = 0;
}
- }
- free(ss);
- free(mbsrc);
- if (len != 0)
- *dest = L'\0';
-
+ *dest = 0;
+ }
+ sverrno = errno;
+ free(xf[0]);
+ free(xf[1]);
+ errno = sverrno;
+
return (slen);
}
-
-static char *
-__mbsdup(const wchar_t *ws)
-{
- static const mbstate_t initial;
- mbstate_t st;
- const wchar_t *wcp;
- size_t len;
- char *mbs;
-
- wcp = ws;
- st = initial;
- if ((len = wcsrtombs(NULL, &wcp, 0, &st)) == (size_t)-1)
- return (NULL);
- if ((mbs = malloc(len + 1)) == NULL)
- return (NULL);
- st = initial;
- wcsrtombs(mbs, &ws, len + 1, &st);
-
- return (mbs);
-}
More information about the p4-projects
mailing list