| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: conv.c,v 1.2 2013/11/22 15:52:05 christos Exp $ */ | | 1 | /* $NetBSD: conv.c,v 1.3 2014/01/07 21:46:47 christos Exp $ */ |
2 | /*- | | 2 | /*- |
3 | * Copyright (c) 1993, 1994 | | 3 | * Copyright (c) 1993, 1994 |
4 | * The Regents of the University of California. All rights reserved. | | 4 | * The Regents of the University of California. All rights reserved. |
5 | * Copyright (c) 1993, 1994, 1995, 1996 | | 5 | * Copyright (c) 1993, 1994, 1995, 1996 |
6 | * Keith Bostic. All rights reserved. | | 6 | * Keith Bostic. All rights reserved. |
7 | * | | 7 | * |
8 | * See the LICENSE file for redistribution information. | | 8 | * See the LICENSE file for redistribution information. |
9 | */ | | 9 | */ |
10 | | | 10 | |
11 | #include "config.h" | | 11 | #include "config.h" |
12 | | | 12 | |
13 | #ifndef lint | | 13 | #ifndef lint |
14 | static const char sccsid[] = "Id: conv.c,v 1.27 2001/08/18 21:41:41 skimo Exp (Berkeley) Date: 2001/08/18 21:41:41 "; | | 14 | static const char sccsid[] = "Id: conv.c,v 1.27 2001/08/18 21:41:41 skimo Exp (Berkeley) Date: 2001/08/18 21:41:41 "; |
| @@ -43,28 +43,30 @@ typedef int iconv_t; | | | @@ -43,28 +43,30 @@ typedef int iconv_t; |
43 | | | 43 | |
44 | #ifdef USE_WIDECHAR | | 44 | #ifdef USE_WIDECHAR |
45 | static int | | 45 | static int |
46 | raw2int(SCR *sp, const char * str, ssize_t len, CONVWIN *cw, size_t *tolen, | | 46 | raw2int(SCR *sp, const char * str, ssize_t len, CONVWIN *cw, size_t *tolen, |
47 | const CHAR_T **dst) | | 47 | const CHAR_T **dst) |
48 | { | | 48 | { |
49 | int i; | | 49 | int i; |
50 | CHAR_T **tostr = (CHAR_T **)(void *)&cw->bp1; | | 50 | CHAR_T **tostr = (CHAR_T **)(void *)&cw->bp1; |
51 | size_t *blen = &cw->blen1; | | 51 | size_t *blen = &cw->blen1; |
52 | | | 52 | |
53 | BINC_RETW(NULL, *tostr, *blen, len); | | 53 | BINC_RETW(NULL, *tostr, *blen, len); |
54 | | | 54 | |
55 | *tolen = len; | | 55 | *tolen = len; |
56 | for (i = 0; i < len; ++i) | | 56 | for (i = 0; i < len; ++i) { |
57 | (*tostr)[i] = (u_char) str[i]; | | 57 | CHAR_T w = (u_char)str[i]; |
| | | 58 | memcpy((*tostr) + i, &w, sizeof(**tostr)); |
| | | 59 | } |
58 | | | 60 | |
59 | *dst = cw->bp1; | | 61 | *dst = cw->bp1; |
60 | | | 62 | |
61 | return 0; | | 63 | return 0; |
62 | } | | 64 | } |
63 | | | 65 | |
64 | #ifndef ERROR_ON_CONVERT | | 66 | #ifndef ERROR_ON_CONVERT |
65 | #define HANDLE_ICONV_ERROR(o, i, ol, il) do { \ | | 67 | #define HANDLE_ICONV_ERROR(o, i, ol, il) do { \ |
66 | *o++ = *i++; \ | | 68 | *o++ = *i++; \ |
67 | ol--; il--; \ | | 69 | ol--; il--; \ |
68 | } while (/*CONSTCOND*/0) | | 70 | } while (/*CONSTCOND*/0) |
69 | #define HANDLE_MBR_ERROR(n, mbs, d, s) do { \ | | 71 | #define HANDLE_MBR_ERROR(n, mbs, d, s) do { \ |
70 | d = s; \ | | 72 | d = s; \ |
| @@ -121,31 +123,35 @@ default_char2int(SCR *sp, const char * s | | | @@ -121,31 +123,35 @@ default_char2int(SCR *sp, const char * s |
121 | MEMSET(&mbs, 0, 1); | | 123 | MEMSET(&mbs, 0, 1); |
122 | BINC_RETW(NULL, *tostr, *blen, nlen); | | 124 | BINC_RETW(NULL, *tostr, *blen, nlen); |
123 | | | 125 | |
124 | #ifdef USE_ICONV | | 126 | #ifdef USE_ICONV |
125 | if (strcmp(nl_langinfo(CODESET), enc)) { | | 127 | if (strcmp(nl_langinfo(CODESET), enc)) { |
126 | id = iconv_open(nl_langinfo(CODESET), enc); | | 128 | id = iconv_open(nl_langinfo(CODESET), enc); |
127 | if (id == (iconv_t)-1) | | 129 | if (id == (iconv_t)-1) |
128 | goto err; | | 130 | goto err; |
129 | CONVERT(str, left, src, len); | | 131 | CONVERT(str, left, src, len); |
130 | } | | 132 | } |
131 | #endif | | 133 | #endif |
132 | | | 134 | |
133 | for (i = 0, j = 0; j < len; ) { | | 135 | for (i = 0, j = 0; j < len; ) { |
134 | n = mbrtowc((*tostr)+i, src+j, len-j, &mbs); | | 136 | CHAR_T w; |
| | | 137 | n = mbrtowc(&w, src + j, len - j, &mbs); |
| | | 138 | memcpy((*tostr) + i, &w, sizeof(**tostr)); |
135 | /* NULL character converted */ | | 139 | /* NULL character converted */ |
136 | if (n == (size_t)-2) error = -(len-j); | | 140 | if (n == (size_t)-2) error = -(len - j); |
137 | if (n == (size_t)-1 || n == (size_t)-2) | | 141 | if (n == (size_t)-1 || n == (size_t)-2) { |
138 | HANDLE_MBR_ERROR(n, mbs, (*tostr)[i], src[j]); | | 142 | HANDLE_MBR_ERROR(n, mbs, w, src[j]); |
| | | 143 | memcpy((*tostr) + i, &w, sizeof(**tostr)); |
| | | 144 | } |
139 | if (n == 0) n = 1; | | 145 | if (n == 0) n = 1; |
140 | j += n; | | 146 | j += n; |
141 | if (++i >= *blen) { | | 147 | if (++i >= *blen) { |
142 | nlen += 256; | | 148 | nlen += 256; |
143 | BINC_RETW(NULL, *tostr, *blen, nlen); | | 149 | BINC_RETW(NULL, *tostr, *blen, nlen); |
144 | } | | 150 | } |
145 | if (id != (iconv_t)-1 && j == len && left) { | | 151 | if (id != (iconv_t)-1 && j == len && left) { |
146 | CONVERT(str, left, src, len); | | 152 | CONVERT(str, left, src, len); |
147 | j = 0; | | 153 | j = 0; |
148 | } | | 154 | } |
149 | } | | 155 | } |
150 | *tolen = i; | | 156 | *tolen = i; |
151 | | | 157 | |
| @@ -206,28 +212,31 @@ CHAR_T_char2int(SCR *sp, const char * st | | | @@ -206,28 +212,31 @@ CHAR_T_char2int(SCR *sp, const char * st |
206 | } | | 212 | } |
207 | | | 213 | |
208 | static int | | 214 | static int |
209 | int2raw(SCR *sp, const CHAR_T * str, ssize_t len, CONVWIN *cw, size_t *tolen, | | 215 | int2raw(SCR *sp, const CHAR_T * str, ssize_t len, CONVWIN *cw, size_t *tolen, |
210 | const char **dst) | | 216 | const char **dst) |
211 | { | | 217 | { |
212 | int i; | | 218 | int i; |
213 | char **tostr = (char **)(void *)&cw->bp1; | | 219 | char **tostr = (char **)(void *)&cw->bp1; |
214 | size_t *blen = &cw->blen1; | | 220 | size_t *blen = &cw->blen1; |
215 | | | 221 | |
216 | BINC_RETC(NULL, *tostr, *blen, len); | | 222 | BINC_RETC(NULL, *tostr, *blen, len); |
217 | | | 223 | |
218 | *tolen = len; | | 224 | *tolen = len; |
219 | for (i = 0; i < len; ++i) | | 225 | for (i = 0; i < len; ++i) { |
220 | (*tostr)[i] = str[i]; | | 226 | CHAR_T w; |
| | | 227 | memcpy(&w, str + i, sizeof(w)); |
| | | 228 | (*tostr)[i] = w; |
| | | 229 | } |
221 | | | 230 | |
222 | *dst = cw->bp1; | | 231 | *dst = cw->bp1; |
223 | | | 232 | |
224 | return 0; | | 233 | return 0; |
225 | } | | 234 | } |
226 | | | 235 | |
227 | static int | | 236 | static int |
228 | default_int2char(SCR *sp, const CHAR_T * str, ssize_t len, CONVWIN *cw, | | 237 | default_int2char(SCR *sp, const CHAR_T * str, ssize_t len, CONVWIN *cw, |
229 | size_t *tolen, const char **pdst, const char *enc) | | 238 | size_t *tolen, const char **pdst, const char *enc) |
230 | { | | 239 | { |
231 | size_t i, j; | | 240 | size_t i, j; |
232 | int offset = 0; | | 241 | int offset = 0; |
233 | char **tostr = (char **)(void *)&cw->bp1; | | 242 | char **tostr = (char **)(void *)&cw->bp1; |
| @@ -272,42 +281,44 @@ default_int2char(SCR *sp, const CHAR_T * | | | @@ -272,42 +281,44 @@ default_int2char(SCR *sp, const CHAR_T * |
272 | BINC_RETC(NULL, *tostr, *blen, nlen); | | 281 | BINC_RETC(NULL, *tostr, *blen, nlen); |
273 | dst = *tostr; buflen = *blen; | | 282 | dst = *tostr; buflen = *blen; |
274 | | | 283 | |
275 | #ifdef USE_ICONV | | 284 | #ifdef USE_ICONV |
276 | if (strcmp(nl_langinfo(CODESET), enc)) { | | 285 | if (strcmp(nl_langinfo(CODESET), enc)) { |
277 | id = iconv_open(enc, nl_langinfo(CODESET)); | | 286 | id = iconv_open(enc, nl_langinfo(CODESET)); |
278 | if (id == (iconv_t)-1) | | 287 | if (id == (iconv_t)-1) |
279 | goto err; | | 288 | goto err; |
280 | dst = buffer; buflen = CONV_BUFFER_SIZE; | | 289 | dst = buffer; buflen = CONV_BUFFER_SIZE; |
281 | } | | 290 | } |
282 | #endif | | 291 | #endif |
283 | | | 292 | |
284 | for (i = 0, j = 0; i < (size_t)len; ++i) { | | 293 | for (i = 0, j = 0; i < (size_t)len; ++i) { |
285 | n = wcrtomb(dst+j, str[i], &mbs); | | 294 | CHAR_T w; |
| | | 295 | memcpy(&w, str + i, sizeof(w)); |
| | | 296 | n = wcrtomb(dst + j, w, &mbs); |
286 | if (n == (size_t)-1) | | 297 | if (n == (size_t)-1) |
287 | HANDLE_MBR_ERROR(n, mbs, dst[j], str[i]); | | 298 | HANDLE_MBR_ERROR(n, mbs, dst[j], w); |
288 | j += n; | | 299 | j += n; |
289 | if (buflen < j + MB_CUR_MAX) { | | 300 | if (buflen < j + MB_CUR_MAX) { |
290 | if (id != (iconv_t)-1) { | | 301 | if (id != (iconv_t)-1) { |
291 | CONVERT2(j, cw, offset); | | 302 | CONVERT2(j, cw, offset); |
292 | } else { | | 303 | } else { |
293 | nlen += 256; | | 304 | nlen += 256; |
294 | BINC_RETC(NULL, *tostr, *blen, nlen); | | 305 | BINC_RETC(NULL, *tostr, *blen, nlen); |
295 | dst = *tostr; buflen = *blen; | | 306 | dst = *tostr; buflen = *blen; |
296 | } | | 307 | } |
297 | } | | 308 | } |
298 | } | | 309 | } |
299 | | | 310 | |
300 | n = wcrtomb(dst+j, L'\0', &mbs); | | 311 | n = wcrtomb(dst + j, L'\0', &mbs); |
301 | j += n - 1; /* don't count NUL at the end */ | | 312 | j += n - 1; /* don't count NUL at the end */ |
302 | *tolen = j; | | 313 | *tolen = j; |
303 | | | 314 | |
304 | if (id != (iconv_t)-1) { | | 315 | if (id != (iconv_t)-1) { |
305 | CONVERT2(j, cw, offset); | | 316 | CONVERT2(j, cw, offset); |
306 | *tolen = offset; | | 317 | *tolen = offset; |
307 | } | | 318 | } |
308 | | | 319 | |
309 | *pdst = cw->bp1; | | 320 | *pdst = cw->bp1; |
310 | | | 321 | |
311 | return 0; | | 322 | return 0; |
312 | err: | | 323 | err: |
313 | *tolen = j; | | 324 | *tolen = j; |