Adjust the 'MSVCRT_' prefix to match the msvcrt headers
[wine.git] / dlls / msvcrt / wcs.c
blob4ba83cc4d00f730001f06911412a298a07bfe156
1 /*
2 * msvcrt.dll wide-char functions
4 * Copyright 1999 Alexandre Julliard
5 * Copyright 2000 Jon Griffiths
6 */
7 #include <limits.h>
8 #include <stdio.h>
9 #include "msvcrt.h"
10 #include "winnls.h"
11 #include "wine/unicode.h"
13 DEFAULT_DEBUG_CHANNEL(msvcrt);
16 /* INTERNAL: MSVCRT_malloc() based wstrndup */
17 LPWSTR msvcrt_wstrndup(LPCWSTR buf, unsigned int size)
19 WCHAR* ret;
20 unsigned int len = strlenW(buf), max_len;
22 max_len = size <= len? size : len + 1;
24 ret = MSVCRT_malloc(max_len * sizeof (WCHAR));
25 if (ret)
27 memcpy(ret,buf,max_len * sizeof (WCHAR));
28 ret[max_len] = 0;
30 return ret;
33 /*********************************************************************
34 * _wcsdup (MSVCRT.@)
36 LPWSTR _wcsdup( LPCWSTR str )
38 LPWSTR ret = NULL;
39 if (str)
41 int size = (strlenW(str) + 1) * sizeof(WCHAR);
42 ret = MSVCRT_malloc( size );
43 if (ret) memcpy( ret, str, size );
45 return ret;
48 /*********************************************************************
49 * _wcsicoll (MSVCRT.@)
51 INT _wcsicoll( LPCWSTR str1, LPCWSTR str2 )
53 /* FIXME: handle collates */
54 return strcmpiW( str1, str2 );
57 /*********************************************************************
58 * _wcsnset (MSVCRT.@)
60 LPWSTR _wcsnset( LPWSTR str, WCHAR c, INT n )
62 LPWSTR ret = str;
63 while ((n-- > 0) && *str) *str++ = c;
64 return ret;
67 /*********************************************************************
68 * _wcsrev (MSVCRT.@)
70 LPWSTR _wcsrev( LPWSTR str )
72 LPWSTR ret = str;
73 LPWSTR end = str + strlenW(str) - 1;
74 while (end > str)
76 WCHAR t = *end;
77 *end-- = *str;
78 *str++ = t;
80 return ret;
83 /*********************************************************************
84 * _wcsset (MSVCRT.@)
86 LPWSTR _wcsset( LPWSTR str, WCHAR c )
88 LPWSTR ret = str;
89 while (*str) *str++ = c;
90 return ret;
93 /*********************************************************************
94 * _vsnwprintf (MSVCRT.@)
96 int _vsnwprintf(WCHAR *str, unsigned int len,
97 const WCHAR *format, va_list valist)
99 /* If you fix a bug in this function, fix it in ntdll/wcstring.c also! */
100 unsigned int written = 0;
101 const WCHAR *iter = format;
102 char bufa[256], fmtbufa[64], *fmta;
104 TRACE("(%d,%s)\n",len,debugstr_w(format));
106 while (*iter)
108 while (*iter && *iter != (WCHAR)L'%')
110 if (written++ >= len)
111 return -1;
112 *str++ = *iter++;
114 if (*iter == (WCHAR)L'%')
116 fmta = fmtbufa;
117 *fmta++ = *iter++;
118 while (*iter == (WCHAR)L'0' ||
119 *iter == (WCHAR)L'+' ||
120 *iter == (WCHAR)L'-' ||
121 *iter == (WCHAR)L' ' ||
122 *iter == (WCHAR)L'0' ||
123 *iter == (WCHAR)L'*' ||
124 *iter == (WCHAR)L'#')
126 if (*iter == (WCHAR)L'*')
128 char *buffiter = bufa;
129 int fieldlen = va_arg(valist, int);
130 sprintf(buffiter, "%d", fieldlen);
131 while (*buffiter)
132 *fmta++ = *buffiter++;
134 else
135 *fmta++ = *iter;
136 iter++;
139 while (isdigit(*iter))
140 *fmta++ = *iter++;
142 if (*iter == (WCHAR)L'.')
144 *fmta++ = *iter++;
145 if (*iter == (WCHAR)L'*')
147 char *buffiter = bufa;
148 int fieldlen = va_arg(valist, int);
149 sprintf(buffiter, "%d", fieldlen);
150 while (*buffiter)
151 *fmta++ = *buffiter++;
153 else
154 while (isdigit(*iter))
155 *fmta++ = *iter++;
157 if (*iter == (WCHAR)L'h' ||
158 *iter == (WCHAR)L'l')
160 *fmta++ = *iter++;
161 *fmta++ = *iter++;
164 switch (*iter)
166 case (WCHAR)L's':
168 static const WCHAR none[] = { '(', 'n', 'u', 'l', 'l', ')', 0 };
169 const WCHAR *wstr = va_arg(valist, const WCHAR *);
170 const WCHAR *striter = wstr ? wstr : none;
171 while (*striter)
173 if (written++ >= len)
174 return -1;
175 *str++ = *striter++;
177 iter++;
178 break;
181 case (WCHAR)L'c':
182 if (written++ >= len)
183 return -1;
184 *str++ = (WCHAR)va_arg(valist, int);
185 iter++;
186 break;
188 default:
190 /* For non wc types, use system sprintf and append to wide char output */
191 /* FIXME: for unrecognised types, should ignore % when printing */
192 char *bufaiter = bufa;
193 if (*iter == (WCHAR)L'p')
194 sprintf(bufaiter, "%08lX", va_arg(valist, long));
195 else
197 *fmta++ = *iter;
198 *fmta = '\0';
199 sprintf(bufaiter, fmtbufa, va_arg(valist, void *));
201 while (*bufaiter)
203 if (written++ >= len)
204 return -1;
205 *str++ = *bufaiter++;
207 iter++;
208 break;
213 if (written >= len)
214 return -1;
215 *str++ = (WCHAR)L'\0';
216 return (int)written;
219 /*********************************************************************
220 * vswprintf (MSVCRT.@)
222 int MSVCRT_vswprintf( LPWSTR str, LPCWSTR format, va_list args )
224 return _vsnwprintf( str, INT_MAX, format, args );
227 /*********************************************************************
228 * wcscoll (MSVCRT.@)
230 DWORD MSVCRT_wcscoll( LPCWSTR str1, LPCWSTR str2 )
232 /* FIXME: handle collates */
233 return strcmpW( str1, str2 );
236 /*********************************************************************
237 * wcspbrk (MSVCRT.@)
239 LPWSTR MSVCRT_wcspbrk( LPCWSTR str, LPCWSTR accept )
241 LPCWSTR p;
242 while (*str)
244 for (p = accept; *p; p++) if (*p == *str) return (LPWSTR)str;
245 str++;
247 return NULL;
250 /*********************************************************************
251 * wctomb (MSVCRT.@)
253 INT MSVCRT_wctomb( char *dst, WCHAR ch )
255 return WideCharToMultiByte( CP_ACP, 0, &ch, 1, dst, 6, NULL, NULL );
258 /*********************************************************************
259 * iswalnum (MSVCRT.@)
261 INT MSVCRT_iswalnum( WCHAR wc )
263 return get_char_typeW(wc) & (C1_ALPHA|C1_DIGIT|C1_LOWER|C1_UPPER);
266 /*********************************************************************
267 * iswalpha (MSVCRT.@)
269 INT MSVCRT_iswalpha( WCHAR wc )
271 return get_char_typeW(wc) & (C1_ALPHA|C1_LOWER|C1_UPPER);
274 /*********************************************************************
275 * iswcntrl (MSVCRT.@)
277 INT MSVCRT_iswcntrl( WCHAR wc )
279 return get_char_typeW(wc) & C1_CNTRL;
282 /*********************************************************************
283 * iswdigit (MSVCRT.@)
285 INT MSVCRT_iswdigit( WCHAR wc )
287 return get_char_typeW(wc) & C1_DIGIT;
290 /*********************************************************************
291 * iswgraph (MSVCRT.@)
293 INT MSVCRT_iswgraph( WCHAR wc )
295 return get_char_typeW(wc) & (C1_ALPHA|C1_PUNCT|C1_DIGIT|C1_LOWER|C1_UPPER);
298 /*********************************************************************
299 * iswlower (MSVCRT.@)
301 INT MSVCRT_iswlower( WCHAR wc )
303 return get_char_typeW(wc) & C1_LOWER;
306 /*********************************************************************
307 * iswprint (MSVCRT.@)
309 INT MSVCRT_iswprint( WCHAR wc )
311 return get_char_typeW(wc) & (C1_ALPHA|C1_BLANK|C1_PUNCT|C1_DIGIT|C1_LOWER|C1_UPPER);
314 /*********************************************************************
315 * iswpunct (MSVCRT.@)
317 INT MSVCRT_iswpunct( WCHAR wc )
319 return get_char_typeW(wc) & C1_PUNCT;
322 /*********************************************************************
323 * iswspace (MSVCRT.@)
325 INT MSVCRT_iswspace( WCHAR wc )
327 return get_char_typeW(wc) & C1_SPACE;
330 /*********************************************************************
331 * iswupper (MSVCRT.@)
333 INT MSVCRT_iswupper( WCHAR wc )
335 return get_char_typeW(wc) & C1_UPPER;
338 /*********************************************************************
339 * iswxdigit (MSVCRT.@)
341 INT MSVCRT_iswxdigit( WCHAR wc )
343 return get_char_typeW(wc) & C1_XDIGIT;
346 extern char *_itoa( long , char *, int);
347 extern char *_ultoa( long , char *, int);
348 extern char *_ltoa( long , char *, int);
350 /*********************************************************************
351 * _itow (MSVCRT.@)
353 WCHAR* _itow(int value,WCHAR* out,int base)
355 char buf[64];
356 _itoa(value, buf, base);
357 MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, buf, -1, out, 128);
358 return out;
361 /*********************************************************************
362 * _ltow (MSVCRT.@)
364 WCHAR* _ltow(long value,WCHAR* out,int base)
366 char buf[128];
367 _ltoa(value, buf, base);
368 MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, buf, -1, out, 128);
369 return out;
372 /*********************************************************************
373 * _ultow (MSVCRT.@)
375 WCHAR* _ultow(unsigned long value,WCHAR* out,int base)
377 char buf[128];
378 _ultoa(value, buf, base);
379 MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, buf, -1, out, 128);
380 return out;