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(