OpenCoverage

xmbsrtowcs.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/bash/src/lib/glob/xmbsrtowcs.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* xmbsrtowcs.c -- replacement function for mbsrtowcs */-
2-
3/* Copyright (C) 2002-2013 Free Software Foundation, Inc.-
4-
5 This file is part of GNU Bash, the Bourne Again SHell.-
6-
7 Bash is free software: you can redistribute it and/or modify-
8 it under the terms of the GNU General Public License as published by-
9 the Free Software Foundation, either version 3 of the License, or-
10 (at your option) any later version.-
11-
12 Bash is distributed in the hope that it will be useful,-
13 but WITHOUT ANY WARRANTY; without even the implied warranty of-
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-
15 GNU General Public License for more details.-
16-
17 You should have received a copy of the GNU General Public License-
18 along with Bash. If not, see <http://www.gnu.org/licenses/>.-
19*/-
20-
21/* Ask for GNU extensions to get extern declaration for mbsnrtowcs if-
22 available via glibc. */-
23#ifndef _GNU_SOURCE-
24# define _GNU_SOURCE 1-
25#endif-
26-
27#include <config.h>-
28-
29#include <bashansi.h>-
30-
31/* <wchar.h>, <wctype.h> and <stdlib.h> are included in "shmbutil.h".-
32 If <wchar.h>, <wctype.h>, mbsrtowcs(), exist, HANDLE_MULTIBYTE-
33 is defined as 1. */-
34#include <shmbutil.h>-
35-
36#if HANDLE_MULTIBYTE-
37-
38#define WSBUF_INC 32-
39-
40#ifndef FREE-
41# define FREE(x) do { if (x) free (x); } while (0)-
42#endif-
43-
44#if ! HAVE_STRCHRNUL-
45extern char *strchrnul __P((const char *, int));-
46#endif-
47-
48/* On some locales (ex. ja_JP.sjis), mbsrtowc doesn't convert 0x5c to U<0x5c>.-
49 So, this function is made for converting 0x5c to U<0x5c>. */-
50-
51static mbstate_t local_state;-
52static int local_state_use = 0;-
53-
54size_t-
55xmbsrtowcs (dest, src, len, pstate)-
56 wchar_t *dest;-
57 const char **src;-
58 size_t len;-
59 mbstate_t *pstate;-
60{-
61 mbstate_t *ps;-
62 size_t mblength, wclength, n;-
63-
64 ps = pstate;-
65 if (pstate == NULL)
pstate == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
66 {-
67 if (!local_state_use)
!local_state_useDescription
TRUEnever evaluated
FALSEnever evaluated
0
68 {-
69 memset (&local_state, '\0', sizeof(mbstate_t));-
70 local_state_use = 1;-
71 }
never executed: end of block
0
72 ps = &local_state;-
73 }
never executed: end of block
0
74-
75 n = strlen (*src);-
76-
77 if (dest == NULL)
dest == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
78 {-
79 wchar_t *wsbuf;-
80 const char *mbs;-
81 mbstate_t psbuf;-
82-
83 /* It doesn't matter if malloc fails here, since mbsrtowcs should do-
84 the right thing with a NULL first argument. */-
85 wsbuf = (wchar_t *) malloc ((n + 1) * sizeof(wchar_t));-
86 mbs = *src;-
87 psbuf = *ps;-
88-
89 wclength = mbsrtowcs (wsbuf, &mbs, n, &psbuf);-
90-
91 if (wsbuf)
wsbufDescription
TRUEnever evaluated
FALSEnever evaluated
0
92 free (wsbuf);
never executed: free (wsbuf);
0
93 return wclength;
never executed: return wclength;
0
94 }-
95 -
96 for (wclength = 0; wclength < len; wclength++, dest++)
wclength < lenDescription
TRUEnever evaluated
FALSEnever evaluated
0
97 {-
98 if (mbsinit(ps))
mbsinit(ps)Description
TRUEnever evaluated
FALSEnever evaluated
0
99 {-
100 if (**src == '\0')
**src == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
101 {-
102 *dest = L'\0';-
103 *src = NULL;-
104 return (wclength);
never executed: return (wclength);
0
105 }-
106 else if (**src == '\\')
**src == '\\'Description
TRUEnever evaluated
FALSEnever evaluated
0
107 {-
108 *dest = L'\\';-
109 mblength = 1;-
110 }
never executed: end of block
0
111 else-
112 mblength = mbrtowc(dest, *src, n, ps);
never executed: mblength = mbrtowc(dest, *src, n, ps);
0
113 }-
114 else-
115 mblength = mbrtowc(dest, *src, n, ps);
never executed: mblength = mbrtowc(dest, *src, n, ps);
0
116-
117 /* Cannot convert multibyte character to wide character. */-
118 if (mblength == (size_t)-1 || mblength == (size_t)-2)
mblength == (size_t)-1Description
TRUEnever evaluated
FALSEnever evaluated
mblength == (size_t)-2Description
TRUEnever evaluated
FALSEnever evaluated
0
119 return (size_t)-1;
never executed: return (size_t)-1;
0
120-
121 *src += mblength;-
122 n -= mblength;-
123-
124 /* The multibyte string has been completely converted,-
125 including the terminating '\0'. */-
126 if (*dest == L'\0')
*dest == L'\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
127 {-
128 *src = NULL;-
129 break;
never executed: break;
0
130 }-
131 }
never executed: end of block
0
132-
133 return (wclength);
never executed: return (wclength);
0
134}-
135-
136#if HAVE_MBSNRTOWCS-
137/* Convert a multibyte string to a wide character string. Memory for the-
138 new wide character string is obtained with malloc.-
139-
140 Fast multiple-character version of xdupmbstowcs used when the indices are-
141 not required and mbsnrtowcs is available. */-
142-
143static size_t-
144xdupmbstowcs2 (destp, src)-
145 wchar_t **destp; /* Store the pointer to the wide character string */-
146 const char *src; /* Multibyte character string */-
147{-
148 const char *p; /* Conversion start position of src */-
149 wchar_t *wsbuf; /* Buffer for wide characters. */-
150 size_t wsbuf_size; /* Size of WSBUF */-
151 size_t wcnum; /* Number of wide characters in WSBUF */-
152 mbstate_t state; /* Conversion State */-
153 size_t n, wcslength; /* Number of wide characters produced by the conversion. */-
154 const char *end_or_backslash;-
155 size_t nms; /* Number of multibyte characters to convert at one time. */-
156 mbstate_t tmp_state;-
157 const char *tmp_p;-
158-
159 memset (&state, '\0', sizeof(mbstate_t));-
160-
161 wsbuf_size = 0;-
162 wsbuf = NULL;-
163-
164 p = src;-
165 wcnum = 0;-
166 do-
167 {-
168 end_or_backslash = strchrnul(p, '\\');-
169 nms = end_or_backslash - p;-
170 if (*end_or_backslash == '\0')
*end_or_backslash == '\0'Description
TRUEevaluated 4634220 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 2315529 times by 1 test
Evaluated by:
  • Self test
2315529-4634220
171 nms++;
executed 4634220 times by 1 test: nms++;
Executed by:
  • Self test
4634220
172-
173 /* Compute the number of produced wide-characters. */-
174 tmp_p = p;-
175 tmp_state = state;-
176-
177 if (nms == 0 && *p == '\\') /* special initial case */
nms == 0Description
TRUEevaluated 2315386 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 4634363 times by 1 test
Evaluated by:
  • Self test
*p == '\\'Description
TRUEevaluated 2315386 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-4634363
178 nms = wcslength = 1;
executed 2315386 times by 1 test: nms = wcslength = 1;
Executed by:
  • Self test
2315386
179 else-
180 wcslength = mbsnrtowcs (NULL, &tmp_p, nms, 0, &tmp_state);
executed 4634363 times by 1 test: wcslength = mbsnrtowcs ( ((void *)0) , &tmp_p, nms, 0, &tmp_state);
Executed by:
  • Self test
4634363
181-
182 if (wcslength == 0)
wcslength == 0Description
TRUEnever evaluated
FALSEevaluated 6949749 times by 1 test
Evaluated by:
  • Self test
0-6949749
183 {-
184 tmp_p = p; /* will need below */-
185 tmp_state = state;-
186 wcslength = 1; /* take a single byte */-
187 }
never executed: end of block
0
188-
189 /* Conversion failed. */-
190 if (wcslength == (size_t)-1)
wcslength == (size_t)-1Description
TRUEevaluated 6 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 6949743 times by 1 test
Evaluated by:
  • Self test
6-6949743
191 {-
192 free (wsbuf);-
193 *destp = NULL;-
194 return (size_t)-1;
executed 6 times by 1 test: return (size_t)-1;
Executed by:
  • Self test
6
195 }-
196-
197 /* Resize the buffer if it is not large enough. */-
198 if (wsbuf_size < wcnum+wcslength+1) /* 1 for the L'\0' or the potential L'\\' */
wsbuf_size < wcnum+wcslength+1Description
TRUEevaluated 4634217 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 2315526 times by 1 test
Evaluated by:
  • Self test
2315526-4634217
199 {-
200 wchar_t *wstmp;-
201-
202 while (wsbuf_size < wcnum+wcslength+1) /* 1 for the L'\0' or the potential L'\\' */
wsbuf_size < wcnum+wcslength+1Description
TRUEevaluated 4634228 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 4634217 times by 1 test
Evaluated by:
  • Self test
4634217-4634228
203 wsbuf_size += WSBUF_INC;
executed 4634228 times by 1 test: wsbuf_size += 32;
Executed by:
  • Self test
4634228
204-
205 wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t));-
206 if (wstmp == NULL)
wstmp == ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 4634217 times by 1 test
Evaluated by:
  • Self test
0-4634217
207 {-
208 free (wsbuf);-
209 *destp = NULL;-
210 return (size_t)-1;
never executed: return (size_t)-1;
0
211 }-
212 wsbuf = wstmp;-
213 }
executed 4634217 times by 1 test: end of block
Executed by:
  • Self test
