[CRT] Fix _matherror and _setusermatherror

We previously used 2 different versions: one from wine and one from mingw-w64.
The former was used in msvcrt, the latter was statically compiled into the executable. When using MS libs, there is only one _matherr, which is statically linked into the executable and does nothing (it's not really a function for users to be called).
_setusermatherror should only exist in msvcrt and not statically, which wouldn't work at all.
This commit is contained in:
Timo Kreuzer 2021-07-24 18:13:06 +02:00
parent 486a4d93ed
commit da2a5673e7
8 changed files with 57 additions and 128 deletions

View file

@ -55,7 +55,6 @@ endif()
list(APPEND CRT_EXCEPT_SOURCE
${LIBCNTPR_EXCEPT_SOURCE}
except/matherr.c
except/stack.c
)

View file

@ -1,49 +0,0 @@
#include <precomp.h>
#define __USE_ISOC9X 1
#define __USE_ISOC99 1
#include <math.h>
#ifdef HAVE_IEEEFP_H
#include <ieeefp.h>
#endif
#ifndef HAVE_FINITE
#ifndef finite /* Could be a macro */
#ifdef isfinite
#define finite(x) isfinite(x)
#else
#define finite(x) (!isnan(x)) /* At least catch some cases */
#endif
#endif
#endif
#ifndef signbit
#define signbit(x) 0
#endif
typedef int (*MSVCRT_matherr_func)(struct _exception *);
static MSVCRT_matherr_func MSVCRT_default_matherr_func = NULL;
int CDECL _matherr(struct _exception *e)
{
if (e)
TRACE("(%p = %d, %s, %g %g %g)\n",e, e->type, e->name, e->arg1, e->arg2,
e->retval);
else
TRACE("(null)\n");
if (MSVCRT_default_matherr_func)
return MSVCRT_default_matherr_func(e);
ERR(":Unhandled math error!\n");
return 0;
}
/*********************************************************************
* __setusermatherr (MSVCRT.@)
*/
void CDECL __setusermatherr(MSVCRT_matherr_func func)
{
MSVCRT_default_matherr_func = func;
TRACE(":new matherr handler %p\n", func);
}

View file

@ -3,6 +3,7 @@ list(APPEND LIBCNTPR_MATH_SOURCE
math/abs.c
math/div.c
math/labs.c
math/usermatherr.c
)
if(ARCH STREQUAL "i386")

View file

@ -0,0 +1,36 @@
/*
* PROJECT: ReactOS CRT library
* LICENSE: MIT (https://spdx.org/licenses/MIT)
* PURPOSE: Implementation of __setusermatherr and _invoke_user_matherr
* COPYRIGHT: Copyright 2021 Timo Kreuzer <timo.kreuzer@reactos.org>
*/
// DO NOT SYNC WITH WINE OR MINGW32
#include <math.h>
/* MS headers have this in corecrt_startup.h */
typedef int (*_UserMathErrorFunctionPointer)(struct _exception *);
static _UserMathErrorFunctionPointer user_matherr = NULL;;
void
__cdecl
__setusermatherr(_UserMathErrorFunctionPointer func)
{
user_matherr = func;
}
int
__cdecl
_invoke_user_matherr(struct _exception *e)
{
if (user_matherr != NULL)
{
return user_matherr(e);
}
else
{
return 0;
}
}

View file

@ -2,6 +2,7 @@
include_directories(include/internal/mingw-w64)
list(APPEND MSVCRTEX_SOURCE
startup/_matherr.c
startup/crtexe.c
startup/wcrtexe.c
startup/crt_handler.c
@ -12,7 +13,6 @@ list(APPEND MSVCRTEX_SOURCE
startup/mingw_helpers.c
startup/natstart.c
startup/charmax.c
startup/merr.c
startup/atonexit.c
startup/dllmain.c
startup/txtmode.c

View file

@ -0,0 +1,18 @@
/*
* PROJECT: ReactOS CRT library
* LICENSE: MIT (https://spdx.org/licenses/MIT)
* PURPOSE: Implementation of _matherr dummy
* COPYRIGHT: Copyright 2021 Timo Kreuzer <timo.kreuzer@reactos.org>
*/
// DO NOT SYNC WITH WINE OR MINGW32
#include <math.h>
/* Dummy function, like in MS CRT */
int
__cdecl
_matherr(struct _exception *pexcept)
{
return 0;
}

View file

@ -1,76 +0,0 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the w64 mingw-runtime package.
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/
#include <internal.h>
#include <math.h>
#include <stdio.h>
typedef int (__cdecl *fUserMathErr)(struct _exception *);
static fUserMathErr stUserMathErr;
void __mingw_raise_matherr (int typ, const char *name, double a1, double a2,
double rslt)
{
struct _exception ex;
if (!stUserMathErr)
return;
ex.type = typ;
ex.name = (char*)name;
ex.arg1 = a1;
ex.arg2 = a2;
ex.retval = rslt;
(*stUserMathErr)(&ex);
}
#undef __setusermatherr
void __mingw_setusermatherr (int (__cdecl *f)(struct _exception *))
{
stUserMathErr = f;
__setusermatherr (f);
}
int __CRTDECL
_matherr (struct _exception *pexcept)
{
const char * type;
switch(pexcept->type)
{
case _DOMAIN:
type = "Argument domain error (DOMAIN)";
break;
case _SING:
type = "Argument singularity (SIGN)";
break;
case _OVERFLOW:
type = "Overflow range error (OVERFLOW)";
break;
case _PLOSS:
type = "Partial loss of significance (PLOSS)";
break;
case _TLOSS:
type = "Total loss of significance (TLOSS)";
break;
case _UNDERFLOW:
type = "The result is too small to be represented (UNDERFLOW)";
break;
default:
type = "Unknown error";
break;
}
__mingw_fprintf (stderr, "_matherr(): %s in %s(%g, %g) (retval=%g)\n",
type, pexcept->name, pexcept->arg1, pexcept->arg2, pexcept->retval);
return 0;
}

View file

@ -1,5 +1,6 @@
list(APPEND CRT_STARTUP_SOURCE
startup/_matherr.c
startup/crtexe.c
startup/wcrtexe.c
startup/crt_handler.c
@ -10,7 +11,6 @@ list(APPEND CRT_STARTUP_SOURCE
startup/mingw_helpers.c
startup/natstart.c
startup/charmax.c
#startup/merr.c
startup/atonexit.c
#startup/txtmode.c
startup/pesect.c