comctl32/tests: Remove some workarounds that no longer apply.
[wine.git] / dlls / user32 / lstr.c
blob80a2cfbe11dde467659beb821b8e20027ebbfe45
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 "winnls.h"
35 #include "winuser.h"
36 #include "winerror.h"
38 #include "wine/exception.h"
41 /***********************************************************************
42 * CharNextA (USER32.@)
44 LPSTR WINAPI CharNextA( LPCSTR ptr )
46 if (!*ptr) return (LPSTR)ptr;
47 if (IsDBCSLeadByte( ptr[0] ) && ptr[1]) return (LPSTR)(ptr + 2);
48 return (LPSTR)(ptr + 1);
52 /***********************************************************************
53 * CharNextExA (USER32.@)
55 LPSTR WINAPI CharNextExA( WORD codepage, LPCSTR ptr, DWORD flags )
57 if (!*ptr) return (LPSTR)ptr;
58 if (IsDBCSLeadByteEx( codepage, ptr[0] ) && ptr[1]) return (LPSTR)(ptr + 2);
59 return (LPSTR)(ptr + 1);
63 /***********************************************************************
64 * CharNextExW (USER32.@)
66 LPWSTR WINAPI CharNextExW( WORD codepage, LPCWSTR ptr, DWORD flags )
68 /* doesn't make sense, there are no codepages for Unicode */
69 return NULL;
73 /***********************************************************************
74 * CharNextW (USER32.@)
76 LPWSTR WINAPI CharNextW(LPCWSTR x)
78 if (*x) x++;
80 return (LPWSTR)x;
84 /***********************************************************************
85 * CharPrevA (USER32.@)
87 LPSTR WINAPI CharPrevA( LPCSTR start, LPCSTR ptr )
89 while (*start && (start < ptr))
91 LPCSTR next = CharNextA( start );
92 if (next >= ptr) break;
93 start = next;
95 return (LPSTR)start;
99 /***********************************************************************
100 * CharPrevExA (USER32.@)
102 LPSTR WINAPI CharPrevExA( WORD codepage, LPCSTR start, LPCSTR ptr, DWORD flags )
104 while (*start && (start < ptr))
106 LPCSTR next = CharNextExA( codepage, start, flags );
107 if (next >= ptr) break;
108 start = next;
110 return (LPSTR)start;
114 /***********************************************************************
115 * CharPrevExW (USER32.@)
117 LPSTR WINAPI CharPrevExW( WORD codepage, LPCWSTR start, LPCWSTR ptr, DWORD flags )
119 /* doesn't make sense, there are no codepages for Unicode */
120 return NULL;
124 /***********************************************************************
125 * CharPrevW (USER32.@)
127 LPWSTR WINAPI CharPrevW(LPCWSTR start,LPCWSTR x)
129 if (x>start) return (LPWSTR)(x-1);
130 else return (LPWSTR)x;
134 /***********************************************************************
135 * CharToOemA (USER32.@)
137 BOOL WINAPI CharToOemA( LPCSTR s, LPSTR d )
139 if (!s || !d) return FALSE;
140 return CharToOemBuffA( s, d, strlen( s ) + 1 );
144 /***********************************************************************
145 * CharToOemBuffA (USER32.@)
147 BOOL WINAPI CharToOemBuffA( LPCSTR s, LPSTR d, DWORD len )
149 WCHAR *bufW;
151 if (!s || !d) return FALSE;
153 bufW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
154 if( bufW )
156 MultiByteToWideChar( CP_ACP, 0, s, len, bufW, len );
157 WideCharToMultiByte( CP_OEMCP, 0, bufW, len, d, len, NULL, NULL );
158 HeapFree( GetProcessHeap(), 0, bufW );
160 return TRUE;
164 /***********************************************************************
165 * CharToOemBuffW (USER32.@)
167 BOOL WINAPI CharToOemBuffW( LPCWSTR s, LPSTR d, DWORD len )
169 if (!s || !d) return FALSE;
170 WideCharToMultiByte( CP_OEMCP, 0, s, len, d, len, NULL, NULL );
171 return TRUE;
175 /***********************************************************************
176 * CharToOemW (USER32.@)
178 BOOL WINAPI CharToOemW( LPCWSTR s, LPSTR d )
180 if (!s || !d) return FALSE;
181 return CharToOemBuffW( s, d, lstrlenW( s ) + 1 );
185 /***********************************************************************
186 * OemToCharA (USER32.@)
188 BOOL WINAPI OemToCharA( LPCSTR s, LPSTR d )
190 if (!s || !d) return FALSE;
191 return OemToCharBuffA( s, d, strlen( s ) + 1 );
195 /***********************************************************************
196 * OemToCharBuffA (USER32.@)
198 BOOL WINAPI OemToCharBuffA( LPCSTR s, LPSTR d, DWORD len )
200 WCHAR *bufW;
202 if (!s || !d) return FALSE;
204 bufW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
205 if( bufW )
207 MultiByteToWideChar( CP_OEMCP, 0, s, len, bufW, len );
208 WideCharToMultiByte( CP_ACP, 0, bufW, len, d, len, NULL, NULL );
209 HeapFree( GetProcessHeap(), 0, bufW );
211 return TRUE;
215 /***********************************************************************
216 * OemToCharBuffW (USER32.@)
218 BOOL WINAPI OemToCharBuffW( LPCSTR s, LPWSTR d, DWORD len )
220 if (!s || !d) return FALSE;
221 MultiByteToWideChar( CP_OEMCP, MB_PRECOMPOSED | MB_USEGLYPHCHARS, s, len, d, len );
222 return TRUE;
226 /***********************************************************************
227 * OemToCharW (USER32.@)
229 BOOL WINAPI OemToCharW( LPCSTR s, LPWSTR d )
231 if (!s || !d) return FALSE;
232 return OemToCharBuffW( s, d, strlen( s ) + 1 );
236 /***********************************************************************
237 * CharLowerA (USER32.@)
239 LPSTR WINAPI CharLowerA(LPSTR str)
241 if (IS_INTRESOURCE(str))
243 char ch = LOWORD(str);
244 CharLowerBuffA( &ch, 1 );
245 return (LPSTR)(UINT_PTR)(BYTE)ch;
248 __TRY
250 CharLowerBuffA( str, strlen(str) );
252 __EXCEPT_PAGE_FAULT
254 SetLastError( ERROR_INVALID_PARAMETER );
255 return NULL;
257 __ENDTRY
258 return str;
262 /***********************************************************************
263 * CharUpperA (USER32.@)
265 LPSTR WINAPI CharUpperA(LPSTR str)
267 if (IS_INTRESOURCE(str))
269 char ch = LOWORD(str);
270 CharUpperBuffA( &ch, 1 );
271 return (LPSTR)(UINT_PTR)(BYTE)ch;
274 __TRY
276 CharUpperBuffA( str, strlen(str) );
278 __EXCEPT_PAGE_FAULT
280 SetLastError( ERROR_INVALID_PARAMETER );
281 return NULL;
283 __ENDTRY
284 return str;
288 /***********************************************************************
289 * CharLowerW (USER32.@)
291 LPWSTR WINAPI CharLowerW( LPWSTR str )
293 if (!IS_INTRESOURCE( str ))
295 CharLowerBuffW( str, lstrlenW( str ));
296 return str;
298 else
300 WCHAR ch = LOWORD( str );
301 CharLowerBuffW( &ch, 1 );
302 return (LPWSTR)(UINT_PTR)ch;
307 /***********************************************************************
308 * CharUpperW (USER32.@)
310 LPWSTR WINAPI CharUpperW( LPWSTR str )
312 if (!IS_INTRESOURCE( str ))
314 CharUpperBuffW( str, lstrlenW( str ));
315 return str;
317 else
319 WCHAR ch = LOWORD( str );
320 CharUpperBuffW( &ch, 1 );
321 return (LPWSTR)(UINT_PTR)ch;
326 /***********************************************************************
327 * CharLowerBuffA (USER32.@)
329 DWORD WINAPI CharLowerBuffA( LPSTR str, DWORD len )
331 DWORD lenW;
332 WCHAR buffer[32];
333 WCHAR *strW = buffer;
335 if (!str) return 0; /* YES */
337 lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
338 if (lenW > sizeof(buffer)/sizeof(WCHAR))
340 strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
341 if (!strW) return 0;
343 MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW);
344 CharLowerBuffW(strW, lenW);
345 len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL);
346 if (strW != buffer) HeapFree(GetProcessHeap(), 0, strW);
347 return len;
351 /***********************************************************************
352 * CharLowerBuffW (USER32.@)
354 DWORD WINAPI CharLowerBuffW( LPWSTR str, DWORD len )
356 if (!str) return 0; /* YES */
357 return LCMapStringW( LOCALE_USER_DEFAULT, LCMAP_LOWERCASE, str, len, str, len );
361 /***********************************************************************
362 * CharUpperBuffA (USER32.@)
364 DWORD WINAPI CharUpperBuffA( LPSTR str, DWORD len )
366 DWORD lenW;
367 WCHAR buffer[32];
368 WCHAR *strW = buffer;
370 if (!str) return 0; /* YES */
372 lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
373 if (lenW > sizeof(buffer)/sizeof(WCHAR))
375 strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
376 if (!strW) return 0;
378 MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW);
379 CharUpperBuffW(strW, lenW);
380 len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL);
381 if (strW != buffer) HeapFree(GetProcessHeap(), 0, strW);
382 return len;
386 /***********************************************************************
387 * CharUpperBuffW (USER32.@)
389 DWORD WINAPI CharUpperBuffW( LPWSTR str, DWORD len )
391 if (!str) return 0; /* YES */
392 return LCMapStringW( LOCALE_USER_DEFAULT, LCMAP_UPPERCASE, str, len, str, len );
396 /***********************************************************************
397 * IsCharLower (USER.436)
398 * IsCharLowerA (USER32.@)
400 BOOL WINAPI IsCharLowerA(CHAR x)
402 WCHAR wch;
403 MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
404 return IsCharLowerW(wch);
408 /***********************************************************************
409 * IsCharLowerW (USER32.@)
411 BOOL WINAPI IsCharLowerW( WCHAR ch )
413 WORD type;
414 return GetStringTypeW( CT_CTYPE1, &ch, 1, &type ) && (type & C1_LOWER);
418 /***********************************************************************
419 * IsCharUpper (USER.435)
420 * IsCharUpperA (USER32.@)
422 BOOL WINAPI IsCharUpperA(CHAR x)
424 WCHAR wch;
425 MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
426 return IsCharUpperW(wch);
430 /***********************************************************************
431 * IsCharUpperW (USER32.@)
433 BOOL WINAPI IsCharUpperW( WCHAR ch )
435 WORD type;
436 return GetStringTypeW( CT_CTYPE1, &ch, 1, &type ) && (type & C1_UPPER);
440 /***********************************************************************
441 * IsCharAlphaNumeric (USER.434)
442 * IsCharAlphaNumericA (USER32.@)
444 BOOL WINAPI IsCharAlphaNumericA(CHAR x)
446 WCHAR wch;
447 MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
448 return IsCharAlphaNumericW(wch);
452 /***********************************************************************
453 * IsCharAlphaNumericW (USER32.@)
455 BOOL WINAPI IsCharAlphaNumericW( WCHAR ch )
457 WORD type;
458 return GetStringTypeW( CT_CTYPE1, &ch, 1, &type ) && (type & (C1_ALPHA|C1_DIGIT));
462 /***********************************************************************
463 * IsCharAlpha (USER.433)
464 * IsCharAlphaA (USER32.@)
466 BOOL WINAPI IsCharAlphaA(CHAR x)
468 WCHAR wch;
469 MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
470 return IsCharAlphaW(wch);
474 /***********************************************************************
475 * IsCharAlphaW (USER32.@)
477 BOOL WINAPI IsCharAlphaW( WCHAR ch )
479 WORD type;
480 return GetStringTypeW( CT_CTYPE1, &ch, 1, &type ) && (type & C1_ALPHA);