Fix some DPA functions so they pass the new tests.
[wine/multimedia.git] / dlls / user / lstr.c
blob9a3473819c021845fdd83af755e70df649fdfd2b
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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"
41 #include "wine/debug.h"
43 WINE_DEFAULT_DEBUG_CHANNEL(resource);
45 /* filter for page-fault exceptions */
46 static WINE_EXCEPTION_FILTER(page_fault)
48 if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ||
49 GetExceptionCode() == EXCEPTION_PRIV_INSTRUCTION)
50 return EXCEPTION_EXECUTE_HANDLER;
51 return EXCEPTION_CONTINUE_SEARCH;
54 /***********************************************************************
55 * CharNextA (USER32.@)
57 LPSTR WINAPI CharNextA( LPCSTR ptr )
59 if (!*ptr) return (LPSTR)ptr;
60 if (IsDBCSLeadByte( ptr[0] ) && ptr[1]) return (LPSTR)(ptr + 2);
61 return (LPSTR)(ptr + 1);
65 /***********************************************************************
66 * CharNextExA (USER32.@)
68 LPSTR WINAPI CharNextExA( WORD codepage, LPCSTR ptr, DWORD flags )
70 if (!*ptr) return (LPSTR)ptr;
71 if (IsDBCSLeadByteEx( codepage, ptr[0] ) && ptr[1]) return (LPSTR)(ptr + 2);
72 return (LPSTR)(ptr + 1);
76 /***********************************************************************
77 * CharNextExW (USER32.@)
79 LPWSTR WINAPI CharNextExW( WORD codepage, LPCWSTR ptr, DWORD flags )
81 /* doesn't make sense, there are no codepages for Unicode */
82 return NULL;
86 /***********************************************************************
87 * CharNextW (USER32.@)
89 LPWSTR WINAPI CharNextW(LPCWSTR x)
91 if (*x) x++;
93 return (LPWSTR)x;
97 /***********************************************************************
98 * CharPrevA (USER32.@)
100 LPSTR WINAPI CharPrevA( LPCSTR start, LPCSTR ptr )
102 while (*start && (start < ptr))
104 LPCSTR next = CharNextA( start );
105 if (next >= ptr) break;
106 start = next;
108 return (LPSTR)start;
112 /***********************************************************************
113 * CharPrevExA (USER32.@)
115 LPSTR WINAPI CharPrevExA( WORD codepage, LPCSTR start, LPCSTR ptr, DWORD flags )
117 while (*start && (start < ptr))
119 LPCSTR next = CharNextExA( codepage, start, flags );
120 if (next >= ptr) break;
121 start = next;
123 return (LPSTR)start;
127 /***********************************************************************
128 * CharPrevExW (USER32.@)
130 LPSTR WINAPI CharPrevExW( WORD codepage, LPCWSTR start, LPCWSTR ptr, DWORD flags )
132 /* doesn't make sense, there are no codepages for Unicode */
133 return NULL;
137 /***********************************************************************
138 * CharPrevW (USER32.@)
140 LPWSTR WINAPI CharPrevW(LPCWSTR start,LPCWSTR x)
142 if (x>start) return (LPWSTR)(x-1);
143 else return (LPWSTR)x;
147 /***********************************************************************
148 * CharToOemA (USER32.@)
150 BOOL WINAPI CharToOemA( LPCSTR s, LPSTR d )
152 if ( !s || !d ) return TRUE;
153 return CharToOemBuffA( s, d, strlen( s ) + 1 );
157 /***********************************************************************
158 * CharToOemBuffA (USER32.@)
160 BOOL WINAPI CharToOemBuffA( LPCSTR s, LPSTR d, DWORD len )
162 WCHAR *bufW;
164 bufW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
165 if( bufW )
167 MultiByteToWideChar( CP_ACP, 0, s, len, bufW, len );
168 WideCharToMultiByte( CP_OEMCP, 0, bufW, len, d, len, NULL, NULL );
169 HeapFree( GetProcessHeap(), 0, bufW );
171 return TRUE;
175 /***********************************************************************
176 * CharToOemBuffW (USER32.@)
178 BOOL WINAPI CharToOemBuffW( LPCWSTR s, LPSTR d, DWORD len )
180 if ( !s || !d ) return TRUE;
181 WideCharToMultiByte( CP_OEMCP, 0, s, len, d, len, NULL, NULL );
182 return TRUE;
186 /***********************************************************************
187 * CharToOemW (USER32.@)
189 BOOL WINAPI CharToOemW( LPCWSTR s, LPSTR d )
191 return CharToOemBuffW( s, d, strlenW( s ) + 1 );
195 /***********************************************************************
196 * OemToCharA (USER32.@)
198 BOOL WINAPI OemToCharA( LPCSTR s, LPSTR d )
200 return OemToCharBuffA( s, d, strlen( s ) + 1 );
204 /***********************************************************************
205 * OemToCharBuffA (USER32.@)
207 BOOL WINAPI OemToCharBuffA( LPCSTR s, LPSTR d, DWORD len )
209 WCHAR *bufW;
211 bufW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
212 if( bufW )
214 MultiByteToWideChar( CP_OEMCP, 0, s, len, bufW, len );
215 WideCharToMultiByte( CP_ACP, 0, bufW, len, d, len, NULL, NULL );
216 HeapFree( GetProcessHeap(), 0, bufW );
218 return TRUE;
222 /***********************************************************************
223 * OemToCharBuffW (USER32.@)
225 BOOL WINAPI OemToCharBuffW( LPCSTR s, LPWSTR d, DWORD len )
227 MultiByteToWideChar( CP_OEMCP, 0, s, len, d, len );
228 return TRUE;
232 /***********************************************************************
233 * OemToCharW (USER32.@)
235 BOOL WINAPI OemToCharW( LPCSTR s, LPWSTR d )
237 return OemToCharBuffW( s, d, strlen( s ) + 1 );
241 /***********************************************************************
242 * CharLowerA (USER32.@)
244 LPSTR WINAPI CharLowerA(LPSTR str)
246 if (!HIWORD(str))
248 char ch = LOWORD(str);
249 CharLowerBuffA( &ch, 1 );
250 return (LPSTR)(UINT_PTR)(BYTE)ch;
253 __TRY
255 CharLowerBuffA( str, strlen(str) );
257 __EXCEPT(page_fault)
259 SetLastError( ERROR_INVALID_PARAMETER );
260 return NULL;
262 __ENDTRY
263 return str;
267 /***********************************************************************
268 * CharUpperA (USER32.@)
270 LPSTR WINAPI CharUpperA(LPSTR str)
272 if (!HIWORD(str))
274 char ch = LOWORD(str);
275 CharUpperBuffA( &ch, 1 );
276 return (LPSTR)(UINT_PTR)(BYTE)ch;
279 __TRY
281 CharUpperBuffA( str, strlen(str) );
283 __EXCEPT(page_fault)
285 SetLastError( ERROR_INVALID_PARAMETER );
286 return NULL;
288 __ENDTRY
289 return str;
293 /***********************************************************************
294 * CharLowerW (USER32.@)
296 LPWSTR WINAPI CharLowerW(LPWSTR x)
298 if (HIWORD(x)) return strlwrW(x);
299 else return (LPWSTR)((UINT)tolowerW(LOWORD(x)));
303 /***********************************************************************
304 * CharUpperW (USER32.@)
306 LPWSTR WINAPI CharUpperW(LPWSTR x)
308 if (HIWORD(x)) return struprW(x);
309 else return (LPWSTR)((UINT)toupperW(LOWORD(x)));
313 /***********************************************************************
314 * CharLowerBuffA (USER32.@)
316 DWORD WINAPI CharLowerBuffA( LPSTR str, DWORD len )
318 DWORD lenW;
319 WCHAR buffer[32];
320 WCHAR *strW = buffer;
322 if (!str) return 0; /* YES */
324 lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
325 if (lenW > sizeof(buffer)/sizeof(WCHAR))
327 strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
328 if (!strW) return 0;
330 MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW);
331 CharLowerBuffW(strW, lenW);
332 len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL);
333 if (strW != buffer) HeapFree(GetProcessHeap(), 0, strW);
334 return len;
338 /***********************************************************************
339 * CharLowerBuffW (USER32.@)
341 DWORD WINAPI CharLowerBuffW( LPWSTR str, DWORD len )
343 DWORD ret = len;
344 if (!str) return 0; /* YES */
345 for (; len; len--, str++) *str = tolowerW(*str);
346 return ret;
350 /***********************************************************************
351 * CharUpperBuffA (USER32.@)
353 DWORD WINAPI CharUpperBuffA( LPSTR str, DWORD len )
355 DWORD lenW;
356 WCHAR buffer[32];
357 WCHAR *strW = buffer;
359 if (!str) return 0; /* YES */
361 lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
362 if (lenW > sizeof(buffer)/sizeof(WCHAR))
364 strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
365 if (!strW) return 0;
367 MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW);
368 CharUpperBuffW(strW, lenW);
369 len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL);
370 if (strW != buffer) HeapFree(GetProcessHeap(), 0, strW);
371 return len;
375 /***********************************************************************
376 * CharUpperBuffW (USER32.@)
378 DWORD WINAPI CharUpperBuffW( LPWSTR str, DWORD len )
380 DWORD ret = len;
381 if (!str) return 0; /* YES */
382 for (; len; len--, str++) *str = toupperW(*str);
383 return ret;
387 /***********************************************************************
388 * IsCharLower (USER.436)
389 * IsCharLowerA (USER32.@)
391 BOOL WINAPI IsCharLowerA(CHAR x)
393 WCHAR wch;
394 MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
395 return IsCharLowerW(wch);
399 /***********************************************************************
400 * IsCharLowerW (USER32.@)
402 BOOL WINAPI IsCharLowerW(WCHAR x)
404 return (get_char_typeW(x) & C1_LOWER) != 0;
408 /***********************************************************************
409 * IsCharUpper (USER.435)
410 * IsCharUpperA (USER32.@)
412 BOOL WINAPI IsCharUpperA(CHAR x)
414 WCHAR wch;
415 MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
416 return IsCharUpperW(wch);
420 /***********************************************************************
421 * IsCharUpperW (USER32.@)
423 BOOL WINAPI IsCharUpperW(WCHAR x)
425 return (get_char_typeW(x) & C1_UPPER) != 0;
429 /***********************************************************************
430 * IsCharAlphaNumeric (USER.434)
431 * IsCharAlphaNumericA (USER32.@)
433 BOOL WINAPI IsCharAlphaNumericA(CHAR x)
435 WCHAR wch;
436 MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
437 return IsCharAlphaNumericW(wch);
441 /***********************************************************************
442 * IsCharAlphaNumericW (USER32.@)
444 BOOL WINAPI IsCharAlphaNumericW(WCHAR x)
446 return (get_char_typeW(x) & (C1_ALPHA|C1_DIGIT)) != 0;
450 /***********************************************************************
451 * IsCharAlpha (USER.433)
452 * IsCharAlphaA (USER32.@)
454 BOOL WINAPI IsCharAlphaA(CHAR x)
456 WCHAR wch;
457 MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
458 return IsCharAlphaW(wch);
462 /***********************************************************************
463 * IsCharAlphaW (USER32.@)
465 BOOL WINAPI IsCharAlphaW(WCHAR x)
467 return (get_char_typeW(x) & C1_ALPHA) != 0;