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
31 #ifdef __WINE_USE_MSVCRT
32 #error This file should not be used with msvcrt headers
35 #ifndef WINE_UNICODE_INLINE
36 #define WINE_UNICODE_INLINE static FORCEINLINE
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
)
52 GetStringTypeW( CT_CTYPE1
, &wc
, 1, &type
);
53 return type
& C1_SPACE
;
56 WINE_UNICODE_INLINE
unsigned int strlenW( const WCHAR
*str
)
63 WINE_UNICODE_INLINE WCHAR
*strcpyW( WCHAR
*dst
, const WCHAR
*src
)
66 while ((*p
++ = *src
++));
70 WINE_UNICODE_INLINE
int strcmpW( const WCHAR
*str1
, const WCHAR
*str2
)
72 while (*str1
&& (*str1
== *str2
)) { str1
++; str2
++; }
76 WINE_UNICODE_INLINE
int strncmpW( const WCHAR
*str1
, const WCHAR
*str2
, int n
)
79 while ((--n
> 0) && *str1
&& (*str1
== *str2
)) { str1
++; str2
++; }
83 WINE_UNICODE_INLINE WCHAR
*strcatW( WCHAR
*dst
, const WCHAR
*src
)
85 strcpyW( dst
+ strlenW(dst
), src
);
89 WINE_UNICODE_INLINE WCHAR
*strchrW( const WCHAR
*str
, WCHAR ch
)
91 do { if (*str
== ch
) return (WCHAR
*)(ULONG_PTR
)str
; } while (*str
++);
95 WINE_UNICODE_INLINE WCHAR
*strrchrW( const WCHAR
*str
, WCHAR ch
)
98 do { if (*str
== ch
) ret
= (WCHAR
*)(ULONG_PTR
)str
; } while (*str
++);
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
;
108 WINE_UNICODE_INLINE WCHAR
*strlwrW( WCHAR
*str
)
111 for (ret
= str
; *str
; str
++) *str
= tolowerW(*str
);
115 WINE_UNICODE_INLINE WCHAR
*memchrW( const WCHAR
*ptr
, WCHAR ch
, size_t n
)
118 for (end
= ptr
+ n
; ptr
< end
; ptr
++) if (*ptr
== ch
) return (WCHAR
*)(ULONG_PTR
)ptr
;
122 WINE_UNICODE_INLINE
int strcmpiW( const WCHAR
*str1
, const WCHAR
*str2
)
126 int ret
= tolowerW(*str1
) - tolowerW(*str2
);
127 if (ret
|| !*str1
) return ret
;
133 WINE_UNICODE_INLINE
int strncmpiW( const WCHAR
*str1
, const WCHAR
*str2
, int n
)
136 for ( ; n
> 0; n
--, str1
++, str2
++)
137 if ((ret
= tolowerW(*str1
) - tolowerW(*str2
)) || !*str1
) break;
141 WINE_UNICODE_INLINE WCHAR
*strstrW( const WCHAR
*str
, const WCHAR
*sub
)
145 const WCHAR
*p1
= str
, *p2
= sub
;
146 while (*p1
&& *p2
&& *p1
== *p2
) { p1
++; p2
++; }
147 if (!*p2
) return (WCHAR
*)str
;
153 WINE_UNICODE_INLINE LONG
strtolW( LPCWSTR s
, LPWSTR
*end
, INT base
)
155 BOOL negative
= FALSE
, empty
= TRUE
;
158 if (base
< 0 || base
== 1 || base
> 36) return 0;
159 if (end
) *end
= (WCHAR
*)s
;
160 while (isspaceW(*s
)) s
++;
167 else if (*s
== '+') s
++;
169 if ((base
== 0 || base
== 16) && s
[0] == '0' && (s
[1] == 'x' || s
[1] == 'X'))
174 if (base
== 0) base
= s
[0] != '0' ? 10 : 8;
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;
184 if (v
>= base
) break;
185 if (negative
) v
= -v
;
189 if (!negative
&& (ret
> MAXLONG
/ base
|| ret
* base
> MAXLONG
- v
))
191 else if (negative
&& (ret
< (LONG
)MINLONG
/ base
|| ret
* base
< (LONG
)(MINLONG
- v
)))
194 ret
= ret
* base
+ v
;
197 if (end
&& !empty
) *end
= (WCHAR
*)s
;
201 WINE_UNICODE_INLINE ULONG
strtoulW( LPCWSTR s
, LPWSTR
*end
, INT base
)
203 BOOL negative
= FALSE
, empty
= TRUE
;
206 if (base
< 0 || base
== 1 || base
> 36) return 0;
207 if (end
) *end
= (WCHAR
*)s
;
208 while (isspaceW(*s
)) s
++;
215 else if (*s
== '+') s
++;
217 if ((base
== 0 || base
== 16) && s
[0] == '0' && (s
[1] == 'x' || s
[1] == 'X'))
222 if (base
== 0) base
= s
[0] != '0' ? 10 : 8;
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;
232 if (v
>= base
) break;
236 if (ret
> MAXDWORD
/ base
|| ret
* base
> MAXDWORD
- v
)
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
, ...)
257 __ms_va_start(valist
, format
);
258 retval
= _vsnwprintf(str
, len
, format
, valist
);
263 static inline int WINAPIV
sprintfW( WCHAR
*str
, const WCHAR
*format
, ...)
267 __ms_va_start(valist
, format
);
268 retval
= _vsnwprintf(str
, MAXLONG
, format
, valist
);
273 #undef WINE_UNICODE_INLINE
275 #endif /* __WINE_WINE_UNICODE_H */