1 /*
2 Copyright (c) 1990 Regents of the University of California.
3 All rights reserved.
4  */
5 /*
6 FUNCTION
7 <<mbstowcs>>---minimal multibyte string to wide char converter
8 
9 INDEX
10 	mbstowcs
11 
12 SYNOPSIS
13 	#include <stdlib.h>
14 	int mbstowcs(wchar_t *restrict <[pwc]>, const char *restrict <[s]>, size_t <[n]>);
15 
16 DESCRIPTION
17 When _MB_CAPABLE is not defined, this is a minimal ANSI-conforming
18 implementation of <<mbstowcs>>.  In this case, the
19 only ``multi-byte character sequences'' recognized are single bytes,
20 and they are ``converted'' to wide-char versions simply by byte
21 extension.
22 
23 When _MB_CAPABLE is defined, this uses a state variable to allow state
24 dependent decoding.  The result is based on the locale setting which
25 may be restricted to a defined set of locales.
26 
27 RETURNS
28 This implementation of <<mbstowcs>> returns <<0>> if
29 <[s]> is <<NULL>> or is the empty string;
30 it returns <<-1>> if _MB_CAPABLE and one of the
31 multi-byte characters is invalid or incomplete;
32 otherwise it returns the minimum of: <<n>> or the
33 number of multi-byte characters in <<s>> plus 1 (to
34 compensate for the nul character).
35 If the return value is -1, the state of the <<pwc>> string is
36 indeterminate.  If the input has a length of 0, the output
37 string will be modified to contain a wchar_t nul terminator.
38 
39 PORTABILITY
40 <<mbstowcs>> is required in the ANSI C standard.  However, the precise
41 effects vary with the locale.
42 
43 <<mbstowcs>> requires no supporting OS subroutines.
44 */
45 
46 #ifndef _REENT_ONLY
47 
48 #include <newlib.h>
49 #include <stdlib.h>
50 #include <wchar.h>
51 #include "local.h"
52 
53 size_t
mbstowcs(wchar_t * __restrict pwcs,const char * __restrict s,size_t n)54 mbstowcs (wchar_t *__restrict pwcs,
55         const char *__restrict s,
56         size_t n)
57 {
58 #ifdef _MB_CAPABLE
59   mbstate_t state;
60   state.__count = 0;
61 
62   size_t ret = 0;
63   char *t = (char *)s;
64   int bytes;
65 
66   if (!pwcs)
67     n = (size_t) 1; /* Value doesn't matter as long as it's not 0. */
68   while (n > 0)
69     {
70       bytes = __MBTOWC (pwcs, t, MB_CUR_MAX, &state);
71       if (bytes < 0)
72 	{
73 	  state.__count = 0;
74 	  return -1;
75 	}
76       else if (bytes == 0)
77 	break;
78       t += bytes;
79       ++ret;
80       if (pwcs)
81 	{
82 	  ++pwcs;
83 	  --n;
84 	}
85     }
86   return ret;
87 #else /* not _MB_CAPABLE */
88 
89   int count = 0;
90 
91   if (n != 0) {
92     do {
93       if ((*pwcs++ = (wchar_t) *s++) == 0)
94 	break;
95       count++;
96     } while (--n != 0);
97   }
98 
99   return count;
100 #endif /* not _MB_CAPABLE */
101 }
102 
103 #endif /* !_REENT_ONLY */
104