]> git.saurik.com Git - apple/libc.git/blob - string/FreeBSD/strxfrm.c.patch
Libc-498.1.7.tar.gz
[apple/libc.git] / string / FreeBSD / strxfrm.c.patch
1 --- strxfrm.c.orig 2003-05-20 15:23:55.000000000 -0700
2 +++ strxfrm.c 2005-04-02 17:59:53.000000000 -0800
3 @@ -28,24 +28,59 @@
4 #include <sys/cdefs.h>
5 __FBSDID("$FreeBSD: src/lib/libc/string/strxfrm.c,v 1.15 2002/09/06 11:24:06 tjr Exp $");
6
7 +#include "xlocale_private.h"
8 +
9 #include <stdlib.h>
10 #include <string.h>
11 +#include <wchar.h>
12 +#include <errno.h>
13 #include "collate.h"
14
15 +/*
16 + * In the non-POSIX case, we transform each character into a string of
17 + * characters representing the character's priority. Since char is usually
18 + * signed, we are limited by 7 bits per byte. To avoid zero, we need to add
19 + * XFRM_OFFSET, so we can't use a full 7 bits. For simplicity, we choose 6
20 + * bits per byte. We choose 4 bytes per character as a good compromise
21 + * between maximum coverage and minimum size. This gives 24 bits, or 16M
22 + * priorities. So we choose COLLATE_MAX_PRIORITY to be (2^24 - 1). This
23 + * this can be increased if more is needed.
24 + */
25 +
26 +#define XFRM_BYTES 4
27 +#define XFRM_OFFSET ('0') /* make all printable characters */
28 +#define XFRM_SHIFT 6
29 +#define XFRM_MASK ((1 << XFRM_SHIFT) - 1)
30 +
31 +static void
32 +xfrm(unsigned char *p, int pri)
33 +{
34 +
35 + p[3] = (pri & XFRM_MASK) + XFRM_OFFSET;
36 + pri >>= XFRM_SHIFT;
37 + p[2] = (pri & XFRM_MASK) + XFRM_OFFSET;
38 + pri >>= XFRM_SHIFT;
39 + p[1] = (pri & XFRM_MASK) + XFRM_OFFSET;
40 + pri >>= XFRM_SHIFT;
41 + p[0] = (pri & XFRM_MASK) + XFRM_OFFSET;
42 +}
43 +
44 size_t
45 -strxfrm(char * __restrict dest, const char * __restrict src, size_t len)
46 +strxfrm_l(char * __restrict dest, const char * __restrict src, size_t len,
47 + locale_t loc)
48 {
49 - int prim, sec, l;
50 size_t slen;
51 - char *s, *ss;
52 + wchar_t *wcs, *xf[2];
53 + int sverrno;
54
55 - if (!*src) {
56 + if (!*src && dest) {
57 if (len > 0)
58 *dest = '\0';
59 return 0;
60 }
61
62 - if (__collate_load_error) {
63 + NORMALIZE_LOCALE(loc);
64 + if (loc->__collate_load_error || (wcs = __collate_mbstowcs(src, loc)) == NULL) {
65 slen = strlen(src);
66 if (len > 0) {
67 if (slen < len)
68 @@ -58,26 +93,63 @@
69 return slen;
70 }
71
72 - slen = 0;
73 - prim = sec = 0;
74 - ss = s = __collate_substitute(src);
75 - while (*s) {
76 - while (*s && !prim) {
77 - __collate_lookup(s, &l, &prim, &sec);
78 - s += l;
79 + __collate_xfrm(wcs, xf, loc);
80 +
81 + slen = wcslen(xf[0]) * XFRM_BYTES;
82 + if (xf[1])
83 + slen += (wcslen(xf[1]) + 1) * XFRM_BYTES;
84 + if (len > 0) {
85 + wchar_t *w = xf[0];
86 + int b = 0;
87 + unsigned char buf[XFRM_BYTES];
88 + unsigned char *bp;
89 + while (len > 1) {
90 + if (!b) {
91 + if (!*w)
92 + break;
93 + xfrm(bp = buf, *w++);
94 + b = XFRM_BYTES;
95 + }
96 + *dest++ = *(char *)bp++;
97 + b--;
98 + len--;
99 }
100 - if (prim) {
101 - if (len > 1) {
102 - *dest++ = (char)prim;
103 + if ((w = xf[1]) != NULL) {
104 + xfrm(bp = buf, 0);
105 + b = XFRM_BYTES;
106 + while (len > 1) {
107 + if (!b)
108 + break;
109 + *dest++ = *(char *)bp++;
110 + b--;
111 + len--;
112 + }
113 + b = 0;
114 + while (len > 1) {
115 + if (!b) {
116 + if (!*w)
117 + break;
118 + xfrm(bp = buf, *w++);
119 + b = XFRM_BYTES;
120 + }
121 + *dest++ = *(char *)bp++;
122 + b--;
123 len--;
124 }
125 - slen++;
126 - prim = 0;
127 }
128 - }
129 - free(ss);
130 - if (len > 0)
131 - *dest = '\0';
132 + *dest = 0;
133 + }
134 + sverrno = errno;
135 + free(wcs);
136 + free(xf[0]);
137 + free(xf[1]);
138 + errno = sverrno;
139
140 return slen;
141 }
142 +
143 +size_t
144 +strxfrm(char * __restrict dest, const char * __restrict src, size_t len)
145 +{
146 + return strxfrm_l(dest, src, len, __current_locale());
147 +}