4 * Copyright 1993 Yngvi Sigurjonsson (yngvi@hafro.is)
5 * Copyright 1996 Marcus Meissner
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
IsCharAlpha16(CHAR ch
)
31 return isalpha(ch
); /* This is probably not right for NLS */
34 /* IsCharAlphanumeric USER 434 */
35 BOOL16
IsCharAlphanumeric16(CHAR ch
)
40 /* IsCharUpper USER 435 */
41 BOOL16
IsCharUpper16(CHAR ch
)
46 /* IsCharLower USER 436 */
47 BOOL16
IsCharLower16(CHAR ch
)
52 /***********************************************************************
53 * AnsiUpper (USER.431)
57 SEGPTR
WIN16_AnsiUpper( SEGPTR strOrChar
)
59 /* I am not sure if the locale stuff works with toupper, but then again
60 I am not sure if the Linux libc locale stuffs works at all */
62 /* uppercase only one char if strOrChar < 0x10000 */
63 if (HIWORD(strOrChar
))
65 char *s
= PTR_SEG_TO_LIN(strOrChar
);
72 else return (SEGPTR
)ToUpper( (int)strOrChar
);
76 LPSTR
AnsiUpper(LPSTR strOrChar
)
79 /* I am not sure if the locale stuff works with toupper, but then again
80 I am not sure if the Linux libc locale stuffs works at all */
90 /***********************************************************************
91 * AnsiUpperBuff (USER.437)
93 UINT
AnsiUpperBuff(LPSTR str
,UINT len
)
96 len
=(len
==0)?65536:len
;
99 str
[i
]=toupper(str
[i
]);
103 /***********************************************************************
104 * AnsiLower (USER.432)
108 SEGPTR
WIN16_AnsiLower(SEGPTR strOrChar
)
110 /* I am not sure if the locale stuff works with toupper, but then again
111 I am not sure if the Linux libc locale stuffs works at all */
113 /* lowercase only one char if strOrChar < 0x10000 */
114 if (HIWORD(strOrChar
))
116 char *s
= PTR_SEG_TO_LIN( strOrChar
);
123 else return (SEGPTR
)ToLower( (int)strOrChar
);
127 LPSTR
AnsiLower(LPSTR strOrChar
)
130 /* I am not sure if the locale stuff works with toupper, but then again
131 I am not sure if the Linux libc locale stuffs works at all */
141 /***********************************************************************
142 * AnsiLowerBuff (USER.438)
144 UINT
AnsiLowerBuff(LPSTR str
,UINT len
)
147 len
=(len
==0)?65536:len
;
151 str
[i
]=tolower(str
[i
]);
157 /* AnsiNext USER.472 */
158 SEGPTR
AnsiNext(SEGPTR current
)
160 return (*(char *)PTR_SEG_TO_LIN(current
)) ? current
+ 1 : current
;
163 /* AnsiPrev USER.473 */
164 SEGPTR
AnsiPrev( SEGPTR start
, SEGPTR current
)
166 return (current
==start
)?start
:current
-1;
170 /***********************************************************************
171 * OutputDebugString (KERNEL.115)
173 void OutputDebugString( LPCSTR str
)
176 char *p
, *buffer
= xmalloc( strlen(str
)+1 );
178 for (p
= buffer
; *str
; str
++) if (*str
!= '\r') *p
++ = *str
;
180 if ((p
> buffer
) && (p
[-1] == '\n')) p
[1] = '\0'; /* Remove trailing \n */
181 module
= MODULE_GetModuleName( GetExePtr(GetCurrentTask()) );
182 fprintf( stderr
, "OutputDebugString: %s says '%s'\n",
183 module
? module
: "???", buffer
);
187 /***********************************************************************
188 * CharNextA (USER32.28)
190 LPSTR
CharNext32A(LPCSTR x
)
192 if (*x
) return (LPSTR
)(x
+1);
193 else return (LPSTR
)x
;
196 /***********************************************************************
197 * CharNextExA (USER32.29)
199 LPSTR
CharNextEx32A(WORD codepage
,LPCSTR x
,DWORD flags
)
201 /* FIXME: add DBCS / codepage stuff */
202 if (*x
) return (LPSTR
)(x
+1);
203 else return (LPSTR
)x
;
206 /***********************************************************************
207 * CharNextExW (USER32.30)
209 LPWSTR
CharNextEx32W(WORD codepage
,LPCWSTR x
,DWORD flags
)
211 /* FIXME: add DBCS / codepage stuff */
212 if (*x
) return (LPWSTR
)(x
+1);
213 else return (LPWSTR
)x
;
216 /***********************************************************************
217 * CharNextW (USER32.31)
219 LPWSTR
CharNext32W(LPCWSTR x
)
221 if (*x
) return (LPWSTR
)(x
+1);
222 else return (LPWSTR
)x
;
225 /***********************************************************************
226 * CharPrevA (USER32.32)
228 LPSTR
CharPrev32A(LPCSTR start
,LPCSTR x
)
230 if (x
>start
) return (LPSTR
)(x
-1);
231 else return (LPSTR
)x
;
234 /***********************************************************************
235 * CharPrevExA (USER32.33)
237 LPSTR
CharPrevEx32A(WORD codepage
,LPCSTR start
,LPCSTR x
,DWORD flags
)
239 /* FIXME: add DBCS / codepage stuff */
240 if (x
>start
) return (LPSTR
)(x
-1);
241 else return (LPSTR
)x
;
244 /***********************************************************************
245 * CharPrevExW (USER32.34)
247 LPWSTR
CharPrevEx32W(WORD codepage
,LPCWSTR start
,LPCWSTR x
,DWORD flags
)
249 /* FIXME: add DBCS / codepage stuff */
250 if (x
>start
) return (LPWSTR
)(x
-1);
251 else return (LPWSTR
)x
;
254 /***********************************************************************
255 * CharPrevW (USER32.35)
257 LPWSTR
CharPrev32W(LPCWSTR start
,LPCWSTR x
)
259 if (x
>start
) return (LPWSTR
)(x
-1);
260 else return (LPWSTR
)x
;
263 /***********************************************************************
264 * CharLowerA (USER32.24)
265 * FIXME: handle current locale
267 LPSTR
CharLower32A(LPSTR x
)
281 else return (LPSTR
)tolower(LOWORD(x
));
284 /***********************************************************************
285 * CharLowerBuffA (USER32.25)
286 * FIXME: handle current locale
288 DWORD
CharLowerBuff32A(LPSTR x
,DWORD buflen
)
292 while (*x
&& (buflen
--))
301 /***********************************************************************
302 * CharLowerBuffW (USER32.26)
303 * FIXME: handle current locale
305 DWORD
CharLowerBuff32W(LPWSTR x
,DWORD buflen
)
309 while (*x
&& (buflen
--))
318 /***********************************************************************
319 * CharLowerW (USER32.27)
320 * FIXME: handle current locale
322 LPWSTR
CharLower32W(LPWSTR x
)
334 else return (LPWSTR
)tolower(LOWORD(x
));
337 /***********************************************************************
338 * CharUpperA (USER32.40)
339 * FIXME: handle current locale
341 LPSTR
CharUpper32A(LPSTR x
)
353 else return (LPSTR
)toupper(LOWORD(x
));
356 /***********************************************************************
357 * CharUpperBuffA (USER32.41)
358 * FIXME: handle current locale
360 DWORD
CharUpperBuff32A(LPSTR x
,DWORD buflen
)
364 while (*x
&& (buflen
--))
373 /***********************************************************************
374 * CharUpperBuffW (USER32.42)
375 * FIXME: handle current locale
377 DWORD
CharUpperBuff32W(LPWSTR x
,DWORD buflen
)
381 while (*x
&& (buflen
--))
390 /***********************************************************************
391 * CharUpperW (USER32.43)
392 * FIXME: handle current locale
394 LPWSTR
CharUpper32W(LPWSTR x
)
406 else return (LPWSTR
)toupper(LOWORD(x
));
409 /***********************************************************************
410 * IsCharAlphaA (USER32.330)
411 * FIXME: handle current locale
413 BOOL32
IsCharAlpha32A(CHAR x
)
418 /***********************************************************************
419 * IsCharAlphaNumericA (USER32.331)
420 * FIXME: handle current locale
422 BOOL32
IsCharAlphaNumeric32A(CHAR x
)
427 /***********************************************************************
428 * IsCharAlphaNumericW (USER32.332)
429 * FIXME: handle current locale
431 BOOL32
IsCharAlphaNumeric32W(WCHAR x
)
436 /***********************************************************************
437 * IsCharAlphaW (USER32.333)
438 * FIXME: handle current locale
440 BOOL32
IsCharAlpha32W(WCHAR x
)
445 /***********************************************************************
446 * IsCharLower32A (USER32.334)
447 * FIXME: handle current locale
449 BOOL32
IsCharLower32A(CHAR x
)
454 /***********************************************************************
455 * IsCharLower32W (USER32.335)
456 * FIXME: handle current locale
458 BOOL32
IsCharLower32W(WCHAR x
)
463 /***********************************************************************
464 * IsCharUpper32A (USER32.336)
465 * FIXME: handle current locale
467 BOOL32
IsCharUpper32A(CHAR x
)
472 /***********************************************************************
473 * IsCharUpper32W (USER32.337)
474 * FIXME: handle current locale
476 BOOL32
IsCharUpper32W(WCHAR x
)
481 /***********************************************************************
482 * FormatMessageA (KERNEL32.138) Library Version
483 * FIXME: missing wrap,FROM_SYSTEM message-loading,
493 LPDWORD args
/* va_list *args */
498 DWORD width
= dwFlags
& FORMAT_MESSAGE_MAX_WIDTH_MASK
;
499 DWORD nolinefeed
= 0;
501 dprintf_resource(stddeb
,
502 "FormatMessage32A(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n",
503 dwFlags
,lpSource
,dwMessageId
,dwLanguageId
,lpBuffer
,nSize
,args
506 fprintf(stdnimp
," - line wrapping not supported.\n");
508 if (dwFlags
& FORMAT_MESSAGE_FROM_STRING
)
509 from
= xstrdup((LPSTR
)lpSource
);
510 if (dwFlags
& FORMAT_MESSAGE_FROM_SYSTEM
) {
511 /* gather information from system message tables ... */
512 fprintf(stdnimp
," - FORMAT_MESSAGE_FROM_SYSTEM not implemented.\n");
514 if (dwFlags
& FORMAT_MESSAGE_FROM_HMODULE
) {
517 dwMessageId
&= 0xFFFF;
518 bufsize
=LoadMessage32A(0,dwMessageId
,dwLanguageId
,NULL
,100);
520 from
= (char*)xmalloc(bufsize
+1);
521 LoadMessage32A(0,dwMessageId
,dwLanguageId
,from
,bufsize
+1);
524 target
= (char*)xmalloc(100);
529 #define ADD_TO_T(c) \
531 if (t-target == talloced) {\
532 target = (char*)xrealloc(target,talloced*2);\
533 t = target+talloced;\
542 char *fmtstr
,*sprintfbuf
,*x
;
552 case '1':case '2':case '3':case '4':case '5':
553 case '6':case '7':case '8':case '9':
556 case '0':case '1':case '2':case '3':
557 case '4':case '5':case '6':case '7':
560 insertnr
=insertnr
*10+*f
-'0';
569 if (NULL
!=(x
=strchr(f
,'!'))) {
571 fmtstr
=(char*)xmalloc(strlen(f
)+2);
572 sprintf(fmtstr
,"%%%s",f
);
577 if (dwFlags
& FORMAT_MESSAGE_ARGUMENT_ARRAY
)
578 argliststart
=args
+insertnr
-1;
580 /* FIXME: not sure that this is
581 * correct for unix-c-varargs.
583 argliststart
=((DWORD
*)&args
)+insertnr
-1;
585 if (fmtstr
[strlen(fmtstr
)]=='s')
586 sprintfbuf
=(char*)xmalloc(strlen((LPSTR
)argliststart
[0])+1);
588 sprintfbuf
=(char*)xmalloc(100);
589 vsprintf(sprintfbuf
,fmtstr
,argliststart
);
601 default:ADD_TO_T(*f
++)
611 if (!nolinefeed
&& t
[-1]!='\n')
613 talloced
= strlen(target
)+1;
614 if (nSize
&& talloced
<nSize
) {
615 target
= (char*)xrealloc(target
,nSize
);
617 if (dwFlags
& FORMAT_MESSAGE_ALLOCATE_BUFFER
) {
618 /* nSize is the MINIMUM size */
619 *((LPVOID
*)lpBuffer
) = (LPVOID
)LocalAlloc32(GMEM_ZEROINIT
,talloced
);
620 memcpy(*(LPSTR
*)lpBuffer
,target
,talloced
);
622 strncpy(lpBuffer
,target
,nSize
);
624 if (from
) free(from
);
625 return (dwFlags
& FORMAT_MESSAGE_ALLOCATE_BUFFER
) ?
626 strlen(*(LPSTR
*)lpBuffer
):
630 /***********************************************************************
631 * FormatMessageA (KERNEL32.138) Emulator Version
634 WIN32_FormatMessage32A(DWORD
*args
) {
635 DWORD dwFlags
= args
[0];
636 LPCVOID lpSource
= (LPCVOID
)args
[1];
637 DWORD dwMessageId
= args
[2];
638 DWORD dwLanguageId
= args
[3];
639 LPSTR lpBuffer
= (LPSTR
)args
[4];
640 DWORD nSize
= args
[5];
643 /* convert possible varargs to an argument array look-a-like */
645 if (dwFlags
& FORMAT_MESSAGE_ARGUMENT_ARRAY
) {
646 xargs
=(DWORD
*)args
[6];
648 /* args[6] is a pointer to a pointer to the start of
649 * a list of arguments.
652 xargs
=(DWORD
*)(((DWORD
*)args
[6])[0]);
655 dwFlags
|=FORMAT_MESSAGE_ARGUMENT_ARRAY
;
657 return FormatMessage32A(
676 LPDWORD args
/* va_list *args */
681 DWORD width
= dwFlags
& FORMAT_MESSAGE_MAX_WIDTH_MASK
;
682 DWORD nolinefeed
= 0;
684 dprintf_resource(stddeb
,
685 "FormatMessage32A(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n",
686 dwFlags
,lpSource
,dwMessageId
,dwLanguageId
,lpBuffer
,nSize
,args
689 fprintf(stdnimp
," - line wrapping not supported.\n");
691 if (dwFlags
& FORMAT_MESSAGE_FROM_STRING
)
692 from
= STRING32_DupUniToAnsi((LPWSTR
)lpSource
);
693 if (dwFlags
& FORMAT_MESSAGE_FROM_SYSTEM
) {
694 /* gather information from system message tables ... */
695 fprintf(stdnimp
," - FORMAT_MESSAGE_FROM_SYSTEM not implemented.\n");
697 if (dwFlags
& FORMAT_MESSAGE_FROM_HMODULE
) {
700 dwMessageId
&= 0xFFFF;
701 bufsize
=LoadMessage32A(0,dwMessageId
,dwLanguageId
,NULL
,100);
703 from
= (char*)xmalloc(bufsize
+1);
704 LoadMessage32A(0,dwMessageId
,dwLanguageId
,from
,bufsize
+1);
707 target
= (char*)xmalloc(100);
712 #define ADD_TO_T(c) \
714 if (t-target == talloced) {\
715 target = (char*)xrealloc(target,talloced*2);\
716 t = target+talloced;\
725 char *fmtstr
,*sprintfbuf
,*x
;
735 case '1':case '2':case '3':case '4':case '5':
736 case '6':case '7':case '8':case '9':
739 case '0':case '1':case '2':case '3':
740 case '4':case '5':case '6':case '7':
743 insertnr
=insertnr
*10+*f
-'0';
752 if (NULL
!=(x
=strchr(f
,'!'))) {
754 fmtstr
=(char*)xmalloc(strlen(f
)+2);
755 sprintf(fmtstr
,"%%%s",f
);
760 if (dwFlags
& FORMAT_MESSAGE_ARGUMENT_ARRAY
)
761 argliststart
=args
+insertnr
-1;
763 /* FIXME: not sure that this is
764 * correct for unix-c-varargs.
766 argliststart
=((DWORD
*)&args
)+insertnr
-1;
768 if (fmtstr
[strlen(fmtstr
)]=='s') {
771 xarr
[0]=(DWORD
)STRING32_DupUniToAnsi((LPWSTR
)(*(argliststart
+0)));
772 /* possible invalid pointers */
773 xarr
[1]=*(argliststart
+1);
774 xarr
[2]=*(argliststart
+2);
775 sprintfbuf
=(char*)xmalloc(lstrlen32W((LPWSTR
)argliststart
[0])*2+1);
776 vsprintf(sprintfbuf
,fmtstr
,xarr
);
778 sprintfbuf
=(char*)xmalloc(100);
779 vsprintf(sprintfbuf
,fmtstr
,argliststart
);
792 default:ADD_TO_T(*f
++)
802 if (!nolinefeed
&& t
[-1]!='\n')
804 talloced
= strlen(target
)+1;
805 if (nSize
&& talloced
<nSize
)
806 target
= (char*)xrealloc(target
,nSize
);
807 if (dwFlags
& FORMAT_MESSAGE_ALLOCATE_BUFFER
) {
808 /* nSize is the MINIMUM size */
809 *((LPVOID
*)lpBuffer
) = (LPVOID
)LocalAlloc32(GMEM_ZEROINIT
,talloced
*2+2);
810 lstrcpynAtoW(*(LPWSTR
*)lpBuffer
,target
,talloced
);
812 lstrcpynAtoW(lpBuffer
,target
,nSize
);
814 if (from
) free(from
);
815 return (dwFlags
& FORMAT_MESSAGE_ALLOCATE_BUFFER
) ?
816 lstrlen32W(*(LPWSTR
*)lpBuffer
):
817 lstrlen32W(lpBuffer
);
820 /***********************************************************************
821 * FormatMessageA (KERNEL32.138) Emulator Version
824 WIN32_FormatMessage32W(DWORD
*args
) {
825 DWORD dwFlags
= args
[0];
826 LPCVOID lpSource
= (LPCVOID
)args
[1];
827 DWORD dwMessageId
= args
[2];
828 DWORD dwLanguageId
= args
[3];
829 LPWSTR lpBuffer
= (LPWSTR
)args
[4];
830 DWORD nSize
= args
[5];
833 /* convert possible varargs to an argument array look-a-like */
835 if (dwFlags
& FORMAT_MESSAGE_ARGUMENT_ARRAY
) {
836 xargs
=(DWORD
*)args
[6];
838 /* args[6] is a pointer to a pointer to the start of
839 * a list of arguments.
842 xargs
=(DWORD
*)(((DWORD
*)args
[6])[0]);
845 dwFlags
|=FORMAT_MESSAGE_ARGUMENT_ARRAY
;
847 return FormatMessage32W(