msi: Handle some error returns (Coverity).
[wine.git] / dlls / user32 / lstr.c
blob8fff22f59c90bca47f7cca1694b954999930e04c
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"
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 TRUE;
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 bufW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
152 if( bufW )
154 MultiByteToWideChar( CP_ACP, 0, s, len, bufW, len );
155 WideCharToMultiByte( CP_OEMCP, 0, bufW, len, d, len, NULL, NULL );
156 HeapFree( GetProcessHeap(), 0, bufW );
158 return TRUE;
162 /***********************************************************************
163 * CharToOemBuffW (USER32.@)
165 BOOL WINAPI CharToOemBuffW( LPCWSTR s, LPSTR d, DWORD len )
167 if ( !s || !d ) return TRUE;
168 WideCharToMultiByte( CP_OEMCP, 0, s, len, d, len, NULL, NULL );
169 return TRUE;
173 /***********************************************************************
174 * CharToOemW (USER32.@)
176 BOOL WINAPI CharToOemW( LPCWSTR s, LPSTR d )
178 return CharToOemBuffW( s, d, strlenW( s ) + 1 );
182 /***********************************************************************
183 * OemToCharA (USER32.@)
185 BOOL WINAPI OemToCharA( LPCSTR s, LPSTR d )
187 return OemToCharBuffA( s, d, strlen( s ) + 1 );
191 /***********************************************************************
192 * OemToCharBuffA (USER32.@)
194 BOOL WINAPI OemToCharBuffA( LPCSTR s, LPSTR d, DWORD len )
196 WCHAR *bufW;
198 bufW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
199 if( bufW )
201 MultiByteToWideChar( CP_OEMCP, 0, s, len, bufW, len );
202 WideCharToMultiByte( CP_ACP, 0, bufW, len, d, len, NULL, NULL );
203 HeapFree( GetProcessHeap(), 0, bufW );
205 return TRUE;
209 /***********************************************************************
210 * OemToCharBuffW (USER32.@)
212 BOOL WINAPI OemToCharBuffW( LPCSTR s, LPWSTR d, DWORD len )
214 MultiByteToWideChar( CP_OEMCP, 0, s, len, d, len );
215 return TRUE;
219 /***********************************************************************
220 * OemToCharW (USER32.@)
222 BOOL WINAPI OemToCharW( LPCSTR s, LPWSTR d )
224 return OemToCharBuffW( s, d, strlen( s ) + 1 );
228 /***********************************************************************
229 * CharLowerA (USER32.@)
231 LPSTR WINAPI CharLowerA(LPSTR str)
233 if (!HIWORD(str))
235 char ch = LOWORD(str);
236 CharLowerBuffA( &ch, 1 );
237 return (LPSTR)(UINT_PTR)(BYTE)ch;
240 __TRY
242 CharLowerBuffA( str, strlen(str) );
244 __EXCEPT_PAGE_FAULT
246 SetLastError( ERROR_INVALID_PARAMETER );
247 return NULL;
249 __ENDTRY
250 return str;
254 /***********************************************************************
255 * CharUpperA (USER32.@)
257 LPSTR WINAPI CharUpperA(LPSTR str)
259 if (!HIWORD(str))
261 char ch = LOWORD(str);
262 CharUpperBuffA( &ch, 1 );
263 return (LPSTR)(UINT_PTR)(BYTE)ch;
266 __TRY
268 CharUpperBuffA( str, strlen(str) );
270 __EXCEPT_PAGE_FAULT
272 SetLastError( ERROR_INVALID_PARAMETER );
273 return NULL;
275 __ENDTRY
276 return str;
280 /***********************************************************************
281 * CharLowerW (USER32.@)
283 LPWSTR WINAPI CharLowerW(LPWSTR x)
285 if (HIWORD(x)) return strlwrW(x);
286 else return (LPWSTR)((UINT_PTR)tolowerW(LOWORD(x)));
290 /***********************************************************************
291 * CharUpperW (USER32.@)
293 LPWSTR WINAPI CharUpperW(LPWSTR x)
295 if (HIWORD(x)) return struprW(x);
296 else return (LPWSTR)((UINT_PTR)toupperW(LOWORD(x)));
300 /***********************************************************************
301 * CharLowerBuffA (USER32.@)
303 DWORD WINAPI CharLowerBuffA( LPSTR str, DWORD len )
305 DWORD lenW;
306 WCHAR buffer[32];
307 WCHAR *strW = buffer;
309 if (!str) return 0; /* YES */
311 lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
312 if (lenW > sizeof(buffer)/sizeof(WCHAR))
314 strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
315 if (!strW) return 0;
317 MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW);
318 CharLowerBuffW(strW, lenW);
319 len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL);
320 if (strW != buffer) HeapFree(GetProcessHeap(), 0, strW);
321 return len;
325 /***********************************************************************
326 * CharLowerBuffW (USER32.@)
328 DWORD WINAPI CharLowerBuffW( LPWSTR str, DWORD len )
330 DWORD ret = len;
331 if (!str) return 0; /* YES */
332 for (; len; len--, str++) *str = tolowerW(*str);
333 return ret;
337 /***********************************************************************
338 * CharUpperBuffA (USER32.@)
340 DWORD WINAPI CharUpperBuffA( LPSTR str, DWORD len )
342 DWORD lenW;
343 WCHAR buffer[32];
344 WCHAR *strW = buffer;
346 if (!str) return 0; /* YES */
348 lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
349 if (lenW > sizeof(buffer)/sizeof(WCHAR))
351 strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
352 if (!strW) return 0;
354 MultiByteToWideChar(CP_ACP, 0, str, len, strW, lenW);
355 CharUpperBuffW(strW, lenW);
356 len = WideCharToMultiByte(CP_ACP, 0, strW, lenW, str, len, NULL, NULL);
357 if (strW != buffer) HeapFree(GetProcessHeap(), 0, strW);
358 return len;
362 /***********************************************************************
363 * CharUpperBuffW (USER32.@)
365 DWORD WINAPI CharUpperBuffW( LPWSTR str, DWORD len )
367 DWORD ret = len;
368 if (!str) return 0; /* YES */
369 for (; len; len--, str++) *str = toupperW(*str);
370 return ret;
374 /***********************************************************************
375 * IsCharLower (USER.436)
376 * IsCharLowerA (USER32.@)
378 BOOL WINAPI IsCharLowerA(CHAR x)
380 WCHAR wch;
381 MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
382 return IsCharLowerW(wch);
386 /***********************************************************************
387 * IsCharLowerW (USER32.@)
389 BOOL WINAPI IsCharLowerW(WCHAR x)
391 return (get_char_typeW(x) & C1_LOWER) != 0;
395 /***********************************************************************
396 * IsCharUpper (USER.435)
397 * IsCharUpperA (USER32.@)
399 BOOL WINAPI IsCharUpperA(CHAR x)
401 WCHAR wch;
402 MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
403 return IsCharUpperW(wch);
407 /***********************************************************************
408 * IsCharUpperW (USER32.@)
410 BOOL WINAPI IsCharUpperW(WCHAR x)
412 return (get_char_typeW(x) & C1_UPPER) != 0;
416 /***********************************************************************
417 * IsCharAlphaNumeric (USER.434)
418 * IsCharAlphaNumericA (USER32.@)
420 BOOL WINAPI IsCharAlphaNumericA(CHAR x)
422 WCHAR wch;
423 MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
424 return IsCharAlphaNumericW(wch);
428 /***********************************************************************
429 * IsCharAlphaNumericW (USER32.@)
431 BOOL WINAPI IsCharAlphaNumericW(WCHAR x)
433 return (get_char_typeW(x) & (C1_ALPHA|C1_DIGIT)) != 0;
437 /***********************************************************************
438 * IsCharAlpha (USER.433)
439 * IsCharAlphaA (USER32.@)
441 BOOL WINAPI IsCharAlphaA(CHAR x)
443 WCHAR wch;
444 MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
445 return IsCharAlphaW(wch);
449 /***********************************************************************
450 * IsCharAlphaW (USER32.@)
452 BOOL WINAPI IsCharAlphaW(WCHAR x)
454 return (get_char_typeW(x) & C1_ALPHA) != 0;