4634217
214-
215 /* Perform the conversion. This is assumed to return 'wcslength'.-
216 It may set 'p' to NULL. */-
217 n = mbsnrtowcs(wsbuf+wcnum, &p, nms, wsbuf_size-wcnum, &state);-
218-
219 if (n == 0 && p == 0)
n == 0Description
TRUEnever evaluated
FALSEevaluated 6949743 times by 1 test
Evaluated by:
  • Self test
p == 0Description
TRUEnever evaluated
FALSEnever evaluated
0-6949743
220 {-
221 wsbuf[wcnum] = L'\0';-
222 break;
never executed: break;
0
223 }-
224-
225 /* Compensate for taking single byte on wcs conversion failure above. */-
226 if (wcslength == 1 && (n == 0 || n == (size_t)-1))
wcslength == 1Description
TRUEevaluated 4631702 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 2318041 times by 1 test
Evaluated by:
  • Self test
n == 0Description
TRUEnever evaluated
FALSEevaluated 4631702 times by 1 test
Evaluated by:
  • Self test
n == (size_t)-1Description
TRUEnever evaluated
FALSEevaluated 4631702 times by 1 test
Evaluated by:
  • Self test
0-4631702
227 {-
228 state = tmp_state;-
229 p = tmp_p;-
230 wsbuf[wcnum] = *p;-
231 if (*p == 0)
*p == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
232 break;
never executed: break;
0
233 else-
234 {-
235 wcnum++; p++;-
236 }
never executed: end of block
0
237 }-
238 else-
239 wcnum += wcslength;
executed 6949743 times by 1 test: wcnum += wcslength;
Executed by:
  • Self test
