Implement ClearCustData.
[wine] / dlls / msvcrt / wcs.c
1 /*
2  * msvcrt.dll wide-char functions
3  *
4  * Copyright 1999 Alexandre Julliard
5  * Copyright 2000 Jon Griffiths
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library 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 GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21 #include <limits.h>
22 #include <stdio.h>
23 #include <math.h>
24 #include "msvcrt.h"
25 #include "winnls.h"
26 #include "wine/unicode.h"
27
28 #include "msvcrt/stdio.h"
29 #include "msvcrt/stdlib.h"
30 #include "msvcrt/string.h"
31 #include "msvcrt/wctype.h"
32
33 #include "wine/debug.h"
34
35 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
36
37
38 /* INTERNAL: MSVCRT_malloc() based wstrndup */
39 MSVCRT_wchar_t* msvcrt_wstrndup(const MSVCRT_wchar_t *buf, unsigned int size)
40 {
41   MSVCRT_wchar_t* ret;
42   unsigned int len = strlenW(buf), max_len;
43
44   max_len = size <= len? size : len + 1;
45
46   ret = MSVCRT_malloc(max_len * sizeof (MSVCRT_wchar_t));
47   if (ret)
48   {
49     memcpy(ret,buf,max_len * sizeof (MSVCRT_wchar_t));
50     ret[max_len] = 0;
51   }
52   return ret;
53 }
54
55 /*********************************************************************
56  *              _wcsdup (MSVCRT.@)
57  */
58 MSVCRT_wchar_t* _wcsdup( const MSVCRT_wchar_t* str )
59 {
60   MSVCRT_wchar_t* ret = NULL;
61   if (str)
62   {
63     int size = (strlenW(str) + 1) * sizeof(MSVCRT_wchar_t);
64     ret = MSVCRT_malloc( size );
65     if (ret) memcpy( ret, str, size );
66   }
67   return ret;
68 }
69
70 /*********************************************************************
71  *              _wcsicoll (MSVCRT.@)
72  */
73 INT _wcsicoll( const MSVCRT_wchar_t* str1, const MSVCRT_wchar_t* str2 )
74 {
75   /* FIXME: handle collates */
76   return strcmpiW( str1, str2 );
77 }
78
79 /*********************************************************************
80  *              _wcsnset (MSVCRT.@)
81  */
82 MSVCRT_wchar_t* _wcsnset( MSVCRT_wchar_t* str, MSVCRT_wchar_t c, MSVCRT_size_t n )
83 {
84   MSVCRT_wchar_t* ret = str;
85   while ((n-- > 0) && *str) *str++ = c;
86   return ret;
87 }
88
89 /*********************************************************************
90  *              _wcsrev (MSVCRT.@)
91  */
92 MSVCRT_wchar_t* _wcsrev( MSVCRT_wchar_t* str )
93 {
94   MSVCRT_wchar_t* ret = str;
95   MSVCRT_wchar_t* end = str + strlenW(str) - 1;
96   while (end > str)
97   {
98     MSVCRT_wchar_t t = *end;
99     *end--  = *str;
100     *str++  = t;
101   }
102   return ret;
103 }
104
105 /*********************************************************************
106  *              _wcsset (MSVCRT.@)
107  */
108 MSVCRT_wchar_t* _wcsset( MSVCRT_wchar_t* str, MSVCRT_wchar_t c )
109 {
110   MSVCRT_wchar_t* ret = str;
111   while (*str) *str++ = c;
112   return ret;
113 }
114
115 /*********************************************************************
116  *              wcstod (MSVCRT.@)
117  */
118 double MSVCRT_wcstod(const MSVCRT_wchar_t* lpszStr, MSVCRT_wchar_t** end)
119 {
120   const MSVCRT_wchar_t* str = lpszStr;
121   int negative = 0;
122   double ret = 0, divisor = 10.0;
123
124   TRACE("(%s,%p) semi-stub\n", debugstr_w(lpszStr), end);
125
126   /* FIXME:
127    * - Should set errno on failure
128    * - Should fail on overflow
129    * - Need to check which input formats are allowed
130    */
131   while (isspaceW(*str))
132     str++;
133
134   if (*str == '-')
135   {
136     negative = 1;
137     str++;
138   }
139
140   while (isdigitW(*str))
141   {
142     ret = ret * 10.0 + (*str - '0');
143     str++;
144   }
145   if (*str == '.')
146     str++;
147   while (isdigitW(*str))
148   {
149     ret = ret + (*str - '0') / divisor;
150     divisor *= 10;
151     str++;
152   }
153
154   if (*str == 'E' || *str == 'e' || *str == 'D' || *str == 'd')
155   {
156     int negativeExponent = 0;
157     int exponent = 0;
158     if (*(++str) == '-')
159     {
160       negativeExponent = 1;
161       str++;
162     }
163     while (isdigitW(*str))
164     {
165       exponent = exponent * 10 + (*str - '0');
166       str++;
167     }
168     if (exponent != 0)
169     {
170       if (negativeExponent)
171         ret = ret / pow(10.0, exponent);
172       else
173         ret = ret * pow(10.0, exponent);
174     }
175   }
176
177   if (negative)
178     ret = -ret;
179
180   if (end)
181     *end = (MSVCRT_wchar_t*)str;
182
183   TRACE("returning %g\n", ret);
184   return ret;
185 }
186
187 /*********************************************************************
188  *              _vsnwprintf (MSVCRT.@)
189  */
190 int _vsnwprintf(MSVCRT_wchar_t *str, unsigned int len,
191                 const MSVCRT_wchar_t *format, va_list valist)
192 {
193     return vsnprintfW(str, len, format, valist);
194 }
195
196 /*********************************************************************
197  *              vswprintf (MSVCRT.@)
198  */
199 int MSVCRT_vswprintf( MSVCRT_wchar_t* str, const MSVCRT_wchar_t* format, va_list args )
200 {
201     return vsnprintfW( str, INT_MAX, format, args );
202 }
203
204 /*********************************************************************
205  *              wcscoll (MSVCRT.@)
206  */
207 int MSVCRT_wcscoll( const MSVCRT_wchar_t* str1, const MSVCRT_wchar_t* str2 )
208 {
209   /* FIXME: handle collates */
210   return strcmpW( str1, str2 );
211 }
212
213 /*********************************************************************
214  *              wcspbrk (MSVCRT.@)
215  */
216 MSVCRT_wchar_t* MSVCRT_wcspbrk( const MSVCRT_wchar_t* str, const MSVCRT_wchar_t* accept )
217 {
218   const MSVCRT_wchar_t* p;
219   while (*str)
220   {
221     for (p = accept; *p; p++) if (*p == *str) return (MSVCRT_wchar_t*)str;
222       str++;
223   }
224   return NULL;
225 }
226
227 /*********************************************************************
228  *              wctomb (MSVCRT.@)
229  */
230 INT MSVCRT_wctomb( char *dst, MSVCRT_wchar_t ch )
231 {
232   return WideCharToMultiByte( CP_ACP, 0, &ch, 1, dst, 6, NULL, NULL );
233 }
234
235 /*********************************************************************
236  *              iswalnum (MSVCRT.@)
237  */
238 INT MSVCRT_iswalnum( MSVCRT_wchar_t wc )
239 {
240     return isalnumW( wc );
241 }
242
243 /*********************************************************************
244  *              iswalpha (MSVCRT.@)
245  */
246 INT MSVCRT_iswalpha( MSVCRT_wchar_t wc )
247 {
248     return isalphaW( wc );
249 }
250
251 /*********************************************************************
252  *              iswcntrl (MSVCRT.@)
253  */
254 INT MSVCRT_iswcntrl( MSVCRT_wchar_t wc )
255 {
256     return iscntrlW( wc );
257 }
258
259 /*********************************************************************
260  *              iswdigit (MSVCRT.@)
261  */
262 INT MSVCRT_iswdigit( MSVCRT_wchar_t wc )
263 {
264     return isdigitW( wc );
265 }
266
267 /*********************************************************************
268  *              iswgraph (MSVCRT.@)
269  */
270 INT MSVCRT_iswgraph( MSVCRT_wchar_t wc )
271 {
272     return isgraphW( wc );
273 }
274
275 /*********************************************************************
276  *              iswlower (MSVCRT.@)
277  */
278 INT MSVCRT_iswlower( MSVCRT_wchar_t wc )
279 {
280     return islowerW( wc );
281 }
282
283 /*********************************************************************
284  *              iswprint (MSVCRT.@)
285  */
286 INT MSVCRT_iswprint( MSVCRT_wchar_t wc )
287 {
288     return isprintW( wc );
289 }
290
291 /*********************************************************************
292  *              iswpunct (MSVCRT.@)
293  */
294 INT MSVCRT_iswpunct( MSVCRT_wchar_t wc )
295 {
296     return ispunctW( wc );
297 }
298
299 /*********************************************************************
300  *              iswspace (MSVCRT.@)
301  */
302 INT MSVCRT_iswspace( MSVCRT_wchar_t wc )
303 {
304     return isspaceW( wc );
305 }
306
307 /*********************************************************************
308  *              iswupper (MSVCRT.@)
309  */
310 INT MSVCRT_iswupper( MSVCRT_wchar_t wc )
311 {
312     return isupperW( wc );
313 }
314
315 /*********************************************************************
316  *              iswxdigit (MSVCRT.@)
317  */
318 INT MSVCRT_iswxdigit( MSVCRT_wchar_t wc )
319 {
320     return isxdigitW( wc );
321 }