ReactOS  0.4.14-dev-50-g13bb5e2
wcs.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS CRT library
3  * LICENSE: LGPL - See COPYING in the top level directory
4  * FILE: lib/sdk/crt/string/wcs.c
5  * PURPOSE: wcs* CRT functions
6  * PROGRAMMERS: Wine team
7  * Ported to ReactOS by Aleksey Bragin (aleksey@reactos.org)
8  */
9 
10 /*
11  * msvcrt.dll wide-char functions
12  *
13  * Copyright 1999 Alexandre Julliard
14  * Copyright 2000 Jon Griffiths
15  *
16  * This library is free software; you can redistribute it and/or
17  * modify it under the terms of the GNU Lesser General Public
18  * License as published by the Free Software Foundation; either
19  * version 2.1 of the License, or (at your option) any later version.
20  *
21  * This library is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24  * Lesser General Public License for more details.
25  *
26  * You should have received a copy of the GNU Lesser General Public
27  * License along with this library; if not, write to the Free Software
28  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29  */
30 #include <precomp.h>
31 #include <assert.h>
32 
33 #ifndef _LIBCNT_
34 #include <internal/wine/msvcrt.h>
35 #endif
36 
37 #include "wine/unicode.h"
38 #undef sprintf
39 #undef wsprintf
40 #undef snprintf
41 #undef vsnprintf
42 #undef vprintf
43 #undef vwprintf
44 
45 #ifdef _MSC_VER
46 #pragma function(_wcsset)
47 #endif
48 
49 #ifndef _LIBCNT_
50 /*********************************************************************
51  * _wcsdup (MSVCRT.@)
52  */
53 wchar_t* CDECL _wcsdup( const wchar_t* str )
54 {
55  wchar_t* ret = NULL;
56  if (str)
57  {
58  size_t size = (strlenW(str) + 1) * sizeof(wchar_t);
59  ret = malloc( size );
60  if (ret) memcpy( ret, str, size );
61  }
62  return ret;
63 }
64 /*********************************************************************
65  * _wcsicoll (MSVCRT.@)
66  */
67 INT CDECL _wcsicoll( const wchar_t* str1, const wchar_t* str2 )
68 {
69  /* FIXME: handle collates */
70  return strcmpiW( str1, str2 );
71 }
72 #endif
73 
74 /*********************************************************************
75  * _wcsnset (MSVCRT.@)
76  */
77 wchar_t* CDECL _wcsnset( wchar_t* str, wchar_t c, size_t n )
78 {
79  wchar_t* ret = str;
80  while ((n-- > 0) && *str) *str++ = c;
81  return ret;
82 }
83 
84 /*********************************************************************
85  * _wcsrev (MSVCRT.@)
86  */
87 wchar_t* CDECL _wcsrev( wchar_t* str )
88 {
89  wchar_t* ret = str;
90  wchar_t* end = str + strlenW(str) - 1;
91  while (end > str)
92  {
93  wchar_t t = *end;
94  *end-- = *str;
95  *str++ = t;
96  }
97  return ret;
98 }
99 
100 #ifndef _LIBCNT_
101 /*********************************************************************
102  * _wcsset (MSVCRT.@)
103  */
104 wchar_t* CDECL _wcsset( wchar_t* str, wchar_t c )
105 {
106  wchar_t* ret = str;
107  while (*str) *str++ = c;
108  return ret;
109 }
110 
111 /******************************************************************
112  * _wcsupr_s (MSVCRT.@)
113  *
114  */
115 INT CDECL _wcsupr_s( wchar_t* str, size_t n )
116 {
117  wchar_t* ptr = str;
118 
119  if (!str || !n)
120  {
121  if (str) *str = '\0';
123  return EINVAL;
124  }
125 
126  while (n--)
127  {
128  if (!*ptr) return 0;
129  *ptr = toupperW(*ptr);
130  ptr++;
131  }
132 
133  /* MSDN claims that the function should return and set errno to
134  * ERANGE, which doesn't seem to be true based on the tests. */
135  *str = '\0';
137  return EINVAL;
138 }
139 
140 /*********************************************************************
141  * wcstod (MSVCRT.@)
142  */
143 double CDECL wcstod(const wchar_t* lpszStr, wchar_t** end)
144 {
145  const wchar_t* str = lpszStr;
146  int negative = 0;
147  double ret = 0, divisor = 10.0;
148 
149  TRACE("(%s,%p) semi-stub\n", debugstr_w(lpszStr), end);
150 
151  /* FIXME:
152  * - Should set errno on failure
153  * - Should fail on overflow
154  * - Need to check which input formats are allowed
155  */
156  while (isspaceW(*str))
157  str++;
158 
159  if (*str == '-')
160  {
161  negative = 1;
162  str++;
163  }
164 
165  while (isdigitW(*str))
166  {
167  ret = ret * 10.0 + (*str - '0');
168  str++;
169  }
170  if (*str == '.')
171  str++;
172  while (isdigitW(*str))
173  {
174  ret = ret + (*str - '0') / divisor;
175  divisor *= 10;
176  str++;
177  }
178 
179  if (*str == 'E' || *str == 'e' || *str == 'D' || *str == 'd')
180  {
181  int negativeExponent = 0;
182  int exponent = 0;
183  if (*(++str) == '-')
184  {
185  negativeExponent = 1;
186  str++;
187  }
188  while (isdigitW(*str))
189  {
190  exponent = exponent * 10 + (*str - '0');
191  str++;
192  }
193  if (exponent != 0)
194  {
195  if (negativeExponent)
196  ret = ret / pow(10.0, exponent);
197  else
198  ret = ret * pow(10.0, exponent);
199  }
200  }
201 
202  if (negative)
203  ret = -ret;
204 
205  if (end)
206  *end = (wchar_t*)str;
207 
208  TRACE("returning %g\n", ret);
209  return ret;
210 }
211 #endif
212 
213 /*********************************************************************
214  * wcscoll (MSVCRT.@)
215  */
216 int CDECL wcscoll( const wchar_t* str1, const wchar_t* str2 )
217 {
218  /* FIXME: handle collates */
219  return strcmpW( str1, str2 );
220 }
221 
222 /*********************************************************************
223  * wcspbrk (MSVCRT.@)
224  */
225 wchar_t* CDECL wcspbrk( const wchar_t* str, const wchar_t* accept )
226 {
227  const wchar_t* p;
228  while (*str)
229  {
230  for (p = accept; *p; p++) if (*p == *str) return (wchar_t*)str;
231  str++;
232  }
233  return NULL;
234 }
235 
236 #ifndef _LIBCNT_
237 
238 /*********************************************************************
239  * wctomb (MSVCRT.@)
240  */
241 /*********************************************************************
242  * wctomb (MSVCRT.@)
243  */
244 INT CDECL wctomb( char *dst, wchar_t ch )
245 {
246  BOOL error;
247  INT size;
248 
249  size = WideCharToMultiByte(get_locinfo()->lc_codepage, 0, &ch, 1, dst, dst ? 6 : 0, NULL, &error);
250  if(!size || error) {
251  *_errno() = EINVAL;
252  return EOF;
253  }
254  return size;
255 }
256 
257 /*********************************************************************
258  * wcsrtombs_l (INTERNAL)
259  */
260 static size_t CDECL wcsrtombs_l(char *mbstr, const wchar_t **wcstr, size_t count, _locale_t locale)
261 {
263  size_t tmp = 0;
264  BOOL used_default;
265 
266  if(!locale)
267  locinfo = get_locinfo();
268  else
269  locinfo = ((MSVCRT__locale_t)locale)->locinfo;
270 
271  if(!mbstr) {
273  *wcstr, -1, NULL, 0, NULL, &used_default)-1;
274  if(used_default)
275  return -1;
276  return tmp;
277  }
278 
279  while(**wcstr) {
280  char buf[3];
281  size_t i, size;
282 
284  *wcstr, 1, buf, 3, NULL, &used_default);
285  if(used_default)
286  return -1;
287  if(tmp+size > count)
288  return tmp;
289 
290  for(i=0; i<size; i++)
291  mbstr[tmp++] = buf[i];
292  (*wcstr)++;
293  }
294 
295  if(tmp < count) {
296  mbstr[tmp] = '\0';
297  *wcstr = NULL;
298  }
299  return tmp;
300 }
301 
302 /*********************************************************************
303  * _wcstombs_l (MSVCRT.@)
304  */
305 size_t CDECL _wcstombs_l(char *mbstr, const wchar_t *wcstr, size_t count, _locale_t locale)
306 {
307  return wcsrtombs_l(mbstr, &wcstr, count, locale);
308 }
309 
310 /*********************************************************************
311  * wcstombs (MSVCRT.@)
312  */
313 size_t CDECL wcstombs(char *mbstr, const wchar_t *wcstr, size_t count)
314 {
315  return wcsrtombs_l(mbstr, &wcstr, count, NULL);
316 }
317 #endif
318 
319 /*********************************************************************
320  * wcscpy_s (MSVCRT.@)
321  */
322 INT CDECL wcscpy_s( wchar_t* wcDest, size_t numElement, const wchar_t *wcSrc)
323 {
324  size_t size = 0;
325 
326  if(!wcDest || !numElement)
327  return EINVAL;
328 
329  wcDest[0] = 0;
330 
331  if(!wcSrc)
332  {
333  return EINVAL;
334  }
335 
336  size = strlenW(wcSrc) + 1;
337 
338  if(size > numElement)
339  {
340  return ERANGE;
341  }
342 
343  memcpy( wcDest, wcSrc, size*sizeof(WCHAR) );
344 
345  return 0;
346 }
347 
348 /******************************************************************
349  * wcsncpy_s (MSVCRT.@)
350  */
351 INT CDECL wcsncpy_s( wchar_t* wcDest, size_t numElement, const wchar_t *wcSrc,
352  size_t count )
353 {
354  size_t size = 0;
355 
356  if (!wcDest || !numElement)
357  return EINVAL;
358 
359  wcDest[0] = 0;
360 
361  if (!wcSrc)
362  {
363  return EINVAL;
364  }
365 
366  size = min(strlenW(wcSrc), count);
367 
368  if (size >= numElement)
369  {
370  return ERANGE;
371  }
372 
373  memcpy( wcDest, wcSrc, size*sizeof(WCHAR) );
374  wcDest[size] = '\0';
375 
376  return 0;
377 }
378 
379 /******************************************************************
380  * wcscat_s (MSVCRT.@)
381  *
382  */
383 INT CDECL wcscat_s(wchar_t* dst, size_t elem, const wchar_t* src)
384 {
385  wchar_t* ptr = dst;
386 
387  if (!dst || elem == 0) return EINVAL;
388  if (!src)
389  {
390  dst[0] = '\0';
391  return EINVAL;
392  }
393 
394  /* seek to end of dst string (or elem if no end of string is found */
395  while (ptr < dst + elem && *ptr != '\0') ptr++;
396  while (ptr < dst + elem)
397  {
398  if ((*ptr++ = *src++) == '\0') return 0;
399  }
400  /* not enough space */
401  dst[0] = '\0';
402  return ERANGE;
403 }
404 
405 /*********************************************************************
406  * wcsncat_s (MSVCRT.@)
407  *
408  */
409 INT CDECL wcsncat_s(wchar_t *dst, size_t elem,
410  const wchar_t *src, size_t count)
411 {
412  size_t srclen;
413  wchar_t dststart;
414  INT ret = 0;
415 
416  if (!MSVCRT_CHECK_PMT(dst != NULL) || !MSVCRT_CHECK_PMT(elem > 0))
417  {
418 #ifndef _LIBCNT_
420 #endif
421  return EINVAL;
422  }
423  if (!MSVCRT_CHECK_PMT(src != NULL || count == 0))
424  return EINVAL;
425  if (count == 0)
426  return 0;
427 
428  for (dststart = 0; dststart < elem; dststart++)
429  {
430  if (dst[dststart] == '\0')
431  break;
432  }
433  if (dststart == elem)
434  {
435  MSVCRT_INVALID_PMT("dst[elem] is not NULL terminated\n", EINVAL);
436  return EINVAL;
437  }
438 
439  if (count == _TRUNCATE)
440  {
441  srclen = strlenW(src);
442  if (srclen >= (elem - dststart))
443  {
444  srclen = elem - dststart - 1;
445  ret = STRUNCATE;
446  }
447  }
448  else
449  srclen = min(strlenW(src), count);
450  if (srclen < (elem - dststart))
451  {
452  memcpy(&dst[dststart], src, srclen*sizeof(wchar_t));
453  dst[dststart+srclen] = '\0';
454  return ret;
455  }
456  MSVCRT_INVALID_PMT("dst[elem] is too small", ERANGE);
457  dst[0] = '\0';
458  return ERANGE;
459 }
460 
errno_t __cdecl _set_errno(_In_ int _Value)
double CDECL wcstod(const wchar_t *lpszStr, wchar_t **end)
Definition: wcs.c:143
WINE_UNICODE_INLINE unsigned int strlenW(const WCHAR *str)
Definition: unicode.h:212
struct MSVCRT_localeinfo_struct * MSVCRT__locale_t
#define WideCharToMultiByte
Definition: compat.h:101
#define error(str)
Definition: mkdosfs.c:1605
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
Definition: arc.h:39
WINE_UNICODE_INLINE int isspaceW(WCHAR wc)
Definition: unicode.h:165
GLuint GLuint GLsizei count
Definition: gl.h:1545
static size_t CDECL wcsrtombs_l(char *mbstr, const wchar_t **wcstr, size_t count, _locale_t locale)
Definition: wcs.c:260
GLdouble n
Definition: glext.h:7729
GLdouble GLdouble t
Definition: gl.h:2047
#define STRUNCATE
Definition: errno.h:110
wchar_t *CDECL _wcsnset(wchar_t *str, wchar_t c, size_t n)
Definition: wcs.c:77
GLuint GLuint end
Definition: gl.h:1545
INT CDECL wctomb(char *dst, wchar_t ch)
Definition: wcs.c:244
wchar_t *CDECL _wcsset(wchar_t *str, wchar_t c)
Definition: wcs.c:104
int32_t INT
Definition: typedefs.h:56
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static const unsigned char *static size_t const wchar_t * wcSrc
Definition: string.c:66
Definition: _locale.h:75
unsigned int BOOL
Definition: ntddk_ex.h:94
float pow(float __x, int __y)
Definition: _cmath.h:458
#define debugstr_w
Definition: kernel32.h:32
static size_t elem
Definition: string.c:68
static PVOID ptr
Definition: dispmode.c:27
wchar_t *CDECL _wcsrev(wchar_t *str)
Definition: wcs.c:87
#define MSVCRT_INVALID_PMT(x)
Definition: mbstowcs_s.c:25
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
#define get_locinfo()
Definition: winesup.h:25
INT CDECL _wcsicoll(const wchar_t *str1, const wchar_t *str2)
Definition: wcs.c:67
INT CDECL wcsncpy_s(wchar_t *wcDest, size_t numElement, const wchar_t *wcSrc, size_t count)
Definition: wcs.c:351
#define _TRUNCATE
Definition: crtdefs.h:241
WINE_UNICODE_INLINE WCHAR toupperW(WCHAR ch)
Definition: unicode.h:141
INT CDECL wcscat_s(wchar_t *dst, size_t elem, const wchar_t *src)
Definition: wcs.c:383
#define TRACE(s)
Definition: solgame.cpp:4
INT CDECL _wcsupr_s(wchar_t *str, size_t n)
Definition: wcs.c:115
GLsizeiptr size
Definition: glext.h:5919
__wchar_t WCHAR
Definition: xmlstorage.h:180
static DWORD LPDWORD LPCSTR DWORD srclen
Definition: directory.c:51
INT CDECL wcscpy_s(wchar_t *wcDest, size_t numElement, const wchar_t *wcSrc)
Definition: wcs.c:322
const GLubyte * c
Definition: glext.h:8905
wchar_t *CDECL _wcsdup(const wchar_t *str)
Definition: wcs.c:53
#define WC_NO_BEST_FIT_CHARS
Definition: unicode.h:46
_CRTIMP int *__cdecl _errno(void)
Definition: errno.c:19
#define ERANGE
Definition: acclib.h:92
int ret
else locinfo
Definition: scanf.h:159
#define MSVCRT_CHECK_PMT(x)
Definition: mbstowcs_s.c:26
size_t CDECL wcstombs(char *mbstr, const wchar_t *wcstr, size_t count)
Definition: wcs.c:313
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum src
Definition: glext.h:6340
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
GLuint divisor
Definition: glext.h:6313
#define strcmpiW(s1, s2)
Definition: unicode.h:39
wchar_t *CDECL wcspbrk(const wchar_t *str, const wchar_t *accept)
Definition: wcs.c:225
#define CDECL
Definition: compat.h:21
GLenum GLenum dst
Definition: glext.h:6340
WINE_UNICODE_INLINE int isdigitW(WCHAR wc)
Definition: unicode.h:170
#define min(a, b)
Definition: monoChain.cc:55
#define EOF
Definition: stdio.h:24
WINE_UNICODE_INLINE int strcmpW(const WCHAR *str1, const WCHAR *str2)
Definition: unicode.h:229
#define c
Definition: ke_i.h:80
#define malloc
Definition: debug_ros.c:4
size_t CDECL _wcstombs_l(char *mbstr, const wchar_t *wcstr, size_t count, _locale_t locale)
Definition: wcs.c:305
GLfloat GLfloat p
Definition: glext.h:8902
INT CDECL wcsncat_s(wchar_t *dst, size_t elem, const wchar_t *src, size_t count)
Definition: wcs.c:409
int CDECL wcscoll(const wchar_t *str1, const wchar_t *str2)
Definition: wcs.c:216