6949743
240-
241 if (mbsinit (&state) && (p != NULL) && (*p == '\\'))
mbsinit (&state)Description
TRUEevaluated 6949743 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
(p != ((void *)0) )Description
TRUEevaluated 2315529 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 4634214 times by 1 test
Evaluated by:
  • Self test
(*p == '\\')Description
TRUEevaluated 143 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 2315386 times by 1 test
Evaluated by:
  • Self test
0-6949743
242 {-
243 wsbuf[wcnum++] = L'\\';-
244 p++;-
245 }
executed 143 times by 1 test: end of block
Executed by:
  • Self test
143
246 }
executed 6949743 times by 1 test: end of block
Executed by:
  • Self test
6949743
247 while (p != NULL);
p != ((void *)0)Description
TRUEevaluated 2315529 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 4634214 times by 1 test
Evaluated by:
  • Self test
2315529-4634214
248-
249 *destp = wsbuf;-
250-
251 /* Return the length of the wide character string, not including `\0'. */-
252 return wcnum;
executed 4634214 times by 1 test: return wcnum;
Executed by:
  • Self test
4634214
253}-
254#endif /* HAVE_MBSNRTOWCS */-
255-
256/* Convert a multibyte string to a wide character string. Memory for the-
257 new wide character string is obtained with malloc.-
258-
259 The return value is the length of the wide character string. Returns a-
260 pointer to the wide character string in DESTP. If INDICESP is not NULL,-
261 INDICESP stores the pointer to the pointer array. Each pointer is to-
262 the first byte of each multibyte character. Memory for the pointer array-
263 is obtained with malloc, too.-
264 If conversion is failed, the return value is (size_t)-1 and the values-
265 of DESTP and INDICESP are NULL. */-
266-
267size_t-
268xdupmbstowcs (destp, indicesp, src)-
269 wchar_t **destp; /* Store the pointer to the wide character string */-
270 char ***indicesp; /* Store the pointer to the pointer array. */-
271 const char *src; /* Multibyte character string */-
272{-
273 const char *p; /* Conversion start position of src */-
274 wchar_t wc; /* Created wide character by conversion */-
275 wchar_t *wsbuf; /* Buffer for wide characters. */-
276 char **indices; /* Buffer for indices. */-
277 size_t wsbuf_size; /* Size of WSBUF */-
278 size_t wcnum; /* Number of wide characters in WSBUF */-
279 mbstate_t state; /* Conversion State */-
280-
281 /* In case SRC or DESP is NULL, conversion doesn't take place. */-
282 if (src == NULL || destp == NULL)
src == ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 4634230 times by 1 test
Evaluated by:
  • Self test
destp == ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 4634230 times by 1 test
Evaluated by:
  • Self test
0-4634230
283 {-
284 if (destp)
destpDescription
TRUEnever evaluated
FALSEnever evaluated
0
285 *destp = NULL;
never executed: *destp = ((void *)0) ;
0
286 if (indicesp)
indicespDescription
TRUEnever evaluated
FALSEnever evaluated
0
287 *indicesp = NULL;
never executed: *indicesp = ((void *)0) ;
0
288 return (size_t)-1;
never executed: return (size_t)-1;
0
289 }-
290-
291#if HAVE_MBSNRTOWCS-
292 if (indicesp == NULL)
indicesp == ((void *)0)Description
TRUEevaluated 4634220 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 10 times by 1 test
Evaluated by:
  • Self test
10-4634220
293 return (xdupmbstowcs2 (destp, src));
executed 4634220 times by 1 test: return (xdupmbstowcs2 (destp, src));
Executed by:
  • Self test
4634220
294#endif-
295-
296 memset (&state, '\0', sizeof(mbstate_t));-
297 wsbuf_size = WSBUF_INC;-
298-
299 wsbuf = (wchar_t *) malloc (wsbuf_size * sizeof(wchar_t));-
300 if (wsbuf == NULL)
wsbuf == ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 10 times by 1 test
Evaluated by:
  • Self test
0-10
301 {-
302 *destp = NULL;-
303 if (indicesp)
indicespDescription
TRUEnever evaluated
FALSEnever evaluated
0
304 *indicesp = NULL;
never executed: *indicesp = ((void *)0) ;
0
305 return (size_t)-1;
never executed: return (size_t)-1;
0
306 }-
307-
308 indices = NULL;-
309 if (indicesp)
indicespDescription
TRUEevaluated 10 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-10
310 {-
311 indices = (char **) malloc (wsbuf_size * sizeof(char *));-
312 if (indices == NULL)
indices == ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 10 times by 1 test
Evaluated by:
  • Self test
0-10
313 {-
314 free (wsbuf);-
315 *destp = NULL;-
316 *indicesp = NULL;-
317 return (size_t)-1;
never executed: return (size_t)-1;
0
318 }-
319 }
executed 10 times by 1 test: end of block
Executed by:
  • Self test
10
320-
321 p = src;-
322 wcnum = 0;-
323 do-
324 {-
325 size_t mblength; /* Byte length of one multibyte character. */-
326-
327 if (mbsinit (&state))
mbsinit (&state)Description
TRUEevaluated 50 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-50
328 {-
329 if (*p == '\0')
*p == '\0'Description
TRUEevaluated 10 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 40 times by 1 test
Evaluated by:
  • Self test
10-40
330 {-
331 wc = L'\0';-
332 mblength = 1;-
333 }
executed 10 times by 1 test: end of block
Executed by:
  • Self test
10
334 else if (*p == '\\')
*p == '\\'Description
TRUEnever evaluated
FALSEevaluated 40 times by 1 test
Evaluated by:
  • Self test
0-40
335 {-
336 wc = L'\\';-
337 mblength = 1;-
338 }
never executed: end of block
0
339 else-
340 mblength = mbrtowc(&wc, p, MB_LEN_MAX, &state);
executed 40 times by 1 test: mblength = mbrtowc(&wc, p, 16 , &state);
Executed by:
  • Self test
40
341 }-
342 else-
343 mblength = mbrtowc(&wc, p, MB_LEN_MAX, &state);
never executed: mblength = mbrtowc(&wc, p, 16 , &state);
0
344-
345 /* Conversion failed. */-
346 if (MB_INVALIDCH (mblength))
(mblength) == (size_t)-1Description
TRUEnever evaluated
FALSEevaluated 50 times by 1 test
Evaluated by:
  • Self test
(mblength) == (size_t)-2Description
TRUEnever evaluated
FALSEevaluated 50 times by 1 test
Evaluated by:
  • Self test
0-50
347 {-
348 free (wsbuf);-
349 FREE (indices);
never executed: free (indices);
indicesDescription
TRUEnever evaluated
FALSEnever evaluated
0
350 *destp = NULL;-
351 if (indicesp)
indicespDescription
TRUEnever evaluated
FALSEnever evaluated
0
352 *indicesp = NULL;
never executed: *indicesp = ((void *)0) ;
0
353 return (size_t)-1;
never executed: return (size_t)-1;
0
354 }-
355-
356 ++wcnum;-
357-
358 /* Resize buffers when they are not large enough. */-
359 if (wsbuf_size < wcnum)
wsbuf_size < wcnumDescription
TRUEnever evaluated
FALSEevaluated 50 times by 1 test
Evaluated by:
  • Self test
0-50
360 {-
361 wchar_t *wstmp;-
362 char **idxtmp;-
363-
364 wsbuf_size += WSBUF_INC;-
365-
366 wstmp = (wchar_t *) realloc (wsbuf, wsbuf_size * sizeof (wchar_t));-
367 if (wstmp == NULL)
wstmp == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
368 {-
369 free (wsbuf);-
370 FREE (indices);
never executed: free (indices);
indicesDescription
TRUEnever evaluated
FALSEnever evaluated
0
371 *destp = NULL;-
372 if (indicesp)
indicespDescription
TRUEnever evaluated
FALSEnever evaluated
0
373 *indicesp = NULL;
never executed: *indicesp = ((void *)0) ;
0
374 return (size_t)-1;
never executed: return (size_t)-1;
0
375 }-
376 wsbuf = wstmp;-
377-
378 if (indicesp)
indicespDescription
TRUEnever evaluated
FALSEnever evaluated
0
379 {-
380 idxtmp = (char **) realloc (indices, wsbuf_size * sizeof (char *));-
381 if (idxtmp == NULL)
idxtmp == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
382 {-
383 free (wsbuf);-
384 free (indices);-
385 *destp = NULL;-
386 if (indicesp)
indicespDescription
TRUEnever evaluated
FALSEnever evaluated
0
387 *indicesp = NULL;
never executed: *indicesp = ((void *)0) ;
0
388 return (size_t)-1;
never executed: return (size_t)-1;
0
389 }-
390 indices = idxtmp;-
391 }
never executed: end of block
0
392 }
never executed: end of block
0
393-
394 wsbuf[wcnum - 1] = wc;-
395 if (indices)
indicesDescription
TRUEevaluated 50 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-50
396 indices[wcnum - 1] = (char *)p;
executed 50 times by 1 test: indices[wcnum - 1] = (char *)p;
Executed by:
  • Self test
50
397 p += mblength;-
398 }
executed 50 times by 1 test: end of block
Executed by:
  • Self test
50
399 while (MB_NULLWCH (wc) == 0);
((wc) == 0) == 0Description
TRUEevaluated 40 times by 1 test
Evaluated by:
  • Self test
FALSEevaluated 10 times by 1 test
Evaluated by:
  • Self test
10-40
400-
401 /* Return the length of the wide character string, not including `\0'. */-
402 *destp = wsbuf;-
403 if (indicesp != NULL)
indicesp != ((void *)0)Description
TRUEevaluated 10 times by 1 test
Evaluated by:
  • Self test
FALSEnever evaluated
0-10
404 *indicesp = indices;
executed 10 times by 1 test: *indicesp = indices;
Executed by:
  • Self test
10
405-
406 return (wcnum - 1);
executed 10 times by 1 test: return (wcnum - 1);
Executed by:
  • Self test
10
407}-
408-
409#endif /* HANDLE_MULTIBYTE */-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2