In reg_get_logfont:
[wine] / dlls / user / lstr.c
1 /*
2  * USER string functions
3  *
4  * Copyright 1993 Yngvi Sigurjonsson (yngvi@hafro.is)
5  * Copyright 1996 Alexandre Julliard
6  * Copyright 1996 Marcus Meissner
7  *
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.
12  *
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.
17  *
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
21  */
22
23 #include "config.h"
24 #include "wine/port.h"
25
26 #include <ctype.h>
27 #include <stdarg.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31
32 #include "windef.h"
33 #include "winbase.h"
34 #include "winuser.h"
35 #include "winerror.h"
36
37 #include "wine/exception.h"
38 #include "wine/unicode.h"
39 #include "excpt.h"
40
41 #include "wine/debug.h"
42
43 WINE_DEFAULT_DEBUG_CHANNEL(resource);
44
45 /* filter for page-fault exceptions */
46 static WINE_EXCEPTION_FILTER(page_fault)
47 {
48     if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ||
49         GetExceptionCode() == EXCEPTION_PRIV_INSTRUCTION)
50         return EXCEPTION_EXECUTE_HANDLER;
51     return EXCEPTION_CONTINUE_SEARCH;
52 }
53
54 /***********************************************************************
55  *           CharNextA   (USER32.@)
56  */
57 LPSTR WINAPI CharNextA( LPCSTR ptr )
58 {
59     if (!*ptr) return (LPSTR)ptr;
60     if (IsDBCSLeadByte( ptr[0] ) && ptr[1]) return (LPSTR)(ptr + 2);
61     return (LPSTR)(ptr + 1);
62 }
63
64
65 /***********************************************************************
66  *           CharNextExA   (USER32.@)
67  */
68 LPSTR WINAPI CharNextExA( WORD codepage, LPCSTR ptr, DWORD flags )
69 {
70     if (!*ptr) return (LPSTR)ptr;
71     if (IsDBCSLeadByteEx( codepage, ptr[0] ) && ptr[1]) return (LPSTR)(ptr + 2);
72     return (LPSTR)(ptr + 1);
73 }
74
75
76 /***********************************************************************
77  *           CharNextExW   (USER32.@)
78  */
79 LPWSTR WINAPI CharNextExW( WORD codepage, LPCWSTR ptr, DWORD flags )
80 {
81     /* doesn't make sense, there are no codepages for Unicode */
82     return NULL;
83 }
84
85
86 /***********************************************************************
87  *           CharNextW   (USER32.@)
88  */
89 LPWSTR WINAPI CharNextW(LPCWSTR x)
90 {
91     if (*x) x++;
92
93     return (LPWSTR)x;
94 }
95
96
97 /***********************************************************************
98  *           CharPrevA   (USER32.@)
99  */
100 LPSTR WINAPI CharPrevA( LPCSTR start, LPCSTR ptr )
101 {
102     while (*start && (start < ptr))
103     {
104         LPCSTR next = CharNextA( start );
105         if (next >= ptr) break;
106         start = next;
107     }
108     return (LPSTR)start;
109 }
110
111
112 /***********************************************************************
113  *           CharPrevExA   (USER32.@)
114  */
115 LPSTR WINAPI CharPrevExA( WORD codepage, LPCSTR start, LPCSTR ptr, DWORD flags )
116 {
117     while (*start && (start < ptr))
118     {
119         LPCSTR next = CharNextExA( codepage, start, flags );
120         if (next >= ptr) break;
121         start = next;
122     }
123     return (LPSTR)start;
124 }
125
126
127 /***********************************************************************
128  *           CharPrevExW   (USER32.@)
129  */
130 LPSTR WINAPI CharPrevExW( WORD codepage, LPCWSTR start, LPCWSTR ptr, DWORD flags )
131 {
132     /* doesn't make sense, there are no codepages for Unicode */
133     return NULL;
134 }
135
136
137 /***********************************************************************
138  *           CharPrevW   (USER32.@)
139  */
140 LPWSTR WINAPI CharPrevW(LPCWSTR start,LPCWSTR x)
141 {
142     if (x>start) return (LPWSTR)(x-1);
143     else return (LPWSTR)x;
144 }
145
146
147 /***********************************************************************
148  *           CharToOemA   (USER32.@)
149  */
150 BOOL WINAPI CharToOemA( LPCSTR s, LPSTR d )
151 {
152     if ( !s || !d ) return TRUE;
153     return CharToOemBuffA( s, d, strlen( s ) + 1 );
154 }
155
156
157 /***********************************************************************
158  *           CharToOemBuffA   (USER32.@)
159  */
160 BOOL WINAPI CharToOemBuffA( LPCSTR s, LPSTR d, DWORD len )
161 {
162     WCHAR *bufW;
163
164     bufW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
165     if( bufW )
166     {
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 );
170     }
171     return TRUE;
172 }
173
174
175 /***********************************************************************
176  *           CharToOemBuffW   (USER32.@)
177  */
178 BOOL WINAPI CharToOemBuffW( LPCWSTR s, LPSTR d, DWORD len )
179 {
180    if ( !s || !d ) return TRUE;
181     WideCharToMultiByte( CP_OEMCP, 0, s, len, d, len, NULL, NULL );
182     return TRUE;
183 }
184
185
186 /***********************************************************************
187  *           CharToOemW   (USER32.@)
188  */
189 BOOL WINAPI CharToOemW( LPCWSTR s, LPSTR d )
190 {
191     return CharToOemBuffW( s, d, strlenW( s ) + 1 );
192 }
193
194
195 /***********************************************************************
196  *           OemToCharA   (USER32.@)
197  */
198 BOOL WINAPI OemToCharA( LPCSTR s, LPSTR d )
199 {
200     return OemToCharBuffA( s, d, strlen( s ) + 1 );
201 }
202
203
204 /***********************************************************************
205  *           OemToCharBuffA   (USER32.@)
206  */
207 BOOL WINAPI OemToCharBuffA( LPCSTR s, LPSTR d, DWORD len )
208 {
209     WCHAR *bufW;
210
211     bufW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
212     if( bufW )
213     {
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 );
217     }
218     return TRUE;
219 }
220
221
222 /***********************************************************************
223  *           OemToCharBuffW   (USER32.@)
224  */
225 BOOL WINAPI OemToCharBuffW( LPCSTR s, LPWSTR d, DWORD len )
226 {
227     MultiByteToWideChar( CP_OEMCP, 0, s, len, d, len );
228     return TRUE;
229 }
230
231
232 /***********************************************************************
233  *           OemToCharW   (USER32.@)
234  */
235 BOOL WINAPI OemToCharW( LPCSTR s, LPWSTR d )
236 {
237     return OemToCharBuffW( s, d, strlen( s ) + 1 );
238 }
239
240
241 /***********************************************************************
242  *           CharLowerA   (USER32.@)
243  */
244 LPSTR WINAPI CharLowerA(LPSTR str)
245 {
246     if (!HIWORD(str))
247     {
248         char ch = LOWORD(str);
249         CharLowerBuffA( &ch, 1 );
250         return (LPSTR)(UINT_PTR)(BYTE)ch;
251     }
252
253     __TRY
254     {
255         CharLowerBuffA( str, strlen(str) );
256     }
257     __EXCEPT(page_fault)
258     {
259         SetLastError( ERROR_INVALID_PARAMETER );
260         return NULL;
261     }
262     __ENDTRY
263     return str;
264 }
265
266
267 /***********************************************************************
268  *           CharUpperA   (USER32.@)
269  */
270 LPSTR WINAPI CharUpperA(LPSTR str)
271 {
272     if (!HIWORD(str))
273     {
274         char ch = LOWORD(str);
275         CharUpperBuffA( &ch, 1 );
276         return (LPSTR)(UINT_PTR)(BYTE)ch;
277     }
278
279     __TRY
280     {
281         CharUpperBuffA( str, strlen(str) );
282     }
283     __EXCEPT(page_fault)
284     {
285         SetLastError( ERROR_INVALID_PARAMETER );
286         return NULL;
287     }
288     __ENDTRY
289     return str;
290 }
291
292
293 /***********************************************************************
294  *           CharLowerW   (USER32.@)
295  */
296 LPWSTR WINAPI CharLowerW(LPWSTR x)
297 {
298     if (HIWORD(x)) return strlwrW(x);
299     else return (LPWSTR)((UINT)tolowerW(LOWORD(x)));
300 }
301
302
303 /***********************************************************************
304  *           CharUpperW   (USER32.@)
305  */
306 LPWSTR WINAPI CharUpperW(LPWSTR x)
307 {
308     if (HIWORD(x)) return struprW(x);
309     else return (LPWSTR)((UINT)toupperW(LOWORD(x)));
310 }
311
312
313 /***********************************************************************
314  *           CharLowerBuffA   (USER32.@)
315  */
316 DWORD WINAPI CharLowerBuffA( LPSTR str, DWORD len )
317 {
318     DWORD lenW;
319     WCHAR buffer[32];
320     WCHAR *strW = buffer;
321
322     if (!str) return 0; /* YES */
323
324     lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
325     if (lenW > sizeof(buffer)/sizeof(WCHAR))
326     {
327         strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
328         if (!strW) return 0;
329     }
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;
335 }
336
337
338 /***********************************************************************
339  *           CharLowerBuffW   (USER32.@)
340  */
341 DWORD WINAPI CharLowerBuffW( LPWSTR str, DWORD len )
342 {
343     DWORD ret = len;
344     if (!str) return 0; /* YES */
345     for (; len; len--, str++) *str = tolowerW(*str);
346     return ret;
347 }
348
349
350 /***********************************************************************
351  *           CharUpperBuffA   (USER32.@)
352  */
353 DWORD WINAPI CharUpperBuffA( LPSTR str, DWORD len )
354 {
355     DWORD lenW;
356     WCHAR buffer[32];
357     WCHAR *strW = buffer;
358
359     if (!str) return 0; /* YES */
360
361     lenW = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0);
362     if (lenW > sizeof(buffer)/sizeof(WCHAR))
363     {
364         strW = HeapAlloc(GetProcessHeap(), 0, lenW * sizeof(WCHAR));
365         if (!strW) return 0;
366     }
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;
372 }
373
374
375 /***********************************************************************
376  *           CharUpperBuffW   (USER32.@)
377  */
378 DWORD WINAPI CharUpperBuffW( LPWSTR str, DWORD len )
379 {
380     DWORD ret = len;
381     if (!str) return 0; /* YES */
382     for (; len; len--, str++) *str = toupperW(*str);
383     return ret;
384 }
385
386
387 /***********************************************************************
388  *           IsCharLower    (USER.436)
389  *           IsCharLowerA   (USER32.@)
390  */
391 BOOL WINAPI IsCharLowerA(CHAR x)
392 {
393     WCHAR wch;
394     MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
395     return IsCharLowerW(wch);
396 }
397
398
399 /***********************************************************************
400  *           IsCharLowerW   (USER32.@)
401  */
402 BOOL WINAPI IsCharLowerW(WCHAR x)
403 {
404     return (get_char_typeW(x) & C1_LOWER) != 0;
405 }
406
407
408 /***********************************************************************
409  *           IsCharUpper    (USER.435)
410  *           IsCharUpperA   (USER32.@)
411  */
412 BOOL WINAPI IsCharUpperA(CHAR x)
413 {
414     WCHAR wch;
415     MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
416     return IsCharUpperW(wch);
417 }
418
419
420 /***********************************************************************
421  *           IsCharUpperW   (USER32.@)
422  */
423 BOOL WINAPI IsCharUpperW(WCHAR x)
424 {
425     return (get_char_typeW(x) & C1_UPPER) != 0;
426 }
427
428
429 /***********************************************************************
430  *           IsCharAlphaNumeric    (USER.434)
431  *           IsCharAlphaNumericA   (USER32.@)
432  */
433 BOOL WINAPI IsCharAlphaNumericA(CHAR x)
434 {
435     WCHAR wch;
436     MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
437     return IsCharAlphaNumericW(wch);
438 }
439
440
441 /***********************************************************************
442  *           IsCharAlphaNumericW   (USER32.@)
443  */
444 BOOL WINAPI IsCharAlphaNumericW(WCHAR x)
445 {
446     return (get_char_typeW(x) & (C1_ALPHA|C1_DIGIT)) != 0;
447 }
448
449
450 /***********************************************************************
451  *           IsCharAlpha    (USER.433)
452  *           IsCharAlphaA   (USER32.@)
453  */
454 BOOL WINAPI IsCharAlphaA(CHAR x)
455 {
456     WCHAR wch;
457     MultiByteToWideChar(CP_ACP, 0, &x, 1, &wch, 1);
458     return IsCharAlphaW(wch);
459 }
460
461
462 /***********************************************************************
463  *           IsCharAlphaW   (USER32.@)
464  */
465 BOOL WINAPI IsCharAlphaW(WCHAR x)
466 {
467     return (get_char_typeW(x) & C1_ALPHA) != 0;
468 }