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