ReactOS  0.4.15-dev-309-g7c8d563
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,
261  size_t count, _locale_t locale)
262 {
264  size_t tmp = 0;
265  BOOL used_default;
266 
267  if(!locale)
268  locinfo = get_locinfo();
269  else
270  locinfo = ((MSVCRT__locale_t)locale)->locinfo;
271 
272  if(!locinfo->lc_codepage) {
273  size_t i;
274 
275  if(!mbstr)
276  return strlenW(*wcstr);
277 
278  for(i=0; i<count; i++) {
279  if((*wcstr)[i] > 255) {
281  return -1;
282  }
283 
284  mbstr[i] = (*wcstr)[i];
285  if(!(*wcstr)[i]) break;
286  }
287  return i;
288  }
289 
290  if(!mbstr) {
292  *wcstr, -1, NULL, 0, NULL, &used_default);
293  if(!tmp || used_default) {
295  return -1;
296  }
297  return tmp-1;
298  }
299 
300  while(**wcstr) {
301  char buf[3];
302  size_t i, size;
303 
305  *wcstr, 1, buf, 3, NULL, &used_default);
306  if(!size || used_default) {
308  return -1;
309  }
310  if(tmp+size > count)
311  return tmp;
312 
313  for(i=0; i<size; i++)
314  mbstr[tmp++] = buf[i];
315  (*wcstr)++;
316  }
317 
318  if(tmp < count) {
319  mbstr[tmp] = '\0';
320  *wcstr = NULL;
321  }
322  return tmp;
323 }
324 
325 /*********************************************************************
326  * _wcstombs_l (MSVCRT.@)
327  */
328 size_t CDECL _wcstombs_l(char *mbstr, const wchar_t *wcstr, size_t count, _locale_t locale)
329 {
330  return wcsrtombs_l(mbstr, &wcstr, count, locale);
331 }
332 
333 /*********************************************************************
334  * wcstombs (MSVCRT.@)
335  */
336 size_t CDECL wcstombs(char *mbstr, const wchar_t *wcstr, size_t count)
337 {
338  return wcsrtombs_l(mbstr, &wcstr, count, NULL);
339 }
340 #endif
341 
342 /*********************************************************************
343  * wcscpy_s (MSVCRT.@)
344  */
345 INT CDECL wcscpy_s( wchar_t* wcDest, size_t numElement, const wchar_t *wcSrc)
346 {
347  size_t size = 0;
348 
349  if(!wcDest || !numElement)
350  return EINVAL;
351 
352  wcDest[0] = 0;
353 
354  if(!wcSrc)
355  {
356  return EINVAL;
357  }
358 
359  size = strlenW(wcSrc) + 1;
360 
361  if(size > numElement)
362  {
363  return ERANGE;
364  }
365 
366  memcpy( wcDest, wcSrc, size*sizeof(WCHAR) );
367 
368  return 0;
369 }
370 
371 /******************************************************************
372  * wcsncpy_s (MSVCRT.@)
373  */
374 INT CDECL wcsncpy_s( wchar_t* wcDest, size_t numElement, const wchar_t *wcSrc,
375  size_t count )
376 {
377  size_t size = 0;
378 
379  if (!wcDest || !numElement)
380  return EINVAL;
381 
382  wcDest[0] = 0;
383 
384  if (!wcSrc)
385  {
386  return EINVAL;
387  }
388 
389  size = min(strlenW(wcSrc), count);
390 
391  if (size >= numElement)
392  {
393  return ERANGE;
394  }
395 
396  memcpy( wcDest, wcSrc, size*sizeof(WCHAR) );
397  wcDest[size] = '\0';
398 
399  return 0;
400 }
401 
402 /******************************************************************
403  * wcscat_s (MSVCRT.@)
404  *
405  */
406 INT CDECL wcscat_s(wchar_t* dst, size_t elem, const wchar_t* src)
407 {
408  wchar_t* ptr = dst;
409 
410  if (!dst || elem == 0) return EINVAL;
411  if (!src)
412  {
413  dst[0] = '\0';
414  return EINVAL;
415  }
416 
417  /* seek to end of dst string (or elem if no end of string is found */
418  while (ptr < dst + elem && *ptr != '\0') ptr++;
419  while (ptr < dst + elem)
420  {
421  if ((*ptr++ = *src++) == '\0') return 0;
422  }
423  /* not enough space */
424  dst[0] = '\0';
425  return ERANGE;
426 }
427 
428 /*********************************************************************
429  * wcsncat_s (MSVCRT.@)
430  *
431  */
432 INT CDECL wcsncat_s(wchar_t *dst, size_t elem,
433  const wchar_t *src, size_t count)
434 {
435  size_t srclen;
436  wchar_t dststart;
437  INT ret = 0;
438 
439  if (!MSVCRT_CHECK_PMT(dst != NULL) || !MSVCRT_CHECK_PMT(elem > 0))
440  {
441 #ifndef _LIBCNT_
443 #endif
444  return EINVAL;
445  }
446  if (!MSVCRT_CHECK_PMT(src != NULL || count == 0))
447  return EINVAL;
448  if (count == 0)
449  return 0;
450 
451  for (dststart = 0; dststart < elem; dststart++)
452  {
453  if (dst[dststart] == '\0')
454  break;
455  }
456  if (dststart == elem)
457  {
458  MSVCRT_INVALID_PMT("dst[elem] is not NULL terminated\n", EINVAL);
459  return EINVAL;
460  }
461 
462  if (count == _TRUNCATE)
463  {
464  srclen = strlenW(src);
465  if (srclen >= (elem - dststart))
466  {
467  srclen = elem - dststart - 1;
468  ret = STRUNCATE;
469  }
470  }
471  else
472  srclen = min(strlenW(src), count);
473  if (srclen < (elem - dststart))
474  {
475  memcpy(&dst[dststart], src, srclen*sizeof(wchar_t));
476  dst[dststart+srclen] = '\0';
477  return ret;
478  }
479  MSVCRT_INVALID_PMT("dst[elem] is too small", ERANGE);
480  dst[0] = '\0';
481  return ERANGE;
482 }
483 
errno_t __cdecl _set_errno(_In_ int _Value)
#define EILSEQ
Definition: errno.h:97
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:57
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:374
#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:406
#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:345
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:336
#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:328
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:432
int CDECL wcscoll(const wchar_t *str1, const wchar_t *str2)
Definition: wcs.c:216