reg: Use is_switch() where possible.
[wine.git] / include / wine / unicode.h
blobd29a371fe53c125bd965182af96c189596a02741
1 /*
2 * Wine internal Unicode definitions
4 * Copyright 2000 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #ifndef __WINE_WINE_UNICODE_H
22 #define __WINE_WINE_UNICODE_H
24 #include <stdarg.h>
26 #include <windef.h>
27 #include <winbase.h>
28 #include <winnls.h>
29 #include <winternl.h>
31 #ifdef __WINE_USE_MSVCRT
32 #error This file should not be used with msvcrt headers
33 #endif
35 #ifndef WINE_UNICODE_INLINE
36 #define WINE_UNICODE_INLINE static FORCEINLINE
37 #endif
39 WINE_UNICODE_INLINE WCHAR tolowerW( WCHAR ch )
41 return RtlDowncaseUnicodeChar( ch );
44 WINE_UNICODE_INLINE WCHAR toupperW( WCHAR ch )
46 return RtlUpcaseUnicodeChar( ch );
49 WINE_UNICODE_INLINE int isspaceW( WCHAR wc )
51 unsigned short type;
52 GetStringTypeW( CT_CTYPE1, &wc, 1, &type );
53 return type & C1_SPACE;
56 WINE_UNICODE_INLINE unsigned int strlenW( const WCHAR *str )
58 const WCHAR *s = str;
59 while (*s) s++;
60 return s - str;
63 WINE_UNICODE_INLINE WCHAR *strcpyW( WCHAR *dst, const WCHAR *src )
65 WCHAR *p = dst;
66 while ((*p++ = *src++));
67 return dst;
70 WINE_UNICODE_INLINE int strcmpW( const WCHAR *str1, const WCHAR *str2 )
72 while (*str1 && (*str1 == *str2)) { str1++; str2++; }
73 return *str1 - *str2;
76 WINE_UNICODE_INLINE int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
78 if (n <= 0) return 0;
79 while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
80 return *str1 - *str2;
83 WINE_UNICODE_INLINE WCHAR *strcatW( WCHAR *dst, const WCHAR *src )
85 strcpyW( dst + strlenW(dst), src );
86 return dst;
89 WINE_UNICODE_INLINE WCHAR *strchrW( const WCHAR *str, WCHAR ch )
91 do { if (*str == ch) return (WCHAR *)(ULONG_PTR)str; } while (*str++);
92 return NULL;
95 WINE_UNICODE_INLINE WCHAR *strrchrW( const WCHAR *str, WCHAR ch )
97 WCHAR *ret = NULL;
98 do { if (*str == ch) ret = (WCHAR *)(ULONG_PTR)str; } while (*str++);
99 return ret;
102 WINE_UNICODE_INLINE WCHAR *strpbrkW( const WCHAR *str, const WCHAR *accept )
104 for ( ; *str; str++) if (strchrW( accept, *str )) return (WCHAR *)(ULONG_PTR)str;
105 return NULL;
108 WINE_UNICODE_INLINE WCHAR *strlwrW( WCHAR *str )
110 WCHAR *ret;
111 for (ret = str; *str; str++) *str = tolowerW(*str);
112 return ret;
115 WINE_UNICODE_INLINE WCHAR *memchrW( const WCHAR *ptr, WCHAR ch, size_t n )
117 const WCHAR *end;
118 for (end = ptr + n; ptr < end; ptr++) if (*ptr == ch) return (WCHAR *)(ULONG_PTR)ptr;
119 return NULL;
122 WINE_UNICODE_INLINE int strcmpiW( const WCHAR *str1, const WCHAR *str2 )
124 for (;;)
126 int ret = tolowerW(*str1) - tolowerW(*str2);
127 if (ret || !*str1) return ret;
128 str1++;
129 str2++;
133 WINE_UNICODE_INLINE int strncmpiW( const WCHAR *str1, const WCHAR *str2, int n )
135 int ret = 0;
136 for ( ; n > 0; n--, str1++, str2++)
137 if ((ret = tolowerW(*str1) - tolowerW(*str2)) || !*str1) break;
138 return ret;
141 WINE_UNICODE_INLINE WCHAR *strstrW( const WCHAR *str, const WCHAR *sub )
143 while (*str)
145 const WCHAR *p1 = str, *p2 = sub;
146 while (*p1 && *p2 && *p1 == *p2) { p1++; p2++; }
147 if (!*p2) return (WCHAR *)str;
148 str++;
150 return NULL;
153 WINE_UNICODE_INLINE LONG strtolW( LPCWSTR s, LPWSTR *end, INT base )
155 BOOL negative = FALSE, empty = TRUE;
156 LONG ret = 0;
158 if (base < 0 || base == 1 || base > 36) return 0;
159 if (end) *end = (WCHAR *)s;
160 while (isspaceW(*s)) s++;
162 if (*s == '-')
164 negative = TRUE;
165 s++;
167 else if (*s == '+') s++;
169 if ((base == 0 || base == 16) && s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
171 base = 16;
172 s += 2;
174 if (base == 0) base = s[0] != '0' ? 10 : 8;
176 while (*s)
178 int v;
180 if ('0' <= *s && *s <= '9') v = *s - '0';
181 else if ('A' <= *s && *s <= 'Z') v = *s - 'A' + 10;
182 else if ('a' <= *s && *s <= 'z') v = *s - 'a' + 10;
183 else break;
184 if (v >= base) break;
185 if (negative) v = -v;
186 s++;
187 empty = FALSE;
189 if (!negative && (ret > MAXLONG / base || ret * base > MAXLONG - v))
190 ret = MAXLONG;
191 else if (negative && (ret < (LONG)MINLONG / base || ret * base < (LONG)(MINLONG - v)))
192 ret = MINLONG;
193 else
194 ret = ret * base + v;
197 if (end && !empty) *end = (WCHAR *)s;
198 return ret;
201 WINE_UNICODE_INLINE ULONG strtoulW( LPCWSTR s, LPWSTR *end, INT base )
203 BOOL negative = FALSE, empty = TRUE;
204 ULONG ret = 0;
206 if (base < 0 || base == 1 || base > 36) return 0;
207 if (end) *end = (WCHAR *)s;
208 while (isspaceW(*s)) s++;
210 if (*s == '-')
212 negative = TRUE;
213 s++;
215 else if (*s == '+') s++;
217 if ((base == 0 || base == 16) && s[0] == '0' && (s[1] == 'x' || s[1] == 'X'))
219 base = 16;
220 s += 2;
222 if (base == 0) base = s[0] != '0' ? 10 : 8;
224 while (*s)
226 int v;
228 if ('0' <= *s && *s <= '9') v = *s - '0';
229 else if ('A' <= *s && *s <= 'Z') v = *s - 'A' + 10;
230 else if ('a' <= *s && *s <= 'z') v = *s - 'a' + 10;
231 else break;
232 if (v >= base) break;
233 s++;
234 empty = FALSE;
236 if (ret > MAXDWORD / base || ret * base > MAXDWORD - v)
237 ret = MAXDWORD;
238 else
239 ret = ret * base + v;
242 if (end && !empty) *end = (WCHAR *)s;
243 return negative ? -ret : ret;
246 WINE_UNICODE_INLINE int atoiW( const WCHAR *str )
248 return (int)strtolW( str, (WCHAR **)0, 10 );
251 NTSYSAPI int __cdecl _vsnwprintf(WCHAR*,size_t,const WCHAR*,__ms_va_list);
253 static inline int WINAPIV snprintfW( WCHAR *str, size_t len, const WCHAR *format, ...)
255 int retval;
256 __ms_va_list valist;
257 __ms_va_start(valist, format);
258 retval = _vsnwprintf(str, len, format, valist);
259 __ms_va_end(valist);
260 return retval;
263 static inline int WINAPIV sprintfW( WCHAR *str, const WCHAR *format, ...)
265 int retval;
266 __ms_va_list valist;
267 __ms_va_start(valist, format);
268 retval = _vsnwprintf(str, MAXLONG, format, valist);
269 __ms_va_end(valist);
270 return retval;
273 #undef WINE_UNICODE_INLINE
275 #endif /* __WINE_WINE_UNICODE_H */