Changes in crossover-wine-src-6.1.0 except for configure
[wine/hacks.git] / dlls / user32 / lstr.c
blobdacca84dfed52e970eaf43c356e8383d507457b0
1 /*
2 * USER string functions
4 * Copyright 1993 Yngvi Sigurjonsson (yngvi@hafro.is)
5 * Copyright 1996 Alexandre Julliard
6 * Copyright 1996 Marcus Meissner
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "config.h"
24 #include "wine/port.h"
26 #include <ctype.h>
27 #include <stdarg.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
32 #include "windef.h"
33 #include "winbase.h"
34 #include "winuser.h"
35 #include "winerror.h"
37 #include "wine/exception.h"
38 #include "wine/unicode.h"
39 #include "excpt.h"
42 /***********************************************************************
43 * CharNextA (USER32.@)
45 LPSTR WINAPI CharNextA( LPCSTR ptr )
47 if (!*ptr) return (LPSTR)ptr;
48 if (IsDBCSLeadByte( ptr[0] ) && ptr[1]) return (LPSTR)(ptr + 2);
49 return (LPSTR)(ptr + 1);
53 /***********************************************************************
54 * CharNextExA (USER32.@)
56 LPSTR WINAPI CharNextExA( WORD codepage, LPCSTR ptr, DWORD flags )
58 if (!*ptr) return (LPSTR)ptr;
59 if (IsDBCSLeadByteEx( codepage, ptr[0] ) && ptr[1]) return (LPSTR)(ptr + 2);
60 return (LPSTR)(ptr + 1);
64 /***********************************************************************
65 * CharNextExW (USER32.@)
67 LPWSTR WINAPI CharNextExW( WORD codepage, LPCWSTR ptr, DWORD flags )
69 /* doesn't make sense, there are no codepages for Unicode */
70 return NULL;
74 /***********************************************************************
75 * CharNextW (USER32.@)
77 LPWSTR WINAPI CharNextW(LPCWSTR x)
79 if (*x) x++;
81 return (LPWSTR)x;
85 /***********************************************************************
86 * CharPrevA (USER32.@)
88 LPSTR WINAPI CharPrevA( LPCSTR start, LPCSTR ptr )
90 while (*start && (start < ptr))
92 LPCSTR next = CharNextA( start );
93 if (next >= ptr) break;
94 start = next;
96 return (LPSTR)start;
100 /***********************************************************************
101 * CharPrevExA (USER32.@)
103 LPSTR WINAPI CharPrevExA( WORD codepage, LPCSTR start, LPCSTR ptr, DWORD flags )
105 while (*start && (start < ptr))
107 LPCSTR next = CharNextExA( codepage, start, flags );
108 if (next >= ptr) break;
109 start = next;
111 return (LPSTR)start;
115 /***********************************************************************
116 * CharPrevExW (USER32.@)
118 LPSTR WINAPI CharPrevExW( WORD codepage, LPCWSTR start, LPCWSTR ptr, DWORD flags )
120 /* doesn't make sense, there are no codepages for Unicode */
121 return NULL;
125 /***********************************************************************
126 * CharPrevW (USER32.@)
128 LPWSTR WINAPI CharPrevW(LPCWSTR start,LPCWSTR x)
130 if (x>start) return (LPWSTR)(x-1);
131 else return (LPWSTR)x;
135 /***********************************************************************
136 * CharToOemA (USER32.@)
138 BOOL WINAPI CharToOemA( LPCSTR s, LPSTR d )
140 if ( !s || !d ) return TRUE;
141 return CharToOemBuffA( s, d, strlen( s ) + 1 );
145 /***********************************************************************
146 * CharToOemBuffA (USER32.@)
148 BOOL WINAPI CharToOemBuffA( LPCSTR s, LPSTR d, DWORD len )
150 WCHAR *bufW;
152 bufW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
153 if( bufW )
155 MultiByteToWideChar( CP_ACP, 0, s, len, bufW, len );
156 WideCharToMultiByte( CP_OEMCP, 0, bufW, len, d, len, NULL, NULL );
157 HeapFree( GetProcessHeap(), 0, bufW );
159 return TRUE;
163 /***********************************************************************
164 * CharToOemBuffW (USER32.@)
166 BOOL WINAPI CharToOemBuffW( LPCWSTR s, LPSTR d, DWORD len )
168 if ( !s || !d ) return TRUE;
169 WideCharToMultiByte( CP_OEMCP, 0, s, len, d, len, NULL, NULL );
170 return TRUE;
174 /***********************************************************************
175 * CharToOemW (USER32.@)
177 BOOL WINAPI CharToOemW( LPCWSTR s, LPSTR d )
179 return CharToOemBuffW( s, d, strlenW( s ) + 1 );
183 /***********************************************************************
184 * OemToCharA (USER32.@)
186 BOOL WINAPI OemToCharA( LPCSTR s, LPSTR d )
188 return OemToCharBuffA( s, d, strlen( s ) + 1 );
192 /***********************************************************************
193 * OemToCharBuffA (USER32.@)
195 BOOL WINAPI OemToCharBuffA( LPCSTR s, LPSTR d, DWORD len )
197 WCHAR *bufW;
199 bufW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
200 if( bufW )
202 MultiByteToWideChar( CP_OEMCP, 0, s, len, bufW, len );
203 WideCharToMultiByte( CP_ACP, 0, bufW, len, d, len, NULL, NULL );
204 HeapFree( GetProcessHeap(), 0, bufW );
206 return TRUE;
210 /***********************************************************************
211 * OemToCharBuffW (USER32.@)
213 BOOL WINAPI OemToCharBuffW( LPCSTR s, LPWSTR d, DWORD len )
215 MultiByteToWideChar( CP_OEMCP, 0, s, len, d, len );
216 return TRUE;
220 /***********************************************************************
221 * OemToCharW (USER32.@)
223 BOOL WINAPI OemToCharW( LPCSTR s, LPWSTR d )
225 return OemToCharBuffW( s, d, strlen( s ) + 1 );
229 /***********************************************************************
230 * CharLowerA (USER32.@)
232 LPSTR WINAPI CharLowerA(LPSTR str)
234 if (!HIWORD(str))
236 char ch = LOWORD(str);
237 CharLowerBuffA( &ch, 1 );
238 return (LPSTR)(UINT_PTR)(BYTE)ch;
241 __TRY
243 CharLowerBuffA( str, strlen(str) );
245 __EXCEPT_PAGE_FAULT
247 SetLastError( ERROR_INVALID_PARAMETER );
248 return NULL;
250 __ENDTRY
251 return str;
255 /***********************************************************************
256 * CharUpperA (USER32.@)
258 LPSTR WINAPI CharUpperA(LPSTR str)
260 if (!HIWORD(str))
262 char ch = LOWORD(str);
263 CharUpperBuffA( &ch, 1 );
264 return (LPSTR)(UINT_PTR)(BYTE)ch;
267 __TRY
269 CharUpperBuffA( str, strlen(str) );
271 __EXCEPT_PAGE_FAULT
273 SetLastError( ERROR_INVALID_PARAMETER );
274 return NULL;
276 __ENDTRY
277 return str;
281 /***********************************************************************
282 * CharLowerW (USER32.@)
284 LPWSTR WINAPI CharLowerW(LPWSTR x)
286 if (HIWORD(x)) return strlwrW(x);
287 else return (LPWSTR)((UINT_PTR)tolowerW(LOWORD(x)));
291 /***********************************************************************
292 * CharUpperW (USER32.@)
294 LPWSTR WINAPI CharUpperW(LPWSTR x)
296 if (HIWORD(x)) return struprW(x);
297 else return (LPWSTR)((UINT_PTR)toupperW(LOWORD(x)));
301 /***********************************************************************
302 * CharLowerBuffA (USER32.@)
304 DWORD WINAPI CharLowerBuffA( LPSTR str, DWORD len )
306 DWORD lenW;
307 WCHAR buffer[32];
308 WCHAR *strW = buffer;
310 if (!str) return 0; /* YES */
312 lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
313 if (lenW > sizeof(buffer)/sizeof(WCHAR))
315 strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
316 if (!strW) return 0;
318 MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW);
319 CharLowerBuffW(strW, lenW);
320 len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL);
321 if (strW != buffer) HeapFree(GetProcessHeap(), 0, strW);
322 return len;
326 /***********************************************************************
327 * CharLowerBuffW (USER32.@)
329 DWORD WINAPI CharLowerBuffW( LPWSTR str, DWORD len )
331 DWORD ret = len;
332 if (!str) return 0; /* YES */
333 for (; len; len--, str++) *str = tolowerW(*str);
334 return ret;
338 /***********************************************************************
339 * CharUpperBuffA (USER32.@)
341 DWORD WINAPI CharUpperBuffA( LPSTR str, DWORD len )
343 DWORD lenW;
344 WCHAR buffer[32];
345 WCHAR *strW = buffer;
347 if (!str) return 0; /* YES */
349 lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
350 if (lenW > sizeof(buffer)/sizeof(WCHAR))
352 strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
353 if (!strW) return 0;
355 MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW);
356 CharUpperBuffW(strW, lenW);
357 len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL);
358 if (strW != buffer) HeapFree(GetProcessHeap(), 0, strW);
359 return len;
363 /***********************************************************************
364 * CharUpperBuffW (USER32.@)
366 DWORD WINAPI CharUpperBuffW( LPWSTR str, DWORD len )
368 DWORD ret = len;
369 if (!str) return 0; /* YES */
370 for (; len; len--, str++) *str = toupperW(*str);
371 return ret;
375 /***********************************************************************
376 * IsCharLower (USER.436)
377 * IsCharLowerA (USER32.@)
379 BOOL WINAPI IsCharLowerA(CHAR x)
381 WCHAR wch;
382 MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
383 return IsCharLowerW(wch);
387 /***********************************************************************
388 * IsCharLowerW (USER32.@)
390 BOOL WINAPI IsCharLowerW(WCHAR x)
392 return (get_char_typeW(x) & C1_LOWER) != 0;
396 /***********************************************************************
397 * IsCharUpper (USER.435)
398 * IsCharUpperA (USER32.@)
400 BOOL WINAPI IsCharUpperA(CHAR x)
402 WCHAR wch;
403 MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
404 return IsCharUpperW(wch);
408 /***********************************************************************
409 * IsCharUpperW (USER32.@)
411 BOOL WINAPI IsCharUpperW(WCHAR x)
413 return (get_char_typeW(x) & C1_UPPER) != 0;
417 /***********************************************************************
418 * IsCharAlphaNumeric (USER.434)
419 * IsCharAlphaNumericA (USER32.@)
421 BOOL WINAPI IsCharAlphaNumericA(CHAR x)
423 WCHAR wch;
424 MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
425 return IsCharAlphaNumericW(wch);
429 /***********************************************************************
430 * IsCharAlphaNumericW (USER32.@)
432 BOOL WINAPI IsCharAlphaNumericW(WCHAR x)
434 return (get_char_typeW(x) & (C1_ALPHA|C1_DIGIT)) != 0;
438 /***********************************************************************
439 * IsCharAlpha (USER.433)
440 * IsCharAlphaA (USER32.@)
442 BOOL WINAPI IsCharAlphaA(CHAR x)
444 WCHAR wch;
445 MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
446 return IsCharAlphaW(wch);
450 /***********************************************************************
451 * IsCharAlphaW (USER32.@)
453 BOOL WINAPI IsCharAlphaW(WCHAR x)
455 return (get_char_typeW(x) & C1_ALPHA) != 0;