4 * Copyright 1993 Yngvi Sigurjonsson (yngvi@hafro.is)
5 * Copyright 1996 Marcus Meissner
15 #include "winnt.h" /* HEAP_ macros */
22 #define ToUpper(c) toupper(c)
23 #define ToLower(c) tolower(c)
26 /* Funny to divide them between user and kernel. */
28 /* IsCharAlpha USER 433 */
29 BOOL16 WINAPI
IsCharAlpha16(CHAR ch
)
31 return isalpha(ch
); /* This is probably not right for NLS */
34 /* IsCharAlphanumeric USER 434 */
35 BOOL16 WINAPI
IsCharAlphaNumeric16(CHAR ch
)
40 /* IsCharUpper USER 435 */
41 BOOL16 WINAPI
IsCharUpper16(CHAR ch
)
46 /* IsCharLower USER 436 */
47 BOOL16 WINAPI
IsCharLower16(CHAR ch
)
52 /***********************************************************************
53 * AnsiUpper16 (USER.431)
55 SEGPTR WINAPI
AnsiUpper16( SEGPTR strOrChar
)
57 /* I am not sure if the locale stuff works with toupper, but then again
58 I am not sure if the Linux libc locale stuffs works at all */
60 /* uppercase only one char if strOrChar < 0x10000 */
61 if (HIWORD(strOrChar
))
64 for (s
= PTR_SEG_TO_LIN(strOrChar
); *s
; s
++) *s
= toupper(*s
);
67 else return (SEGPTR
)ToUpper( (int)strOrChar
);
71 /***********************************************************************
72 * AnsiUpperBuff16 (USER.437)
74 UINT16 WINAPI
AnsiUpperBuff16( LPSTR str
, UINT16 len
)
76 UINT32 count
= len
? len
: 65536;
77 for (; count
; count
--, str
++) *str
= toupper(*str
);
81 /***********************************************************************
82 * AnsiLower16 (USER.432)
84 SEGPTR WINAPI
AnsiLower16( SEGPTR strOrChar
)
86 /* I am not sure if the locale stuff works with toupper, but then again
87 I am not sure if the Linux libc locale stuffs works at all */
89 /* lowercase only one char if strOrChar < 0x10000 */
90 if (HIWORD(strOrChar
))
93 for (s
= PTR_SEG_TO_LIN( strOrChar
); *s
; s
++) *s
= tolower( *s
);
96 else return (SEGPTR
)tolower( (int)strOrChar
);
100 /***********************************************************************
101 * AnsiLowerBuff16 (USER.438)
103 UINT16 WINAPI
AnsiLowerBuff16( LPSTR str
, UINT16 len
)
105 UINT32 count
= len
? len
: 65536;
106 for (; count
; count
--, str
++) *str
= tolower(*str
);
111 /***********************************************************************
112 * AnsiNext16 (USER.472)
114 SEGPTR WINAPI
AnsiNext16(SEGPTR current
)
116 return (*(char *)PTR_SEG_TO_LIN(current
)) ? current
+ 1 : current
;
120 /***********************************************************************
121 * AnsiPrev16 (USER.473)
123 SEGPTR WINAPI
AnsiPrev16( SEGPTR start
, SEGPTR current
)
125 return (current
== start
) ? start
: current
- 1;
129 /***********************************************************************
130 * OutputDebugString16 (KERNEL.115)
132 void WINAPI
OutputDebugString16( LPCSTR str
)
135 char *p
, *buffer
= HeapAlloc( GetProcessHeap(), 0, strlen(str
)+2 );
137 for (p
= buffer
; *str
; str
++) if (*str
!= '\r') *p
++ = *str
;
139 if ((p
> buffer
) && (p
[-1] == '\n')) p
[1] = '\0'; /* Remove trailing \n */
140 module
= MODULE_GetModuleName( GetCurrentTask() );
141 fprintf( stderr
, "OutputDebugString: %s says '%s'\n",
142 module
? module
: "???", buffer
);
143 HeapFree( GetProcessHeap(), 0, buffer
);
147 /***********************************************************************
148 * OutputDebugString32A (KERNEL32
150 void WINAPI
OutputDebugString32A( LPCSTR str
)
152 OutputDebugString16( str
);
157 /***********************************************************************
158 * OutputDebugString32W (KERNEL32
160 void WINAPI
OutputDebugString32W( LPCWSTR str
)
162 LPSTR p
= HEAP_strdupWtoA( GetProcessHeap(), 0, str
);
163 OutputDebugString32A( p
);
164 HeapFree( GetProcessHeap(), 0, p
);
169 /***********************************************************************
170 * CharNext32A (USER32.28)
172 LPSTR WINAPI
CharNext32A( LPCSTR ptr
)
174 if (!*ptr
) return (LPSTR
)ptr
;
175 if (IsDBCSLeadByte32( *ptr
)) return (LPSTR
)(ptr
+ 2);
176 return (LPSTR
)(ptr
+ 1);
180 /***********************************************************************
181 * CharNextEx32A (USER32.29)
183 LPSTR WINAPI
CharNextEx32A( WORD codepage
, LPCSTR ptr
, DWORD flags
)
185 if (!*ptr
) return (LPSTR
)ptr
;
186 if (IsDBCSLeadByteEx( codepage
, *ptr
)) return (LPSTR
)(ptr
+ 2);
187 return (LPSTR
)(ptr
+ 1);
191 /***********************************************************************
192 * CharNextExW (USER32.30)
194 LPWSTR WINAPI
CharNextEx32W(WORD codepage
,LPCWSTR x
,DWORD flags
)
196 /* FIXME: add DBCS / codepage stuff */
197 if (*x
) return (LPWSTR
)(x
+1);
198 else return (LPWSTR
)x
;
201 /***********************************************************************
202 * CharNextW (USER32.31)
204 LPWSTR WINAPI
CharNext32W(LPCWSTR x
)
206 if (*x
) return (LPWSTR
)(x
+1);
207 else return (LPWSTR
)x
;
210 /***********************************************************************
211 * CharPrev32A (USER32.32)
213 LPSTR WINAPI
CharPrev32A( LPCSTR start
, LPCSTR ptr
)
215 while (*start
&& (start
< ptr
))
217 LPCSTR next
= CharNext32A( start
);
218 if (next
>= ptr
) break;
225 /***********************************************************************
226 * CharPrevEx32A (USER32.33)
228 LPSTR WINAPI
CharPrevEx32A( WORD codepage
, LPCSTR start
, LPCSTR ptr
, DWORD flags
)
230 while (*start
&& (start
< ptr
))
232 LPCSTR next
= CharNextEx32A( codepage
, start
, flags
);
233 if (next
> ptr
) break;
240 /***********************************************************************
241 * CharPrevExW (USER32.34)
243 LPWSTR WINAPI
CharPrevEx32W(WORD codepage
,LPCWSTR start
,LPCWSTR x
,DWORD flags
)
245 /* FIXME: add DBCS / codepage stuff */
246 if (x
>start
) return (LPWSTR
)(x
-1);
247 else return (LPWSTR
)x
;
250 /***********************************************************************
251 * CharPrevW (USER32.35)
253 LPWSTR WINAPI
CharPrev32W(LPCWSTR start
,LPCWSTR x
)
255 if (x
>start
) return (LPWSTR
)(x
-1);
256 else return (LPWSTR
)x
;
259 /***********************************************************************
260 * CharLowerA (USER32.24)
261 * FIXME: handle current locale
263 LPSTR WINAPI
CharLower32A(LPSTR x
)
277 else return (LPSTR
)tolower(LOWORD(x
));
280 /***********************************************************************
281 * CharLowerBuffA (USER32.25)
282 * FIXME: handle current locale
284 DWORD WINAPI
CharLowerBuff32A(LPSTR x
,DWORD buflen
)
288 while (*x
&& (buflen
--))
297 /***********************************************************************
298 * CharLowerBuffW (USER32.26)
299 * FIXME: handle current locale
301 DWORD WINAPI
CharLowerBuff32W(LPWSTR x
,DWORD buflen
)
305 while (*x
&& (buflen
--))
314 /***********************************************************************
315 * CharLowerW (USER32.27)
316 * FIXME: handle current locale
318 LPWSTR WINAPI
CharLower32W(LPWSTR x
)
330 else return (LPWSTR
)tolower(LOWORD(x
));
333 /***********************************************************************
334 * CharUpper32A (USER32.40)
335 * FIXME: handle current locale
337 LPSTR WINAPI
CharUpper32A(LPSTR x
)
349 else return (LPSTR
)toupper(LOWORD(x
));
352 /***********************************************************************
353 * CharUpperBuffA (USER32.41)
354 * FIXME: handle current locale
356 DWORD WINAPI
CharUpperBuff32A(LPSTR x
,DWORD buflen
)
360 while (*x
&& (buflen
--))
369 /***********************************************************************
370 * CharUpperBuffW (USER32.42)
371 * FIXME: handle current locale
373 DWORD WINAPI
CharUpperBuff32W(LPWSTR x
,DWORD buflen
)
377 while (*x
&& (buflen
--))
386 /***********************************************************************
387 * CharUpperW (USER32.43)
388 * FIXME: handle current locale
390 LPWSTR WINAPI
CharUpper32W(LPWSTR x
)
402 else return (LPWSTR
)toupper(LOWORD(x
));
405 /***********************************************************************
406 * IsCharAlphaA (USER32.330)
407 * FIXME: handle current locale
409 BOOL32 WINAPI
IsCharAlpha32A(CHAR x
)
414 /***********************************************************************
415 * IsCharAlphaNumericA (USER32.331)
416 * FIXME: handle current locale
418 BOOL32 WINAPI
IsCharAlphaNumeric32A(CHAR x
)
423 /***********************************************************************
424 * IsCharAlphaNumericW (USER32.332)
425 * FIXME: handle current locale
427 BOOL32 WINAPI
IsCharAlphaNumeric32W(WCHAR x
)
432 /***********************************************************************
433 * IsCharAlphaW (USER32.333)
434 * FIXME: handle current locale
436 BOOL32 WINAPI
IsCharAlpha32W(WCHAR x
)
441 /***********************************************************************
442 * IsCharLower32A (USER32.334)
443 * FIXME: handle current locale
445 BOOL32 WINAPI
IsCharLower32A(CHAR x
)
450 /***********************************************************************
451 * IsCharLower32W (USER32.335)
452 * FIXME: handle current locale
454 BOOL32 WINAPI
IsCharLower32W(WCHAR x
)
459 /***********************************************************************
460 * IsCharUpper32A (USER32.336)
461 * FIXME: handle current locale
463 BOOL32 WINAPI
IsCharUpper32A(CHAR x
)
468 /***********************************************************************
469 * IsCharUpper32W (USER32.337)
470 * FIXME: handle current locale
472 BOOL32 WINAPI
IsCharUpper32W(WCHAR x
)
477 /***********************************************************************
478 * FormatMessage32A (KERNEL32.138)
479 * FIXME: missing wrap,FROM_SYSTEM message-loading,
481 DWORD WINAPI
FormatMessage32A(
488 LPDWORD args
/* va_list *args */
493 DWORD width
= dwFlags
& FORMAT_MESSAGE_MAX_WIDTH_MASK
;
494 DWORD nolinefeed
= 0;
496 dprintf_resource(stddeb
,
497 "FormatMessage32A(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n",
498 dwFlags
,lpSource
,dwMessageId
,dwLanguageId
,lpBuffer
,nSize
,args
501 fprintf(stdnimp
," - line wrapping not supported.\n");
503 if (dwFlags
& FORMAT_MESSAGE_FROM_STRING
)
504 from
= HEAP_strdupA( GetProcessHeap(), 0, (LPSTR
)lpSource
);
505 if (dwFlags
& FORMAT_MESSAGE_FROM_SYSTEM
) {
506 from
= HeapAlloc( GetProcessHeap(),0,200 );
507 sprintf(from
,"Systemmessage, messageid = 0x%08lx\n",dwMessageId
);
509 if (dwFlags
& FORMAT_MESSAGE_FROM_HMODULE
) {
512 dwMessageId
&= 0xFFFF;
513 bufsize
=LoadMessage32A(0,dwMessageId
,dwLanguageId
,NULL
,100);
515 from
= HeapAlloc( GetProcessHeap(), 0, bufsize
+ 1 );
516 LoadMessage32A(0,dwMessageId
,dwLanguageId
,from
,bufsize
+1);
519 target
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, 100);
523 #define ADD_TO_T(c) \
525 if (t-target == talloced) {\
526 target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
527 t = target+talloced;\
536 char *fmtstr
,*sprintfbuf
,*x
,*lastf
;
547 case '1':case '2':case '3':case '4':case '5':
548 case '6':case '7':case '8':case '9':
551 case '0':case '1':case '2':case '3':
552 case '4':case '5':case '6':case '7':
555 insertnr
=insertnr
*10+*f
-'0';
564 if (NULL
!=(x
=strchr(f
,'!'))) {
566 fmtstr
=HeapAlloc(GetProcessHeap(),0,strlen(f
)+2);
567 sprintf(fmtstr
,"%%%s",f
);
570 fmtstr
=HeapAlloc(GetProcessHeap(),0,strlen(f
));
571 sprintf(fmtstr
,"%%%s",f
);
572 f
+=strlen(f
); /*at \0*/
575 fmtstr
=HEAP_strdupA(GetProcessHeap(),0,"%s");
577 if (dwFlags
& FORMAT_MESSAGE_ARGUMENT_ARRAY
)
578 argliststart
=args
+insertnr
-1;
580 argliststart
=(*(DWORD
**)args
)+insertnr
-1;
582 if (fmtstr
[strlen(fmtstr
)]=='s')
583 sprintfbuf
=HeapAlloc(GetProcessHeap(),0,strlen((LPSTR
)argliststart
[0])+1);
585 sprintfbuf
=HeapAlloc(GetProcessHeap(),0,100);
587 /* CMF - This makes a BIG assumption about va_list */
588 vsprintf(sprintfbuf
, fmtstr
, (va_list) argliststart
);
593 HeapFree(GetProcessHeap(),0,sprintfbuf
);
595 /* NULL args - copy formatstr
602 HeapFree(GetProcessHeap(),0,fmtstr
);
605 /* FIXME: perhaps add \r too? */
613 default:ADD_TO_T(*f
++)
623 if (!nolinefeed
&& t
[-1]!='\n')
625 talloced
= strlen(target
)+1;
626 if (nSize
&& talloced
<nSize
) {
627 target
= (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,target
,nSize
);
629 if (dwFlags
& FORMAT_MESSAGE_ALLOCATE_BUFFER
) {
630 /* nSize is the MINIMUM size */
631 *((LPVOID
*)lpBuffer
) = (LPVOID
)LocalAlloc32(GMEM_ZEROINIT
,talloced
);
632 memcpy(*(LPSTR
*)lpBuffer
,target
,talloced
);
634 strncpy(lpBuffer
,target
,nSize
);
635 HeapFree(GetProcessHeap(),0,target
);
636 if (from
) HeapFree(GetProcessHeap(),0,from
);
637 return (dwFlags
& FORMAT_MESSAGE_ALLOCATE_BUFFER
) ?
638 strlen(*(LPSTR
*)lpBuffer
):
644 /***********************************************************************
645 * FormatMessage32W (KERNEL32.138)
647 DWORD WINAPI
FormatMessage32W(
654 LPDWORD args
/* va_list *args */
659 DWORD width
= dwFlags
& FORMAT_MESSAGE_MAX_WIDTH_MASK
;
660 DWORD nolinefeed
= 0;
662 dprintf_resource(stddeb
,
663 "FormatMessage32A(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n",
664 dwFlags
,lpSource
,dwMessageId
,dwLanguageId
,lpBuffer
,nSize
,args
667 fprintf(stdnimp
," - line wrapping not supported.\n");
669 if (dwFlags
& FORMAT_MESSAGE_FROM_STRING
)
670 from
= HEAP_strdupWtoA(GetProcessHeap(),0,(LPWSTR
)lpSource
);
671 if (dwFlags
& FORMAT_MESSAGE_FROM_SYSTEM
) {
672 /* gather information from system message tables ... */
673 from
= HeapAlloc( GetProcessHeap(),0,200 );
674 sprintf(from
,"Systemmessage, messageid = 0x%08lx\n",dwMessageId
);
676 if (dwFlags
& FORMAT_MESSAGE_FROM_HMODULE
) {
679 dwMessageId
&= 0xFFFF;
680 bufsize
=LoadMessage32A(0,dwMessageId
,dwLanguageId
,NULL
,100);
683 from
= HeapAlloc( GetProcessHeap(), 0, bufsize
+ 1 );
684 LoadMessage32A(0,dwMessageId
,dwLanguageId
,from
,bufsize
+1);
687 target
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, 100 );
691 #define ADD_TO_T(c) \
693 if (t-target == talloced) {\
694 target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
695 t = target+talloced;\
704 char *fmtstr
,*sprintfbuf
,*x
;
714 case '1':case '2':case '3':case '4':case '5':
715 case '6':case '7':case '8':case '9':
718 case '0':case '1':case '2':case '3':
719 case '4':case '5':case '6':case '7':
722 insertnr
=insertnr
*10+*f
-'0';
731 if (NULL
!=(x
=strchr(f
,'!')))
734 fmtstr
=HeapAlloc( GetProcessHeap(), 0, strlen(f
)+2);
735 sprintf(fmtstr
,"%%%s",f
);
738 fmtstr
=HeapAlloc(GetProcessHeap(),0,strlen(f
));
739 sprintf(fmtstr
,"%%%s",f
);
740 f
+=strlen(f
); /*at \0*/
743 fmtstr
=HEAP_strdupA( GetProcessHeap(),0,"%s");
744 if (dwFlags
& FORMAT_MESSAGE_ARGUMENT_ARRAY
)
745 argliststart
=args
+insertnr
-1;
747 argliststart
=(*(DWORD
**)args
)+insertnr
-1;
749 if (fmtstr
[strlen(fmtstr
)]=='s') {
752 xarr
[0]=(DWORD
)HEAP_strdupWtoA(GetProcessHeap(),0,(LPWSTR
)(*(argliststart
+0)));
753 /* possible invalid pointers */
754 xarr
[1]=*(argliststart
+1);
755 xarr
[2]=*(argliststart
+2);
756 sprintfbuf
=HeapAlloc(GetProcessHeap(),0,lstrlen32W((LPWSTR
)argliststart
[0])*2+1);
758 /* CMF - This makes a BIG assumption about va_list */
759 vsprintf(sprintfbuf
, fmtstr
, (va_list) xarr
);
761 sprintfbuf
=HeapAlloc(GetProcessHeap(),0,100);
763 /* CMF - This makes a BIG assumption about va_list */
764 vsprintf(sprintfbuf
, fmtstr
, (va_list) argliststart
);
770 HeapFree(GetProcessHeap(),0,sprintfbuf
);
771 HeapFree(GetProcessHeap(),0,fmtstr
);
774 /* FIXME: perhaps add \r too? */
782 default:ADD_TO_T(*f
++)
792 if (!nolinefeed
&& t
[-1]!='\n')
794 talloced
= strlen(target
)+1;
795 if (nSize
&& talloced
<nSize
)
796 target
= (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,target
,nSize
);
797 if (dwFlags
& FORMAT_MESSAGE_ALLOCATE_BUFFER
) {
798 /* nSize is the MINIMUM size */
799 *((LPVOID
*)lpBuffer
) = (LPVOID
)LocalAlloc32(GMEM_ZEROINIT
,talloced
*2+2);
800 lstrcpynAtoW(*(LPWSTR
*)lpBuffer
,target
,talloced
);
802 lstrcpynAtoW(lpBuffer
,target
,nSize
);
803 HeapFree(GetProcessHeap(),0,target
);
804 if (from
) HeapFree(GetProcessHeap(),0,from
);
805 return (dwFlags
& FORMAT_MESSAGE_ALLOCATE_BUFFER
) ?
806 lstrlen32W(*(LPWSTR
*)lpBuffer
):
807 lstrlen32W(lpBuffer
);