2 * msvcrt.dll wide-char functions
4 * Copyright 1999 Alexandre Julliard
5 * Copyright 2000 Jon Griffiths
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.
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.
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
26 #include "wine/unicode.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt
);
32 /* INTERNAL: MSVCRT_malloc() based wstrndup */
33 MSVCRT_wchar_t
* msvcrt_wstrndup(const MSVCRT_wchar_t
*buf
, unsigned int size
)
36 unsigned int len
= strlenW(buf
), max_len
;
38 max_len
= size
<= len
? size
: len
+ 1;
40 ret
= MSVCRT_malloc(max_len
* sizeof (MSVCRT_wchar_t
));
43 memcpy(ret
,buf
,max_len
* sizeof (MSVCRT_wchar_t
));
49 /*********************************************************************
52 MSVCRT_wchar_t
* _wcsdup( const MSVCRT_wchar_t
* str
)
54 MSVCRT_wchar_t
* ret
= NULL
;
57 int size
= (strlenW(str
) + 1) * sizeof(MSVCRT_wchar_t
);
58 ret
= MSVCRT_malloc( size
);
59 if (ret
) memcpy( ret
, str
, size
);
64 /*********************************************************************
65 * _wcsicoll (MSVCRT.@)
67 INT
_wcsicoll( const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
)
69 /* FIXME: handle collates */
70 return strcmpiW( str1
, str2
);
73 /*********************************************************************
76 MSVCRT_wchar_t
* _wcsnset( MSVCRT_wchar_t
* str
, MSVCRT_wchar_t c
, MSVCRT_size_t n
)
78 MSVCRT_wchar_t
* ret
= str
;
79 while ((n
-- > 0) && *str
) *str
++ = c
;
83 /*********************************************************************
86 MSVCRT_wchar_t
* _wcsrev( MSVCRT_wchar_t
* str
)
88 MSVCRT_wchar_t
* ret
= str
;
89 MSVCRT_wchar_t
* end
= str
+ strlenW(str
) - 1;
92 MSVCRT_wchar_t t
= *end
;
99 /*********************************************************************
102 MSVCRT_wchar_t
* _wcsset( MSVCRT_wchar_t
* str
, MSVCRT_wchar_t c
)
104 MSVCRT_wchar_t
* ret
= str
;
105 while (*str
) *str
++ = c
;
109 /*********************************************************************
112 double MSVCRT_wcstod(const MSVCRT_wchar_t
* lpszStr
, MSVCRT_wchar_t
** end
)
114 const MSVCRT_wchar_t
* str
= lpszStr
;
116 double ret
= 0, divisor
= 10.0;
118 TRACE("(%s,%p) semi-stub\n", debugstr_w(lpszStr
), end
);
121 * - Should set errno on failure
122 * - Should fail on overflow
123 * - Need to check which input formats are allowed
125 while (isspaceW(*str
))
134 while (isdigitW(*str
))
136 ret
= ret
* 10.0 + (*str
- '0');
141 while (isdigitW(*str
))
143 ret
= ret
+ (*str
- '0') / divisor
;
148 if (*str
== 'E' || *str
== 'e' || *str
== 'D' || *str
== 'd')
150 int negativeExponent
= 0;
154 negativeExponent
= 1;
157 while (isdigitW(*str
))
159 exponent
= exponent
* 10 + (*str
- '0');
164 if (negativeExponent
)
165 ret
= ret
/ pow(10.0, exponent
);
167 ret
= ret
* pow(10.0, exponent
);
175 *end
= (MSVCRT_wchar_t
*)str
;
177 TRACE("returning %g\n", ret
);
181 static int MSVCRT_vsnprintfW(WCHAR
*str
, size_t len
, const WCHAR
*format
, va_list valist
)
183 unsigned int written
= 0;
184 const WCHAR
*iter
= format
;
185 char bufa
[256], fmtbufa
[64], *fmta
;
189 while (*iter
&& *iter
!= '%')
191 if (written
++ >= len
)
199 if (written
++ >= len
)
201 *str
++ = '%'; /* "%%"->'%' */
208 while (*iter
== '0' ||
217 char *buffiter
= bufa
;
218 int fieldlen
= va_arg(valist
, int);
219 sprintf(buffiter
, "%d", fieldlen
);
221 *fmta
++ = *buffiter
++;
228 while (isdigit(*iter
))
236 char *buffiter
= bufa
;
237 int fieldlen
= va_arg(valist
, int);
238 sprintf(buffiter
, "%d", fieldlen
);
240 *fmta
++ = *buffiter
++;
243 while (isdigit(*iter
))
246 if (*iter
== 'h' || *iter
== 'l')
253 static const char *none
= "(null)";
254 const char *astr
= va_arg(valist
, const char *);
255 const char *striter
= astr
? astr
: none
;
262 if( IsDBCSLeadByte( *striter
) )
264 r
= MultiByteToWideChar( CP_ACP
, 0,
265 striter
, n
, str
, len
- written
);
276 static const WCHAR none
[] = { '(','n','u','l','l',')',0 };
277 const WCHAR
*wstr
= va_arg(valist
, const WCHAR
*);
278 const WCHAR
*striter
= wstr
? wstr
: none
;
281 if (written
++ >= len
)
290 if (written
++ >= len
)
292 *str
++ = (WCHAR
)va_arg(valist
, int);
298 /* For non wc types, use system sprintf and append to wide char output */
299 /* FIXME: for unrecognised types, should ignore % when printing */
300 char *bufaiter
= bufa
;
302 sprintf(bufaiter
, "%08lX", va_arg(valist
, long));
307 if (*iter
== 'a' || *iter
== 'A' ||
308 *iter
== 'e' || *iter
== 'E' ||
309 *iter
== 'f' || *iter
== 'F' ||
310 *iter
== 'g' || *iter
== 'G')
311 sprintf(bufaiter
, fmtbufa
, va_arg(valist
, double));
314 /* FIXME: On 32 bit systems this doesn't handle int 64's.
315 * on 64 bit systems this doesn't work for 32 bit types
317 sprintf(bufaiter
, fmtbufa
, va_arg(valist
, void *));
322 if (written
++ >= len
)
324 *str
++ = *bufaiter
++;
338 /*********************************************************************
339 * swprintf (MSVCRT.@)
341 int MSVCRT_swprintf( MSVCRT_wchar_t
*str
, const MSVCRT_wchar_t
*format
, ... )
346 va_start( ap
, format
);
347 r
= MSVCRT_vsnprintfW( str
, INT_MAX
, format
, ap
);
352 /*********************************************************************
353 * _vsnwprintf (MSVCRT.@)
355 int _vsnwprintf(MSVCRT_wchar_t
*str
, unsigned int len
,
356 const MSVCRT_wchar_t
*format
, va_list valist
)
358 return MSVCRT_vsnprintfW(str
, len
, format
, valist
);
361 /*********************************************************************
362 * vswprintf (MSVCRT.@)
364 int MSVCRT_vswprintf( MSVCRT_wchar_t
* str
, const MSVCRT_wchar_t
* format
, va_list args
)
366 return MSVCRT_vsnprintfW( str
, INT_MAX
, format
, args
);
369 /*********************************************************************
372 int MSVCRT_wcscoll( const MSVCRT_wchar_t
* str1
, const MSVCRT_wchar_t
* str2
)
374 /* FIXME: handle collates */
375 return strcmpW( str1
, str2
);
378 /*********************************************************************
381 MSVCRT_wchar_t
* MSVCRT_wcspbrk( const MSVCRT_wchar_t
* str
, const MSVCRT_wchar_t
* accept
)
383 const MSVCRT_wchar_t
* p
;
386 for (p
= accept
; *p
; p
++) if (*p
== *str
) return (MSVCRT_wchar_t
*)str
;
392 /*********************************************************************
395 INT
MSVCRT_wctomb( char *dst
, MSVCRT_wchar_t ch
)
397 return WideCharToMultiByte( CP_ACP
, 0, &ch
, 1, dst
, 6, NULL
, NULL
);
400 /*********************************************************************
401 * iswalnum (MSVCRT.@)
403 INT
MSVCRT_iswalnum( MSVCRT_wchar_t wc
)
405 return isalnumW( wc
);
408 /*********************************************************************
409 * iswalpha (MSVCRT.@)
411 INT
MSVCRT_iswalpha( MSVCRT_wchar_t wc
)
413 return isalphaW( wc
);
416 /*********************************************************************
417 * iswcntrl (MSVCRT.@)
419 INT
MSVCRT_iswcntrl( MSVCRT_wchar_t wc
)
421 return iscntrlW( wc
);
424 /*********************************************************************
425 * iswdigit (MSVCRT.@)
427 INT
MSVCRT_iswdigit( MSVCRT_wchar_t wc
)
429 return isdigitW( wc
);
432 /*********************************************************************
433 * iswgraph (MSVCRT.@)
435 INT
MSVCRT_iswgraph( MSVCRT_wchar_t wc
)
437 return isgraphW( wc
);
440 /*********************************************************************
441 * iswlower (MSVCRT.@)
443 INT
MSVCRT_iswlower( MSVCRT_wchar_t wc
)
445 return islowerW( wc
);
448 /*********************************************************************
449 * iswprint (MSVCRT.@)
451 INT
MSVCRT_iswprint( MSVCRT_wchar_t wc
)
453 return isprintW( wc
);
456 /*********************************************************************
457 * iswpunct (MSVCRT.@)
459 INT
MSVCRT_iswpunct( MSVCRT_wchar_t wc
)
461 return ispunctW( wc
);
464 /*********************************************************************
465 * iswspace (MSVCRT.@)
467 INT
MSVCRT_iswspace( MSVCRT_wchar_t wc
)
469 return isspaceW( wc
);
472 /*********************************************************************
473 * iswupper (MSVCRT.@)
475 INT
MSVCRT_iswupper( MSVCRT_wchar_t wc
)
477 return isupperW( wc
);
480 /*********************************************************************
481 * iswxdigit (MSVCRT.@)
483 INT
MSVCRT_iswxdigit( MSVCRT_wchar_t wc
)
485 return isxdigitW( wc
);