1 /* xmbsrtowcs.c -- replacement function for mbsrtowcs */
3 /* Copyright (C) 2002 Free Software Foundation, Inc.
5 This file is part of GNU Bash, the Bourne Again SHell.
7 Bash is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License along
18 with Bash; see the file COPYING. If not, write to the Free Software
19 Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
24 /* <wchar.h>, <wctype.h> and <stdlib.h> are included in "shmbutil.h".
25 If <wchar.h>, <wctype.h>, mbsrtowcs(), exist, HANDLE_MULTIBYTE
30 /* On some locales (ex. ja_JP.sjis), mbsrtowc doesn't convert 0x5c to U<0x5c>.
31 So, this function is made for converting 0x5c to U<0x5c>. */
33 static mbstate_t local_state;
34 static int local_state_use = 0;
37 xmbsrtowcs (dest, src, len, pstate)
44 size_t mblength, wclength, n;
51 memset (&local_state, '\0', sizeof(mbstate_t));
65 wsbuf = (wchar_t *) malloc ((n + 1) * sizeof(wchar_t));
69 wclength = mbsrtowcs (wsbuf, &mbs, n, &psbuf);
75 for (wclength = 0; wclength < len; wclength++, dest++)
85 else if (**src == '\\')
91 mblength = mbrtowc(dest, *src, n, ps);
94 mblength = mbrtowc(dest, *src, n, ps);
96 /* Cannot convert multibyte character to wide character. */
97 if (mblength == (size_t)-1 || mblength == (size_t)-2)
103 /* The multibyte string has been completely converted,
104 including the terminating '\0'. */
115 /* Convert a multibyte string to a wide character string. Memory for the
116 new wide character string is obtained with malloc.
118 The return value is the length of the wide character string. Returns a
119 pointer to the wide character string in DESTP. If INDICESP is not NULL,
120 INDICESP stores the pointer to the pointer array. Each pointer is to
121 the first byte of each multibyte character. Memory for the pointer array
122 is obtained with malloc, too.
123 If conversion is failed, the return value is (size_t)-1 and the values
124 of DESTP and INDICESP are NULL. */
129 xdupmbstowcs (destp, indicesp, src)
130 wchar_t **destp; /* Store the pointer to the wide character string */
131 char ***indicesp; /* Store the pointer to the pointer array. */
132 const char *src; /* Multibyte character string */
134 const char *p; /* Conversion start position of src */
135 wchar_t wc; /* Created wide character by conversion */
136 wchar_t *wsbuf; /* Buffer for wide characters. */
137 char **indices; /* Buffer for indices. */
138 size_t wsbuf_size; /* Size of WSBUF */
139 size_t wcnum; /* Number of wide characters in WSBUF */
140 mbstate_t state; /* Conversion State */
142 /* In case SRC or DESP is NULL, conversion doesn't take place. */
143 if (src == NULL || destp == NULL)
149 memset (&state, '\0', sizeof(mbstate_t));
150 wsbuf_size = WSBUF_INC;
152 wsbuf = (wchar_t *) malloc (wsbuf_size * sizeof(wchar_t));
159 indices = (char **) malloc (wsbuf_size * sizeof(char *));
170 size_t mblength; /* Byte length of one multibyte character. */
185 mblength = mbrtowc(&wc, p, MB_LEN_MAX, &state);
188 mblength = mbrtowc(&wc, p, MB_LEN_MAX, &state);
190 /* Conversion failed. */
191 if (MB_INVALIDCH (mblength))
201 /* Resize buffers when they are not large enough. */
202 if (wsbuf_size < wcnum)
207 wsbuf_size += WSBUF_INC;
209 wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t));
219 idxtmp = (char **) realloc (indices, wsbuf_size * sizeof (char **));
230 wsbuf[wcnum - 1] = wc;
231 indices[wcnum - 1] = (char *)p;
233 } while (MB_NULLWCH (wc) == 0);
235 /* Return the length of the wide character string, not including `\0'. */
237 if (indicesp != NULL)
245 #endif /* HANDLE_MULTIBYTE */