ReactOS 0.4.15-dev-7953-g1f49173
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_
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 */
53wchar_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 */
67INT 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 */
77wchar_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 */
87wchar_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 */
104wchar_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 */
115INT 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 */
143double 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 */
216int 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 */
225wchar_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 */
244INT 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 */
260static 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)
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 */
328size_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 */
336size_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 */
345INT 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 */
374INT 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
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 */
406INT 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 */
432INT 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
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
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
#define EINVAL
Definition: acclib.h:90
#define ERANGE
Definition: acclib.h:92
Definition: _locale.h:75
#define _TRUNCATE
Definition: crtdefs.h:262
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define CDECL
Definition: compat.h:29
#define WideCharToMultiByte
Definition: compat.h:111
unsigned int BOOL
Definition: ntddk_ex.h:94
double pow(double x, double y)
Definition: freeldr.c:112
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble t
Definition: gl.h:2047
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLenum src
Definition: glext.h:6340
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLenum dst
Definition: glext.h:6340
GLuint divisor
Definition: glext.h:6313
GLfloat GLfloat p
Definition: glext.h:8902
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
#define WC_NO_BEST_FIT_CHARS
Definition: unicode.h:46
#define EOF
Definition: stdio.h:24
#define c
Definition: ke_i.h:80
#define debugstr_w
Definition: kernel32.h:32
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define wcscpy_s(d, l, s)
Definition: utility.h:201
#define wcsncpy_s(d, l, s, n)
Definition: utility.h:202
static PVOID ptr
Definition: dispmode.c:27
#define MSVCRT_INVALID_PMT(x)
Definition: mbstowcs_s.c:25
#define MSVCRT_CHECK_PMT(x)
Definition: mbstowcs_s.c:26
struct MSVCRT_localeinfo_struct * MSVCRT__locale_t
static const unsigned char *static size_t const wchar_t * wcSrc
Definition: string.c:66
static size_t elem
Definition: string.c:68
static DWORD LPDWORD LPCSTR DWORD srclen
Definition: directory.c:52
#define min(a, b)
Definition: monoChain.cc:55
#define toupperW(n)
Definition: unicode.h:45
#define isdigitW(n)
Definition: unicode.h:50
#define strcmpW(s1, s2)
Definition: unicode.h:38
#define strcmpiW(s1, s2)
Definition: unicode.h:39
#define strlenW(s)
Definition: unicode.h:28
#define isspaceW(n)
Definition: unicode.h:52
const WCHAR * str
else locinfo
Definition: scanf.h:159
#define STRUNCATE
Definition: errno.h:110
_CRTIMP int *__cdecl _errno(void)
Definition: errno.c:17
errno_t __cdecl _set_errno(_In_ int _Value)
#define EILSEQ
Definition: errno.h:109
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
#define TRACE(s)
Definition: solgame.cpp:4
#define wctomb(cp, wc)
Definition: wchar.h:161
int32_t INT
Definition: typedefs.h:58
wchar_t *CDECL _wcsset(wchar_t *str, wchar_t c)
Definition: wcs.c:104
static size_t CDECL wcsrtombs_l(char *mbstr, const wchar_t **wcstr, size_t count, _locale_t locale)
Definition: wcs.c:260
wchar_t *CDECL _wcsrev(wchar_t *str)
Definition: wcs.c:87
INT CDECL _wcsicoll(const wchar_t *str1, const wchar_t *str2)
Definition: wcs.c:67
int CDECL wcscoll(const wchar_t *str1, const wchar_t *str2)
Definition: wcs.c:216
wchar_t *CDECL _wcsnset(wchar_t *str, wchar_t c, size_t n)
Definition: wcs.c:77
INT CDECL wcsncat_s(wchar_t *dst, size_t elem, const wchar_t *src, size_t count)
Definition: wcs.c:432
wchar_t *CDECL wcspbrk(const wchar_t *str, const wchar_t *accept)
Definition: wcs.c:225
double CDECL wcstod(const wchar_t *lpszStr, wchar_t **end)
Definition: wcs.c:143
size_t CDECL wcstombs(char *mbstr, const wchar_t *wcstr, size_t count)
Definition: wcs.c:336
size_t CDECL _wcstombs_l(char *mbstr, const wchar_t *wcstr, size_t count, _locale_t locale)
Definition: wcs.c:328
INT CDECL _wcsupr_s(wchar_t *str, size_t n)
Definition: wcs.c:115
wchar_t *CDECL _wcsdup(const wchar_t *str)
Definition: wcs.c:53
INT CDECL wcscat_s(wchar_t *dst, size_t elem, const wchar_t *src)
Definition: wcs.c:406
int ret
#define get_locinfo()
Definition: winesup.h:25
__wchar_t WCHAR
Definition: xmlstorage.h:180