diff --git a/lib/libc/mingw/crt/cinitexe.c b/lib/libc/mingw/crt/cinitexe.c index ee441ed77f..9e6931c4fc 100644 --- a/lib/libc/mingw/crt/cinitexe.c +++ b/lib/libc/mingw/crt/cinitexe.c @@ -1,13 +1,12 @@ #include #include +#include #ifdef _MSC_VER #pragma comment(linker, "/merge:.CRT=.rdata") #endif -typedef void (__cdecl *_PVFV)(void); - -_CRTALLOC(".CRT$XIA") _PVFV __xi_a[] = { NULL }; -_CRTALLOC(".CRT$XIZ") _PVFV __xi_z[] = { NULL }; +_CRTALLOC(".CRT$XIA") _PIFV __xi_a[] = { NULL }; +_CRTALLOC(".CRT$XIZ") _PIFV __xi_z[] = { NULL }; _CRTALLOC(".CRT$XCA") _PVFV __xc_a[] = { NULL }; _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[] = { NULL }; diff --git a/lib/libc/mingw/crt/crt_handler.c b/lib/libc/mingw/crt/crt_handler.c index c49a2b3b57..6e0f85af56 100644 --- a/lib/libc/mingw/crt/crt_handler.c +++ b/lib/libc/mingw/crt/crt_handler.c @@ -51,10 +51,6 @@ __mingw_init_ehandler (void) if (_FindPESectionByName (".pdata") != NULL) return 1; - /* Allocate # of e tables and entries. */ - memset (emu_pdata, 0, sizeof (RUNTIME_FUNCTION) * MAX_PDATA_ENTRIES); - memset (emu_xdata, 0, sizeof (UNWIND_INFO) * MAX_PDATA_ENTRIES); - e = 0; /* Fill tables and entries. */ while (e < MAX_PDATA_ENTRIES && (pSec = _FindPESectionExec (e)) != NULL) diff --git a/lib/libc/mingw/crt/crtdll.c b/lib/libc/mingw/crt/crtdll.c index d08d2a81f0..90da38e604 100644 --- a/lib/libc/mingw/crt/crtdll.c +++ b/lib/libc/mingw/crt/crtdll.c @@ -97,7 +97,8 @@ WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) { __native_startup_state = __initializing; - _initterm ((_PVFV *) (void *) __xi_a, (_PVFV *) (void *) __xi_z); + if (_initterm_e (__xi_a, __xi_z) != 0) + return FALSE; } if (__native_startup_state == __initializing) { @@ -147,15 +148,15 @@ WINBOOL WINAPI DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) { __mingw_app_type = 0; - if (dwReason == DLL_PROCESS_ATTACH) - { -#if defined(__x86_64__) && !defined(__SEH__) - __mingw_init_ehandler (); -#endif - } return __DllMainCRTStartup (hDllHandle, dwReason, lpreserved); } +static +#if defined(__i386__) || defined(_X86_) +/* We need to make sure that we align the stack to 16 bytes for the sake of SSE + opts in DllMain/DllEntryPoint or in functions called from DllMain/DllEntryPoint. */ +__attribute__((force_align_arg_pointer)) +#endif __declspec(noinline) WINBOOL __DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) { @@ -168,6 +169,12 @@ __DllMainCRTStartup (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved) goto i__leave; } _pei386_runtime_relocator (); + +#if defined(__x86_64__) && !defined(__SEH__) + if (dwReason == DLL_PROCESS_ATTACH) + __mingw_init_ehandler (); +#endif + if (dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH) { retcode = _CRT_INIT (hDllHandle, dwReason, lpreserved); diff --git a/lib/libc/mingw/crt/crtexe.c b/lib/libc/mingw/crt/crtexe.c index cdf5dcd258..328cc305b9 100644 --- a/lib/libc/mingw/crt/crtexe.c +++ b/lib/libc/mingw/crt/crtexe.c @@ -58,11 +58,9 @@ extern void __main(void); static _TCHAR **argv; static _TCHAR **envp; -static int argret; static int mainret=0; static int managedapp; static int has_cctor = 0; -static _startupinfo startinfo; extern LPTOP_LEVEL_EXCEPTION_FILTER __mingw_oldexcpt_handler; extern void _pei386_runtime_relocator (void); @@ -97,6 +95,7 @@ __mingw_invalidParameterHandler (const wchar_t * __UNUSED_PARAM_1(expression), static int __cdecl pre_c_init (void) { + int ret; managedapp = check_managed_app (); if (__mingw_app_type) __set_app_type(_GUI_APP); @@ -107,10 +106,12 @@ pre_c_init (void) * __p__commode() = _commode; #ifdef _UNICODE - _wsetargv(); + ret = _wsetargv(); #else - _setargv(); + ret = _setargv(); #endif + if (ret < 0) + _amsg_exit(8); /* _RT_SPACEARG */ if (_MINGW_INSTALL_DEBUG_MATHERR == 1) { __setusermatherr (_matherr); @@ -125,6 +126,9 @@ pre_c_init (void) static void __cdecl pre_cpp_init (void) { + _startupinfo startinfo; + int argret; + startinfo.newmode = _newmode; #ifdef _UNICODE @@ -132,6 +136,8 @@ pre_cpp_init (void) #else argret = __getmainargs(&argc,&argv,&envp,_dowildcard,&startinfo); #endif + if (argret < 0) + _amsg_exit(8); /* _RT_SPACEARG */ } static int __tmainCRTStartup (void); @@ -197,7 +203,7 @@ int mainCRTStartup (void) static #if defined(__i386__) || defined(_X86_) /* We need to make sure that we align the stack to 16 bytes for the sake of SSE - opts in main or in functions called main. */ + opts in main or in functions called from main. */ __attribute__((force_align_arg_pointer)) #endif __declspec(noinline) int @@ -223,7 +229,8 @@ __tmainCRTStartup (void) else if (__native_startup_state == __uninitialized) { __native_startup_state = __initializing; - _initterm ((_PVFV *)(void *)__xi_a, (_PVFV *)(void *) __xi_z); + if (_initterm_e (__xi_a, __xi_z) != 0) + return 255; } else has_cctor = 1; diff --git a/lib/libc/mingw/crt/tlssup.c b/lib/libc/mingw/crt/tlssup.c index 3ff03971e9..de546dcb4d 100644 --- a/lib/libc/mingw/crt/tlssup.c +++ b/lib/libc/mingw/crt/tlssup.c @@ -32,6 +32,7 @@ typedef struct TlsDtorNode { _PVFV funcs[FUNCS_PER_NODE]; } TlsDtorNode; +__attribute__((used)) ULONG _tls_index = 0; /* TLS raw template data start and end. diff --git a/lib/libc/mingw/def-include/crt-aliases.def.in b/lib/libc/mingw/def-include/crt-aliases.def.in index 3fb824c654..be873c0df3 100644 --- a/lib/libc/mingw/def-include/crt-aliases.def.in +++ b/lib/libc/mingw/def-include/crt-aliases.def.in @@ -231,6 +231,12 @@ ADD_UNDERSCORE(y1) ADD_UNDERSCORE(yn) ; This is list of symbol aliases for C95 functions +#ifdef WITH_GET_PUT_WCHAR_ALIASES +getwc == fgetwc +getwchar == _fgetwchar +putwc == fputwc +putwchar == _fputwchar +#endif #ifdef USE_WCSTOK_S_FOR_WCSTOK wcstok == wcstok_s #endif @@ -531,24 +537,22 @@ __ms_printf == printf __ms_scanf == scanf __ms_sprintf == sprintf __ms_sscanf == sscanf -#ifdef PRE_C95_SWPRINTF -__ms_swprintf == swprintf -#else -__ms_swprintf == _swprintf -#endif __ms_swscanf == swscanf __ms_vfprintf == vfprintf __ms_vfwprintf == vfwprintf __ms_vprintf == vprintf __ms_vsprintf == vsprintf -#ifdef PRE_C95_SWPRINTF -__ms_vswprintf == vswprintf -#else -__ms_vswprintf == _vswprintf -#endif __ms_vwprintf == vwprintf __ms_wprintf == wprintf __ms_wscanf == wscanf +#ifdef WITH_MS_VSCANF_ALIASES +__ms_vfscanf == vfscanf +__ms_vfwscanf == vfwscanf +__ms_vscanf == vscanf +__ms_vsscanf == vsscanf +__ms_vswscanf == vswscanf +__ms_vwscanf == vwscanf +#endif #endif ; This is list of additional symbol aliases not available in any library as neither native symbols nor aliases diff --git a/lib/libc/mingw/include/msvcrt.h b/lib/libc/mingw/include/msvcrt.h index c6f1052247..9e48bf0694 100644 --- a/lib/libc/mingw/include/msvcrt.h +++ b/lib/libc/mingw/include/msvcrt.h @@ -1,10 +1,15 @@ -#include - #ifndef __LIBMSVCRT_OS__ #error "This file should only be used in libmsvcrt-os.a" #endif -static inline HANDLE __mingw_get_msvcrt_handle(void) +#ifndef MSVCRT_H +#define MSVCRT_H + +#include + +static inline HMODULE __mingw_get_msvcrt_handle(void) { - return GetModuleHandleW(L"msvcrt.dll"); + return GetModuleHandleA("msvcrt.dll"); } + +#endif diff --git a/lib/libc/mingw/crt/intrincs/RtlSecureZeroMemory.c b/lib/libc/mingw/intrincs/RtlSecureZeroMemory.c similarity index 100% rename from lib/libc/mingw/crt/intrincs/RtlSecureZeroMemory.c rename to lib/libc/mingw/intrincs/RtlSecureZeroMemory.c diff --git a/lib/libc/mingw/lib-common/kernel32.def.in b/lib/libc/mingw/lib-common/kernel32.def.in index f46a43246b..2b7fffc7a1 100644 --- a/lib/libc/mingw/lib-common/kernel32.def.in +++ b/lib/libc/mingw/lib-common/kernel32.def.in @@ -25,6 +25,7 @@ AddVectoredContinueHandler AddVectoredExceptionHandler AdjustCalendarDate AllocConsole +AllocConsoleWithOptions AllocateUserPhysicalPages AllocateUserPhysicalPagesNuma AppPolicyGetClrCompat @@ -447,6 +448,7 @@ FindVolumeMountPointClose FlsAlloc FlsFree FlsGetValue +FlsGetValue2 FlsSetValue FlushConsoleInputBuffer FlushFileBuffers @@ -626,6 +628,7 @@ GetFileAttributesW GetFileBandwidthReservation GetFileInformationByHandle GetFileInformationByHandleEx +GetFileInformationByName GetFileMUIInfo GetFileMUIPath GetFileSize @@ -1282,6 +1285,7 @@ ReleaseActCtxWorker ReleaseMutex ReleaseMutexWhenCallbackReturns ReleasePackageVirtualizationContext +ReleasePseudoConsole ReleaseSRWLockExclusive ReleaseSRWLockShared ReleaseSemaphore @@ -1543,6 +1547,7 @@ Thread32Next TlsAlloc TlsFree TlsGetValue +TlsGetValue2 TlsSetValue Toolhelp32ReadProcessMemory TransactNamedPipe diff --git a/lib/libc/mingw/lib-common/vcruntime140-common.def.in b/lib/libc/mingw/lib-common/vcruntime140-common.def.in new file mode 100644 index 0000000000..6dc643f706 --- /dev/null +++ b/lib/libc/mingw/lib-common/vcruntime140-common.def.in @@ -0,0 +1,89 @@ +_CreateFrameInfo +F_I386(_CxxThrowException@8) +F_NON_I386(_CxxThrowException) +F_I386(_EH_prolog) +_FindAndUnlinkFrame +_IsExceptionObjectToBeDestroyed +F_I386(_NLG_Dispatch2@4) +F_I386(_NLG_Return@12) +F_I386(_NLG_Return2) +_SetWinRTOutOfMemoryExceptionCallback +__AdjustPointer +__BuildCatchObject +__BuildCatchObjectHelper +F_NON_I386(__C_specific_handler) +F_NON_I386(__C_specific_handler_noexcept) +__CxxDetectRethrow +__CxxExceptionFilter +__CxxFrameHandler +__CxxFrameHandler2 +__CxxFrameHandler3 +F_I386(__CxxLongjmpUnwind@4) +__CxxQueryExceptionSize +__CxxRegisterExceptionObject +__CxxUnregisterExceptionObject +__DestructExceptionObject +__FrameUnwindFilter +__GetPlatformExceptionInfo +F_NON_I386(__NLG_Dispatch2) +F_NON_I386(__NLG_Return2) +__RTCastToVoid +__RTDynamicCast +__RTtypeid +__TypeMatch +__current_exception +__current_exception_context +F_NON_ARM64(__intrinsic_setjmp) +F_NON_I386(__intrinsic_setjmpex) +F_ARM32(__jump_unwind) +__processing_throw +__report_gsfailure +__std_exception_copy +__std_exception_destroy +__std_terminate +__std_type_info_compare +__std_type_info_destroy_list +__std_type_info_hash +__std_type_info_name +__telemetry_main_invoke_trigger +__telemetry_main_return_trigger +__unDName +__unDNameEx +__uncaught_exception +__uncaught_exceptions +__vcrt_GetModuleFileNameW +__vcrt_GetModuleHandleW +__vcrt_InitializeCriticalSectionEx +__vcrt_LoadLibraryExW +F_I386(_chkesp) +F_I386(_except_handler2) +F_I386(_except_handler3) +F_I386(_except_handler4_common) +_get_purecall_handler +_get_unexpected +F_I386(_global_unwind2) +_is_exception_typeof +F64(_local_unwind) +F_I386(_local_unwind2) +F_I386(_local_unwind4) +F_I386(_longjmpex) +_purecall +F_I386(_seh_longjmp_unwind4@4) +F_I386(_seh_longjmp_unwind@4) +_set_purecall_handler +_set_se_translator +F_I386(_setjmp3) +longjmp +memchr +memcmp +memcpy +memmove +memset +set_unexpected +strchr +strrchr +strstr +unexpected +wcschr +wcsrchr +wcsstr diff --git a/lib/libc/mingw/lib-common/vcruntime140.def.in b/lib/libc/mingw/lib-common/vcruntime140.def.in index 4d507d03c4..b3b548e29c 100644 --- a/lib/libc/mingw/lib-common/vcruntime140.def.in +++ b/lib/libc/mingw/lib-common/vcruntime140.def.in @@ -2,93 +2,4 @@ LIBRARY "VCRUNTIME140.dll" EXPORTS #include "func.def.in" - -_CreateFrameInfo -F_I386(_CxxThrowException@8) -F_NON_I386(_CxxThrowException) -F_I386(_EH_prolog) -_FindAndUnlinkFrame -_IsExceptionObjectToBeDestroyed -F_I386(_NLG_Dispatch2@4) -F_I386(_NLG_Return@12) -F_I386(_NLG_Return2) -_SetWinRTOutOfMemoryExceptionCallback -__AdjustPointer -__BuildCatchObject -__BuildCatchObjectHelper -F_NON_I386(__C_specific_handler) -F_NON_I386(__C_specific_handler_noexcept) -__CxxDetectRethrow -__CxxExceptionFilter -__CxxFrameHandler -__CxxFrameHandler2 -__CxxFrameHandler3 -F_I386(__CxxLongjmpUnwind@4) -__CxxQueryExceptionSize -__CxxRegisterExceptionObject -__CxxUnregisterExceptionObject -__DestructExceptionObject -__FrameUnwindFilter -__GetPlatformExceptionInfo -F_NON_I386(__NLG_Dispatch2) -F_NON_I386(__NLG_Return2) -__RTCastToVoid -__RTDynamicCast -__RTtypeid -__TypeMatch -__current_exception -__current_exception_context -F_NON_ARM64(__intrinsic_setjmp) -F_NON_I386(__intrinsic_setjmpex) -F_ARM32(__jump_unwind) -__processing_throw -__report_gsfailure -__std_exception_copy -__std_exception_destroy -__std_terminate -__std_type_info_compare -__std_type_info_destroy_list -__std_type_info_hash -__std_type_info_name -__telemetry_main_invoke_trigger -__telemetry_main_return_trigger -__unDName -__unDNameEx -__uncaught_exception -__uncaught_exceptions -__vcrt_GetModuleFileNameW -__vcrt_GetModuleHandleW -__vcrt_InitializeCriticalSectionEx -__vcrt_LoadLibraryExW -F_I386(_chkesp) -F_I386(_except_handler2) -F_I386(_except_handler3) -F_I386(_except_handler4_common) -_get_purecall_handler -_get_unexpected -F_I386(_global_unwind2) -_is_exception_typeof -F64(_local_unwind) -F_I386(_local_unwind2) -F_I386(_local_unwind4) -F_I386(_longjmpex) -_purecall -F_I386(_seh_longjmp_unwind4@4) -F_I386(_seh_longjmp_unwind@4) -_set_purecall_handler -_set_se_translator -F_I386(_setjmp3) -longjmp -memchr -memcmp -memcpy -memmove -memset -set_unexpected -strchr -strrchr -strstr -unexpected -wcschr -wcsrchr -wcsstr +#include "vcruntime140-common.def.in" diff --git a/lib/libc/mingw/lib-common/vcruntime140_app.def.in b/lib/libc/mingw/lib-common/vcruntime140_app.def.in index f4f70060ec..3048e9770d 100644 --- a/lib/libc/mingw/lib-common/vcruntime140_app.def.in +++ b/lib/libc/mingw/lib-common/vcruntime140_app.def.in @@ -1,95 +1,5 @@ -LIBRARY vcruntime140_app - +LIBRARY "VCRUNTIME140_APP.dll" EXPORTS #include "func.def.in" - -_CreateFrameInfo -F_I386(_CxxThrowException@8) -F_NON_I386(_CxxThrowException) -F_I386(_EH_prolog) -_FindAndUnlinkFrame -_IsExceptionObjectToBeDestroyed -F_I386(_NLG_Dispatch2) -F_I386(_NLG_Return) -F_I386(_NLG_Return2) -_SetWinRTOutOfMemoryExceptionCallback -__AdjustPointer -__BuildCatchObject -__BuildCatchObjectHelper -F_NON_I386(__C_specific_handler) -F_NON_I386(__C_specific_handler_noexcept) -__CxxDetectRethrow -__CxxExceptionFilter -__CxxFrameHandler -__CxxFrameHandler2 -__CxxFrameHandler3 -F_I386(__CxxLongjmpUnwind@4) -__CxxQueryExceptionSize -__CxxRegisterExceptionObject -__CxxUnregisterExceptionObject -__DestructExceptionObject -__FrameUnwindFilter -__GetPlatformExceptionInfo -F_NON_I386(__NLG_Dispatch2) -F_NON_I386(__NLG_Return2) -__RTCastToVoid -__RTDynamicCast -__RTtypeid -__TypeMatch -__current_exception -__current_exception_context -F_NON_ARM64(__intrinsic_setjmp) -F_NON_I386(__intrinsic_setjmpex) -F_ARM32(__jump_unwind) -__processing_throw -__report_gsfailure -__std_exception_copy -__std_exception_destroy -__std_terminate -__std_type_info_compare -__std_type_info_destroy_list -__std_type_info_hash -__std_type_info_name -__telemetry_main_invoke_trigger -__telemetry_main_return_trigger -__unDName -__unDNameEx -__uncaught_exception -__uncaught_exceptions -__vcrt_GetModuleFileNameW -__vcrt_GetModuleHandleW -__vcrt_InitializeCriticalSectionEx -__vcrt_LoadLibraryExW -F_I386(_chkesp) -F_I386(_except_handler2) -F_I386(_except_handler3) -F_I386(_except_handler4_common) -_get_purecall_handler -_get_unexpected -F_I386(_global_unwind2) -_is_exception_typeof -F_I386(_local_unwind2) -F_I386(_local_unwind4) -F_I386(_longjmpex) -F64(_local_unwind) -_purecall -F_I386(_seh_longjmp_unwind4@4) -F_I386(_seh_longjmp_unwind@4) -_set_purecall_handler -_set_se_translator -F_I386(_setjmp3) -longjmp -memchr -memcmp -memcpy -memmove -memset -set_unexpected -strchr -strrchr -strstr -unexpected -wcschr -wcsrchr -wcsstr +#include "vcruntime140-common.def.in" diff --git a/lib/libc/mingw/lib-common/vcruntime140d.def.in b/lib/libc/mingw/lib-common/vcruntime140d.def.in index c0ac6c9d67..50819fab55 100644 --- a/lib/libc/mingw/lib-common/vcruntime140d.def.in +++ b/lib/libc/mingw/lib-common/vcruntime140d.def.in @@ -2,93 +2,4 @@ LIBRARY "VCRUNTIME140D.dll" EXPORTS #include "func.def.in" - -_CreateFrameInfo -F_I386(_CxxThrowException@8) -F_NON_I386(_CxxThrowException) -F_I386(_EH_prolog) -_FindAndUnlinkFrame -_IsExceptionObjectToBeDestroyed -F_I386(_NLG_Dispatch2@4) -F_I386(_NLG_Return@12) -F_I386(_NLG_Return2) -_SetWinRTOutOfMemoryExceptionCallback -__AdjustPointer -__BuildCatchObject -__BuildCatchObjectHelper -F_NON_I386(__C_specific_handler) -F_NON_I386(__C_specific_handler_noexcept) -__CxxDetectRethrow -__CxxExceptionFilter -__CxxFrameHandler -__CxxFrameHandler2 -__CxxFrameHandler3 -F_I386(__CxxLongjmpUnwind@4) -__CxxQueryExceptionSize -__CxxRegisterExceptionObject -__CxxUnregisterExceptionObject -__DestructExceptionObject -__FrameUnwindFilter -__GetPlatformExceptionInfo -F_NON_I386(__NLG_Dispatch2) -F_NON_I386(__NLG_Return2) -__RTCastToVoid -__RTDynamicCast -__RTtypeid -__TypeMatch -__current_exception -__current_exception_context -F_NON_ARM64(__intrinsic_setjmp) -F_NON_I386(__intrinsic_setjmpex) -F_ARM32(__jump_unwind) -__processing_throw -__report_gsfailure -__std_exception_copy -__std_exception_destroy -__std_terminate -__std_type_info_compare -__std_type_info_destroy_list -__std_type_info_hash -__std_type_info_name -__telemetry_main_invoke_trigger -__telemetry_main_return_trigger -__unDName -__unDNameEx -__uncaught_exception -__uncaught_exceptions -__vcrt_GetModuleFileNameW -__vcrt_GetModuleHandleW -__vcrt_InitializeCriticalSectionEx -__vcrt_LoadLibraryExW -F_I386(_chkesp) -F_I386(_except_handler2) -F_I386(_except_handler3) -F_I386(_except_handler4_common) -_get_purecall_handler -_get_unexpected -F_I386(_global_unwind2) -_is_exception_typeof -F64(_local_unwind) -F_I386(_local_unwind2) -F_I386(_local_unwind4) -F_I386(_longjmpex) -_purecall -F_I386(_seh_longjmp_unwind4@4) -F_I386(_seh_longjmp_unwind@4) -_set_purecall_handler -_set_se_translator -F_I386(_setjmp3) -longjmp -memchr -memcmp -memcpy -memmove -memset -set_unexpected -strchr -strrchr -strstr -unexpected -wcschr -wcsrchr -wcsstr +#include "vcruntime140-common.def.in" diff --git a/lib/libc/mingw/lib32/dxva2.def b/lib/libc/mingw/lib32/dxva2.def index d43af5be36..ea343a53fe 100644 --- a/lib/libc/mingw/lib32/dxva2.def +++ b/lib/libc/mingw/lib32/dxva2.def @@ -8,6 +8,7 @@ EXPORTS CapabilitiesRequestAndCapabilitiesReply@12 DXVA2CreateDirect3DDeviceManager9@8 DXVA2CreateVideoService@12 +DXVAHD_CreateDevice@20 DegaussMonitor@4 DestroyPhysicalMonitor@4 DestroyPhysicalMonitors@8 diff --git a/lib/libc/mingw/lib32/kernel32.def b/lib/libc/mingw/lib32/kernel32.def index e5a8dc456c..51582f24c4 100644 --- a/lib/libc/mingw/lib32/kernel32.def +++ b/lib/libc/mingw/lib32/kernel32.def @@ -30,6 +30,7 @@ AddVectoredContinueHandler@8 AddVectoredExceptionHandler@8 AdjustCalendarDate@12 AllocConsole@0 +AllocConsoleWithOptions@8 AllocateUserPhysicalPages@12 AllocateUserPhysicalPagesNuma@16 AppPolicyGetClrCompat@8 @@ -440,6 +441,7 @@ FindVolumeClose@4 FindVolumeMountPointClose@4 FlsAlloc@4 FlsFree@4 +FlsGetValue2@4 FlsGetValue@4 FlsSetValue@8 FlushConsoleInputBuffer@4 @@ -616,6 +618,7 @@ GetFileAttributesW@4 GetFileBandwidthReservation@24 GetFileInformationByHandle@8 GetFileInformationByHandleEx@16 +GetFileInformationByName@16 GetFileMUIInfo@16 GetFileMUIPath@28 GetFileSize@8 @@ -1270,6 +1273,7 @@ ReleaseActCtxWorker@4 ReleaseMutex@4 ReleaseMutexWhenCallbackReturns@8 ReleasePackageVirtualizationContext@4 +ReleasePseudoConsole@4 ReleaseSRWLockExclusive@4 ReleaseSRWLockShared@4 ReleaseSemaphore@12 @@ -1518,6 +1522,7 @@ Thread32First@8 Thread32Next@8 TlsAlloc@0 TlsFree@4 +TlsGetValue2@4 TlsGetValue@4 TlsSetValue@8 Toolhelp32ReadProcessMemory@20 @@ -1605,7 +1610,7 @@ WerRegisterRuntimeExceptionModuleWorker@8 WerSetFlags@4 WerSetFlagsWorker@4 WerUnregisterAdditionalProcess@4 -WerUnregisterAppLocalDump +WerUnregisterAppLocalDump@0 WerUnregisterCustomMetadata@4 WerUnregisterExcludedMemoryBlock@4 WerUnregisterFile@4 diff --git a/lib/libc/mingw/lib64/kernel32.def b/lib/libc/mingw/lib64/kernel32.def index 5259839aae..85686a13a3 100644 --- a/lib/libc/mingw/lib64/kernel32.def +++ b/lib/libc/mingw/lib64/kernel32.def @@ -24,6 +24,7 @@ AddVectoredContinueHandler AddVectoredExceptionHandler AdjustCalendarDate AllocConsole +AllocConsoleWithOptions AllocateUserPhysicalPages AllocateUserPhysicalPagesNuma AppPolicyGetClrCompat @@ -446,6 +447,7 @@ FindVolumeMountPointClose FlsAlloc FlsFree FlsGetValue +FlsGetValue2 FlsSetValue FlushConsoleInputBuffer FlushFileBuffers @@ -625,6 +627,7 @@ GetFileAttributesW GetFileBandwidthReservation GetFileInformationByHandle GetFileInformationByHandleEx +GetFileInformationByName GetFileMUIInfo GetFileMUIPath GetFileSize @@ -1281,6 +1284,7 @@ ReleaseActCtxWorker ReleaseMutex ReleaseMutexWhenCallbackReturns ReleasePackageVirtualizationContext +ReleasePseudoConsole ReleaseSRWLockExclusive ReleaseSRWLockShared ReleaseSemaphore @@ -1542,6 +1546,7 @@ Thread32Next TlsAlloc TlsFree TlsGetValue +TlsGetValue2 TlsSetValue Toolhelp32ReadProcessMemory TransactNamedPipe diff --git a/lib/libc/mingw/libsrc/wia-uuid.c b/lib/libc/mingw/libsrc/wia-uuid.c index cd5609a048..bc9e918704 100644 --- a/lib/libc/mingw/libsrc/wia-uuid.c +++ b/lib/libc/mingw/libsrc/wia-uuid.c @@ -1,106 +1,6 @@ /* unknwn-uuid.c */ /* Generate GUIDs for WIA interfaces */ -/* All IIDs defined in this file were extracted from - * HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Interface\ */ - #define INITGUID #include - -// Image types -DEFINE_GUID(WiaImgFmt_UNDEFINED,0xb96b3ca9,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e); -DEFINE_GUID(WiaImgFmt_RAWRGB,0xbca48b55,0xf272,0x4371,0xb0,0xf1,0x4a,0x15,0x0d,0x05,0x7b,0xb4); -DEFINE_GUID(WiaImgFmt_MEMORYBMP,0xb96b3caa,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e); -DEFINE_GUID(WiaImgFmt_BMP,0xb96b3cab,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e); -DEFINE_GUID(WiaImgFmt_EMF,0xb96b3cac,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e); -DEFINE_GUID(WiaImgFmt_WMF,0xb96b3cad,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e); -DEFINE_GUID(WiaImgFmt_JPEG,0xb96b3cae,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e); -DEFINE_GUID(WiaImgFmt_PNG,0xb96b3caf,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e); -DEFINE_GUID(WiaImgFmt_GIF,0xb96b3cb0,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e); -DEFINE_GUID(WiaImgFmt_TIFF,0xb96b3cb1,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e); -DEFINE_GUID(WiaImgFmt_EXIF,0xb96b3cb2,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e); -DEFINE_GUID(WiaImgFmt_PHOTOCD,0xb96b3cb3,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e); -DEFINE_GUID(WiaImgFmt_FLASHPIX,0xb96b3cb4,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e); -DEFINE_GUID(WiaImgFmt_ICO,0xb96b3cb5,0x0728,0x11d3,0x9d,0x7b,0x00,0x00,0xf8,0x1e,0xf3,0x2e); -DEFINE_GUID(WiaImgFmt_CIFF,0x9821a8ab,0x3a7e,0x4215,0x94,0xe0,0xd2,0x7a,0x46,0x0c,0x03,0xb2); -DEFINE_GUID(WiaImgFmt_PICT,0xa6bc85d8,0x6b3e,0x40ee,0xa9,0x5c,0x25,0xd4,0x82,0xe4,0x1a,0xdc); -DEFINE_GUID(WiaImgFmt_JPEG2K,0x344ee2b2,0x39db,0x4dde,0x81,0x73,0xc4,0xb7,0x5f,0x8f,0x1e,0x49); -DEFINE_GUID(WiaImgFmt_JPEG2KX,0x43e14614,0xc80a,0x4850,0xba,0xf3,0x4b,0x15,0x2d,0xc8,0xda,0x27); - -// Document and other types -DEFINE_GUID(WiaImgFmt_RTF,0x573dd6a3,0x4834,0x432d,0xa9,0xb5,0xe1,0x98,0xdd,0x9e,0x89,0x0d); -DEFINE_GUID(WiaImgFmt_XML,0xb9171457,0xdac8,0x4884,0xb3,0x93,0x15,0xb4,0x71,0xd5,0xf0,0x7e); -DEFINE_GUID(WiaImgFmt_HTML,0xc99a4e62,0x99de,0x4a94,0xac,0xca,0x71,0x95,0x6a,0xc2,0x97,0x7d); -DEFINE_GUID(WiaImgFmt_TXT,0xfafd4d82,0x723f,0x421f,0x93,0x18,0x30,0x50,0x1a,0xc4,0x4b,0x59); -DEFINE_GUID(WiaImgFmt_MPG,0xecd757e4,0xd2ec,0x4f57,0x95,0x5d,0xbc,0xf8,0xa9,0x7c,0x4e,0x52); -DEFINE_GUID(WiaImgFmt_AVI,0x32f8ca14,0x087c,0x4908,0xb7,0xc4,0x67,0x57,0xfe,0x7e,0x90,0xab); -DEFINE_GUID(WiaImgFmt_ASF,0x8d948ee9,0xd0aa,0x4a12,0x9d,0x9a,0x9c,0xc5,0xde,0x36,0x19,0x9b); -DEFINE_GUID(WiaImgFmt_SCRIPT,0xfe7d6c53,0x2dac,0x446a,0xb0,0xbd,0xd7,0x3e,0x21,0xe9,0x24,0xc9); -DEFINE_GUID(WiaImgFmt_EXEC,0x485da097,0x141e,0x4aa5,0xbb,0x3b,0xa5,0x61,0x8d,0x95,0xd0,0x2b); -DEFINE_GUID(WiaImgFmt_UNICODE16,0x1b7639b6,0x6357,0x47d1,0x9a,0x07,0x12,0x45,0x2d,0xc0,0x73,0xe9); -DEFINE_GUID(WiaImgFmt_DPOF,0x369eeeab,0xa0e8,0x45ca,0x86,0xa6,0xa8,0x3c,0xe5,0x69,0x7e,0x28); - -// Audio types -DEFINE_GUID(WiaAudFmt_WAV,0xf818e146,0x07af,0x40ff,0xae,0x55,0xbe,0x8f,0x2c,0x06,0x5d,0xbe); -DEFINE_GUID(WiaAudFmt_MP3,0x0fbc71fb,0x43bf,0x49f2,0x91,0x90,0xe6,0xfe,0xcf,0xf3,0x7e,0x54); -DEFINE_GUID(WiaAudFmt_AIFF,0x66e2bf4f,0xb6fc,0x443f,0x94,0xc8,0x2f,0x33,0xc8,0xa6,0x5a,0xaf); -DEFINE_GUID(WiaAudFmt_WMA,0xd61d6413,0x8bc2,0x438f,0x93,0xad,0x21,0xbd,0x48,0x4d,0xb6,0xa1); - -// Event GUIDs -DEFINE_GUID(WIA_EVENT_DEVICE_DISCONNECTED,0x143e4e83,0x6497,0x11d2,0xa2,0x31,0x00,0xc0,0x4f,0xa3,0x18,0x09); -DEFINE_GUID(WIA_EVENT_DEVICE_CONNECTED,0xa28bbade,0x64b6,0x11d2,0xa2,0x31,0x00,0xc0,0x4f,0xa3,0x18,0x09); -DEFINE_GUID(WIA_EVENT_ITEM_DELETED,0x1d22a559,0xe14f,0x11d2,0xb3,0x26,0x00,0xc0,0x4f,0x68,0xce,0x61); -DEFINE_GUID(WIA_EVENT_ITEM_CREATED,0x4c8f4ef5,0xe14f,0x11d2,0xb3,0x26,0x00,0xc0,0x4f,0x68,0xce,0x61); -DEFINE_GUID(WIA_EVENT_TREE_UPDATED,0xc9859b91,0x4ab2,0x4cd6,0xa1,0xfc,0x58,0x2e,0xec,0x55,0xe5,0x85); -DEFINE_GUID(WIA_EVENT_VOLUME_INSERT,0x9638bbfd,0xd1bd,0x11d2,0xb3,0x1f,0x00,0xc0,0x4f,0x68,0xce,0x61); -DEFINE_GUID(WIA_EVENT_SCAN_IMAGE,0xa6c5a715,0x8c6e,0x11d2,0x97,0x7a,0x00,0x00,0xf8,0x7a,0x92,0x6f); -DEFINE_GUID(WIA_EVENT_SCAN_PRINT_IMAGE,0xb441f425,0x8c6e,0x11d2,0x97,0x7a,0x00,0x00,0xf8,0x7a,0x92,0x6f); -DEFINE_GUID(WIA_EVENT_SCAN_FAX_IMAGE,0xc00eb793,0x8c6e,0x11d2,0x97,0x7a,0x00,0x00,0xf8,0x7a,0x92,0x6f); -DEFINE_GUID(WIA_EVENT_SCAN_OCR_IMAGE,0x9d095b89,0x37d6,0x4877,0xaf,0xed,0x62,0xa2,0x97,0xdc,0x6d,0xbe); -DEFINE_GUID(WIA_EVENT_SCAN_EMAIL_IMAGE,0xc686dcee,0x54f2,0x419e,0x9a,0x27,0x2f,0xc7,0xf2,0xe9,0x8f,0x9e); -DEFINE_GUID(WIA_EVENT_SCAN_FILM_IMAGE,0x9b2b662c,0x6185,0x438c,0xb6,0x8b,0xe3,0x9e,0xe2,0x5e,0x71,0xcb); -DEFINE_GUID(WIA_EVENT_SCAN_IMAGE2,0xfc4767c1,0xc8b3,0x48a2,0x9c,0xfa,0x2e,0x90,0xcb,0x3d,0x35,0x90); -DEFINE_GUID(WIA_EVENT_SCAN_IMAGE3,0x154e27be,0xb617,0x4653,0xac,0xc5,0x0f,0xd7,0xbd,0x4c,0x65,0xce); -DEFINE_GUID(WIA_EVENT_SCAN_IMAGE4,0xa65b704a,0x7f3c,0x4447,0xa7,0x5d,0x8a,0x26,0xdf,0xca,0x1f,0xdf); -DEFINE_GUID(WIA_EVENT_STORAGE_CREATED,0x353308b2,0xfe73,0x46c8,0x89,0x5e,0xfa,0x45,0x51,0xcc,0xc8,0x5a); -DEFINE_GUID(WIA_EVENT_STORAGE_DELETED,0x5e41e75e,0x9390,0x44c5,0x9a,0x51,0xe4,0x70,0x19,0xe3,0x90,0xcf); -DEFINE_GUID(WIA_EVENT_STI_PROXY,0xd711f81f,0x1f0d,0x422d,0x86,0x41,0x92,0x7d,0x1b,0x93,0xe5,0xe5); -DEFINE_GUID(WIA_EVENT_CANCEL_IO,0xc860f7b8,0x9ccd,0x41ea,0xbb,0xbf,0x4d,0xd0,0x9c,0x5b,0x17,0x95); - -// Power management event GUIDs,sent by the WIA service to drivers -DEFINE_GUID(WIA_EVENT_POWER_SUSPEND,0xa0922ff9,0xc3b4,0x411c,0x9e,0x29,0x03,0xa6,0x69,0x93,0xd2,0xbe); -DEFINE_GUID(WIA_EVENT_POWER_RESUME,0x618f153e,0xf686,0x4350,0x96,0x34,0x41,0x15,0xa3,0x04,0x83,0x0c); - -// No action handler and prompt handler -DEFINE_GUID(WIA_EVENT_HANDLER_NO_ACTION,0xe0372b7d,0xe115,0x4525,0xbc,0x55,0xb6,0x29,0xe6,0x8c,0x74,0x5a); -DEFINE_GUID(WIA_EVENT_HANDLER_PROMPT,0x5f4baad0,0x4d59,0x4fcd,0xb2,0x13,0x78,0x3c,0xe7,0xa9,0x2f,0x22); - -// WIA Commands -DEFINE_GUID(WIA_CMD_SYNCHRONIZE,0x9b26b7b2,0xacad,0x11d2,0xa0,0x93,0x00,0xc0,0x4f,0x72,0xdc,0x3c); -DEFINE_GUID(WIA_CMD_TAKE_PICTURE,0xaf933cac,0xacad,0x11d2,0xa0,0x93,0x00,0xc0,0x4f,0x72,0xdc,0x3c); -DEFINE_GUID(WIA_CMD_DELETE_ALL_ITEMS,0xe208c170,0xacad,0x11d2,0xa0,0x93,0x00,0xc0,0x4f,0x72,0xdc,0x3c); -DEFINE_GUID(WIA_CMD_CHANGE_DOCUMENT,0x04e725b0,0xacae,0x11d2,0xa0,0x93,0x00,0xc0,0x4f,0x72,0xdc,0x3c); -DEFINE_GUID(WIA_CMD_UNLOAD_DOCUMENT,0x1f3b3d8e,0xacae,0x11d2,0xa0,0x93,0x00,0xc0,0x4f,0x72,0xdc,0x3c); -DEFINE_GUID(WIA_CMD_DIAGNOSTIC,0x10ff52f5,0xde04,0x4cf0,0xa5,0xad,0x69,0x1f,0x8d,0xce,0x01,0x41); - -DEFINE_GUID(WIA_CMD_DELETE_DEVICE_TREE,0x73815942,0xdbea,0x11d2,0x84,0x16,0x00,0xc0,0x4f,0xa3,0x61,0x45); -DEFINE_GUID(WIA_CMD_BUILD_DEVICE_TREE,0x9cba5ce0,0xdbea,0x11d2,0x84,0x16,0x00,0xc0,0x4f,0xa3,0x61,0x45); - -DEFINE_GUID(IID_IWiaUIExtension,0xDA319113,0x50EE,0x4C80,0xB4,0x60,0x57,0xD0,0x05,0xD4,0x4A,0x2C); - -DEFINE_GUID(IID_IWiaDevMgr,0x5eb2502a,0x8cf1,0x11d1,0xbf,0x92,0x00,0x60,0x08,0x1e,0xd8,0x11); -DEFINE_GUID(IID_IEnumWIA_DEV_INFO,0x5e38b83c,0x8cf1,0x11d1,0xbf,0x92,0x00,0x60,0x08,0x1e,0xd8,0x11); -DEFINE_GUID(IID_IWiaEventCallback,0xae6287b0,0x0084,0x11d2,0x97,0x3b,0x00,0xa0,0xc9,0x06,0x8f,0x2e); -DEFINE_GUID(IID_IWiaDataCallback,0xa558a866,0xa5b0,0x11d2,0xa0,0x8f,0x00,0xc0,0x4f,0x72,0xdc,0x3c); -DEFINE_GUID(IID_IWiaDataTransfer,0xa6cef998,0xa5b0,0x11d2,0xa0,0x8f,0x00,0xc0,0x4f,0x72,0xdc,0x3c); -DEFINE_GUID(IID_IWiaItem,0x4db1ad10,0x3391,0x11d2,0x9a,0x33,0x00,0xc0,0x4f,0xa3,0x61,0x45); -DEFINE_GUID(IID_IWiaPropertyStorage,0x98B5E8A0,0x29CC,0x491a,0xAA,0xC0,0xE6,0xDB,0x4F,0xDC,0xCE,0xB6); -DEFINE_GUID(IID_IEnumWiaItem,0x5e8383fc,0x3391,0x11d2,0x9a,0x33,0x00,0xc0,0x4f,0xa3,0x61,0x45); -DEFINE_GUID(IID_IEnumWIA_DEV_CAPS,0x1fcc4287,0xaca6,0x11d2,0xa0,0x93,0x00,0xc0,0x4f,0x72,0xdc,0x3c); -DEFINE_GUID(IID_IEnumWIA_FORMAT_INFO,0x81BEFC5B,0x656D,0x44f1,0xB2,0x4C,0xD4,0x1D,0x51,0xB4,0xDC,0x81); -DEFINE_GUID(IID_IWiaLog,0xA00C10B6,0x82A1,0x452f,0x8B,0x6C,0x86,0x06,0x2A,0xAD,0x68,0x90); -DEFINE_GUID(IID_IWiaLogEx,0xAF1F22AC,0x7A40,0x4787,0xB4,0x21,0xAE,0xb4,0x7A,0x1F,0xBD,0x0B); -DEFINE_GUID(IID_IWiaNotifyDevMgr,0x70681EA0,0xE7BF,0x4291,0x9F,0xB1,0x4E,0x88,0x13,0xA3,0xF7,0x8E); -DEFINE_GUID(IID_IWiaItemExtras,0x6291ef2c,0x36ef,0x4532,0x87,0x6a,0x8e,0x13,0x25,0x93,0x77,0x8d); -DEFINE_GUID(CLSID_WiaDevMgr,0xa1f4e726,0x8cf1,0x11d1,0xbf,0x92,0x00,0x60,0x08,0x1e,0xd8,0x11); -DEFINE_GUID(CLSID_WiaLog,0xA1E75357,0x881A,0x419e,0x83,0xE2,0xBB,0x16,0xDB,0x19,0x7C,0x68); +#include diff --git a/lib/libc/mingw/math/x86/cossin.c b/lib/libc/mingw/math/x86/cossin.c index cb3340545d..b86fbfc9e8 100644 --- a/lib/libc/mingw/math/x86/cossin.c +++ b/lib/libc/mingw/math/x86/cossin.c @@ -5,7 +5,6 @@ */ void sincos (double __x, double *p_sin, double *p_cos); -void sincosl (long double __x, long double *p_sin, long double *p_cos); void sincosf (float __x, float *p_sin, float *p_cos); void sincos (double __x, double *p_sin, double *p_cos) @@ -51,25 +50,3 @@ void sincosf (float __x, float *p_sin, float *p_cos) *p_sin = (float) s; *p_cos = (float) c; } - -void sincosl (long double __x, long double *p_sin, long double *p_cos) -{ - long double c, s; - - __asm__ __volatile__ ("fsincos\n\t" - "fnstsw %%ax\n\t" - "testl $0x400, %%eax\n\t" - "jz 1f\n\t" - "fldpi\n\t" - "fadd %%st(0)\n\t" - "fxch %%st(1)\n\t" - "2: fprem1\n\t" - "fnstsw %%ax\n\t" - "testl $0x400, %%eax\n\t" - "jnz 2b\n\t" - "fstp %%st(1)\n\t" - "fsincos\n\t" - "1:" : "=t" (c), "=u" (s) : "0" (__x) : "eax"); - *p_sin = s; - *p_cos = c; -} diff --git a/lib/libc/mingw/math/x86/cossinl.c b/lib/libc/mingw/math/x86/cossinl.c new file mode 100644 index 0000000000..cfd172dcbd --- /dev/null +++ b/lib/libc/mingw/math/x86/cossinl.c @@ -0,0 +1,29 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +void sincosl (long double __x, long double *p_sin, long double *p_cos); + +void sincosl (long double __x, long double *p_sin, long double *p_cos) +{ + long double c, s; + + __asm__ __volatile__ ("fsincos\n\t" + "fnstsw %%ax\n\t" + "testl $0x400, %%eax\n\t" + "jz 1f\n\t" + "fldpi\n\t" + "fadd %%st(0)\n\t" + "fxch %%st(1)\n\t" + "2: fprem1\n\t" + "fnstsw %%ax\n\t" + "testl $0x400, %%eax\n\t" + "jnz 2b\n\t" + "fstp %%st(1)\n\t" + "fsincos\n\t" + "1:" : "=t" (c), "=u" (s) : "0" (__x) : "eax"); + *p_sin = s; + *p_cos = c; +} diff --git a/lib/libc/mingw/misc/isblank.c b/lib/libc/mingw/misc/isblank.c deleted file mode 100644 index ce6247c1c3..0000000000 --- a/lib/libc/mingw/misc/isblank.c +++ /dev/null @@ -1,7 +0,0 @@ -#define __NO_CTYPE_LINES -#include - -int __cdecl isblank (int _C) -{ - return (_isctype(_C, _BLANK) || _C == '\t'); -} diff --git a/lib/libc/mingw/misc/iswblank.c b/lib/libc/mingw/misc/iswblank.c deleted file mode 100644 index bdf73e5649..0000000000 --- a/lib/libc/mingw/misc/iswblank.c +++ /dev/null @@ -1,7 +0,0 @@ -#define _CRT_WCTYPE_NOINLINE -#include - -int __cdecl iswblank (wint_t _C) -{ - return (iswctype(_C, _BLANK) || _C == '\t'); -} diff --git a/lib/libc/mingw/misc/wctob.c b/lib/libc/mingw/misc/wctob.c index 008e691170..995f6db6e1 100644 --- a/lib/libc/mingw/misc/wctob.c +++ b/lib/libc/mingw/misc/wctob.c @@ -25,5 +25,5 @@ int wctob (wint_t wc ) || invalid_char) return EOF; - return (int) c; + return (unsigned char) c; } diff --git a/lib/libc/mingw/misc/wctrans.c b/lib/libc/mingw/misc/wctrans.c deleted file mode 100644 index bcd9ef9fa2..0000000000 --- a/lib/libc/mingw/misc/wctrans.c +++ /dev/null @@ -1,65 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ -/* - wctrans.c - 7.25.3.2 Extensible wide-character case mapping functions - - Contributed by: Danny Smith - 2005-02-24 - - This source code is placed in the PUBLIC DOMAIN. It is modified - from the Q8 package created by Doug Gwyn - - */ - -#include -#include - -/* - This differs from the MS implementation of wctrans which - returns 0 for tolower and 1 for toupper. According to - C99, a 0 return value indicates invalid input. - - These two function go in the same translation unit so that we - can ensure that - towctrans(wc, wctrans("tolower")) == towlower(wc) - towctrans(wc, wctrans("toupper")) == towupper(wc) - It also ensures that - towctrans(wc, wctrans("")) == wc - which is not required by standard. -*/ - -static const struct { - const char *name; - wctrans_t val; } tmap[] = { - {"tolower", _LOWER}, - {"toupper", _UPPER} - }; - -#define NTMAP (sizeof tmap / sizeof tmap[0]) - -wctrans_t -wctrans (const char* property) -{ - int i; - for ( i = 0; i < (int) NTMAP; ++i ) - if (strcmp (property, tmap[i].name) == 0) - return tmap[i].val; - return 0; -} - -wint_t towctrans (wint_t wc, wctrans_t desc) -{ - switch (desc) - { - case _LOWER: - return towlower (wc); - case _UPPER: - return towupper (wc); - default: - return wc; - } -} diff --git a/lib/libc/mingw/misc/wctype.c b/lib/libc/mingw/misc/wctype.c deleted file mode 100644 index b6cfc1ddff..0000000000 --- a/lib/libc/mingw/misc/wctype.c +++ /dev/null @@ -1,65 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ -/* - wctype.c - 7.25.2.2.2 The wctype function - - Contributed by: Danny Smith - 2005-02-24 - - This source code is placed in the PUBLIC DOMAIN. It is modified - from the Q8 package created by Doug Gwyn - - The wctype function constructs a value with type wctype_t that - describes a class of wide characters identified by the string - argument property. - - In particular, we map the property strings so that: - - iswctype(wc, wctype("alnum")) == iswalnum(wc) - iswctype(wc, wctype("alpha")) == iswalpha(wc) - iswctype(wc, wctype("cntrl")) == iswcntrl(wc) - iswctype(wc, wctype("digit")) == iswdigit(wc) - iswctype(wc, wctype("graph")) == iswgraph(wc) - iswctype(wc, wctype("lower")) == iswlower(wc) - iswctype(wc, wctype("print")) == iswprint(wc) - iswctype(wc, wctype("punct")) == iswpunct(wc) - iswctype(wc, wctype("space")) == iswspace(wc) - iswctype(wc, wctype("upper")) == iswupper(wc) - iswctype(wc, wctype("xdigit")) == iswxdigit(wc) - -*/ - -#include -#include - -/* Using the bit-OR'd ctype character classification flags as return - values achieves compatibility with MS iswctype(). */ -static const struct { - const char *name; - wctype_t flags;} cmap[] = { - {"alnum", _ALPHA|_DIGIT}, - {"alpha", _ALPHA}, - {"cntrl", _CONTROL}, - {"digit", _DIGIT}, - {"graph", _PUNCT|_ALPHA|_DIGIT}, - {"lower", _LOWER}, - {"print", _BLANK|_PUNCT|_ALPHA|_DIGIT}, - {"punct", _PUNCT}, - {"space", _SPACE}, - {"upper", _UPPER}, - {"xdigit", _HEX} - }; - -#define NCMAP (sizeof cmap / sizeof cmap[0]) -wctype_t wctype (const char *property) -{ - int i; - for (i = 0; i < (int) NCMAP; ++i) - if (strcmp (property, cmap[i].name) == 0) - return cmap[i].flags; - return 0; -} diff --git a/lib/libc/mingw/stdio/mingw_fprintfw.c b/lib/libc/mingw/stdio/mingw_fwprintf.c similarity index 100% rename from lib/libc/mingw/stdio/mingw_fprintfw.c rename to lib/libc/mingw/stdio/mingw_fwprintf.c diff --git a/lib/libc/mingw/stdio/mingw_pformat.h b/lib/libc/mingw/stdio/mingw_pformat.h index 4777804322..3381ff8ba9 100644 --- a/lib/libc/mingw/stdio/mingw_pformat.h +++ b/lib/libc/mingw/stdio/mingw_pformat.h @@ -72,13 +72,20 @@ # define __printf __mingw_wprintf # define __fprintf __mingw_fwprintf -# define __sprintf __mingw_swprintf +#ifdef __BUILD_WIDEAPI_ISO +# define __snprintf __mingw_swprintf +#else # define __snprintf __mingw_snwprintf +#endif # define __vprintf __mingw_vwprintf # define __vfprintf __mingw_vfwprintf -# define __vsprintf __mingw_vswprintf +#ifdef __BUILD_WIDEAPI_ISO +# define __vsnprintf __mingw_vswprintf +#else # define __vsnprintf __mingw_vsnwprintf +#endif + #else # define __pformat __mingw_pformat #define __fputc(X,STR) fputc((X), (STR)) diff --git a/lib/libc/mingw/stdio/mingw_sformat.c b/lib/libc/mingw/stdio/mingw_sformat.c new file mode 100644 index 0000000000..040c2ae887 --- /dev/null +++ b/lib/libc/mingw/stdio/mingw_sformat.c @@ -0,0 +1,1602 @@ +/* + This Software is provided under the Zope Public License (ZPL) Version 2.1. + + Copyright (c) 2011 by the mingw-w64 project + + See the AUTHORS file for the list of contributors to the mingw-w64 project. + + This license has been certified as open source. It has also been designated + as GPL compatible by the Free Software Foundation (FSF). + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions in source code must retain the accompanying copyright + notice, this list of conditions, and the following disclaimer. + 2. Redistributions in binary form must reproduce the accompanying + copyright notice, this list of conditions, and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + 3. Names of the copyright holders must not be used to endorse or promote + products derived from this software without prior written permission + from the copyright holders. + 4. The right to distribute this software or to use it for any purpose does + not give you the right to use Servicemarks (sm) or Trademarks (tm) of + the copyright holders. Use of them is covered by separate agreement + with the copyright holders. + 5. If any files are modified, you must cause the modified files to carry + prominent notices stating that you changed the files and the date of + any change. + + Disclaimer + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#define __LARGE_MBSTATE_T + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mingw_sformat.h" + +/* Helper flags for conversion. */ +#define IS_C 0x0001 +#define IS_S 0x0002 +#define IS_L 0x0004 +#define IS_LL 0x0008 +#define IS_SIGNED_NUM 0x0010 +#define IS_POINTER 0x0020 +#define IS_HEX_FLOAT 0x0040 +#define IS_SUPPRESSED 0x0080 +#define USE_GROUP 0x0100 +#define USE_GNU_ALLOC 0x0200 +#define USE_POSIX_ALLOC 0x0400 + +#define IS_ALLOC_USED (USE_GNU_ALLOC | USE_POSIX_ALLOC) + +static void * +get_va_nth (va_list argp, unsigned int n) +{ + va_list ap; + if (!n) abort (); + va_copy (ap, argp); + while (--n > 0) + (void) va_arg(ap, void *); + return va_arg (ap, void *); +} + +static void +optimize_alloc (char **p, char *end, size_t alloc_sz) +{ + size_t need_sz; + char *h; + + if (!p || !*p) + return; + + need_sz = end - *p; + if (need_sz == alloc_sz) + return; + + if ((h = (char *) realloc (*p, need_sz)) != NULL) + *p = h; +} + +static void +back_ch (int c, _IFP *s, size_t *rin, int not_eof) +{ + if (!not_eof && c == EOF) + return; + if (s->is_string == 0) + { + FILE *fp = s->fp; + ungetc (c, fp); + rin[0] -= 1; + return; + } + rin[0] -= 1; + s->bch[s->back_top] = c; + s->back_top += 1; +} + +static int +in_ch (_IFP *s, size_t *rin) +{ + int r; + if (s->back_top) + { + s->back_top -= 1; + r = s->bch[s->back_top]; + rin[0] += 1; + } + else if (s->seen_eof) + { + return EOF; + } + else if (s->is_string) + { + const char *ps = s->str; + r = ((int) *ps) & 0xff; + ps++; + if (r != 0) + { + rin[0] += 1; + s->str = ps; + return r; + } + s->seen_eof = 1; + return EOF; + } + else + { + FILE *fp = (FILE *) s->fp; + r = getc (fp); + if (r != EOF) + rin[0] += 1; + else s->seen_eof = 1; + } + return r; +} + +static int +match_string (_IFP *s, size_t *rin, int *c, const char *str) +{ + int ch = *c; + + if (*str == 0) + return 1; + + if (*str != (char) tolower (ch)) + return 0; + ++str; + while (*str != 0) + { + if ((ch = in_ch (s, rin)) == EOF) + { + c[0] = ch; + return 0; + } + + if (*str != (char) tolower (ch)) + { + c[0] = ch; + return 0; + } + ++str; + } + c[0] = ch; + return 1; +} + +struct gcollect +{ + size_t count; + struct gcollect *next; + char **ptrs[32]; +}; + +static void +release_ptrs (struct gcollect **pt, char **wbuf) +{ + struct gcollect *pf; + size_t cnt; + + if (wbuf) + { + free (*wbuf); + *wbuf = NULL; + } + if (!pt || (pf = *pt) == NULL) + return; + while (pf != NULL) + { + struct gcollect *pf_sv = pf; + for (cnt = 0; cnt < pf->count; ++cnt) + { + free (*pf->ptrs[cnt]); + *pf->ptrs[cnt] = NULL; + } + pf = pf->next; + free (pf_sv); + } + *pt = NULL; +} + +static int +cleanup_return (int rval, struct gcollect **pfree, char **strp, char **wbuf) +{ + if (rval == EOF) + release_ptrs (pfree, wbuf); + else + { + if (pfree) + { + struct gcollect *pf = *pfree, *pf_sv; + while (pf != NULL) + { + pf_sv = pf; + pf = pf->next; + free (pf_sv); + } + *pfree = NULL; + } + if (strp != NULL) + { + free (*strp); + *strp = NULL; + } + if (wbuf) + { + free (*wbuf); + *wbuf = NULL; + } + } + return rval; +} + +static struct gcollect * +resize_gcollect (struct gcollect *pf) +{ + struct gcollect *np; + if (pf && pf->count < 32) + return pf; + np = malloc (sizeof (struct gcollect)); + np->count = 0; + np->next = pf; + return np; +} + +static char * +resize_wbuf (size_t wpsz, size_t *wbuf_max_sz, char *old) +{ + char *wbuf; + size_t nsz; + if (*wbuf_max_sz != wpsz) + return old; + nsz = (256 > (2 * wbuf_max_sz[0]) ? 256 : (2 * wbuf_max_sz[0])); + if (!old) + wbuf = (char *) malloc (nsz); + else + wbuf = (char *) realloc (old, nsz); + if (!wbuf) + { + if (old) + free (old); + } + else + *wbuf_max_sz = nsz; + return wbuf; +} + +int +__cdecl +__mingw_sformat (_IFP *s, const char *format, va_list argp) +{ + const char *f = format; + struct gcollect *gcollect = NULL; + size_t read_in = 0, wbuf_max_sz = 0, cnt; + ssize_t str_sz = 0; + char *str = NULL, **pstr = NULL, *wbuf = NULL; + wchar_t *wstr = NULL; + int rval = 0, c = 0, ignore_ws = 0; + va_list arg; + unsigned char fc; + unsigned int npos; + int width, flags, base = 0, errno_sv; + size_t wbuf_cur_sz, read_in_sv, new_sz, n; + char seen_dot, seen_exp, is_neg, not_in; + char *tmp_wbuf_ptr, buf[MB_LEN_MAX]; + const char *lc_decimal_point, *lc_thousands_sep; + mbstate_t state, cstate; + union { + unsigned long long ull; + unsigned long ul; + long long ll; + long l; + } cv_val; + + arg = argp; + + if (!s || s->fp == NULL || !format) + { + errno = EINVAL; + return EOF; + } + + memset (&state, 0, sizeof (state)); + + lc_decimal_point = localeconv()->decimal_point; + lc_thousands_sep = localeconv()->thousands_sep; + if (lc_thousands_sep != NULL && *lc_thousands_sep == 0) + lc_thousands_sep = NULL; + + while (*f != 0) + { + if (!isascii ((unsigned char) *f)) + { + int len; + + if ((len = mbrlen (f, strlen (f), &state)) > 0) + { + do + { + if ((c = in_ch (s, &read_in)) == EOF || c != (unsigned char) *f++) + { + back_ch (c, s, &read_in, 1); + return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); + } + } + while (--len > 0); + + continue; + } + } + + fc = *f++; + if (fc != '%') + { + if (isspace (fc)) + ignore_ws = 1; + else + { + if ((c = in_ch (s, &read_in)) == EOF) + return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); + + if (ignore_ws) + { + ignore_ws = 0; + if (isspace (c)) + { + do + { + if ((c = in_ch (s, &read_in)) == EOF) + return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); + } + while (isspace (c)); + } + } + + if (c != fc) + { + back_ch (c, s, &read_in, 0); + return cleanup_return (rval, &gcollect, pstr, &wbuf); + } + } + + continue; + } + + width = flags = 0; + npos = 0; + wbuf_cur_sz = 0; + + if (isdigit ((unsigned char) *f)) + { + const char *svf = f; + npos = (unsigned char) *f++ - '0'; + while (isdigit ((unsigned char) *f)) + npos = npos * 10 + ((unsigned char) *f++ - '0'); + if (*f != '$') + { + npos = 0; + f = svf; + } + else + f++; + } + + do + { + if (*f == '*') + flags |= IS_SUPPRESSED; + else if (*f == '\'') + { + if (lc_thousands_sep) + flags |= USE_GROUP; + } + else if (*f == 'I') + { + /* we don't support locale's digits (i18N), but ignore it for now silently. */ + ; +#ifdef _WIN32 + if (f[1] == '6' && f[2] == '4') + { + flags |= IS_LL | IS_L; + f += 2; + } + else if (f[1] == '3' && f[2] == '2') + { + flags |= IS_L; + f += 2; + } + else + { +#ifdef _WIN64 + flags |= IS_LL | IS_L; +#else + flags |= IS_L; +#endif + } +#endif + } + else + break; + ++f; + } + while (1); + + while (isdigit ((unsigned char) *f)) + width = width * 10 + ((unsigned char) *f++ - '0'); + + if (!width) + width = -1; + + switch (*f) + { + case 'h': + ++f; + flags |= (*f == 'h' ? IS_C : IS_S); + if (*f == 'h') + ++f; + break; + case 'l': + ++f; + flags |= (*f == 'l' ? IS_LL : 0) | IS_L; + if (*f == 'l') + ++f; + break; + case 'q': case 'L': + ++f; + flags |= IS_LL | IS_L; + break; + case 'a': + if (f[1] != 's' && f[1] != 'S' && f[1] != '[') + break; + ++f; + flags |= USE_GNU_ALLOC; + break; + case 'm': + flags |= USE_POSIX_ALLOC; + ++f; + if (*f == 'l') + { + flags |= IS_L; + f++; + } + break; + case 'z': +#ifdef _WIN64 + flags |= IS_LL | IS_L; +#else + flags |= IS_L; +#endif + ++f; + break; + case 'j': + if (sizeof (uintmax_t) > sizeof (unsigned long)) + flags |= IS_LL; + else if (sizeof (uintmax_t) > sizeof (unsigned int)) + flags |= IS_L; + ++f; + break; + case 't': +#ifdef _WIN64 + flags |= IS_LL; +#else + flags |= IS_L; +#endif + ++f; + break; + case 0: + return cleanup_return (rval, &gcollect, pstr, &wbuf); + default: + break; + } + + if (*f == 0) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + + fc = *f++; + if (ignore_ws || (fc != '[' && fc != 'c' && fc != 'C' && fc != 'n')) + { + errno_sv = errno; + errno = 0; + do + { + if ((c == EOF || (c = in_ch (s, &read_in)) == EOF) + && errno == EINTR) + return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); + } + while (isspace (c)); + + ignore_ws = 0; + errno = errno_sv; + back_ch (c, s, &read_in, 0); + } + + switch (fc) + { + case 'c': + if ((flags & IS_L) != 0) + fc = 'C'; + break; + case 's': + if ((flags & IS_L) != 0) + fc = 'S'; + break; + } + + switch (fc) + { + case '%': + if ((c = in_ch (s, &read_in)) == EOF) + return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); + if (c != fc) + { + back_ch (c, s, &read_in, 1); + return cleanup_return (rval, &gcollect, pstr, &wbuf); + } + break; + + case 'n': + if ((flags & IS_SUPPRESSED) == 0) + { + if ((flags & IS_LL) != 0) + *(npos != 0 ? (long long *) get_va_nth (argp, npos) : va_arg (arg, long long *)) = read_in; + else if ((flags & IS_L) != 0) + *(npos != 0 ? (long *) get_va_nth (argp, npos) : va_arg (arg, long *)) = read_in; + else if ((flags & IS_S) != 0) + *(npos != 0 ? (short *) get_va_nth (argp, npos) : va_arg (arg, short *)) = read_in; + else if ((flags & IS_C) != 0) + *(npos != 0 ? (char *) get_va_nth (argp, npos) : va_arg (arg, char *)) = read_in; + else + *(npos != 0 ? (int *) get_va_nth (argp, npos) : va_arg (arg, int *)) = read_in; + } + break; + + case 'c': + if (width == -1) + width = 1; + + if ((flags & IS_SUPPRESSED) == 0) + { + if ((flags & IS_ALLOC_USED) != 0) + { + if (npos != 0) + pstr = (char **) get_va_nth (argp, npos); + else + pstr = va_arg (arg, char **); + + if (!pstr) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + + str_sz = (width > 1024 ? 1024 : width); + if ((str = *pstr = (char *) malloc (str_sz)) == NULL) + return cleanup_return (((flags & USE_POSIX_ALLOC) != 0 ? EOF : rval), &gcollect, pstr, &wbuf); + + gcollect = resize_gcollect (gcollect); + gcollect->ptrs[gcollect->count++] = pstr; + } + else + { + if (npos != 0) + str = (char *) get_va_nth (argp, npos); + else + str = va_arg (arg, char *); + if (!str) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + } + } + + if ((c = in_ch (s, &read_in)) == EOF) + return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); + + if ((flags & IS_SUPPRESSED) == 0) + { + do + { + if ((flags & IS_ALLOC_USED) != 0 && str == (*pstr + str_sz)) + { + new_sz = str_sz + (str_sz >= width ? width - 1 : str_sz); + while ((str = (char *) realloc (*pstr, new_sz)) == NULL + && new_sz > (size_t) (str_sz + 1)) + new_sz = str_sz + 1; + if (!str) + { + release_ptrs (&gcollect, &wbuf); + return EOF; + } + *pstr = str; + str += str_sz; + str_sz = new_sz; + } + *str++ = c; + } + while (--width > 0 && (c = in_ch (s, &read_in)) != EOF); + } + else + while (--width > 0 && (c = in_ch (s, &read_in)) != EOF); + + if ((flags & IS_SUPPRESSED) == 0) + { + optimize_alloc (pstr, str, str_sz); + pstr = NULL; + ++rval; + } + + break; + + case 'C': + if (width == -1) + width = 1; + + if ((flags & IS_SUPPRESSED) == 0) + { + if ((flags & IS_ALLOC_USED) != 0) + { + if (npos != 0) + pstr = (char **) get_va_nth (argp, npos); + else + pstr = va_arg (arg, char **); + + if (!pstr) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + str_sz = (width > 1024 ? 1024 : width); + *pstr = (char *) malloc (str_sz * sizeof (wchar_t)); + if ((wstr = (wchar_t *) *pstr) == NULL) + return cleanup_return (((flags & USE_POSIX_ALLOC) != 0 ? EOF : rval), &gcollect, pstr, &wbuf); + gcollect = resize_gcollect (gcollect); + gcollect->ptrs[gcollect->count++] = pstr; + } + else + { + if (npos != 0) + wstr = (wchar_t *) get_va_nth (argp, npos); + else + wstr = va_arg (arg, wchar_t *); + if (!wstr) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + } + } + + if ((c = in_ch (s, &read_in)) == EOF) + return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); + + memset (&cstate, 0, sizeof (cstate)); + + do + { + buf[0] = c; + + if ((flags & IS_SUPPRESSED) == 0 && (flags & IS_ALLOC_USED) != 0 + && wstr == ((wchar_t *) *pstr + str_sz)) + { + new_sz = str_sz + (str_sz > width ? width - 1 : str_sz); + + while ((wstr = (wchar_t *) realloc (*pstr, new_sz * sizeof (wchar_t))) == NULL + && new_sz > (size_t) (str_sz + 1)) + new_sz = str_sz + 1; + if (!wstr) + { + release_ptrs (&gcollect, &wbuf); + return EOF; + } + *pstr = (char *) wstr; + wstr += str_sz; + str_sz = new_sz; + } + + while (1) + { + n = mbrtowc ((flags & IS_SUPPRESSED) == 0 ? wstr : NULL, buf, 1, &cstate); + + if (n == (size_t) -2) + { + if ((c = in_ch (s, &read_in)) == EOF) + { + errno = EILSEQ; + return cleanup_return (rval, &gcollect, pstr, &wbuf); + } + + buf[0] = c; + continue; + } + + if (n != 1) + { + errno = EILSEQ; + return cleanup_return (rval, &gcollect, pstr, &wbuf); + } + break; + } + + ++wstr; + } + while (--width > 0 && (c = in_ch (s, &read_in)) != EOF); + + if ((flags & IS_SUPPRESSED) == 0) + { + optimize_alloc (pstr, (char *) wstr, str_sz * sizeof (wchar_t)); + pstr = NULL; + ++rval; + } + break; + + case 's': + if ((flags & IS_SUPPRESSED) == 0) + { + if ((flags & IS_ALLOC_USED) != 0) + { + if (npos != 0) + pstr = (char **) get_va_nth (argp, npos); + else + pstr = va_arg (arg, char **); + + if (!pstr) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + + str_sz = 100; + if ((str = *pstr = (char *) malloc (100)) == NULL) + return cleanup_return (((flags & USE_POSIX_ALLOC) != 0 ? EOF : rval), &gcollect, pstr, &wbuf); + gcollect = resize_gcollect (gcollect); + gcollect->ptrs[gcollect->count++] = pstr; + } + else + { + if (npos != 0) + str = (char *) get_va_nth (argp, npos); + else + str = va_arg (arg, char *); + if (!str) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + } + } + + if ((c = in_ch (s, &read_in)) == EOF) + return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); + + do + { + if (isspace (c)) + { + back_ch (c, s, &read_in, 1); + break; + } + + if ((flags & IS_SUPPRESSED) == 0) + { + *str++ = c; + if ((flags & IS_ALLOC_USED) != 0 && str == (*pstr + str_sz)) + { + new_sz = str_sz * 2; + + while ((str = (char *) realloc (*pstr, new_sz)) == NULL + && new_sz > (size_t) (str_sz + 1)) + new_sz = str_sz + 1; + if (!str) + { + if ((flags & USE_POSIX_ALLOC) == 0) + { + (*pstr)[str_sz - 1] = 0; + pstr = NULL; + ++rval; + } + return cleanup_return (((flags & USE_POSIX_ALLOC) != 0 ? EOF : rval), &gcollect, pstr, &wbuf); + } + *pstr = str; + str += str_sz; + str_sz = new_sz; + } + } + } + while ((width <= 0 || --width > 0) && (c = in_ch (s, &read_in)) != EOF); + + if ((flags & IS_SUPPRESSED) == 0) + { + *str++ = 0; + optimize_alloc (pstr, str, str_sz); + pstr = NULL; + ++rval; + } + break; + + case 'S': + if ((flags & IS_SUPPRESSED) == 0) + { + if ((flags & IS_ALLOC_USED) != 0) + { + if (npos != 0) + pstr = (char **) get_va_nth (argp, npos); + else + pstr = va_arg (arg, char **); + + if (!pstr) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + + str_sz = 100; + *pstr = (char *) malloc (100 * sizeof (wchar_t)); + if ((wstr = (wchar_t *) *pstr) == NULL) + return cleanup_return (((flags & USE_POSIX_ALLOC) != 0 ? EOF : rval), &gcollect, pstr, &wbuf); + gcollect = resize_gcollect (gcollect); + gcollect->ptrs[gcollect->count++] = pstr; + } + else + { + if (npos != 0) + wstr = (wchar_t *) get_va_nth (argp, npos); + else + wstr = va_arg (arg, wchar_t *); + if (!wstr) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + } + } + + if ((c = in_ch (s, &read_in)) == EOF) + return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); + + memset (&cstate, 0, sizeof (cstate)); + + do + { + if (isspace (c)) + { + back_ch (c, s, &read_in, 1); + break; + } + + buf[0] = c; + + while (1) + { + n = mbrtowc ((flags & IS_SUPPRESSED) == 0 ? wstr : NULL, buf, 1, &cstate); + + if (n == (size_t) -2) + { + if ((c = in_ch (s, &read_in)) == EOF) + { + errno = EILSEQ; + return cleanup_return (rval, &gcollect, pstr, &wbuf); + } + + buf[0] = c; + continue; + } + + if (n != 1) + { + errno = EILSEQ; + return cleanup_return (rval, &gcollect, pstr, &wbuf); + } + + ++wstr; + break; + } + + if ((flags & IS_SUPPRESSED) == 0 && (flags & IS_ALLOC_USED) != 0 + && wstr == ((wchar_t *) *pstr + str_sz)) + { + new_sz = str_sz * 2; + while ((wstr = (wchar_t *) realloc (*pstr, new_sz * sizeof (wchar_t))) == NULL + && new_sz > (size_t) (str_sz + 1)) + new_sz = str_sz + 1; + if (!wstr) + { + if ((flags & USE_POSIX_ALLOC) == 0) + { + ((wchar_t *) (*pstr))[str_sz - 1] = 0; + pstr = NULL; + ++rval; + } + return cleanup_return (((flags & USE_POSIX_ALLOC) != 0 ? EOF : rval), &gcollect, pstr, &wbuf); + } + *pstr = (char *) wstr; + wstr += str_sz; + str_sz = new_sz; + } + } + while ((width <= 0 || --width > 0) && (c = in_ch (s, &read_in)) != EOF); + + if ((flags & IS_SUPPRESSED) == 0) + { + *wstr++ = 0; + optimize_alloc (pstr, (char *) wstr, str_sz * sizeof (wchar_t)); + pstr = NULL; + ++rval; + } + break; + + case 'd': case 'i': + case 'o': case 'p': + case 'u': + case 'x': case 'X': + switch (fc) + { + case 'd': + flags |= IS_SIGNED_NUM; + base = 10; + break; + case 'i': + flags |= IS_SIGNED_NUM; + base = 0; + break; + case 'o': + base = 8; + break; + case 'p': + base = 16; + flags &= ~(IS_S | IS_LL | IS_L); + #ifdef _WIN64 + flags |= IS_LL; + #endif + flags |= IS_L | IS_POINTER; + break; + case 'u': + base = 10; + break; + case 'x': case 'X': + base = 16; + break; + } + + if ((c = in_ch (s, &read_in)) == EOF) + return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); + if (c == '+' || c == '-') + { + wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); + wbuf[wbuf_cur_sz++] = c; + if (width > 0) + --width; + c = in_ch (s, &read_in); + } + if (width != 0 && c == '0') + { + if (width > 0) + --width; + + wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); + wbuf[wbuf_cur_sz++] = c; + c = in_ch (s, &read_in); + + if (width != 0 && tolower (c) == 'x') + { + if (!base) + base = 16; + if (base == 16) + { + if (width > 0) + --width; + c = in_ch (s, &read_in); + } + } + else if (!base) + base = 8; + } + + if (!base) + base = 10; + + while (c != EOF && width != 0) + { + if (base == 16) + { + if (!isxdigit (c)) + break; + } + else if (!isdigit (c) || (int) (c - '0') >= base) + { + const char *p = lc_thousands_sep; + int remain; + + if (base != 10 || (flags & USE_GROUP) == 0) + break; + remain = width > 0 ? width : INT_MAX; + while ((unsigned char) *p == c && remain >= 0) + { + /* As our conversion routines aren't supporting thousands + separators, we are filtering them here. */ + + ++p; + if (*p == 0 || !remain || (c = in_ch (s, &read_in)) == EOF) + break; + --remain; + } + + if (*p != 0) + { + if (p > lc_thousands_sep) + { + back_ch (c, s, &read_in, 0); + while (--p > lc_thousands_sep) + back_ch ((unsigned char) *p, s, &read_in, 1); + c = (unsigned char) *p; + } + break; + } + + if (width > 0) + width = remain; + --wbuf_cur_sz; + } + wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); + wbuf[wbuf_cur_sz++] = c; + if (width > 0) + --width; + + c = in_ch (s, &read_in); + } + + if (!wbuf_cur_sz || (wbuf_cur_sz == 1 && (wbuf[0] == '+' || wbuf[0] == '-'))) + { + if (!wbuf_cur_sz && (flags & IS_POINTER) != 0 + && match_string (s, &read_in, &c, "(nil)")) + { + wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); + wbuf[wbuf_cur_sz++] = '0'; + } + else + { + back_ch (c, s, &read_in, 0); + return cleanup_return (rval, &gcollect, pstr, &wbuf); + } + } + else + back_ch (c, s, &read_in, 0); + + wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); + wbuf[wbuf_cur_sz++] = 0; + + if ((flags & IS_LL)) + { + if (flags & IS_SIGNED_NUM) + cv_val.ll = strtoll (wbuf, &tmp_wbuf_ptr, base/*, flags & USE_GROUP*/); + else + cv_val.ull = strtoull (wbuf, &tmp_wbuf_ptr, base); + } + else + { + if (flags & IS_SIGNED_NUM) + cv_val.l = strtol (wbuf, &tmp_wbuf_ptr, base/*, flags & USE_GROUP*/); + else + cv_val.ul = strtoul (wbuf, &tmp_wbuf_ptr, base); + } + if (wbuf == tmp_wbuf_ptr) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + + if ((flags & IS_SUPPRESSED) == 0) + { + if ((flags & IS_SIGNED_NUM) != 0) + { + if ((flags & IS_LL) != 0) + *(npos != 0 ? (long long *) get_va_nth (argp, npos) : va_arg (arg, long long *)) = cv_val.ll; + else if ((flags & IS_L) != 0) + *(npos != 0 ? (long *) get_va_nth (argp, npos) : va_arg (arg, long *)) = cv_val.l; + else if ((flags & IS_S) != 0) + *(npos != 0 ? (short *) get_va_nth (argp, npos) : va_arg (arg, short *)) = (short) cv_val.l; + else if ((flags & IS_C) != 0) + *(npos != 0 ? (signed char *) get_va_nth (argp, npos) : va_arg (arg, signed char *)) = (signed char) cv_val.ul; + else + *(npos != 0 ? (int *) get_va_nth (argp, npos) : va_arg (arg, int *)) = (int) cv_val.l; + } + else + { + if ((flags & IS_LL) != 0) + *(npos != 0 ? (unsigned long long *) get_va_nth (argp, npos) : va_arg (arg, unsigned long long *)) = cv_val.ull; + else if ((flags & IS_L) != 0) + *(npos != 0 ? (unsigned long *) get_va_nth (argp, npos) : va_arg (arg, unsigned long *)) = cv_val.ul; + else if ((flags & IS_S) != 0) + *(npos != 0 ? (unsigned short *) get_va_nth (argp, npos) : va_arg (arg, unsigned short *)) + = (unsigned short) cv_val.ul; + else if ((flags & IS_C) != 0) + *(npos != 0 ? (unsigned char *) get_va_nth (argp, npos) : va_arg (arg, unsigned char *)) = (unsigned char) cv_val.ul; + else + *(npos != 0 ? (unsigned int *) get_va_nth (argp, npos) : va_arg (arg, unsigned int *)) = (unsigned int) cv_val.ul; + } + ++rval; + } + break; + + case 'e': case 'E': + case 'f': case 'F': + case 'g': case 'G': + case 'a': case 'A': + if (width > 0) + --width; + if ((c = in_ch (s, &read_in)) == EOF) + return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); + + seen_dot = seen_exp = 0; + is_neg = (c == '-' ? 1 : 0); + + if (c == '-' || c == '+') + { + if (width == 0 || (c = in_ch (s, &read_in)) == EOF) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + if (width > 0) + --width; + } + + if (tolower (c) == 'n') + { + const char *match_txt = "nan"; + + wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); + wbuf[wbuf_cur_sz++] = c; + + ++match_txt; + do + { + if (width == 0 || (c = in_ch (s, &read_in)) == EOF || tolower (c) != match_txt[0]) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + + if (width > 0) + --width; + + wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); + wbuf[wbuf_cur_sz++] = c; + ++match_txt; + } + while (*match_txt != 0); + } + else if (tolower (c) == 'i') + { + const char *match_txt = "inf"; + + wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); + wbuf[wbuf_cur_sz++] = c; + + ++match_txt; + do + { + if (width == 0 || (c = in_ch (s, &read_in)) == EOF || tolower (c) != match_txt[0]) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + if (width > 0) + --width; + + wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); + wbuf[wbuf_cur_sz++] = c; + ++match_txt; + } + while (*match_txt != 0); + + if (width != 0 && (c = in_ch (s, &read_in)) != EOF && tolower (c) == 'i') + { + match_txt = "inity"; + + if (width > 0) + --width; + + wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); + wbuf[wbuf_cur_sz++] = c; + ++match_txt; + + do + { + if (width == 0 || (c = in_ch (s, &read_in)) == EOF || tolower (c) != match_txt[0]) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + if (width > 0) + --width; + + wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); + wbuf[wbuf_cur_sz++] = c; + ++match_txt; + } + while (*match_txt != 0); + } + else if (width != 0 && c != EOF) + back_ch (c, s, &read_in, 0); + } + else + { + not_in = 'e'; + if (width != 0 && c == '0') + { + wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); + wbuf[wbuf_cur_sz++] = c; + + c = in_ch (s, &read_in); + if (width > 0) + --width; + if (width != 0 && tolower (c) == 'x') + { + wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); + wbuf[wbuf_cur_sz++] = c; + + flags |= IS_HEX_FLOAT; + not_in = 'p'; + + flags &= ~USE_GROUP; + c = in_ch (s, &read_in); + if (width > 0) + --width; + } + } + + while (1) + { + if (isdigit (c) || (!seen_exp && (flags & IS_HEX_FLOAT) != 0 && isxdigit (c)) + || (seen_exp && wbuf[wbuf_cur_sz - 1] == not_in && (c == '-' || c == '+'))) + { + wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); + wbuf[wbuf_cur_sz++] = c; + } + else if (wbuf_cur_sz > 0 && !seen_exp && (char) tolower (c) == not_in) + { + wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); + wbuf[wbuf_cur_sz++] = not_in; + seen_exp = seen_dot = 1; + } + else + { + const char *p = lc_decimal_point; + int remain = width > 0 ? width : INT_MAX; + + if (! seen_dot) + { + while ((unsigned char) *p == c && remain >= 0) + { + ++p; + if (*p == 0 || !remain || (c = in_ch (s, &read_in)) == EOF) + break; + --remain; + } + } + + if (*p == 0) + { + for (p = lc_decimal_point; *p != 0; ++p) + { + wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); + wbuf[wbuf_cur_sz++] = (unsigned char) *p; + } + if (width > 0) + width = remain; + seen_dot = 1; + } + else + { + const char *pp = lc_thousands_sep; + + if (!seen_dot && (flags & USE_GROUP) != 0) + { + while ((pp - lc_thousands_sep) < (p - lc_decimal_point) + && *pp == lc_decimal_point[(pp - lc_thousands_sep)]) + ++pp; + if ((pp - lc_thousands_sep) == (p - lc_decimal_point)) + { + while ((unsigned char) *pp == c && remain >= 0) + { + ++pp; + if (*pp == 0 || !remain || (c = in_ch (s, &read_in)) == EOF) + break; + --remain; + } + } + } + + if (pp != NULL && *pp == 0) + { + /* As our conversion routines aren't supporting thousands + separators, we are filtering them here. */ + if (width > 0) + width = remain; + } + else + { + back_ch (c, s, &read_in, 0); + break; + } + } + } + + if (width == 0 || (c = in_ch (s, &read_in)) == EOF) + break; + + if (width > 0) + --width; + } + + if (!wbuf_cur_sz || ((flags & IS_HEX_FLOAT) != 0 && wbuf_cur_sz == 2)) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + } + + wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); + wbuf[wbuf_cur_sz++] = 0; + + if ((flags & IS_LL) != 0) + { + long double ld; + ld = __mingw_strtold (wbuf, &tmp_wbuf_ptr/*, flags & USE_GROUP*/); + if ((flags & IS_SUPPRESSED) == 0 && tmp_wbuf_ptr != wbuf) + *(npos != 0 ? (long double *) get_va_nth (argp, npos) : va_arg (arg, long double *)) = is_neg ? -ld : ld; + } + else if ((flags & IS_L) != 0) + { + double d; + d = (double) __mingw_strtold (wbuf, &tmp_wbuf_ptr/*, flags & USE_GROUP*/); + if ((flags & IS_SUPPRESSED) == 0 && tmp_wbuf_ptr != wbuf) + *(npos != 0 ? (double *) get_va_nth (argp, npos) : va_arg (arg, double *)) = is_neg ? -d : d; + } + else + { + float d = __mingw_strtof (wbuf, &tmp_wbuf_ptr/*, flags & USE_GROUP*/); + if ((flags & IS_SUPPRESSED) == 0 && tmp_wbuf_ptr != wbuf) + *(npos != 0 ? (float *) get_va_nth (argp, npos) : va_arg (arg, float *)) = is_neg ? -d : d; + } + + if (wbuf == tmp_wbuf_ptr) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + + if ((flags & IS_SUPPRESSED) == 0) + ++rval; + break; + + case '[': + if ((flags & IS_L) != 0) + { + if ((flags & IS_SUPPRESSED) == 0) + { + if ((flags & IS_ALLOC_USED) != 0) + { + if (npos != 0) + pstr = (char **) get_va_nth (argp, npos); + else + pstr = va_arg (arg, char **); + + if (!pstr) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + + str_sz = 100; + *pstr = (char *) malloc (100 * sizeof (wchar_t)); + + if ((wstr = (wchar_t *) *pstr) == NULL) + return cleanup_return (((flags & USE_POSIX_ALLOC) != 0 ? EOF : rval), &gcollect, pstr, &wbuf); + gcollect = resize_gcollect (gcollect); + gcollect->ptrs[gcollect->count++] = pstr; + } + else + { + if (npos != 0) + wstr = (wchar_t *) get_va_nth (argp, npos); + else + wstr = va_arg (arg, wchar_t *); + if (!wstr) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + } + } + } + else if ((flags & IS_SUPPRESSED) == 0) + { + if ((flags & IS_ALLOC_USED) != 0) + { + if (npos != 0) + pstr = (char **) get_va_nth (argp, npos); + else + pstr = va_arg (arg, char **); + + if (!pstr) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + + str_sz = 100; + if ((str = *pstr = (char *) malloc (100)) == NULL) + return cleanup_return (((flags & USE_POSIX_ALLOC) != 0 ? EOF : rval), &gcollect, pstr, &wbuf); + + gcollect = resize_gcollect (gcollect); + gcollect->ptrs[gcollect->count++] = pstr; + } + else + { + if (npos != 0) + str = (char *) get_va_nth (argp, npos); + else + str = va_arg (arg, char *); + if (!str) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + } + } + + not_in = (*f == '^' ? 1 : 0); + if (*f == '^') + f++; + + if (width < 0) + width = INT_MAX; + + if (wbuf_max_sz < 256) + { + wbuf_max_sz = 256; + if (wbuf) + free (wbuf); + wbuf = (char *) malloc (wbuf_max_sz); + } + memset (wbuf, 0, 256); + + fc = *f; + if (fc == ']' || fc == '-') + { + wbuf[fc] = 1; + ++f; + } + + while ((fc = *f++) != 0 && fc != ']') + { + if (fc == '-' && *f != 0 && *f != ']' && (unsigned char) f[-2] <= (unsigned char) *f) + { + for (fc = (unsigned char) f[-2]; fc < (unsigned char) *f; ++fc) + wbuf[fc] = 1; + } + else + wbuf[fc] = 1; + } + + if (!fc) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + + if ((flags & IS_L) != 0) + { + read_in_sv = read_in; + cnt = 0; + + if ((c = in_ch (s, &read_in)) == EOF) + return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); + + memset (&cstate, 0, sizeof (cstate)); + + do + { + if (wbuf[c] == not_in) + { + back_ch (c, s, &read_in, 1); + break; + } + + if ((flags & IS_SUPPRESSED) == 0) + { + buf[0] = c; + n = mbrtowc (wstr, buf, 1, &cstate); + + if (n == (size_t) -2) + { + ++cnt; + continue; + } + cnt = 0; + + ++wstr; + if ((flags & IS_ALLOC_USED) != 0 && wstr == ((wchar_t *) *pstr + str_sz)) + { + new_sz = str_sz * 2; + while ((wstr = (wchar_t *) realloc (*pstr, new_sz * sizeof (wchar_t))) == NULL + && new_sz > (size_t) (str_sz + 1)) + new_sz = str_sz + 1; + if (!wstr) + { + if ((flags & USE_POSIX_ALLOC) == 0) + { + ((wchar_t *) (*pstr))[str_sz - 1] = 0; + pstr = NULL; + ++rval; + } + else + rval = EOF; + return cleanup_return (rval, &gcollect, pstr, &wbuf); + } + *pstr = (char *) wstr; + wstr += str_sz; + str_sz = new_sz; + } + } + + if (--width <= 0) + break; + } + while ((c = in_ch (s, &read_in)) != EOF); + + if (cnt != 0) + { + errno = EILSEQ; + return cleanup_return (rval, &gcollect, pstr, &wbuf); + } + + if (read_in_sv == read_in) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + + + if ((flags & IS_SUPPRESSED) == 0) + { + *wstr++ = 0; + optimize_alloc (pstr, (char *) wstr, str_sz * sizeof (wchar_t)); + pstr = NULL; + ++rval; + } + } + else + { + read_in_sv = read_in; + + if ((c = in_ch (s, &read_in)) == EOF) + return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); + + do + { + if (wbuf[c] == not_in) + { + back_ch (c, s, &read_in, 1); + break; + } + + if ((flags & IS_SUPPRESSED) == 0) + { + *str++ = c; + if ((flags & IS_ALLOC_USED) != 0 && str == (*pstr + str_sz)) + { + new_sz = str_sz * 2; + + while ((str = (char *) realloc (*pstr, new_sz)) == NULL + && new_sz > (size_t) (str_sz + 1)) + new_sz = str_sz + 1; + if (!str) + { + if ((flags & USE_POSIX_ALLOC) == 0) + { + (*pstr)[str_sz - 1] = 0; + pstr = NULL; + ++rval; + } + else + rval = EOF; + return cleanup_return (rval, &gcollect, pstr, &wbuf); + } + *pstr = str; + str += str_sz; + str_sz = new_sz; + } + } + } + while (--width > 0 && (c = in_ch (s, &read_in)) != EOF); + + if (read_in_sv == read_in) + return cleanup_return (rval, &gcollect, pstr, &wbuf); + + if ((flags & IS_SUPPRESSED) == 0) + { + *str++ = 0; + optimize_alloc (pstr, str, str_sz); + pstr = NULL; + ++rval; + } + } + break; + + default: + return cleanup_return (rval, &gcollect, pstr, &wbuf); + } + } + + if (ignore_ws) + { + while (isspace ((c = in_ch (s, &read_in)))); + back_ch (c, s, &read_in, 0); + } + + return cleanup_return (rval, &gcollect, pstr, &wbuf); +} diff --git a/lib/libc/mingw/stdio/mingw_sformat.h b/lib/libc/mingw/stdio/mingw_sformat.h new file mode 100644 index 0000000000..7d133dd7f2 --- /dev/null +++ b/lib/libc/mingw/stdio/mingw_sformat.h @@ -0,0 +1,63 @@ +/* + This Software is provided under the Zope Public License (ZPL) Version 2.1. + + Copyright (c) 2011 by the mingw-w64 project + + See the AUTHORS file for the list of contributors to the mingw-w64 project. + + This license has been certified as open source. It has also been designated + as GPL compatible by the Free Software Foundation (FSF). + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions in source code must retain the accompanying copyright + notice, this list of conditions, and the following disclaimer. + 2. Redistributions in binary form must reproduce the accompanying + copyright notice, this list of conditions, and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + 3. Names of the copyright holders must not be used to endorse or promote + products derived from this software without prior written permission + from the copyright holders. + 4. The right to distribute this software or to use it for any purpose does + not give you the right to use Servicemarks (sm) or Trademarks (tm) of + the copyright holders. Use of them is covered by separate agreement + with the copyright holders. + 5. If any files are modified, you must cause the modified files to carry + prominent notices stating that you changed the files and the date of + any change. + + Disclaimer + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef SFORMAT_H +#define SFORMAT_H + +/* internal stream structure with back-buffer. */ +typedef struct _IFP +{ + __extension__ union { + void *fp; + const char *str; + }; + int bch[1024]; + unsigned int is_string : 1; + int back_top; + unsigned int seen_eof : 1; +} _IFP; + +int __cdecl __mingw_sformat(_IFP *, const char *, va_list) __MINGW_NOTHROW; + +#endif /* !defined SFORMAT_H */ diff --git a/lib/libc/mingw/stdio/mingw_snprintfw.c b/lib/libc/mingw/stdio/mingw_snwprintf.c similarity index 100% rename from lib/libc/mingw/stdio/mingw_snprintfw.c rename to lib/libc/mingw/stdio/mingw_snwprintf.c diff --git a/lib/libc/mingw/stdio/mingw_wvfscanf.c b/lib/libc/mingw/stdio/mingw_swformat.c similarity index 97% rename from lib/libc/mingw/stdio/mingw_wvfscanf.c rename to lib/libc/mingw/stdio/mingw_swformat.c index 81cb46b661..5f4b2c08f3 100644 --- a/lib/libc/mingw/stdio/mingw_wvfscanf.c +++ b/lib/libc/mingw/stdio/mingw_swformat.c @@ -57,6 +57,8 @@ #include #include +#include "mingw_swformat.h" + #ifndef CP_UTF8 #define CP_UTF8 65001 #endif @@ -80,19 +82,6 @@ #define IS_ALLOC_USED (USE_GNU_ALLOC | USE_POSIX_ALLOC) -/* internal stream structure with back-buffer. */ -typedef struct _IFP -{ - __extension__ union { - void *fp; - const wchar_t *str; - }; - int bch[1024]; - unsigned int is_string : 1; - int back_top; - unsigned int seen_eof : 1; -} _IFP; - static void * get_va_nth (va_list argp, unsigned int n) { @@ -123,7 +112,7 @@ optimize_alloc (char **p, char *end, size_t alloc_sz) } static void -back_ch (int c, _IFP *s, size_t *rin, int not_eof) +back_ch (int c, _IFPW *s, size_t *rin, int not_eof) { if (!not_eof && c == WEOF) return; @@ -140,7 +129,7 @@ back_ch (int c, _IFP *s, size_t *rin, int not_eof) } static int -in_ch (_IFP *s, size_t *rin) +in_ch (_IFPW *s, size_t *rin) { int r; if (s->back_top) @@ -179,7 +168,7 @@ in_ch (_IFP *s, size_t *rin) } static int -match_string (_IFP *s, size_t *rin, wint_t *c, const wchar_t *str) +match_string (_IFPW *s, size_t *rin, wint_t *c, const wchar_t *str) { int ch = *c; @@ -308,8 +297,9 @@ resize_wbuf (size_t wpsz, size_t *wbuf_max_sz, wchar_t *old) return wbuf; } -static int -__mingw_swformat (_IFP *s, const wchar_t *format, va_list argp) +int +__cdecl +__mingw_swformat (_IFPW *s, const wchar_t *format, va_list argp) { const wchar_t *f = format; struct gcollect *gcollect = NULL; @@ -1609,23 +1599,3 @@ __mingw_swformat (_IFP *s, const wchar_t *format, va_list argp) return cleanup_return (rval, &gcollect, pstr, &wbuf); } - -int -__mingw_vfwscanf (FILE *s, const wchar_t *format, va_list argp) -{ - _IFP ifp; - memset (&ifp, 0, sizeof (_IFP)); - ifp.fp = s; - return __mingw_swformat (&ifp, format, argp); -} - -int -__mingw_vswscanf (const wchar_t *s, const wchar_t *format, va_list argp) -{ - _IFP ifp; - memset (&ifp, 0, sizeof (_IFP)); - ifp.str = s; - ifp.is_string = 1; - return __mingw_swformat (&ifp, format, argp); -} - diff --git a/lib/libc/mingw/stdio/mingw_swformat.h b/lib/libc/mingw/stdio/mingw_swformat.h new file mode 100644 index 0000000000..aea4c53fb6 --- /dev/null +++ b/lib/libc/mingw/stdio/mingw_swformat.h @@ -0,0 +1,63 @@ +/* + This Software is provided under the Zope Public License (ZPL) Version 2.1. + + Copyright (c) 2011 by the mingw-w64 project + + See the AUTHORS file for the list of contributors to the mingw-w64 project. + + This license has been certified as open source. It has also been designated + as GPL compatible by the Free Software Foundation (FSF). + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions in source code must retain the accompanying copyright + notice, this list of conditions, and the following disclaimer. + 2. Redistributions in binary form must reproduce the accompanying + copyright notice, this list of conditions, and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + 3. Names of the copyright holders must not be used to endorse or promote + products derived from this software without prior written permission + from the copyright holders. + 4. The right to distribute this software or to use it for any purpose does + not give you the right to use Servicemarks (sm) or Trademarks (tm) of + the copyright holders. Use of them is covered by separate agreement + with the copyright holders. + 5. If any files are modified, you must cause the modified files to carry + prominent notices stating that you changed the files and the date of + any change. + + Disclaimer + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef SWFORMAT_H +#define SWFORMAT_H + +/* internal stream structure with back-buffer. */ +typedef struct _IFPW +{ + __extension__ union { + void *fp; + const wchar_t *str; + }; + int bch[1024]; + unsigned int is_string : 1; + int back_top; + unsigned int seen_eof : 1; +} _IFPW; + +int __cdecl __mingw_swformat(_IFPW *, const wchar_t *, va_list) __MINGW_NOTHROW; + +#endif /* !defined SWFORMAT_H */ diff --git a/lib/libc/mingw/stdio/mingw_sprintfw.c b/lib/libc/mingw/stdio/mingw_swprintf.c similarity index 78% rename from lib/libc/mingw/stdio/mingw_sprintfw.c rename to lib/libc/mingw/stdio/mingw_swprintf.c index 0baf1e4f38..179c27970e 100644 --- a/lib/libc/mingw/stdio/mingw_sprintfw.c +++ b/lib/libc/mingw/stdio/mingw_swprintf.c @@ -4,7 +4,7 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ #define __BUILD_WIDEAPI 1 -#define _CRT_NON_CONFORMING_SWPRINTFS 1 +#define __BUILD_WIDEAPI_ISO 1 -#include "mingw_sprintf.c" +#include "mingw_snprintf.c" diff --git a/lib/libc/mingw/stdio/mingw_vfscanf.c b/lib/libc/mingw/stdio/mingw_vfscanf.c index 8ca81b54e1..eadc9be321 100644 --- a/lib/libc/mingw/stdio/mingw_vfscanf.c +++ b/lib/libc/mingw/stdio/mingw_vfscanf.c @@ -1,1615 +1,8 @@ -/* - This Software is provided under the Zope Public License (ZPL) Version 2.1. - - Copyright (c) 2011 by the mingw-w64 project - - See the AUTHORS file for the list of contributors to the mingw-w64 project. - - This license has been certified as open source. It has also been designated - as GPL compatible by the Free Software Foundation (FSF). - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions in source code must retain the accompanying copyright - notice, this list of conditions, and the following disclaimer. - 2. Redistributions in binary form must reproduce the accompanying - copyright notice, this list of conditions, and the following disclaimer - in the documentation and/or other materials provided with the - distribution. - 3. Names of the copyright holders must not be used to endorse or promote - products derived from this software without prior written permission - from the copyright holders. - 4. The right to distribute this software or to use it for any purpose does - not give you the right to use Servicemarks (sm) or Trademarks (tm) of - the copyright holders. Use of them is covered by separate agreement - with the copyright holders. - 5. If any files are modified, you must cause the modified files to carry - prominent notices stating that you changed the files and the date of - any change. - - Disclaimer - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED - OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#define __LARGE_MBSTATE_T - -#include -#include #include #include -#include -#include #include -#include -#include -#include -#include -#include -/* Helper flags for conversion. */ -#define IS_C 0x0001 -#define IS_S 0x0002 -#define IS_L 0x0004 -#define IS_LL 0x0008 -#define IS_SIGNED_NUM 0x0010 -#define IS_POINTER 0x0020 -#define IS_HEX_FLOAT 0x0040 -#define IS_SUPPRESSED 0x0080 -#define USE_GROUP 0x0100 -#define USE_GNU_ALLOC 0x0200 -#define USE_POSIX_ALLOC 0x0400 - -#define IS_ALLOC_USED (USE_GNU_ALLOC | USE_POSIX_ALLOC) - -/* internal stream structure with back-buffer. */ -typedef struct _IFP -{ - __extension__ union { - void *fp; - const char *str; - }; - int bch[1024]; - unsigned int is_string : 1; - int back_top; - unsigned int seen_eof : 1; -} _IFP; - -static void * -get_va_nth (va_list argp, unsigned int n) -{ - va_list ap; - if (!n) abort (); - va_copy (ap, argp); - while (--n > 0) - (void) va_arg(ap, void *); - return va_arg (ap, void *); -} - -static void -optimize_alloc (char **p, char *end, size_t alloc_sz) -{ - size_t need_sz; - char *h; - - if (!p || !*p) - return; - - need_sz = end - *p; - if (need_sz == alloc_sz) - return; - - if ((h = (char *) realloc (*p, need_sz)) != NULL) - *p = h; -} - -static void -back_ch (int c, _IFP *s, size_t *rin, int not_eof) -{ - if (!not_eof && c == EOF) - return; - if (s->is_string == 0) - { - FILE *fp = s->fp; - ungetc (c, fp); - rin[0] -= 1; - return; - } - rin[0] -= 1; - s->bch[s->back_top] = c; - s->back_top += 1; -} - -static int -in_ch (_IFP *s, size_t *rin) -{ - int r; - if (s->back_top) - { - s->back_top -= 1; - r = s->bch[s->back_top]; - rin[0] += 1; - } - else if (s->seen_eof) - { - return EOF; - } - else if (s->is_string) - { - const char *ps = s->str; - r = ((int) *ps) & 0xff; - ps++; - if (r != 0) - { - rin[0] += 1; - s->str = ps; - return r; - } - s->seen_eof = 1; - return EOF; - } - else - { - FILE *fp = (FILE *) s->fp; - r = getc (fp); - if (r != EOF) - rin[0] += 1; - else s->seen_eof = 1; - } - return r; -} - -static int -match_string (_IFP *s, size_t *rin, int *c, const char *str) -{ - int ch = *c; - - if (*str == 0) - return 1; - - if (*str != (char) tolower (ch)) - return 0; - ++str; - while (*str != 0) - { - if ((ch = in_ch (s, rin)) == EOF) - { - c[0] = ch; - return 0; - } - - if (*str != (char) tolower (ch)) - { - c[0] = ch; - return 0; - } - ++str; - } - c[0] = ch; - return 1; -} - -struct gcollect -{ - size_t count; - struct gcollect *next; - char **ptrs[32]; -}; - -static void -release_ptrs (struct gcollect **pt, char **wbuf) -{ - struct gcollect *pf; - size_t cnt; - - if (wbuf) - { - free (*wbuf); - *wbuf = NULL; - } - if (!pt || (pf = *pt) == NULL) - return; - while (pf != NULL) - { - struct gcollect *pf_sv = pf; - for (cnt = 0; cnt < pf->count; ++cnt) - { - free (*pf->ptrs[cnt]); - *pf->ptrs[cnt] = NULL; - } - pf = pf->next; - free (pf_sv); - } - *pt = NULL; -} - -static int -cleanup_return (int rval, struct gcollect **pfree, char **strp, char **wbuf) -{ - if (rval == EOF) - release_ptrs (pfree, wbuf); - else - { - if (pfree) - { - struct gcollect *pf = *pfree, *pf_sv; - while (pf != NULL) - { - pf_sv = pf; - pf = pf->next; - free (pf_sv); - } - *pfree = NULL; - } - if (strp != NULL) - { - free (*strp); - *strp = NULL; - } - if (wbuf) - { - free (*wbuf); - *wbuf = NULL; - } - } - return rval; -} - -static struct gcollect * -resize_gcollect (struct gcollect *pf) -{ - struct gcollect *np; - if (pf && pf->count < 32) - return pf; - np = malloc (sizeof (struct gcollect)); - np->count = 0; - np->next = pf; - return np; -} - -static char * -resize_wbuf (size_t wpsz, size_t *wbuf_max_sz, char *old) -{ - char *wbuf; - size_t nsz; - if (*wbuf_max_sz != wpsz) - return old; - nsz = (256 > (2 * wbuf_max_sz[0]) ? 256 : (2 * wbuf_max_sz[0])); - if (!old) - wbuf = (char *) malloc (nsz); - else - wbuf = (char *) realloc (old, nsz); - if (!wbuf) - { - if (old) - free (old); - } - else - *wbuf_max_sz = nsz; - return wbuf; -} - -static int -__mingw_sformat (_IFP *s, const char *format, va_list argp) -{ - const char *f = format; - struct gcollect *gcollect = NULL; - size_t read_in = 0, wbuf_max_sz = 0, cnt; - ssize_t str_sz = 0; - char *str = NULL, **pstr = NULL, *wbuf = NULL; - wchar_t *wstr = NULL; - int rval = 0, c = 0, ignore_ws = 0; - va_list arg; - unsigned char fc; - unsigned int npos; - int width, flags, base = 0, errno_sv; - size_t wbuf_cur_sz, read_in_sv, new_sz, n; - char seen_dot, seen_exp, is_neg, not_in; - char *tmp_wbuf_ptr, buf[MB_LEN_MAX]; - const char *lc_decimal_point, *lc_thousands_sep; - mbstate_t state, cstate; - union { - unsigned long long ull; - unsigned long ul; - long long ll; - long l; - } cv_val; - - arg = argp; - - if (!s || s->fp == NULL || !format) - { - errno = EINVAL; - return EOF; - } - - memset (&state, 0, sizeof (state)); - - lc_decimal_point = localeconv()->decimal_point; - lc_thousands_sep = localeconv()->thousands_sep; - if (lc_thousands_sep != NULL && *lc_thousands_sep == 0) - lc_thousands_sep = NULL; - - while (*f != 0) - { - if (!isascii ((unsigned char) *f)) - { - int len; - - if ((len = mbrlen (f, strlen (f), &state)) > 0) - { - do - { - if ((c = in_ch (s, &read_in)) == EOF || c != (unsigned char) *f++) - { - back_ch (c, s, &read_in, 1); - return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - } - } - while (--len > 0); - - continue; - } - } - - fc = *f++; - if (fc != '%') - { - if (isspace (fc)) - ignore_ws = 1; - else - { - if ((c = in_ch (s, &read_in)) == EOF) - return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - - if (ignore_ws) - { - ignore_ws = 0; - if (isspace (c)) - { - do - { - if ((c = in_ch (s, &read_in)) == EOF) - return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - } - while (isspace (c)); - } - } - - if (c != fc) - { - back_ch (c, s, &read_in, 0); - return cleanup_return (rval, &gcollect, pstr, &wbuf); - } - } - - continue; - } - - width = flags = 0; - npos = 0; - wbuf_cur_sz = 0; - - if (isdigit ((unsigned char) *f)) - { - const char *svf = f; - npos = (unsigned char) *f++ - '0'; - while (isdigit ((unsigned char) *f)) - npos = npos * 10 + ((unsigned char) *f++ - '0'); - if (*f != '$') - { - npos = 0; - f = svf; - } - else - f++; - } - - do - { - if (*f == '*') - flags |= IS_SUPPRESSED; - else if (*f == '\'') - { - if (lc_thousands_sep) - flags |= USE_GROUP; - } - else if (*f == 'I') - { - /* we don't support locale's digits (i18N), but ignore it for now silently. */ - ; -#ifdef _WIN32 - if (f[1] == '6' && f[2] == '4') - { - flags |= IS_LL | IS_L; - f += 2; - } - else if (f[1] == '3' && f[2] == '2') - { - flags |= IS_L; - f += 2; - } - else - { -#ifdef _WIN64 - flags |= IS_LL | IS_L; -#else - flags |= IS_L; -#endif - } -#endif - } - else - break; - ++f; - } - while (1); - - while (isdigit ((unsigned char) *f)) - width = width * 10 + ((unsigned char) *f++ - '0'); - - if (!width) - width = -1; - - switch (*f) - { - case 'h': - ++f; - flags |= (*f == 'h' ? IS_C : IS_S); - if (*f == 'h') - ++f; - break; - case 'l': - ++f; - flags |= (*f == 'l' ? IS_LL : 0) | IS_L; - if (*f == 'l') - ++f; - break; - case 'q': case 'L': - ++f; - flags |= IS_LL | IS_L; - break; - case 'a': - if (f[1] != 's' && f[1] != 'S' && f[1] != '[') - break; - ++f; - flags |= USE_GNU_ALLOC; - break; - case 'm': - flags |= USE_POSIX_ALLOC; - ++f; - if (*f == 'l') - { - flags |= IS_L; - f++; - } - break; - case 'z': -#ifdef _WIN64 - flags |= IS_LL | IS_L; -#else - flags |= IS_L; -#endif - ++f; - break; - case 'j': - if (sizeof (uintmax_t) > sizeof (unsigned long)) - flags |= IS_LL; - else if (sizeof (uintmax_t) > sizeof (unsigned int)) - flags |= IS_L; - ++f; - break; - case 't': -#ifdef _WIN64 - flags |= IS_LL; -#else - flags |= IS_L; -#endif - ++f; - break; - case 0: - return cleanup_return (rval, &gcollect, pstr, &wbuf); - default: - break; - } - - if (*f == 0) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - - fc = *f++; - if (ignore_ws || (fc != '[' && fc != 'c' && fc != 'C' && fc != 'n')) - { - errno_sv = errno; - errno = 0; - do - { - if ((c == EOF || (c = in_ch (s, &read_in)) == EOF) - && errno == EINTR) - return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - } - while (isspace (c)); - - ignore_ws = 0; - errno = errno_sv; - back_ch (c, s, &read_in, 0); - } - - switch (fc) - { - case 'c': - if ((flags & IS_L) != 0) - fc = 'C'; - break; - case 's': - if ((flags & IS_L) != 0) - fc = 'S'; - break; - } - - switch (fc) - { - case '%': - if ((c = in_ch (s, &read_in)) == EOF) - return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - if (c != fc) - { - back_ch (c, s, &read_in, 1); - return cleanup_return (rval, &gcollect, pstr, &wbuf); - } - break; - - case 'n': - if ((flags & IS_SUPPRESSED) == 0) - { - if ((flags & IS_LL) != 0) - *(npos != 0 ? (long long *) get_va_nth (argp, npos) : va_arg (arg, long long *)) = read_in; - else if ((flags & IS_L) != 0) - *(npos != 0 ? (long *) get_va_nth (argp, npos) : va_arg (arg, long *)) = read_in; - else if ((flags & IS_S) != 0) - *(npos != 0 ? (short *) get_va_nth (argp, npos) : va_arg (arg, short *)) = read_in; - else if ((flags & IS_C) != 0) - *(npos != 0 ? (char *) get_va_nth (argp, npos) : va_arg (arg, char *)) = read_in; - else - *(npos != 0 ? (int *) get_va_nth (argp, npos) : va_arg (arg, int *)) = read_in; - } - break; - - case 'c': - if (width == -1) - width = 1; - - if ((flags & IS_SUPPRESSED) == 0) - { - if ((flags & IS_ALLOC_USED) != 0) - { - if (npos != 0) - pstr = (char **) get_va_nth (argp, npos); - else - pstr = va_arg (arg, char **); - - if (!pstr) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - - str_sz = (width > 1024 ? 1024 : width); - if ((str = *pstr = (char *) malloc (str_sz)) == NULL) - return cleanup_return (((flags & USE_POSIX_ALLOC) != 0 ? EOF : rval), &gcollect, pstr, &wbuf); - - gcollect = resize_gcollect (gcollect); - gcollect->ptrs[gcollect->count++] = pstr; - } - else - { - if (npos != 0) - str = (char *) get_va_nth (argp, npos); - else - str = va_arg (arg, char *); - if (!str) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - } - } - - if ((c = in_ch (s, &read_in)) == EOF) - return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - - if ((flags & IS_SUPPRESSED) == 0) - { - do - { - if ((flags & IS_ALLOC_USED) != 0 && str == (*pstr + str_sz)) - { - new_sz = str_sz + (str_sz >= width ? width - 1 : str_sz); - while ((str = (char *) realloc (*pstr, new_sz)) == NULL - && new_sz > (size_t) (str_sz + 1)) - new_sz = str_sz + 1; - if (!str) - { - release_ptrs (&gcollect, &wbuf); - return EOF; - } - *pstr = str; - str += str_sz; - str_sz = new_sz; - } - *str++ = c; - } - while (--width > 0 && (c = in_ch (s, &read_in)) != EOF); - } - else - while (--width > 0 && (c = in_ch (s, &read_in)) != EOF); - - if ((flags & IS_SUPPRESSED) == 0) - { - optimize_alloc (pstr, str, str_sz); - pstr = NULL; - ++rval; - } - - break; - - case 'C': - if (width == -1) - width = 1; - - if ((flags & IS_SUPPRESSED) == 0) - { - if ((flags & IS_ALLOC_USED) != 0) - { - if (npos != 0) - pstr = (char **) get_va_nth (argp, npos); - else - pstr = va_arg (arg, char **); - - if (!pstr) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - str_sz = (width > 1024 ? 1024 : width); - *pstr = (char *) malloc (str_sz * sizeof (wchar_t)); - if ((wstr = (wchar_t *) *pstr) == NULL) - return cleanup_return (((flags & USE_POSIX_ALLOC) != 0 ? EOF : rval), &gcollect, pstr, &wbuf); - gcollect = resize_gcollect (gcollect); - gcollect->ptrs[gcollect->count++] = pstr; - } - else - { - if (npos != 0) - wstr = (wchar_t *) get_va_nth (argp, npos); - else - wstr = va_arg (arg, wchar_t *); - if (!wstr) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - } - } - - if ((c = in_ch (s, &read_in)) == EOF) - return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - - memset (&cstate, 0, sizeof (cstate)); - - do - { - buf[0] = c; - - if ((flags & IS_SUPPRESSED) == 0 && (flags & IS_ALLOC_USED) != 0 - && wstr == ((wchar_t *) *pstr + str_sz)) - { - new_sz = str_sz + (str_sz > width ? width - 1 : str_sz); - - while ((wstr = (wchar_t *) realloc (*pstr, new_sz * sizeof (wchar_t))) == NULL - && new_sz > (size_t) (str_sz + 1)) - new_sz = str_sz + 1; - if (!wstr) - { - release_ptrs (&gcollect, &wbuf); - return EOF; - } - *pstr = (char *) wstr; - wstr += str_sz; - str_sz = new_sz; - } - - while (1) - { - n = mbrtowc ((flags & IS_SUPPRESSED) == 0 ? wstr : NULL, buf, 1, &cstate); - - if (n == (size_t) -2) - { - if ((c = in_ch (s, &read_in)) == EOF) - { - errno = EILSEQ; - return cleanup_return (rval, &gcollect, pstr, &wbuf); - } - - buf[0] = c; - continue; - } - - if (n != 1) - { - errno = EILSEQ; - return cleanup_return (rval, &gcollect, pstr, &wbuf); - } - break; - } - - ++wstr; - } - while (--width > 0 && (c = in_ch (s, &read_in)) != EOF); - - if ((flags & IS_SUPPRESSED) == 0) - { - optimize_alloc (pstr, (char *) wstr, str_sz * sizeof (wchar_t)); - pstr = NULL; - ++rval; - } - break; - - case 's': - if ((flags & IS_SUPPRESSED) == 0) - { - if ((flags & IS_ALLOC_USED) != 0) - { - if (npos != 0) - pstr = (char **) get_va_nth (argp, npos); - else - pstr = va_arg (arg, char **); - - if (!pstr) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - - str_sz = 100; - if ((str = *pstr = (char *) malloc (100)) == NULL) - return cleanup_return (((flags & USE_POSIX_ALLOC) != 0 ? EOF : rval), &gcollect, pstr, &wbuf); - gcollect = resize_gcollect (gcollect); - gcollect->ptrs[gcollect->count++] = pstr; - } - else - { - if (npos != 0) - str = (char *) get_va_nth (argp, npos); - else - str = va_arg (arg, char *); - if (!str) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - } - } - - if ((c = in_ch (s, &read_in)) == EOF) - return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - - do - { - if (isspace (c)) - { - back_ch (c, s, &read_in, 1); - break; - } - - if ((flags & IS_SUPPRESSED) == 0) - { - *str++ = c; - if ((flags & IS_ALLOC_USED) != 0 && str == (*pstr + str_sz)) - { - new_sz = str_sz * 2; - - while ((str = (char *) realloc (*pstr, new_sz)) == NULL - && new_sz > (size_t) (str_sz + 1)) - new_sz = str_sz + 1; - if (!str) - { - if ((flags & USE_POSIX_ALLOC) == 0) - { - (*pstr)[str_sz - 1] = 0; - pstr = NULL; - ++rval; - } - return cleanup_return (((flags & USE_POSIX_ALLOC) != 0 ? EOF : rval), &gcollect, pstr, &wbuf); - } - *pstr = str; - str += str_sz; - str_sz = new_sz; - } - } - } - while ((width <= 0 || --width > 0) && (c = in_ch (s, &read_in)) != EOF); - - if ((flags & IS_SUPPRESSED) == 0) - { - *str++ = 0; - optimize_alloc (pstr, str, str_sz); - pstr = NULL; - ++rval; - } - break; - - case 'S': - if ((flags & IS_SUPPRESSED) == 0) - { - if ((flags & IS_ALLOC_USED) != 0) - { - if (npos != 0) - pstr = (char **) get_va_nth (argp, npos); - else - pstr = va_arg (arg, char **); - - if (!pstr) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - - str_sz = 100; - *pstr = (char *) malloc (100 * sizeof (wchar_t)); - if ((wstr = (wchar_t *) *pstr) == NULL) - return cleanup_return (((flags & USE_POSIX_ALLOC) != 0 ? EOF : rval), &gcollect, pstr, &wbuf); - gcollect = resize_gcollect (gcollect); - gcollect->ptrs[gcollect->count++] = pstr; - } - else - { - if (npos != 0) - wstr = (wchar_t *) get_va_nth (argp, npos); - else - wstr = va_arg (arg, wchar_t *); - if (!wstr) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - } - } - - if ((c = in_ch (s, &read_in)) == EOF) - return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - - memset (&cstate, 0, sizeof (cstate)); - - do - { - if (isspace (c)) - { - back_ch (c, s, &read_in, 1); - break; - } - - buf[0] = c; - - while (1) - { - n = mbrtowc ((flags & IS_SUPPRESSED) == 0 ? wstr : NULL, buf, 1, &cstate); - - if (n == (size_t) -2) - { - if ((c = in_ch (s, &read_in)) == EOF) - { - errno = EILSEQ; - return cleanup_return (rval, &gcollect, pstr, &wbuf); - } - - buf[0] = c; - continue; - } - - if (n != 1) - { - errno = EILSEQ; - return cleanup_return (rval, &gcollect, pstr, &wbuf); - } - - ++wstr; - break; - } - - if ((flags & IS_SUPPRESSED) == 0 && (flags & IS_ALLOC_USED) != 0 - && wstr == ((wchar_t *) *pstr + str_sz)) - { - new_sz = str_sz * 2; - while ((wstr = (wchar_t *) realloc (*pstr, new_sz * sizeof (wchar_t))) == NULL - && new_sz > (size_t) (str_sz + 1)) - new_sz = str_sz + 1; - if (!wstr) - { - if ((flags & USE_POSIX_ALLOC) == 0) - { - ((wchar_t *) (*pstr))[str_sz - 1] = 0; - pstr = NULL; - ++rval; - } - return cleanup_return (((flags & USE_POSIX_ALLOC) != 0 ? EOF : rval), &gcollect, pstr, &wbuf); - } - *pstr = (char *) wstr; - wstr += str_sz; - str_sz = new_sz; - } - } - while ((width <= 0 || --width > 0) && (c = in_ch (s, &read_in)) != EOF); - - if ((flags & IS_SUPPRESSED) == 0) - { - *wstr++ = 0; - optimize_alloc (pstr, (char *) wstr, str_sz * sizeof (wchar_t)); - pstr = NULL; - ++rval; - } - break; - - case 'd': case 'i': - case 'o': case 'p': - case 'u': - case 'x': case 'X': - switch (fc) - { - case 'd': - flags |= IS_SIGNED_NUM; - base = 10; - break; - case 'i': - flags |= IS_SIGNED_NUM; - base = 0; - break; - case 'o': - base = 8; - break; - case 'p': - base = 16; - flags &= ~(IS_S | IS_LL | IS_L); - #ifdef _WIN64 - flags |= IS_LL; - #endif - flags |= IS_L | IS_POINTER; - break; - case 'u': - base = 10; - break; - case 'x': case 'X': - base = 16; - break; - } - - if ((c = in_ch (s, &read_in)) == EOF) - return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - if (c == '+' || c == '-') - { - wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); - wbuf[wbuf_cur_sz++] = c; - if (width > 0) - --width; - c = in_ch (s, &read_in); - } - if (width != 0 && c == '0') - { - if (width > 0) - --width; - - wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); - wbuf[wbuf_cur_sz++] = c; - c = in_ch (s, &read_in); - - if (width != 0 && tolower (c) == 'x') - { - if (!base) - base = 16; - if (base == 16) - { - if (width > 0) - --width; - c = in_ch (s, &read_in); - } - } - else if (!base) - base = 8; - } - - if (!base) - base = 10; - - while (c != EOF && width != 0) - { - if (base == 16) - { - if (!isxdigit (c)) - break; - } - else if (!isdigit (c) || (int) (c - '0') >= base) - { - const char *p = lc_thousands_sep; - int remain; - - if (base != 10 || (flags & USE_GROUP) == 0) - break; - remain = width > 0 ? width : INT_MAX; - while ((unsigned char) *p == c && remain >= 0) - { - /* As our conversion routines aren't supporting thousands - separators, we are filtering them here. */ - - ++p; - if (*p == 0 || !remain || (c = in_ch (s, &read_in)) == EOF) - break; - --remain; - } - - if (*p != 0) - { - if (p > lc_thousands_sep) - { - back_ch (c, s, &read_in, 0); - while (--p > lc_thousands_sep) - back_ch ((unsigned char) *p, s, &read_in, 1); - c = (unsigned char) *p; - } - break; - } - - if (width > 0) - width = remain; - --wbuf_cur_sz; - } - wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); - wbuf[wbuf_cur_sz++] = c; - if (width > 0) - --width; - - c = in_ch (s, &read_in); - } - - if (!wbuf_cur_sz || (wbuf_cur_sz == 1 && (wbuf[0] == '+' || wbuf[0] == '-'))) - { - if (!wbuf_cur_sz && (flags & IS_POINTER) != 0 - && match_string (s, &read_in, &c, "(nil)")) - { - wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); - wbuf[wbuf_cur_sz++] = '0'; - } - else - { - back_ch (c, s, &read_in, 0); - return cleanup_return (rval, &gcollect, pstr, &wbuf); - } - } - else - back_ch (c, s, &read_in, 0); - - wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); - wbuf[wbuf_cur_sz++] = 0; - - if ((flags & IS_LL)) - { - if (flags & IS_SIGNED_NUM) - cv_val.ll = strtoll (wbuf, &tmp_wbuf_ptr, base/*, flags & USE_GROUP*/); - else - cv_val.ull = strtoull (wbuf, &tmp_wbuf_ptr, base); - } - else - { - if (flags & IS_SIGNED_NUM) - cv_val.l = strtol (wbuf, &tmp_wbuf_ptr, base/*, flags & USE_GROUP*/); - else - cv_val.ul = strtoul (wbuf, &tmp_wbuf_ptr, base); - } - if (wbuf == tmp_wbuf_ptr) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - - if ((flags & IS_SUPPRESSED) == 0) - { - if ((flags & IS_SIGNED_NUM) != 0) - { - if ((flags & IS_LL) != 0) - *(npos != 0 ? (long long *) get_va_nth (argp, npos) : va_arg (arg, long long *)) = cv_val.ll; - else if ((flags & IS_L) != 0) - *(npos != 0 ? (long *) get_va_nth (argp, npos) : va_arg (arg, long *)) = cv_val.l; - else if ((flags & IS_S) != 0) - *(npos != 0 ? (short *) get_va_nth (argp, npos) : va_arg (arg, short *)) = (short) cv_val.l; - else if ((flags & IS_C) != 0) - *(npos != 0 ? (signed char *) get_va_nth (argp, npos) : va_arg (arg, signed char *)) = (signed char) cv_val.ul; - else - *(npos != 0 ? (int *) get_va_nth (argp, npos) : va_arg (arg, int *)) = (int) cv_val.l; - } - else - { - if ((flags & IS_LL) != 0) - *(npos != 0 ? (unsigned long long *) get_va_nth (argp, npos) : va_arg (arg, unsigned long long *)) = cv_val.ull; - else if ((flags & IS_L) != 0) - *(npos != 0 ? (unsigned long *) get_va_nth (argp, npos) : va_arg (arg, unsigned long *)) = cv_val.ul; - else if ((flags & IS_S) != 0) - *(npos != 0 ? (unsigned short *) get_va_nth (argp, npos) : va_arg (arg, unsigned short *)) - = (unsigned short) cv_val.ul; - else if ((flags & IS_C) != 0) - *(npos != 0 ? (unsigned char *) get_va_nth (argp, npos) : va_arg (arg, unsigned char *)) = (unsigned char) cv_val.ul; - else - *(npos != 0 ? (unsigned int *) get_va_nth (argp, npos) : va_arg (arg, unsigned int *)) = (unsigned int) cv_val.ul; - } - ++rval; - } - break; - - case 'e': case 'E': - case 'f': case 'F': - case 'g': case 'G': - case 'a': case 'A': - if (width > 0) - --width; - if ((c = in_ch (s, &read_in)) == EOF) - return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - - seen_dot = seen_exp = 0; - is_neg = (c == '-' ? 1 : 0); - - if (c == '-' || c == '+') - { - if (width == 0 || (c = in_ch (s, &read_in)) == EOF) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - if (width > 0) - --width; - } - - if (tolower (c) == 'n') - { - const char *match_txt = "nan"; - - wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); - wbuf[wbuf_cur_sz++] = c; - - ++match_txt; - do - { - if (width == 0 || (c = in_ch (s, &read_in)) == EOF || tolower (c) != match_txt[0]) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - - if (width > 0) - --width; - - wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); - wbuf[wbuf_cur_sz++] = c; - ++match_txt; - } - while (*match_txt != 0); - } - else if (tolower (c) == 'i') - { - const char *match_txt = "inf"; - - wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); - wbuf[wbuf_cur_sz++] = c; - - ++match_txt; - do - { - if (width == 0 || (c = in_ch (s, &read_in)) == EOF || tolower (c) != match_txt[0]) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - if (width > 0) - --width; - - wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); - wbuf[wbuf_cur_sz++] = c; - ++match_txt; - } - while (*match_txt != 0); - - if (width != 0 && (c = in_ch (s, &read_in)) != EOF && tolower (c) == 'i') - { - match_txt = "inity"; - - if (width > 0) - --width; - - wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); - wbuf[wbuf_cur_sz++] = c; - ++match_txt; - - do - { - if (width == 0 || (c = in_ch (s, &read_in)) == EOF || tolower (c) != match_txt[0]) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - if (width > 0) - --width; - - wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); - wbuf[wbuf_cur_sz++] = c; - ++match_txt; - } - while (*match_txt != 0); - } - else if (width != 0 && c != EOF) - back_ch (c, s, &read_in, 0); - } - else - { - not_in = 'e'; - if (width != 0 && c == '0') - { - wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); - wbuf[wbuf_cur_sz++] = c; - - c = in_ch (s, &read_in); - if (width > 0) - --width; - if (width != 0 && tolower (c) == 'x') - { - wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); - wbuf[wbuf_cur_sz++] = c; - - flags |= IS_HEX_FLOAT; - not_in = 'p'; - - flags &= ~USE_GROUP; - c = in_ch (s, &read_in); - if (width > 0) - --width; - } - } - - while (1) - { - if (isdigit (c) || (!seen_exp && (flags & IS_HEX_FLOAT) != 0 && isxdigit (c)) - || (seen_exp && wbuf[wbuf_cur_sz - 1] == not_in && (c == '-' || c == '+'))) - { - wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); - wbuf[wbuf_cur_sz++] = c; - } - else if (wbuf_cur_sz > 0 && !seen_exp && (char) tolower (c) == not_in) - { - wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); - wbuf[wbuf_cur_sz++] = not_in; - seen_exp = seen_dot = 1; - } - else - { - const char *p = lc_decimal_point; - int remain = width > 0 ? width : INT_MAX; - - if (! seen_dot) - { - while ((unsigned char) *p == c && remain >= 0) - { - ++p; - if (*p == 0 || !remain || (c = in_ch (s, &read_in)) == EOF) - break; - --remain; - } - } - - if (*p == 0) - { - for (p = lc_decimal_point; *p != 0; ++p) - { - wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); - wbuf[wbuf_cur_sz++] = (unsigned char) *p; - } - if (width > 0) - width = remain; - seen_dot = 1; - } - else - { - const char *pp = lc_thousands_sep; - - if (!seen_dot && (flags & USE_GROUP) != 0) - { - while ((pp - lc_thousands_sep) < (p - lc_decimal_point) - && *pp == lc_decimal_point[(pp - lc_thousands_sep)]) - ++pp; - if ((pp - lc_thousands_sep) == (p - lc_decimal_point)) - { - while ((unsigned char) *pp == c && remain >= 0) - { - ++pp; - if (*pp == 0 || !remain || (c = in_ch (s, &read_in)) == EOF) - break; - --remain; - } - } - } - - if (pp != NULL && *pp == 0) - { - /* As our conversion routines aren't supporting thousands - separators, we are filtering them here. */ - if (width > 0) - width = remain; - } - else - { - back_ch (c, s, &read_in, 0); - break; - } - } - } - - if (width == 0 || (c = in_ch (s, &read_in)) == EOF) - break; - - if (width > 0) - --width; - } - - if (!wbuf_cur_sz || ((flags & IS_HEX_FLOAT) != 0 && wbuf_cur_sz == 2)) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - } - - wbuf = resize_wbuf (wbuf_cur_sz, &wbuf_max_sz, wbuf); - wbuf[wbuf_cur_sz++] = 0; - - if ((flags & IS_LL) != 0) - { - long double ld; - ld = __mingw_strtold (wbuf, &tmp_wbuf_ptr/*, flags & USE_GROUP*/); - if ((flags & IS_SUPPRESSED) == 0 && tmp_wbuf_ptr != wbuf) - *(npos != 0 ? (long double *) get_va_nth (argp, npos) : va_arg (arg, long double *)) = is_neg ? -ld : ld; - } - else if ((flags & IS_L) != 0) - { - double d; - d = (double) __mingw_strtold (wbuf, &tmp_wbuf_ptr/*, flags & USE_GROUP*/); - if ((flags & IS_SUPPRESSED) == 0 && tmp_wbuf_ptr != wbuf) - *(npos != 0 ? (double *) get_va_nth (argp, npos) : va_arg (arg, double *)) = is_neg ? -d : d; - } - else - { - float d = __mingw_strtof (wbuf, &tmp_wbuf_ptr/*, flags & USE_GROUP*/); - if ((flags & IS_SUPPRESSED) == 0 && tmp_wbuf_ptr != wbuf) - *(npos != 0 ? (float *) get_va_nth (argp, npos) : va_arg (arg, float *)) = is_neg ? -d : d; - } - - if (wbuf == tmp_wbuf_ptr) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - - if ((flags & IS_SUPPRESSED) == 0) - ++rval; - break; - - case '[': - if ((flags & IS_L) != 0) - { - if ((flags & IS_SUPPRESSED) == 0) - { - if ((flags & IS_ALLOC_USED) != 0) - { - if (npos != 0) - pstr = (char **) get_va_nth (argp, npos); - else - pstr = va_arg (arg, char **); - - if (!pstr) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - - str_sz = 100; - *pstr = (char *) malloc (100 * sizeof (wchar_t)); - - if ((wstr = (wchar_t *) *pstr) == NULL) - return cleanup_return (((flags & USE_POSIX_ALLOC) != 0 ? EOF : rval), &gcollect, pstr, &wbuf); - gcollect = resize_gcollect (gcollect); - gcollect->ptrs[gcollect->count++] = pstr; - } - else - { - if (npos != 0) - wstr = (wchar_t *) get_va_nth (argp, npos); - else - wstr = va_arg (arg, wchar_t *); - if (!wstr) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - } - } - } - else if ((flags & IS_SUPPRESSED) == 0) - { - if ((flags & IS_ALLOC_USED) != 0) - { - if (npos != 0) - pstr = (char **) get_va_nth (argp, npos); - else - pstr = va_arg (arg, char **); - - if (!pstr) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - - str_sz = 100; - if ((str = *pstr = (char *) malloc (100)) == NULL) - return cleanup_return (((flags & USE_POSIX_ALLOC) != 0 ? EOF : rval), &gcollect, pstr, &wbuf); - - gcollect = resize_gcollect (gcollect); - gcollect->ptrs[gcollect->count++] = pstr; - } - else - { - if (npos != 0) - str = (char *) get_va_nth (argp, npos); - else - str = va_arg (arg, char *); - if (!str) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - } - } - - not_in = (*f == '^' ? 1 : 0); - if (*f == '^') - f++; - - if (width < 0) - width = INT_MAX; - - if (wbuf_max_sz < 256) - { - wbuf_max_sz = 256; - if (wbuf) - free (wbuf); - wbuf = (char *) malloc (wbuf_max_sz); - } - memset (wbuf, 0, 256); - - fc = *f; - if (fc == ']' || fc == '-') - { - wbuf[fc] = 1; - ++f; - } - - while ((fc = *f++) != 0 && fc != ']') - { - if (fc == '-' && *f != 0 && *f != ']' && (unsigned char) f[-2] <= (unsigned char) *f) - { - for (fc = (unsigned char) f[-2]; fc < (unsigned char) *f; ++fc) - wbuf[fc] = 1; - } - else - wbuf[fc] = 1; - } - - if (!fc) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - - if ((flags & IS_L) != 0) - { - read_in_sv = read_in; - cnt = 0; - - if ((c = in_ch (s, &read_in)) == EOF) - return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - - memset (&cstate, 0, sizeof (cstate)); - - do - { - if (wbuf[c] == not_in) - { - back_ch (c, s, &read_in, 1); - break; - } - - if ((flags & IS_SUPPRESSED) == 0) - { - buf[0] = c; - n = mbrtowc (wstr, buf, 1, &cstate); - - if (n == (size_t) -2) - { - ++cnt; - continue; - } - cnt = 0; - - ++wstr; - if ((flags & IS_ALLOC_USED) != 0 && wstr == ((wchar_t *) *pstr + str_sz)) - { - new_sz = str_sz * 2; - while ((wstr = (wchar_t *) realloc (*pstr, new_sz * sizeof (wchar_t))) == NULL - && new_sz > (size_t) (str_sz + 1)) - new_sz = str_sz + 1; - if (!wstr) - { - if ((flags & USE_POSIX_ALLOC) == 0) - { - ((wchar_t *) (*pstr))[str_sz - 1] = 0; - pstr = NULL; - ++rval; - } - else - rval = EOF; - return cleanup_return (rval, &gcollect, pstr, &wbuf); - } - *pstr = (char *) wstr; - wstr += str_sz; - str_sz = new_sz; - } - } - - if (--width <= 0) - break; - } - while ((c = in_ch (s, &read_in)) != EOF); - - if (cnt != 0) - { - errno = EILSEQ; - return cleanup_return (rval, &gcollect, pstr, &wbuf); - } - - if (read_in_sv == read_in) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - - - if ((flags & IS_SUPPRESSED) == 0) - { - *wstr++ = 0; - optimize_alloc (pstr, (char *) wstr, str_sz * sizeof (wchar_t)); - pstr = NULL; - ++rval; - } - } - else - { - read_in_sv = read_in; - - if ((c = in_ch (s, &read_in)) == EOF) - return cleanup_return ((!rval ? EOF : rval), &gcollect, pstr, &wbuf); - - do - { - if (wbuf[c] == not_in) - { - back_ch (c, s, &read_in, 1); - break; - } - - if ((flags & IS_SUPPRESSED) == 0) - { - *str++ = c; - if ((flags & IS_ALLOC_USED) != 0 && str == (*pstr + str_sz)) - { - new_sz = str_sz * 2; - - while ((str = (char *) realloc (*pstr, new_sz)) == NULL - && new_sz > (size_t) (str_sz + 1)) - new_sz = str_sz + 1; - if (!str) - { - if ((flags & USE_POSIX_ALLOC) == 0) - { - (*pstr)[str_sz - 1] = 0; - pstr = NULL; - ++rval; - } - else - rval = EOF; - return cleanup_return (rval, &gcollect, pstr, &wbuf); - } - *pstr = str; - str += str_sz; - str_sz = new_sz; - } - } - } - while (--width > 0 && (c = in_ch (s, &read_in)) != EOF); - - if (read_in_sv == read_in) - return cleanup_return (rval, &gcollect, pstr, &wbuf); - - if ((flags & IS_SUPPRESSED) == 0) - { - *str++ = 0; - optimize_alloc (pstr, str, str_sz); - pstr = NULL; - ++rval; - } - } - break; - - default: - return cleanup_return (rval, &gcollect, pstr, &wbuf); - } - } - - if (ignore_ws) - { - while (isspace ((c = in_ch (s, &read_in)))); - back_ch (c, s, &read_in, 0); - } - - return cleanup_return (rval, &gcollect, pstr, &wbuf); -} +#include "mingw_sformat.h" int __mingw_vfscanf (FILE *s, const char *format, va_list argp) @@ -1619,14 +12,3 @@ __mingw_vfscanf (FILE *s, const char *format, va_list argp) ifp.fp = s; return __mingw_sformat (&ifp, format, argp); } - -int -__mingw_vsscanf (const char *s, const char *format, va_list argp) -{ - _IFP ifp; - memset (&ifp, 0, sizeof (_IFP)); - ifp.str = s; - ifp.is_string = 1; - return __mingw_sformat (&ifp, format, argp); -} - diff --git a/lib/libc/mingw/stdio/mingw_vfprintfw.c b/lib/libc/mingw/stdio/mingw_vfwprintf.c similarity index 100% rename from lib/libc/mingw/stdio/mingw_vfprintfw.c rename to lib/libc/mingw/stdio/mingw_vfwprintf.c diff --git a/lib/libc/mingw/stdio/mingw_vfwscanf.c b/lib/libc/mingw/stdio/mingw_vfwscanf.c new file mode 100644 index 0000000000..dfb156f6d0 --- /dev/null +++ b/lib/libc/mingw/stdio/mingw_vfwscanf.c @@ -0,0 +1,14 @@ +#include +#include +#include + +#include "mingw_swformat.h" + +int +__mingw_vfwscanf (FILE *s, const wchar_t *format, va_list argp) +{ + _IFPW ifp; + memset (&ifp, 0, sizeof (_IFPW)); + ifp.fp = s; + return __mingw_swformat (&ifp, format, argp); +} diff --git a/lib/libc/mingw/stdio/mingw_vsnprintf.c b/lib/libc/mingw/stdio/mingw_vsnprintf.c index b477300f97..b9c3578627 100644 --- a/lib/libc/mingw/stdio/mingw_vsnprintf.c +++ b/lib/libc/mingw/stdio/mingw_vsnprintf.c @@ -34,11 +34,20 @@ int __cdecl __vsnprintf(APICHAR *buf, size_t length, const APICHAR *fmt, va_list register int retval; if( length == (size_t)(0) ) + { +#if defined(__BUILD_WIDEAPI) && defined(__BUILD_WIDEAPI_ISO) + /* No buffer; for wide api ISO C95+ vswprintf() function + * simply returns negative value as required by ISO C95+. + */ + return -1; +#else /* * No buffer; simply compute and return the size required, * without actually emitting any data. */ return __pformat( 0, buf, 0, fmt, argv); +#endif + } /* If we get to here, then we have a buffer... * Emit data up to the limit of buffer length less one, @@ -47,6 +56,15 @@ int __cdecl __vsnprintf(APICHAR *buf, size_t length, const APICHAR *fmt, va_list retval = __pformat( 0, buf, --length, fmt, argv ); buf[retval < (int) length ? retval : (int)length] = '\0'; +#if defined(__BUILD_WIDEAPI) && defined(__BUILD_WIDEAPI_ISO) + /* For wide api ISO C95+ vswprintf() when requested length + * is equal or larger than buffer length, returns negative + * value as required by ISO C95+. + */ + if( retval >= (int) length ) + retval = -1; +#endif + return retval; } diff --git a/lib/libc/mingw/stdio/mingw_vsnprintfw.c b/lib/libc/mingw/stdio/mingw_vsnwprintf.c similarity index 100% rename from lib/libc/mingw/stdio/mingw_vsnprintfw.c rename to lib/libc/mingw/stdio/mingw_vsnwprintf.c diff --git a/lib/libc/mingw/stdio/mingw_vsscanf.c b/lib/libc/mingw/stdio/mingw_vsscanf.c new file mode 100644 index 0000000000..52d72d9f0a --- /dev/null +++ b/lib/libc/mingw/stdio/mingw_vsscanf.c @@ -0,0 +1,15 @@ +#include +#include +#include + +#include "mingw_sformat.h" + +int +__mingw_vsscanf (const char *s, const char *format, va_list argp) +{ + _IFP ifp; + memset (&ifp, 0, sizeof (_IFP)); + ifp.str = s; + ifp.is_string = 1; + return __mingw_sformat (&ifp, format, argp); +} diff --git a/lib/libc/mingw/stdio/mingw_vsprintfw.c b/lib/libc/mingw/stdio/mingw_vswprintf.c similarity index 78% rename from lib/libc/mingw/stdio/mingw_vsprintfw.c rename to lib/libc/mingw/stdio/mingw_vswprintf.c index fd8808bf47..6d70b2cfa1 100644 --- a/lib/libc/mingw/stdio/mingw_vsprintfw.c +++ b/lib/libc/mingw/stdio/mingw_vswprintf.c @@ -4,7 +4,7 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ #define __BUILD_WIDEAPI 1 -#define _CRT_NON_CONFORMING_SWPRINTFS 1 +#define __BUILD_WIDEAPI_ISO 1 -#include "mingw_vsprintf.c" +#include "mingw_vsnprintf.c" diff --git a/lib/libc/mingw/stdio/mingw_vswscanf.c b/lib/libc/mingw/stdio/mingw_vswscanf.c new file mode 100644 index 0000000000..48767f2297 --- /dev/null +++ b/lib/libc/mingw/stdio/mingw_vswscanf.c @@ -0,0 +1,15 @@ +#include +#include +#include + +#include "mingw_swformat.h" + +int +__mingw_vswscanf (const wchar_t *s, const wchar_t *format, va_list argp) +{ + _IFPW ifp; + memset (&ifp, 0, sizeof (_IFPW)); + ifp.str = s; + ifp.is_string = 1; + return __mingw_swformat (&ifp, format, argp); +} diff --git a/lib/libc/mingw/stdio/mingw_vprintfw.c b/lib/libc/mingw/stdio/mingw_vwprintf.c similarity index 100% rename from lib/libc/mingw/stdio/mingw_vprintfw.c rename to lib/libc/mingw/stdio/mingw_vwprintf.c diff --git a/lib/libc/mingw/stdio/mingw_pformatw.c b/lib/libc/mingw/stdio/mingw_wpformat.c similarity index 100% rename from lib/libc/mingw/stdio/mingw_pformatw.c rename to lib/libc/mingw/stdio/mingw_wpformat.c diff --git a/lib/libc/mingw/stdio/mingw_printfw.c b/lib/libc/mingw/stdio/mingw_wprintf.c similarity index 100% rename from lib/libc/mingw/stdio/mingw_printfw.c rename to lib/libc/mingw/stdio/mingw_wprintf.c diff --git a/lib/libc/mingw/stdio/scanf.S b/lib/libc/mingw/stdio/scanf.S deleted file mode 100644 index 41ff64598c..0000000000 --- a/lib/libc/mingw/stdio/scanf.S +++ /dev/null @@ -1,243 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ - -/* vsscanf, vswscanf, vfscanf, and vfwscanf all come here for i386 and arm. - - The goal of this routine is to turn a call to v*scanf into a call to - s*scanf. This is needed because mingw-w64 uses msvcr100.dll, which doesn't - support the v*scanf functions instead of msvcr120.dll which does. -*/ - -/* The function prototype here is (essentially): - - int __ms_v*scanf_internal (void *s, - void *format, - void *arg, - size_t count, - void *func); - - I say 'essentially' because passing a function pointer as void in ISO - is not supported. But in the end, I take the first parameter (which - may be a char *, a wchar_t *, or a FILE *) and put it into the newly - formed stack, and eventually call the address in func. */ - -#if defined (__x86_64__) - - .text - .align 16 - - /* scl 2: C_EXT - External (public) symbol - covers globals and externs - type 32: DT_FCN - function returning T - */ - .def __argtos; .scl 2; .type 32; .endef - - .seh_proc __argtos -__argtos: - - /* When we are done: - - s must be in rcx. That's where it is on entry. - - format must be in rdx. That's where it is on entry. - - The first pointer in arg must be in r8. arg is in r8 on entry. - - The second pointer in arg must be in r9. arg is in r8 on entry. - - The (count - 2) other pointers in arg must be on the stack, - starting 32bytes into rsp. */ - - pushq %rbp - .seh_pushreg %rbp - movq %rsp, %rbp - .seh_setframe %rbp, 0 - - /* We need to always reserve space to shadow 4 parameters. */ - subq $32, %rsp - .seh_stackalloc 32 - .seh_endprologue - - movq 48(%rbp), %r10 /* func. */ - - /* We need enough room to shadow all the other args. - Except the first 2, since they will be loaded in registers. */ - cmpq $2, %r9 /* count. */ - jbe .SKIP - subq $2, %r9 /* # of ptrs to copy. */ - /* Calculate stack size (arg is 8byte) and keep the stack 16byte aligned. */ - leaq 8(, %r9, 8), %rax /* %rax = (%r9 + 1) * 8 */ - andq $-16, %rax - subq %rax, %rsp - - /* We are going to copy parameters from arg to our local stack. - The first 32 bytes are in registers, but by spec, space - must still be reserved for them on the stack. Put the - rest of the pointers in the stack after that. */ - lea 32(%rsp), %r11 /* dst. */ - -.LOOP: - subq $1, %r9 - - /* Use 16 to skip over the first 2 pointers. */ - movq 16(%r8, %r9, 8), %rax - movq %rax, (%r11, %r9, 8) - jnz .LOOP - -.SKIP: - /* The stack is now correctly populated, and so are rcx and rdx. - But we need to load the last 2 regs before making the call. */ - movq 0x8(%r8), %r9 /* 2nd dest location (may be garbage if only 1 arg). */ - movq (%r8), %r8 /* 1st dest location (may be garbage if no arg). */ - - /* Make the call. */ - callq *%r10 - - /* Restore stack. */ - movq %rbp, %rsp - - popq %rbp - retq - .seh_endproc - -#elif defined (_X86_) - - .text - .align 16 - - /* scl 2: C_EXT - External (public) symbol - covers globals and externs - type 32: DT_FCN - function returning T - */ - .def __argtos; .scl 2; .type 32; .endef - -__argtos: - pushl %ebp - movl %esp, %ebp - pushl %edi - pushl %ebx - - /* Reserve enough stack space for everything. - - Stack usage will look like: - 4 bytes - s - 4 bytes - format - 4*count bytes - variable # of parameters for sscanf (all ptrs). */ - - movl 20(%ebp), %ebx /* count. */ - addl $2, %ebx /* s + format. */ - sall $2, %ebx /* (count + 2) * 4. */ - subl %ebx, %esp - - /* Write out s and format where they need to be for the sscanf call. */ - movl 8(%ebp), %eax - movl %eax, (%esp) /* s. */ - movl 12(%ebp), %edx - movl %edx, 0x4(%esp) /* format. */ - - /* We are going to copy _count_ pointers from arg to our - local stack. */ - movl 20(%ebp), %ecx /* # of ptrs to copy. */ - testl %ecx, %ecx - jz .SKIP - lea 8(%esp), %edi /* dst. */ - movl 16(%ebp), %edx /* src. */ - -.LOOP: - subl $1, %ecx - - movl (%edx, %ecx, 4), %eax - movl %eax, (%edi, %ecx, 4) - jnz .LOOP - -.SKIP: - /* The stack is now correctly populated. */ - - /* Make the call. */ - call *24(%ebp) - - /* Restore stack. */ - addl %ebx, %esp - - popl %ebx - popl %edi - leave - - ret - -#elif defined (__arm__) - - .text - .align 2 - .thumb_func - .globl __argtos - -__argtos: - push {r4-r8, lr} - ldr r12, [sp, #24] - - ldr r5, [r2], #4 - ldr r6, [r2], #4 - - subs r3, r3, #2 - mov r8, #0 - ble 2f - - /* Round the number of entries to an even number, to maintain - * 8 byte stack alignment. */ - mov r8, r3 - add r8, r8, #1 - bic r8, r8, #1 - sub sp, sp, r8, lsl #2 - mov r4, sp -1: ldr r7, [r2], #4 - subs r3, r3, #1 - str r7, [r4], #4 - bne 1b - -2: - mov r2, r5 - mov r3, r6 - blx r12 - - add sp, sp, r8, lsl #2 - pop {r4-r8, pc} - -#elif defined (__aarch64__) - - .text - .align 2 - .globl __argtos - -__argtos: - stp x29, x30, [sp, #-16]! - mov x29, sp - mov x10, x2 - mov x11, x3 - mov x12, x4 - - ldr x2, [x10], #8 - ldr x3, [x10], #8 - ldr x4, [x10], #8 - ldr x5, [x10], #8 - ldr x6, [x10], #8 - ldr x7, [x10], #8 - - subs x11, x11, #6 - b.le 2f - - /* Round the number of entries to an even number, to maintain - * 16 byte stack alignment. */ - mov x13, x11 - add x13, x13, #1 - bic x13, x13, #1 - sub sp, sp, x13, lsl #3 - mov x9, sp -1: ldr x13, [x10], #8 - subs x11, x11, #1 - str x13, [x9], #8 - b.ne 1b - -2: - blr x12 - mov sp, x29 - ldp x29, x30, [sp], #16 - ret - -#endif diff --git a/lib/libc/mingw/stdio/scanf2-argcount-char.c b/lib/libc/mingw/stdio/scanf2-argcount-char.c deleted file mode 100644 index bc18dc5685..0000000000 --- a/lib/libc/mingw/stdio/scanf2-argcount-char.c +++ /dev/null @@ -1,9 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ - -#define FUNC __ms_scanf_max_arg_count_internal -#define TYPE char -#include "scanf2-argcount-template.c" diff --git a/lib/libc/mingw/stdio/scanf2-argcount-template.c b/lib/libc/mingw/stdio/scanf2-argcount-template.c deleted file mode 100644 index fec8a09397..0000000000 --- a/lib/libc/mingw/stdio/scanf2-argcount-template.c +++ /dev/null @@ -1,18 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ - -#include - -size_t FUNC(const TYPE *format); -size_t FUNC(const TYPE *format) -{ - size_t count = 0; - for (; *format; format++) { - if (*format == (TYPE)'%') - count++; - } - return count; -} diff --git a/lib/libc/mingw/stdio/scanf2-argcount-wchar.c b/lib/libc/mingw/stdio/scanf2-argcount-wchar.c deleted file mode 100644 index cece837a3e..0000000000 --- a/lib/libc/mingw/stdio/scanf2-argcount-wchar.c +++ /dev/null @@ -1,9 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ - -#define FUNC __ms_wscanf_max_arg_count_internal -#define TYPE wchar_t -#include "scanf2-argcount-template.c" diff --git a/lib/libc/mingw/stdio/scanf2-template.S b/lib/libc/mingw/stdio/scanf2-template.S deleted file mode 100644 index 3c9aa2a4bc..0000000000 --- a/lib/libc/mingw/stdio/scanf2-template.S +++ /dev/null @@ -1,32 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ - -#if defined(_ARM_) || defined(__arm__) - .thumb -#endif - .text - .p2align 4,,15 - .globl FCT - .def FCT; .scl 2; .type 32; .endef -#ifdef __x86_64__ - .seh_proc FCT -#endif -FCT: -#ifdef __x86_64__ - .seh_endprologue -#endif -#if defined(_AMD64_) || defined(__x86_64__) || defined(_X86_) || defined(__i386__) - jmp FWD -#elif defined(_ARM_) || defined(__arm__) - .thumb_func - b FWD -#elif defined(_ARM64_) || defined(__aarch64__) - b FWD -#endif -#ifdef __x86_64__ - .seh_endproc -#endif - .def FWD; .scl 2; .type 32; .endef diff --git a/lib/libc/mingw/stdio/snwprintf.c b/lib/libc/mingw/stdio/snwprintf.c index c57a46d893..6abf77a444 100644 --- a/lib/libc/mingw/stdio/snwprintf.c +++ b/lib/libc/mingw/stdio/snwprintf.c @@ -12,7 +12,7 @@ int __cdecl __ms_snwprintf(wchar_t *buffer, size_t n, const wchar_t *format, ... va_list argptr; va_start(argptr, format); - retval = _vsnwprintf(buffer, n, format, argptr); + retval = __ms_vsnwprintf(buffer, n, format, argptr); va_end(argptr); return retval; } diff --git a/lib/libc/mingw/stdio/ucrt_ms_fprintf.c b/lib/libc/mingw/stdio/ucrt_ms_fprintf.c new file mode 100644 index 0000000000..15588bcae7 --- /dev/null +++ b/lib/libc/mingw/stdio/ucrt_ms_fprintf.c @@ -0,0 +1,22 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#undef __MSVCRT_VERSION__ +#define _UCRT + +#include +#include + +int __cdecl __ms_fprintf(FILE * restrict file, const char * restrict format, ...) +{ + va_list ap; + int ret; + va_start(ap, format); + ret = __stdio_common_vfprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, file, format, NULL, ap); + va_end(ap); + return ret; +} +int __cdecl (*__MINGW_IMP_SYMBOL(__ms_fprintf))(FILE * restrict, const char * restrict, ...) = __ms_fprintf; diff --git a/lib/libc/mingw/stdio/vfscanf.c b/lib/libc/mingw/stdio/vfscanf.c deleted file mode 100644 index c3282a3edb..0000000000 --- a/lib/libc/mingw/stdio/vfscanf.c +++ /dev/null @@ -1,35 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ - -#include -#include - -extern int __ms_vfscanf_internal ( - FILE * s, - const char * format, - va_list arg, - size_t count, - int (*func)(FILE * __restrict__, const char * __restrict__, ...)) - asm("__argtos"); - -extern size_t __ms_scanf_max_arg_count_internal (const char * format); - -int __ms_vfscanf (FILE * __restrict__ stream, const char * __restrict__ format, va_list arg) -{ - size_t count = __ms_scanf_max_arg_count_internal (format); - int ret; - -#if defined(_AMD64_) || defined(__x86_64__) || \ - defined(_X86_) || defined(__i386__) || \ - defined(_ARM_) || defined(__arm__) || \ - defined(_ARM64_) || defined(__aarch64__) - ret = __ms_vfscanf_internal (stream, format, arg, count, fscanf); -#else -#error "unknown platform" -#endif - - return ret; -} diff --git a/lib/libc/mingw/stdio/vfscanf2.S b/lib/libc/mingw/stdio/vfscanf2.S deleted file mode 100644 index 36f38c5fd8..0000000000 --- a/lib/libc/mingw/stdio/vfscanf2.S +++ /dev/null @@ -1,12 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ -#include <_mingw_mac.h> - -#define FCT __MINGW_USYMBOL(vfscanf) -#define FWD __MINGW_USYMBOL(__ms_vfscanf) - - .file "vfscanf2.S" -#include "scanf2-template.S" diff --git a/lib/libc/mingw/stdio/vfwscanf.c b/lib/libc/mingw/stdio/vfwscanf.c deleted file mode 100644 index f8e465d361..0000000000 --- a/lib/libc/mingw/stdio/vfwscanf.c +++ /dev/null @@ -1,36 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ - -#include -#include - -extern int __ms_vfwscanf_internal ( - FILE * s, - const wchar_t * format, - va_list arg, - size_t count, - int (*func)(FILE * __restrict__, const wchar_t * __restrict__, ...)) - asm("__argtos"); - -extern size_t __ms_wscanf_max_arg_count_internal (const wchar_t * format); - -int __ms_vfwscanf (FILE * __restrict__ stream, - const wchar_t * __restrict__ format, va_list arg) -{ - size_t count = __ms_wscanf_max_arg_count_internal (format); - int ret; - -#if defined(_AMD64_) || defined(__x86_64__) || \ - defined(_X86_) || defined(__i386__) || \ - defined(_ARM_) || defined(__arm__) || \ - defined (_ARM64_) || defined (__aarch64__) - ret = __ms_vfwscanf_internal (stream, format, arg, count, fwscanf); -#else -#error "unknown platform" -#endif - - return ret; -} diff --git a/lib/libc/mingw/stdio/vfwscanf2.S b/lib/libc/mingw/stdio/vfwscanf2.S deleted file mode 100644 index 9d98647a76..0000000000 --- a/lib/libc/mingw/stdio/vfwscanf2.S +++ /dev/null @@ -1,12 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ -#include <_mingw_mac.h> - -#define FCT __MINGW_USYMBOL(vfwscanf) -#define FWD __MINGW_USYMBOL(__ms_vfwscanf) - - .file "vfwscanf2.S" -#include "scanf2-template.S" diff --git a/lib/libc/mingw/stdio/vscanf.c b/lib/libc/mingw/stdio/vscanf.c deleted file mode 100644 index f255e6825c..0000000000 --- a/lib/libc/mingw/stdio/vscanf.c +++ /dev/null @@ -1,15 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ -// By aaronwl 2003-01-28 for mingw-msvcrt -// Public domain: all copyrights disclaimed, absolutely no warranties - -#include -#include - -int __ms_vscanf(const char * __restrict__ format, va_list arg) -{ - return __ms_vfscanf(stdin, format, arg); -} diff --git a/lib/libc/mingw/stdio/vscanf2.S b/lib/libc/mingw/stdio/vscanf2.S deleted file mode 100644 index b0e2a09f07..0000000000 --- a/lib/libc/mingw/stdio/vscanf2.S +++ /dev/null @@ -1,12 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ -#include <_mingw_mac.h> - -#define FCT __MINGW_USYMBOL(vscanf) -#define FWD __MINGW_USYMBOL(__ms_vscanf) - - .file "vscanf2.S" -#include "scanf2-template.S" diff --git a/lib/libc/mingw/stdio/vsnwprintf.c b/lib/libc/mingw/stdio/vsnwprintf.c index b5c5ae65cf..626889a304 100644 --- a/lib/libc/mingw/stdio/vsnwprintf.c +++ b/lib/libc/mingw/stdio/vsnwprintf.c @@ -12,5 +12,23 @@ int __cdecl __ms_vsnwprintf(wchar_t *buffer, size_t n, const wchar_t * format, int __cdecl __ms_vsnwprintf(wchar_t *buffer, size_t n, const wchar_t * format, va_list argptr) { - return _vsnwprintf(buffer, n, format, argptr); + int retval; + + /* _vsnwprintf() does not work with zero length buffer + * so count number of characters by _vscwprintf() call */ + if (n == 0) + return _vscwprintf(format, argptr); + + retval = _vsnwprintf(buffer, n, format, argptr); + + /* _vsnwprintf() does not fill trailing null character if there is not place for it */ + if (retval < 0 || (size_t)retval == n) + buffer[n-1] = '\0'; + + /* _vsnwprintf() returns negative number if buffer is too small + * so count number of characters by _vscwprintf() call */ + if (retval < 0) + retval = _vscwprintf(format, argptr); + + return retval; } diff --git a/lib/libc/mingw/stdio/vsscanf.c b/lib/libc/mingw/stdio/vsscanf.c deleted file mode 100644 index 9b3b650ded..0000000000 --- a/lib/libc/mingw/stdio/vsscanf.c +++ /dev/null @@ -1,36 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ - -#include -#include - -extern int __ms_vsscanf_internal ( - const char * s, - const char * format, - va_list arg, - size_t count, - int (*func)(const char * __restrict__, const char * __restrict__, ...)) - asm("__argtos"); - -extern size_t __ms_scanf_max_arg_count_internal (const char * format); - -int __ms_vsscanf (const char * __restrict__ s, - const char * __restrict__ format, va_list arg) -{ - size_t count = __ms_scanf_max_arg_count_internal (format); - int ret; - -#if defined(_AMD64_) || defined(__x86_64__) || \ - defined(_X86_) || defined(__i386__) || \ - defined(_ARM_) || defined(__arm__) || \ - defined(_ARM64_) || defined(__aarch64__) - ret = __ms_vsscanf_internal (s, format, arg, count, sscanf); -#else -#error "unknown platform" -#endif - - return ret; -} diff --git a/lib/libc/mingw/stdio/vsscanf2.S b/lib/libc/mingw/stdio/vsscanf2.S deleted file mode 100644 index e840a972b6..0000000000 --- a/lib/libc/mingw/stdio/vsscanf2.S +++ /dev/null @@ -1,12 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ -#include <_mingw_mac.h> - -#define FCT __MINGW_USYMBOL(vsscanf) -#define FWD __MINGW_USYMBOL(__ms_vsscanf) - - .file "vsscanf2.S" -#include "scanf2-template.S" diff --git a/lib/libc/mingw/stdio/vswscanf.c b/lib/libc/mingw/stdio/vswscanf.c deleted file mode 100644 index 01c811b32e..0000000000 --- a/lib/libc/mingw/stdio/vswscanf.c +++ /dev/null @@ -1,36 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ - -#include -#include - -extern int __ms_vswscanf_internal ( - const wchar_t * s, - const wchar_t * format, - va_list arg, - size_t count, - int (*func)(const wchar_t * __restrict__, const wchar_t * __restrict__, ...)) - asm("__argtos"); - -extern size_t __ms_wscanf_max_arg_count_internal (const wchar_t * format); - -int __ms_vswscanf(const wchar_t * __restrict__ s, const wchar_t * __restrict__ format, - va_list arg) -{ - size_t count = __ms_wscanf_max_arg_count_internal (format); - int ret; - -#if defined(_AMD64_) || defined(__x86_64__) || \ - defined(_X86_) || defined(__i386__) || \ - defined(_ARM_) || defined(__arm__) || \ - defined(_ARM64_) || defined(__aarch64__) - ret = __ms_vswscanf_internal (s, format, arg, count, swscanf); -#else -#error "unknown platform" -#endif - - return ret; -} diff --git a/lib/libc/mingw/stdio/vswscanf2.S b/lib/libc/mingw/stdio/vswscanf2.S deleted file mode 100644 index 529f71b7ed..0000000000 --- a/lib/libc/mingw/stdio/vswscanf2.S +++ /dev/null @@ -1,12 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ -#include <_mingw_mac.h> - -#define FCT __MINGW_USYMBOL(vswscanf) -#define FWD __MINGW_USYMBOL(__ms_vswscanf) - - .file "vswscanf2.S" -#include "scanf2-template.S" diff --git a/lib/libc/mingw/stdio/vwscanf.c b/lib/libc/mingw/stdio/vwscanf.c deleted file mode 100644 index 3360eefad1..0000000000 --- a/lib/libc/mingw/stdio/vwscanf.c +++ /dev/null @@ -1,16 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ -// By aaronwl 2003-01-28 for mingw-msvcrt. -// Public domain: all copyrights disclaimed, absolutely no warranties. - -#include -#include -#include - -int __ms_vwscanf (const wchar_t * __restrict__ format, va_list arg) -{ - return __ms_vfwscanf(stdin, format, arg); -} diff --git a/lib/libc/mingw/stdio/vwscanf2.S b/lib/libc/mingw/stdio/vwscanf2.S deleted file mode 100644 index e52c8c2a0d..0000000000 --- a/lib/libc/mingw/stdio/vwscanf2.S +++ /dev/null @@ -1,12 +0,0 @@ -/** - * This file has no copyright assigned and is placed in the Public Domain. - * This file is part of the mingw-w64 runtime package. - * No warranty is given; refer to the file DISCLAIMER.PD within this package. - */ -#include <_mingw_mac.h> - -#define FCT __MINGW_USYMBOL(vwscanf) -#define FWD __MINGW_USYMBOL(__ms_vwscanf) - - .file "vwscanf2.S" -#include "scanf2-template.S" diff --git a/lib/libc/mingw/winpthreads/thread.c b/lib/libc/mingw/winpthreads/thread.c index 68858cfa63..d5b3aaa054 100644 --- a/lib/libc/mingw/winpthreads/thread.c +++ b/lib/libc/mingw/winpthreads/thread.c @@ -970,7 +970,8 @@ void _pthread_cleanup_dest (pthread_t t) { _pthread_v *tv; - unsigned int i, j; + unsigned int j; + int i; if (!t) return; @@ -983,7 +984,7 @@ _pthread_cleanup_dest (pthread_t t) int flag = 0; pthread_spin_lock (&tv->spin_keys); - for (i = 0; i < tv->keymax; i++) + for (i = tv->keymax - 1; i >= 0; i--) { void *val = tv->keyval[i]; diff --git a/lib/libc/mingw/winpthreads/thread.h b/lib/libc/mingw/winpthreads/thread.h index 5b88226e98..1603bae589 100644 --- a/lib/libc/mingw/winpthreads/thread.h +++ b/lib/libc/mingw/winpthreads/thread.h @@ -74,6 +74,6 @@ void thread_print_set(int state); void thread_print(volatile pthread_t t, char *txt); #endif int __pthread_shallcancel(void); -struct _pthread_v *WINPTHREAD_API __pth_gpointer_locked (pthread_t id); +WINPTHREAD_API struct _pthread_v * __pth_gpointer_locked (pthread_t id); #endif diff --git a/src/mingw.zig b/src/mingw.zig index 17c0a49b11..d24921909c 100644 --- a/src/mingw.zig +++ b/src/mingw.zig @@ -497,7 +497,7 @@ const mingw32_generic_src = [_][]const u8{ "crt" ++ path.sep_str ++ "cxa_atexit.c", "crt" ++ path.sep_str ++ "cxa_thread_atexit.c", "crt" ++ path.sep_str ++ "tls_atexit.c", - "crt" ++ path.sep_str ++ "intrincs" ++ path.sep_str ++ "RtlSecureZeroMemory.c", + "intrincs" ++ path.sep_str ++ "RtlSecureZeroMemory.c", // mingwex "cfguard" ++ path.sep_str ++ "mingw_cfguard_support.c", "complex" ++ path.sep_str ++ "_cabs.c", @@ -630,8 +630,6 @@ const mingw32_generic_src = [_][]const u8{ "misc" ++ path.sep_str ++ "getlogin.c", "misc" ++ path.sep_str ++ "getopt.c", "misc" ++ path.sep_str ++ "gettimeofday.c", - "misc" ++ path.sep_str ++ "isblank.c", - "misc" ++ path.sep_str ++ "iswblank.c", "misc" ++ path.sep_str ++ "mempcpy.c", "misc" ++ path.sep_str ++ "mingw-access.c", "misc" ++ path.sep_str ++ "mingw-aligned-malloc.c", @@ -658,8 +656,6 @@ const mingw32_generic_src = [_][]const u8{ "misc" ++ path.sep_str ++ "wcstold.c", "misc" ++ path.sep_str ++ "wcstoumax.c", "misc" ++ path.sep_str ++ "wctob.c", - "misc" ++ path.sep_str ++ "wctrans.c", - "misc" ++ path.sep_str ++ "wctype.c", "misc" ++ path.sep_str ++ "wdirent.c", "misc" ++ path.sep_str ++ "winbs_uint64.c", "misc" ++ path.sep_str ++ "winbs_ulong.c", @@ -692,35 +688,36 @@ const mingw32_generic_src = [_][]const u8{ "stdio" ++ path.sep_str ++ "lseek64.c", "stdio" ++ path.sep_str ++ "mingw_asprintf.c", "stdio" ++ path.sep_str ++ "mingw_fprintf.c", - "stdio" ++ path.sep_str ++ "mingw_fprintfw.c", + "stdio" ++ path.sep_str ++ "mingw_fwprintf.c", "stdio" ++ path.sep_str ++ "mingw_fscanf.c", "stdio" ++ path.sep_str ++ "mingw_fwscanf.c", "stdio" ++ path.sep_str ++ "mingw_pformat.c", - "stdio" ++ path.sep_str ++ "mingw_pformatw.c", + "stdio" ++ path.sep_str ++ "mingw_sformat.c", + "stdio" ++ path.sep_str ++ "mingw_swformat.c", + "stdio" ++ path.sep_str ++ "mingw_wpformat.c", "stdio" ++ path.sep_str ++ "mingw_printf.c", - "stdio" ++ path.sep_str ++ "mingw_printfw.c", + "stdio" ++ path.sep_str ++ "mingw_wprintf.c", "stdio" ++ path.sep_str ++ "mingw_scanf.c", "stdio" ++ path.sep_str ++ "mingw_snprintf.c", - "stdio" ++ path.sep_str ++ "mingw_snprintfw.c", + "stdio" ++ path.sep_str ++ "mingw_snwprintf.c", "stdio" ++ path.sep_str ++ "mingw_sprintf.c", - "stdio" ++ path.sep_str ++ "mingw_sprintfw.c", + "stdio" ++ path.sep_str ++ "mingw_swprintf.c", "stdio" ++ path.sep_str ++ "mingw_sscanf.c", "stdio" ++ path.sep_str ++ "mingw_swscanf.c", "stdio" ++ path.sep_str ++ "mingw_vasprintf.c", "stdio" ++ path.sep_str ++ "mingw_vfprintf.c", - "stdio" ++ path.sep_str ++ "mingw_vfprintfw.c", + "stdio" ++ path.sep_str ++ "mingw_vfwprintf.c", "stdio" ++ path.sep_str ++ "mingw_vfscanf.c", "stdio" ++ path.sep_str ++ "mingw_vprintf.c", - "stdio" ++ path.sep_str ++ "mingw_vprintfw.c", + "stdio" ++ path.sep_str ++ "mingw_vsscanf.c", + "stdio" ++ path.sep_str ++ "mingw_vwprintf.c", "stdio" ++ path.sep_str ++ "mingw_vsnprintf.c", - "stdio" ++ path.sep_str ++ "mingw_vsnprintfw.c", + "stdio" ++ path.sep_str ++ "mingw_vsnwprintf.c", "stdio" ++ path.sep_str ++ "mingw_vsprintf.c", - "stdio" ++ path.sep_str ++ "mingw_vsprintfw.c", + "stdio" ++ path.sep_str ++ "mingw_vswprintf.c", "stdio" ++ path.sep_str ++ "mingw_wscanf.c", - "stdio" ++ path.sep_str ++ "mingw_wvfscanf.c", - "stdio" ++ path.sep_str ++ "scanf2-argcount-char.c", - "stdio" ++ path.sep_str ++ "scanf2-argcount-wchar.c", - "stdio" ++ path.sep_str ++ "scanf.S", + "stdio" ++ path.sep_str ++ "mingw_vfwscanf.c", + "stdio" ++ path.sep_str ++ "mingw_vswscanf.c", "stdio" ++ path.sep_str ++ "snprintf.c", "stdio" ++ path.sep_str ++ "snwprintf.c", "stdio" ++ path.sep_str ++ "strtok_r.c", @@ -728,20 +725,8 @@ const mingw32_generic_src = [_][]const u8{ "stdio" ++ path.sep_str ++ "ulltoa.c", "stdio" ++ path.sep_str ++ "ulltow.c", "stdio" ++ path.sep_str ++ "vasprintf.c", - "stdio" ++ path.sep_str ++ "vfscanf.c", - "stdio" ++ path.sep_str ++ "vfscanf2.S", - "stdio" ++ path.sep_str ++ "vfwscanf.c", - "stdio" ++ path.sep_str ++ "vfwscanf2.S", - "stdio" ++ path.sep_str ++ "vscanf.c", - "stdio" ++ path.sep_str ++ "vscanf2.S", "stdio" ++ path.sep_str ++ "vsnprintf.c", "stdio" ++ path.sep_str ++ "vsnwprintf.c", - "stdio" ++ path.sep_str ++ "vsscanf.c", - "stdio" ++ path.sep_str ++ "vsscanf2.S", - "stdio" ++ path.sep_str ++ "vswscanf.c", - "stdio" ++ path.sep_str ++ "vswscanf2.S", - "stdio" ++ path.sep_str ++ "vwscanf.c", - "stdio" ++ path.sep_str ++ "vwscanf2.S", "stdio" ++ path.sep_str ++ "wtoll.c", // mingwthrd "libsrc" ++ path.sep_str ++ "mingwthrd_mt.c", @@ -768,6 +753,7 @@ const mingw32_generic_src = [_][]const u8{ "stdio" ++ path.sep_str ++ "ucrt_fprintf.c", "stdio" ++ path.sep_str ++ "ucrt_fscanf.c", "stdio" ++ path.sep_str ++ "ucrt_fwprintf.c", + "stdio" ++ path.sep_str ++ "ucrt_ms_fprintf.c", "stdio" ++ path.sep_str ++ "ucrt_ms_fwprintf.c", "stdio" ++ path.sep_str ++ "ucrt_printf.c", "stdio" ++ path.sep_str ++ "ucrt_scanf.c", @@ -933,6 +919,7 @@ const mingw32_x86_src = [_][]const u8{ "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "cosl.c", "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "cosl_internal.S", "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "cossin.c", + "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "cossinl.c", "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "exp2l.S", "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "expl.c", "math" ++ path.sep_str ++ "x86" ++ path.sep_str ++ "expm1l.c",