4 * Copyright 1993 Yngvi Sigurjonsson (yngvi@hafro.is)
5 * Copyright 1996 Marcus Meissner
18 # define towlower(c) tolower(c)
19 # define towupper(c) toupper(c)
20 # define iswalnum(c) isalnum(c)
21 # define iswalpha(c) isalpha(c)
22 # define iswupper(c) isupper(c)
23 # define iswlower(c) islower(c)
24 #endif /* HAVE_WCTYPE_H */
28 #include "winnt.h" /* HEAP_ macros */
32 #include "stackframe.h"
36 /* Funny to divide them between user and kernel. */
38 /* be careful: always use functions from wctype.h if character > 255 */
40 /***********************************************************************
41 * IsCharAlpha (USER.433)
43 BOOL16 WINAPI
IsCharAlpha16(CHAR ch
)
45 return isalpha(ch
); /* This is probably not right for NLS */
48 /***********************************************************************
49 * IsCharAlphanumeric (USER.434)
51 BOOL16 WINAPI
IsCharAlphaNumeric16(CHAR ch
)
56 /***********************************************************************
57 * IsCharUpper (USER.435)
59 BOOL16 WINAPI
IsCharUpper16(CHAR ch
)
64 /***********************************************************************
65 * IsCharLower (USER.436)
67 BOOL16 WINAPI
IsCharLower16(CHAR ch
)
72 /***********************************************************************
73 * AnsiUpper16 (USER.431)
75 SEGPTR WINAPI
AnsiUpper16( SEGPTR strOrChar
)
77 /* I am not sure if the locale stuff works with toupper, but then again
78 I am not sure if the Linux libc locale stuffs works at all */
80 /* uppercase only one char if strOrChar < 0x10000 */
81 if (HIWORD(strOrChar
))
84 for (s
= PTR_SEG_TO_LIN(strOrChar
); *s
; s
++) *s
= toupper(*s
);
87 else return toupper((char)strOrChar
);
91 /***********************************************************************
92 * AnsiUpperBuff16 (USER.437)
94 UINT16 WINAPI
AnsiUpperBuff16( LPSTR str
, UINT16 len
)
96 UINT32 count
= len
? len
: 65536;
97 for (; count
; count
--, str
++) *str
= toupper(*str
);
101 /***********************************************************************
102 * AnsiLower16 (USER.432)
104 SEGPTR WINAPI
AnsiLower16( SEGPTR strOrChar
)
106 /* I am not sure if the locale stuff works with toupper, but then again
107 I am not sure if the Linux libc locale stuffs works at all */
109 /* lowercase only one char if strOrChar < 0x10000 */
110 if (HIWORD(strOrChar
))
113 for (s
= PTR_SEG_TO_LIN( strOrChar
); *s
; s
++) *s
= tolower( *s
);
116 else return tolower((char)strOrChar
);
120 /***********************************************************************
121 * AnsiLowerBuff16 (USER.438)
123 UINT16 WINAPI
AnsiLowerBuff16( LPSTR str
, UINT16 len
)
125 UINT32 count
= len
? len
: 65536;
126 for (; count
; count
--, str
++) *str
= tolower(*str
);
131 /***********************************************************************
132 * AnsiNext16 (USER.472)
134 SEGPTR WINAPI
AnsiNext16(SEGPTR current
)
136 return (*(char *)PTR_SEG_TO_LIN(current
)) ? current
+ 1 : current
;
140 /***********************************************************************
141 * AnsiPrev16 (USER.473)
143 SEGPTR WINAPI
AnsiPrev16( SEGPTR start
, SEGPTR current
)
145 return (current
== start
) ? start
: current
- 1;
149 /***********************************************************************
150 * OutputDebugString16 (KERNEL.115)
152 void WINAPI
OutputDebugString16( LPCSTR str
)
155 char *p
, *buffer
= HeapAlloc( GetProcessHeap(), 0, strlen(str
)+2 );
157 for (p
= buffer
; *str
; str
++) if (*str
!= '\r') *p
++ = *str
;
159 if ((p
> buffer
) && (p
[-1] == '\n')) p
[1] = '\0'; /* Remove trailing \n */
160 module
= MODULE_GetModuleName( GetCurrentTask() );
161 fprintf( stderr
, "OutputDebugString: %s says '%s'\n",
162 module
? module
: "???", buffer
);
163 HeapFree( GetProcessHeap(), 0, buffer
);
167 /***********************************************************************
168 * OutputDebugString32A (KERNEL32
170 void WINAPI
OutputDebugString32A( LPCSTR str
)
172 OutputDebugString16( str
);
177 /***********************************************************************
178 * OutputDebugString32W (KERNEL32
180 void WINAPI
OutputDebugString32W( LPCWSTR str
)
182 LPSTR p
= HEAP_strdupWtoA( GetProcessHeap(), 0, str
);
183 OutputDebugString32A( p
);
184 HeapFree( GetProcessHeap(), 0, p
);
189 /***********************************************************************
190 * CharNext32A (USER32.28)
192 LPSTR WINAPI
CharNext32A( LPCSTR ptr
)
194 if (!*ptr
) return (LPSTR
)ptr
;
195 if (IsDBCSLeadByte32( *ptr
)) return (LPSTR
)(ptr
+ 2);
196 return (LPSTR
)(ptr
+ 1);
200 /***********************************************************************
201 * CharNextEx32A (USER32.29)
203 LPSTR WINAPI
CharNextEx32A( WORD codepage
, LPCSTR ptr
, DWORD flags
)
205 if (!*ptr
) return (LPSTR
)ptr
;
206 if (IsDBCSLeadByteEx( codepage
, *ptr
)) return (LPSTR
)(ptr
+ 2);
207 return (LPSTR
)(ptr
+ 1);
211 /***********************************************************************
212 * CharNextExW (USER32.30)
214 LPWSTR WINAPI
CharNextEx32W(WORD codepage
,LPCWSTR x
,DWORD flags
)
216 /* FIXME: add DBCS / codepage stuff */
217 if (*x
) return (LPWSTR
)(x
+1);
218 else return (LPWSTR
)x
;
221 /***********************************************************************
222 * CharNextW (USER32.31)
224 LPWSTR WINAPI
CharNext32W(LPCWSTR x
)
226 if (*x
) return (LPWSTR
)(x
+1);
227 else return (LPWSTR
)x
;
230 /***********************************************************************
231 * CharPrev32A (USER32.32)
233 LPSTR WINAPI
CharPrev32A( LPCSTR start
, LPCSTR ptr
)
235 while (*start
&& (start
< ptr
))
237 LPCSTR next
= CharNext32A( start
);
238 if (next
>= ptr
) break;
245 /***********************************************************************
246 * CharPrevEx32A (USER32.33)
248 LPSTR WINAPI
CharPrevEx32A( WORD codepage
, LPCSTR start
, LPCSTR ptr
, DWORD flags
)
250 while (*start
&& (start
< ptr
))
252 LPCSTR next
= CharNextEx32A( codepage
, start
, flags
);
253 if (next
> ptr
) break;
260 /***********************************************************************
261 * CharPrevExW (USER32.34)
263 LPWSTR WINAPI
CharPrevEx32W(WORD codepage
,LPCWSTR start
,LPCWSTR x
,DWORD flags
)
265 /* FIXME: add DBCS / codepage stuff */
266 if (x
>start
) return (LPWSTR
)(x
-1);
267 else return (LPWSTR
)x
;
270 /***********************************************************************
271 * CharPrevW (USER32.35)
273 LPWSTR WINAPI
CharPrev32W(LPCWSTR start
,LPCWSTR x
)
275 if (x
>start
) return (LPWSTR
)(x
-1);
276 else return (LPWSTR
)x
;
279 /***********************************************************************
280 * CharLowerA (USER32.24)
281 * FIXME: handle current locale
283 LPSTR WINAPI
CharLower32A(LPSTR x
)
297 else return (LPSTR
)tolower((char)(int)x
);
300 /***********************************************************************
301 * CharLowerBuffA (USER32.25)
302 * FIXME: handle current locale
304 DWORD WINAPI
CharLowerBuff32A(LPSTR x
,DWORD buflen
)
308 if (!x
) return 0; /* YES */
309 while (*x
&& (buflen
--))
318 /***********************************************************************
319 * CharLowerBuffW (USER32.26)
320 * FIXME: handle current locale
322 DWORD WINAPI
CharLowerBuff32W(LPWSTR x
,DWORD buflen
)
326 if (!x
) return 0; /* YES */
327 while (*x
&& (buflen
--))
336 /***********************************************************************
337 * CharLowerW (USER32.27)
338 * FIXME: handle current locale
340 LPWSTR WINAPI
CharLower32W(LPWSTR x
)
352 else return (LPWSTR
)towlower(LOWORD(x
));
355 /***********************************************************************
356 * CharUpper32A (USER32.40)
357 * FIXME: handle current locale
359 LPSTR WINAPI
CharUpper32A(LPSTR x
)
371 return (LPSTR
)toupper((char)(int)x
);
374 /***********************************************************************
375 * CharUpperBuffA (USER32.41)
376 * FIXME: handle current locale
378 DWORD WINAPI
CharUpperBuff32A(LPSTR x
,DWORD buflen
)
382 if (!x
) return 0; /* YES */
383 while (*x
&& (buflen
--))
392 /***********************************************************************
393 * CharUpperBuffW (USER32.42)
394 * FIXME: handle current locale
396 DWORD WINAPI
CharUpperBuff32W(LPWSTR x
,DWORD buflen
)
400 if (!x
) return 0; /* YES */
401 while (*x
&& (buflen
--))
410 /***********************************************************************
411 * CharUpperW (USER32.43)
412 * FIXME: handle current locale
414 LPWSTR WINAPI
CharUpper32W(LPWSTR x
)
426 else return (LPWSTR
)towupper(LOWORD(x
));
429 /***********************************************************************
430 * IsCharAlphaA (USER32.330)
431 * FIXME: handle current locale
433 BOOL32 WINAPI
IsCharAlpha32A(CHAR x
)
438 /***********************************************************************
439 * IsCharAlphaNumericA (USER32.331)
440 * FIXME: handle current locale
442 BOOL32 WINAPI
IsCharAlphaNumeric32A(CHAR x
)
447 /***********************************************************************
448 * IsCharAlphaNumericW (USER32.332)
449 * FIXME: handle current locale
451 BOOL32 WINAPI
IsCharAlphaNumeric32W(WCHAR x
)
456 /***********************************************************************
457 * IsCharAlphaW (USER32.333)
458 * FIXME: handle current locale
460 BOOL32 WINAPI
IsCharAlpha32W(WCHAR x
)
465 /***********************************************************************
466 * IsCharLower32A (USER32.334)
467 * FIXME: handle current locale
469 BOOL32 WINAPI
IsCharLower32A(CHAR x
)
474 /***********************************************************************
475 * IsCharLower32W (USER32.335)
476 * FIXME: handle current locale
478 BOOL32 WINAPI
IsCharLower32W(WCHAR x
)
483 /***********************************************************************
484 * IsCharUpper32A (USER32.336)
485 * FIXME: handle current locale
487 BOOL32 WINAPI
IsCharUpper32A(CHAR x
)
492 /***********************************************************************
493 * IsCharUpper32W (USER32.337)
494 * FIXME: handle current locale
496 BOOL32 WINAPI
IsCharUpper32W(WCHAR x
)
501 /***********************************************************************
502 * FormatMessage32A (KERNEL32.138)
503 * FIXME: missing wrap,FROM_SYSTEM message-loading,
505 DWORD WINAPI
FormatMessage32A(
512 LPDWORD args
/* va_list *args */
517 DWORD width
= dwFlags
& FORMAT_MESSAGE_MAX_WIDTH_MASK
;
518 DWORD nolinefeed
= 0;
520 dprintf_info(resource
,
521 "FormatMessage32A(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n",
522 dwFlags
,lpSource
,dwMessageId
,dwLanguageId
,lpBuffer
,nSize
,args
525 fprintf(stdnimp
," - line wrapping not supported.\n");
527 if (dwFlags
& FORMAT_MESSAGE_FROM_STRING
)
528 from
= HEAP_strdupA( GetProcessHeap(), 0, (LPSTR
)lpSource
);
529 if (dwFlags
& FORMAT_MESSAGE_FROM_SYSTEM
) {
530 from
= HeapAlloc( GetProcessHeap(),0,200 );
531 sprintf(from
,"Systemmessage, messageid = 0x%08lx\n",dwMessageId
);
533 if (dwFlags
& FORMAT_MESSAGE_FROM_HMODULE
) {
536 dwMessageId
&= 0xFFFF;
537 bufsize
=LoadMessage32A((HMODULE32
)lpSource
,dwMessageId
,dwLanguageId
,NULL
,100);
539 from
= HeapAlloc( GetProcessHeap(), 0, bufsize
+ 1 );
540 LoadMessage32A((HMODULE32
)lpSource
,dwMessageId
,dwLanguageId
,from
,bufsize
+1);
543 target
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, 100);
547 #define ADD_TO_T(c) \
549 if (t-target == talloced) {\
550 target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
551 t = target+talloced;\
560 char *fmtstr
,*sprintfbuf
,*x
,*lastf
;
571 case '1':case '2':case '3':case '4':case '5':
572 case '6':case '7':case '8':case '9':
575 case '0':case '1':case '2':case '3':
576 case '4':case '5':case '6':case '7':
579 insertnr
=insertnr
*10+*f
-'0';
588 if (NULL
!=(x
=strchr(f
,'!'))) {
590 fmtstr
=HeapAlloc(GetProcessHeap(),0,strlen(f
)+2);
591 sprintf(fmtstr
,"%%%s",f
);
594 fmtstr
=HeapAlloc(GetProcessHeap(),0,strlen(f
));
595 sprintf(fmtstr
,"%%%s",f
);
596 f
+=strlen(f
); /*at \0*/
599 fmtstr
=HEAP_strdupA(GetProcessHeap(),0,"%s");
601 if (dwFlags
& FORMAT_MESSAGE_ARGUMENT_ARRAY
)
602 argliststart
=args
+insertnr
-1;
604 argliststart
=(*(DWORD
**)args
)+insertnr
-1;
606 if (fmtstr
[strlen(fmtstr
)]=='s')
607 sprintfbuf
=HeapAlloc(GetProcessHeap(),0,strlen((LPSTR
)argliststart
[0])+1);
609 sprintfbuf
=HeapAlloc(GetProcessHeap(),0,100);
611 /* CMF - This makes a BIG assumption about va_list */
612 vsprintf(sprintfbuf
, fmtstr
, (va_list) argliststart
);
617 HeapFree(GetProcessHeap(),0,sprintfbuf
);
619 /* NULL args - copy formatstr
626 HeapFree(GetProcessHeap(),0,fmtstr
);
629 /* FIXME: perhaps add \r too? */
637 default:ADD_TO_T(*f
++)
647 if (!nolinefeed
&& t
[-1]!='\n')
649 talloced
= strlen(target
)+1;
650 if (nSize
&& talloced
<nSize
) {
651 target
= (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,target
,nSize
);
653 if (dwFlags
& FORMAT_MESSAGE_ALLOCATE_BUFFER
) {
654 /* nSize is the MINIMUM size */
655 *((LPVOID
*)lpBuffer
) = (LPVOID
)LocalAlloc32(GMEM_ZEROINIT
,talloced
);
656 memcpy(*(LPSTR
*)lpBuffer
,target
,talloced
);
658 strncpy(lpBuffer
,target
,nSize
);
659 HeapFree(GetProcessHeap(),0,target
);
660 if (from
) HeapFree(GetProcessHeap(),0,from
);
661 return (dwFlags
& FORMAT_MESSAGE_ALLOCATE_BUFFER
) ?
662 strlen(*(LPSTR
*)lpBuffer
):
668 /***********************************************************************
669 * FormatMessage32W (KERNEL32.138)
671 DWORD WINAPI
FormatMessage32W(
678 LPDWORD args
/* va_list *args */
683 DWORD width
= dwFlags
& FORMAT_MESSAGE_MAX_WIDTH_MASK
;
684 DWORD nolinefeed
= 0;
686 dprintf_info(resource
,
687 "FormatMessage32A(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n",
688 dwFlags
,lpSource
,dwMessageId
,dwLanguageId
,lpBuffer
,nSize
,args
691 fprintf(stdnimp
," - line wrapping not supported.\n");
693 if (dwFlags
& FORMAT_MESSAGE_FROM_STRING
)
694 from
= HEAP_strdupWtoA(GetProcessHeap(),0,(LPWSTR
)lpSource
);
695 if (dwFlags
& FORMAT_MESSAGE_FROM_SYSTEM
) {
696 /* gather information from system message tables ... */
697 from
= HeapAlloc( GetProcessHeap(),0,200 );
698 sprintf(from
,"Systemmessage, messageid = 0x%08lx\n",dwMessageId
);
700 if (dwFlags
& FORMAT_MESSAGE_FROM_HMODULE
) {
703 dwMessageId
&= 0xFFFF;
704 bufsize
=LoadMessage32A((HMODULE32
)lpSource
,dwMessageId
,dwLanguageId
,NULL
,100);
707 from
= HeapAlloc( GetProcessHeap(), 0, bufsize
+ 1 );
708 LoadMessage32A((HMODULE32
)lpSource
,dwMessageId
,dwLanguageId
,from
,bufsize
+1);
711 target
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, 100 );
715 #define ADD_TO_T(c) \
717 if (t-target == talloced) {\
718 target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
719 t = target+talloced;\
728 char *fmtstr
,*sprintfbuf
,*x
;
738 case '1':case '2':case '3':case '4':case '5':
739 case '6':case '7':case '8':case '9':
742 case '0':case '1':case '2':case '3':
743 case '4':case '5':case '6':case '7':
746 insertnr
=insertnr
*10+*f
-'0';
755 if (NULL
!=(x
=strchr(f
,'!')))
758 fmtstr
=HeapAlloc( GetProcessHeap(), 0, strlen(f
)+2);
759 sprintf(fmtstr
,"%%%s",f
);
762 fmtstr
=HeapAlloc(GetProcessHeap(),0,strlen(f
));
763 sprintf(fmtstr
,"%%%s",f
);
764 f
+=strlen(f
); /*at \0*/
767 fmtstr
=HEAP_strdupA( GetProcessHeap(),0,"%s");
768 if (dwFlags
& FORMAT_MESSAGE_ARGUMENT_ARRAY
)
769 argliststart
=args
+insertnr
-1;
771 argliststart
=(*(DWORD
**)args
)+insertnr
-1;
773 if (fmtstr
[strlen(fmtstr
)]=='s') {
776 xarr
[0]=(DWORD
)HEAP_strdupWtoA(GetProcessHeap(),0,(LPWSTR
)(*(argliststart
+0)));
777 /* possible invalid pointers */
778 xarr
[1]=*(argliststart
+1);
779 xarr
[2]=*(argliststart
+2);
780 sprintfbuf
=HeapAlloc(GetProcessHeap(),0,lstrlen32W((LPWSTR
)argliststart
[0])*2+1);
782 /* CMF - This makes a BIG assumption about va_list */
783 vsprintf(sprintfbuf
, fmtstr
, (va_list) xarr
);
785 sprintfbuf
=HeapAlloc(GetProcessHeap(),0,100);
787 /* CMF - This makes a BIG assumption about va_list */
788 vsprintf(sprintfbuf
, fmtstr
, (va_list) argliststart
);
794 HeapFree(GetProcessHeap(),0,sprintfbuf
);
795 HeapFree(GetProcessHeap(),0,fmtstr
);
798 /* FIXME: perhaps add \r too? */
806 default:ADD_TO_T(*f
++)
816 if (!nolinefeed
&& t
[-1]!='\n')
818 talloced
= strlen(target
)+1;
819 if (nSize
&& talloced
<nSize
)
820 target
= (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,target
,nSize
);
821 if (dwFlags
& FORMAT_MESSAGE_ALLOCATE_BUFFER
) {
822 /* nSize is the MINIMUM size */
823 *((LPVOID
*)lpBuffer
) = (LPVOID
)LocalAlloc32(GMEM_ZEROINIT
,talloced
*2+2);
824 lstrcpynAtoW(*(LPWSTR
*)lpBuffer
,target
,talloced
);
826 lstrcpynAtoW(lpBuffer
,target
,nSize
);
827 HeapFree(GetProcessHeap(),0,target
);
828 if (from
) HeapFree(GetProcessHeap(),0,from
);
829 return (dwFlags
& FORMAT_MESSAGE_ALLOCATE_BUFFER
) ?
830 lstrlen32W(*(LPWSTR
*)lpBuffer
):
831 lstrlen32W(lpBuffer
);