1 /* xmbsrtowcs.c -- replacement function for mbsrtowcs */
3 /* Copyright (C) 2002-2004 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 /* It doesn't matter if malloc fails here, since mbsrtowcs should do
66 the right thing with a NULL first argument. */
67 wsbuf = (wchar_t *) malloc ((n + 1) * sizeof(wchar_t));
71 wclength = mbsrtowcs (wsbuf, &mbs, n, &psbuf);
78 for (wclength = 0; wclength < len; wclength++, dest++)
88 else if (**src == '\\')
94 mblength = mbrtowc(dest, *src, n, ps);
97 mblength = mbrtowc(dest, *src, n, ps);
99 /* Cannot convert multibyte character to wide character. */
100 if (mblength == (size_t)-1 || mblength == (size_t)-2)
106 /* The multibyte string has been completely converted,
107 including the terminating '\0'. */
118 /* Convert a multibyte string to a wide character string. Memory for the
119 new wide character string is obtained with malloc.
121 The return value is the length of the wide character string. Returns a
122 pointer to the wide character string in DESTP. If INDICESP is not NULL,
123 INDICESP stores the pointer to the pointer array. Each pointer is to
124 the first byte of each multibyte character. Memory for the pointer array
125 is obtained with malloc, too.
126 If conversion is failed, the return value is (size_t)-1 and the values
127 of DESTP and INDICESP are NULL. */
132 xdupmbstowcs (destp, indicesp, src)
133 wchar_t **destp; /* Store the pointer to the wide character string */
134 char ***indicesp; /* Store the pointer to the pointer array. */
135 const char *src; /* Multibyte character string */
137 const char *p; /* Conversion start position of src */
138 wchar_t wc; /* Created wide character by conversion */
139 wchar_t *wsbuf; /* Buffer for wide characters. */
140 char **indices; /* Buffer for indices. */
141 size_t wsbuf_size; /* Size of WSBUF */
142 size_t wcnum; /* Number of wide characters in WSBUF */
143 mbstate_t state; /* Conversion State */
145 /* In case SRC or DESP is NULL, conversion doesn't take place. */
146 if (src == NULL || destp == NULL)
153 memset (&state, '\0', sizeof(mbstate_t));
154 wsbuf_size = WSBUF_INC;
156 wsbuf = (wchar_t *) malloc (wsbuf_size * sizeof(wchar_t));
163 indices = (char **) malloc (wsbuf_size * sizeof(char *));
175 size_t mblength; /* Byte length of one multibyte character. */
177 if (mbsinit (&state))
190 mblength = mbrtowc(&wc, p, MB_LEN_MAX, &state);
193 mblength = mbrtowc(&wc, p, MB_LEN_MAX, &state);
195 /* Conversion failed. */
196 if (MB_INVALIDCH (mblength))
206 /* Resize buffers when they are not large enough. */
207 if (wsbuf_size < wcnum)
212 wsbuf_size += WSBUF_INC;
214 wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t));
224 idxtmp = (char **) realloc (indices, wsbuf_size * sizeof (char **));
235 wsbuf[wcnum - 1] = wc;
236 indices[wcnum - 1] = (char *)p;
239 while (MB_NULLWCH (wc) == 0);
241 /* Return the length of the wide character string, not including `\0'. */
243 if (indicesp != NULL)
251 #endif /* HANDLE_MULTIBYTE */