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 #include <stdlib.h>
47 #include <wchar.h>
48 #include "local.h"
49 
50 size_t
mbstowcs(wchar_t * __restrict pwcs,const char * __restrict s,size_t n)51 mbstowcs (wchar_t *__restrict pwcs,
52         const char *__restrict s,
53         size_t n)
54 {
55 #ifdef _MB_CAPABLE
56   mbstate_t state;
57   state.__count = 0;
58 
59   size_t ret = 0;
60   char *t = (char *)s;
61   int bytes;
62 
63   if (!pwcs)
64     n = (size_t) 1; /* Value doesn't matter as long as it's not 0. */
65   while (n > 0)
66     {
67       bytes = __MBTOWC (pwcs, t, MB_CUR_MAX, &state);
68       if (bytes < 0)
69 	{
70 	  state.__count = 0;
71 	  return -1;
72 	}
73       else if (bytes == 0)
74 	break;
75       t += bytes;
76       ++ret;
77       if (pwcs)
78 	{
79 	  ++pwcs;
80 	  --n;
81 	}
82     }
83   return ret;
84 #else /* not _MB_CAPABLE */
85 
86   int count = 0;
87 
88   if (n != 0) {
89     do {
90       if ((*pwcs++ = (wchar_t) *s++) == 0)
91 	break;
92       count++;
93     } while (--n != 0);
94   }
95 
96   return count;
97 #endif /* not _MB_CAPABLE */
98 }
99