Create a branch for cmake bringup.

svn path=/branches/cmake-bringup/; revision=48236
This commit is contained in:
Amine Khaldi 2010-07-24 18:52:44 +00:00
parent a28e798006
commit c424146e2c
20602 changed files with 0 additions and 1140137 deletions

10
lib/sdk/crt/README.txt Normal file
View file

@ -0,0 +1,10 @@
Big chunks of this CRT library are taken from Wine's msvcrt implementation,
you can find a list of synced files in README.WINE file.
Notes:
1. When syncing, omit MSVCRT_ prefix where possible, Wine has to keep this
because they are linking with *both* original crt, and ms crt implementation.
ReactOS has the only CRT, so no need to make distinct functions.
2. ReactOS compiles two versions of the CRT library, one for usermode
(called just "crt"), and one version for kernelmode usage (called "libcntpr").
In order to separate the code, you can use #ifdef _LIBCNT_ for libcntpr code.

73
lib/sdk/crt/conio/cgets.c Normal file
View file

@ -0,0 +1,73 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: msvcrt/conio/cgets.c
* PURPOSE: C Runtime
* PROGRAMMER: Eric Kohl (Imported from DJGPP)
*/
#include <precomp.h>
/*
* @implemented
*/
char *_cgets(char *string)
{
unsigned len = 0;
unsigned int maxlen_wanted;
char *sp;
int c;
/*
* Be smart and check for NULL pointer.
* Don't know wether TURBOC does this.
*/
if (!string)
return(NULL);
maxlen_wanted = (unsigned int)((unsigned char)string[0]);
sp = &(string[2]);
/*
* Should the string be shorter maxlen_wanted including or excluding
* the trailing '\0' ? We don't take any risk.
*/
while(len < maxlen_wanted-1)
{
c=_getch();
/*
* shold we check for backspace here?
* TURBOC does (just checked) but doesn't in cscanf (thats harder
* or even impossible). We do the same.
*/
if (c == '\b')
{
if (len > 0)
{
_cputs("\b \b"); /* go back, clear char on screen with space
and go back again */
len--;
sp[len] = '\0'; /* clear the character in the string */
}
}
else if (c == '\r')
{
sp[len] = '\0';
break;
}
else if (c == 0)
{
/* special character ends input */
sp[len] = '\0';
_ungetch(c); /* keep the char for later processing */
break;
}
else
{
sp[len] = _putch(c);
len++;
}
}
sp[maxlen_wanted-1] = '\0';
string[1] = (char)((unsigned char)len);
return(sp);
}

View file

@ -0,0 +1,40 @@
/*
* COPYRIGHT: Winehq
* PROJECT: wine
* FILE: msvcrt/conio/cprintf.c
* PURPOSE: C Runtime
* PROGRAMMER: Magnus Olsen (Imported from wine cvs 2006-05-23)
*/
#include <precomp.h>
/*
* @implemented
*/
int
_cprintf(const char *fmt, ...)
{
char buf[2048], *mem = buf;
int written, resize = sizeof(buf), retval;
va_list valist;
va_start( valist, fmt );
while ((written = _vsnprintf( mem, resize, fmt, valist )) == -1 ||
written > resize)
{
resize = (written == -1 ? resize * 2 : written + 1);
if (mem != buf)
free (mem);
if (!(mem = (char *)malloc(resize)))
return EOF;
va_end ( valist );
va_start( valist, fmt );
}
va_end ( valist );
retval = _cputs( mem );
if (mem != buf)
free (mem);
return retval;
}

35
lib/sdk/crt/conio/cputs.c Normal file
View file

@ -0,0 +1,35 @@
/*
* COPYRIGHT: LGPL - See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/msvcrt/conio/cputs.c
* PURPOSE: Writes a character to stdout
* PROGRAMER: Aleksey Bragin
*/
#include <precomp.h>
extern FDINFO *fdesc;
/*
* @implemented
*/
int _cputs(const char *_str)
{
#if 0
DWORD count;
int retval = EOF;
LOCK_CONSOLE;
if (WriteConsoleA(console_out, str, strlen(str), &count, NULL)
&& count == 1)
retval = 0;
UNLOCK_CONSOLE;
return retval;
#else
int len = strlen(_str);
DWORD written = 0;
if (!WriteFile( fdesc[stdout->_file].hFile ,_str,len,&written,NULL))
return -1;
return 0;
#endif
}

55
lib/sdk/crt/conio/getch.c Normal file
View file

@ -0,0 +1,55 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/msvcrt/conio/getch.c
* PURPOSE: Writes a character to stdout
* PROGRAMER: Ariadne
* UPDATE HISTORY:
* 28/12/98: Created
*/
#include <precomp.h>
/*
* @implemented
*/
int _getch(void)
{
DWORD NumberOfCharsRead = 0;
char c;
HANDLE ConsoleHandle;
BOOL RestoreMode;
DWORD ConsoleMode;
if (char_avail) {
c = ungot_char;
char_avail = 0;
} else {
/*
* _getch() is documented to NOT echo characters. Testing shows it
* doesn't wait for a CR either. So we need to switch off
* ENABLE_ECHO_INPUT and ENABLE_LINE_INPUT if they're currently
* switched on.
*/
ConsoleHandle = (HANDLE) _get_osfhandle(stdin->_file);
RestoreMode = GetConsoleMode(ConsoleHandle, &ConsoleMode) &&
(0 != (ConsoleMode &
(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT)));
if (RestoreMode) {
SetConsoleMode(ConsoleHandle,
ConsoleMode & (~ (ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT)));
}
ReadConsoleA((HANDLE)_get_osfhandle(stdin->_file),
&c,
1,
&NumberOfCharsRead,
NULL);
if (RestoreMode) {
SetConsoleMode(ConsoleHandle, ConsoleMode);
}
}
if (c == 10)
c = 13;
return c;
}

View file

@ -0,0 +1,29 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details
* PROJECT: ReactOS system libraries
* FILE: lib/msvcrt/conio/getche.c
* PURPOSE: Reads a character from stdin
* PROGRAMER: DJ Delorie
Ariadne
* UPDATE HISTORY:
* 28/12/98: Created
*/
#include <precomp.h>
int _getche(void)
{
if (char_avail)
/*
* We don't know, wether the ungot char was already echoed
* we assume yes (for example in cscanf, probably the only
* place where ungetch is ever called.
* There is no way to check for this really, because
* ungetch could have been called with a character that
* hasn't been got by a conio function.
* We don't echo again.
*/
return(_getch());
return (_putch(_getch()));
}

101
lib/sdk/crt/conio/kbhit.c Normal file
View file

@ -0,0 +1,101 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/msvcrt/conio/kbhit.c
* PURPOSE: Checks for keyboard hits
* PROGRAMERS: Ariadne, Russell
* UPDATE HISTORY:
* 28/12/98: Created
* 27/9/08: An almost 100% working version of _kbhit()
*/
#include <precomp.h>
static CRITICAL_SECTION CriticalSection;
volatile BOOL CriticalSectionInitialized=FALSE;
/*
* FIXME Initial keyboard char not detected on first punch
*
* @implemented
*/
int _kbhit(void)
{
PINPUT_RECORD InputRecord = NULL;
DWORD NumberRead = 0;
DWORD EventsRead = 0;
DWORD RecordIndex = 0;
DWORD BufferIndex = 0;
HANDLE StdInputHandle = 0;
DWORD ConsoleInputMode = 0;
/* Attempt some thread safety */
if (!CriticalSectionInitialized)
{
InitializeCriticalSectionAndSpinCount(&CriticalSection, 0x80000400);
CriticalSectionInitialized = TRUE;
}
EnterCriticalSection(&CriticalSection);
if (char_avail)
{
LeaveCriticalSection(&CriticalSection);
return 1;
}
StdInputHandle = GetStdHandle(STD_INPUT_HANDLE);
/* Turn off processed input so we get key modifiers as well */
GetConsoleMode(StdInputHandle, &ConsoleInputMode);
SetConsoleMode(StdInputHandle, ConsoleInputMode & ~ENABLE_PROCESSED_INPUT);
/* Start the process */
if (!GetNumberOfConsoleInputEvents(StdInputHandle, &EventsRead))
{
LeaveCriticalSection(&CriticalSection);
return 0;
}
if (!EventsRead)
{
LeaveCriticalSection(&CriticalSection);
return 0;
}
if (!(InputRecord = (PINPUT_RECORD)malloc(EventsRead * sizeof(INPUT_RECORD))))
{
LeaveCriticalSection(&CriticalSection);
return 0;
}
if (!ReadConsoleInput(StdInputHandle, InputRecord, EventsRead, &NumberRead))
{
free(InputRecord);
LeaveCriticalSection(&CriticalSection);
return 0;
}
for (RecordIndex = 0; RecordIndex < NumberRead; RecordIndex++)
{
if (InputRecord[RecordIndex].EventType == KEY_EVENT &&
InputRecord[RecordIndex].Event.KeyEvent.bKeyDown)
{
BufferIndex = 1;
break;
}
}
free(InputRecord);
/* Restore console input mode */
SetConsoleMode(StdInputHandle, ConsoleInputMode);
LeaveCriticalSection(&CriticalSection);
return BufferIndex;
}

24
lib/sdk/crt/conio/putch.c Normal file
View file

@ -0,0 +1,24 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/msvcrt/conio/putch.c
* PURPOSE: Writes a character to stdout
* PROGRAMER: Ariadne
* UPDATE HISTORY:
* 28/12/98: Created
*/
#include <precomp.h>
/*
* @implemented
*/
int _putch(int c)
{
DWORD NumberOfCharsWritten;
if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),&c,1,&NumberOfCharsWritten,NULL)) {
return -1;
}
return NumberOfCharsWritten;
}

View file

@ -0,0 +1,29 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details
* PROJECT: ReactOS system libraries
* FILE: lib/msvcrt/conio/ungetch.c
* PURPOSE: Ungets a character from stdin
* PROGRAMER: DJ Delorie
Ariadne [ Adapted from djgpp libc ]
* UPDATE HISTORY:
* 28/12/98: Created
*/
#include <precomp.h>
int char_avail = 0;
int ungot_char = 0;
/*
* @implemented
*/
int _ungetch(int c)
{
if (char_avail)
return(EOF);
ungot_char = c;
char_avail = 1;
return(c);
}

524
lib/sdk/crt/crt.rbuild Normal file
View file

@ -0,0 +1,524 @@
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
<group>
<module name="chkstk" type="staticlibrary">
<directory name="except">
<if property="ARCH" value="i386">
<directory name="i386">
<file>chkstk_asm.s</file>
</directory>
</if>
<if property="ARCH" value="powerpc">
<directory name="powerpc">
<file>chkstk_asm.s</file>
</directory>
</if>
</directory>
</module>
<module name="crt" type="staticlibrary">
<library>chkstk</library>
<include base="crt">.</include>
<include base="crt">include</include>
<define name="__MINGW_IMPORT">extern</define>
<define name="USE_MSVCRT_PREFIX" />
<define name="_MSVCRT_LIB_" />
<define name="_MSVCRT_" />
<define name="_MT" />
<define name="_CRTBLD" />
<directory name="conio">
<file>cgets.c</file>
<file>cprintf.c</file>
<file>cputs.c</file>
<file>getch.c</file>
<file>getche.c</file>
<file>kbhit.c</file>
<file>putch.c</file>
<file>ungetch.c</file>
</directory>
<directory name="direct">
<file>chdir.c</file>
<file>chdrive.c</file>
<file>getcwd.c</file>
<file>getdcwd.c</file>
<file>getdfree.c</file>
<file>getdrive.c</file>
<file>mkdir.c</file>
<file>rmdir.c</file>
<file>wchdir.c</file>
<file>wgetcwd.c</file>
<file>wgetdcwd.c</file>
<file>wmkdir.c</file>
<file>wrmdir.c</file>
</directory>
<directory name="except">
<file>abnorter.c</file>
<file>checkesp.c</file>
<file>cpp.c</file>
<file>cppexcept.c</file>
<file>except.c</file>
<file>matherr.c</file>
<if property="ARCH" value="i386">
<directory name="i386">
<file>prolog.s</file>
<file>seh.s</file>
<file>unwind.c</file>
</directory>
</if>
<if property="ARCH" value="powerpc">
<directory name="powerpc">
<file>seh.s</file>
</directory>
</if>
<if property="ARCH" value="amd64">
<directory name="amd64">
<file>seh.s</file>
<file>chkstk_asm.s</file>
</directory>
</if>
<file>xcptfil.c</file>
</directory>
<directory name="float">
<file>chgsign.c</file>
<file>copysign.c</file>
<file>fpclass.c</file>
<file>fpecode.c</file>
<file>isnan.c</file>
<file>nafter.c</file>
<file>scalb.c</file>
<if property="ARCH" value="i386">
<directory name="i386">
<file>clearfp.c</file>
<file>cntrlfp.c</file>
<file>fpreset.c</file>
<file>logb.c</file>
<file>statfp.c</file>
</directory>
</if>
<if property="ARCH" value="amd64">
<directory name="i386">
<file>clearfp.c</file>
<file>cntrlfp.c</file>
<file>fpreset.c</file>
<file>logb.c</file>
<file>statfp.c</file>
</directory>
</if>
</directory>
<directory name="locale">
<file>locale.c</file>
</directory>
<directory name="math">
<file>acos.c</file>
<file>adjust.c</file>
<file>asin.c</file>
<file>cabs.c</file>
<file>cosf.c</file>
<file>cosh.c</file>
<file>div.c</file>
<file>fdivbug.c</file>
<file>frexp.c</file>
<file>huge_val.c</file>
<file>hypot.c</file>
<file>ldiv.c</file>
<file>modf.c</file>
<file>rand.c</file>
<file>s_modf.c</file>
<file>sinf.c</file>
<file>sinh.c</file>
<file>tanh.c</file>
<file>pow_asm.c</file>
<if property="ARCH" value="i386">
<directory name="i386">
<file>alldiv_asm.s</file>
<file>alldvrm_asm.s</file>
<file>allmul_asm.s</file>
<file>allrem_asm.s</file>
<file>allshl_asm.s</file>
<file>allshr_asm.s</file>
<file>atan_asm.s</file>
<file>aulldiv_asm.s</file>
<file>aulldvrm_asm.s</file>
<file>aullrem_asm.s</file>
<file>aullshr_asm.s</file>
<file>ceil_asm.s</file>
<file>ceilf.S</file>
<file>cos_asm.s</file>
<file>fabs_asm.s</file>
<file>floor_asm.s</file>
<file>floorf.S</file>
<file>ftol_asm.s</file>
<file>log_asm.s</file>
<file>log10_asm.s</file>
<file>pow_asm.s</file>
<file>sin_asm.s</file>
<file>sqrt_asm.s</file>
<file>tan_asm.s</file>
<file>atan2.c</file>
<file>ci.c</file>
<file>exp.c</file>
<file>fmod.c</file>
<file>fmodf.c</file>
<file>ldexp.c</file>
<file>sqrtf.c</file>
</directory>
<!-- FIXME: we don't actually implement these... they recursively call themselves through an alias -->
<!--<file>j0_y0.c</file>
<file>j1_y1.c</file>
<file>jn_yn.c</file>-->
</if>
<if property="ARCH" value="amd64">
<file>cos.c</file>
<file>sin.c</file>
<directory name="amd64">
<file>alldiv.S</file>
<file>atan.S</file>
<file>atan2.S</file>
<file>ceil.S</file>
<file>ceilf.S</file>
<file>exp.S</file>
<file>fabs.S</file>
<file>floor.S</file>
<file>floorf.S</file>
<file>fmod.S</file>
<file>fmodf.S</file>
<file>ldexp.S</file>
<file>log.S</file>
<file>log10.S</file>
<file>pow.S</file>
<file>sqrt.S</file>
<file>sqrtf.S</file>
<file>tan.S</file>
</directory>
<!-- FIXME: we don't actually implement these... they recursively call themselves through an alias -->
<!--<file>j0_y0.c</file>
<file>j1_y1.c</file>
<file>jn_yn.c</file>-->
</if>
<ifnot property="ARCH" value="i386">
<file>stubs.c</file>
</ifnot>
</directory>
<directory name="mbstring">
<file>hanzen.c</file>
<file>ischira.c</file>
<file>iskana.c</file>
<file>iskmoji.c</file>
<file>iskpun.c</file>
<file>islead.c</file>
<file>islwr.c</file>
<file>ismbal.c</file>
<file>ismbaln.c</file>
<file>ismbc.c</file>
<file>ismbgra.c</file>
<file>ismbkaln.c</file>
<file>ismblead.c</file>
<file>ismbpri.c</file>
<file>ismbpun.c</file>
<file>ismbtrl.c</file>
<file>isuppr.c</file>
<file>jistojms.c</file>
<file>jmstojis.c</file>
<file>mbbtype.c</file>
<file>mbccpy.c</file>
<file>mbclen.c</file>
<file>mbscat.c</file>
<file>mbschr.c</file>
<file>mbscmp.c</file>
<file>mbscoll.c</file>
<file>mbscpy.c</file>
<file>mbscspn.c</file>
<file>mbsdec.c</file>
<file>mbsdup.c</file>
<file>mbsicmp.c</file>
<file>mbsicoll.c</file>
<file>mbsinc.c</file>
<file>mbslen.c</file>
<file>mbslwr.c</file>
<file>mbsncat.c</file>
<file>mbsnccnt.c</file>
<file>mbsncmp.c</file>
<file>mbsncoll.c</file>
<file>mbsncpy.c</file>
<file>mbsnextc.c</file>
<file>mbsnicmp.c</file>
<file>mbsnicoll.c</file>
<file>mbsninc.c</file>
<file>mbsnset.c</file>
<file>mbspbrk.c</file>
<file>mbsrchr.c</file>
<file>mbsrev.c</file>
<file>mbsset.c</file>
<file>mbsspn.c</file>
<file>mbsspnp.c</file>
<file>mbsstr.c</file>
<file>mbstok.c</file>
<file>mbstrlen.c</file>
<file>mbsupr.c</file>
</directory>
<directory name="mem">
<if property="ARCH" value="i386">
<directory name="i386">
<file>memchr_asm.s</file>
<file>memcpy_asm.s</file>
<file>memmove_asm.s</file>
<file>memset_asm.s</file>
</directory>
</if>
<ifnot property="ARCH" value="i386">
<file>memchr.c</file>
<file>memcpy.c</file>
<file>memmove.c</file>
<file>memset.c</file>
</ifnot>
<file>memcmp.c</file>
<file>memccpy.c</file>
<file>memicmp.c</file>
</directory>
<directory name="misc">
<file>amsg.c</file>
<file>assert.c</file>
<file>crtmain.c</file>
<file>environ.c</file>
<file>getargs.c</file>
<file>initterm.c</file>
<file>lock.c</file>
<file>purecall.c</file>
<file>stubs.c</file>
<file>tls.c</file>
</directory>
<directory name="process">
<file>_cwait.c</file>
<file>_system.c</file>
<file>dll.c</file>
<file>process.c</file>
<file>procid.c</file>
<file>thread.c</file>
<file>threadid.c</file>
<file>threadx.c</file>
<file>wprocess.c</file>
</directory>
<directory name="search">
<file>bsearch.c</file>
<file>lfind.c</file>
<file>lsearch.c</file>
</directory>
<directory name="setjmp">
<if property="ARCH" value="i386">
<directory name="i386">
<file>setjmp.s</file>
</directory>
</if>
<if property="ARCH" value="amd64">
<directory name="amd64">
<file>setjmp.s</file>
</directory>
</if>
</directory>
<directory name="signal">
<file>signal.c</file>
<file>xcptinfo.c</file>
</directory>
<directory name="stdio">
<file>access.c</file>
<file>file.c</file>
<file>find.c</file>
<file>find64.c</file>
<file>findi64.c</file>
<file>fmode.c</file>
<file>lnx_sprintf.c</file>
<file>perror.c</file>
<file>popen.c</file>
<file>stat.c</file>
<file>stat64.c</file>
<file>waccess.c</file>
<file>wfind.c</file>
<file>wfind64.c</file>
<file>wfindi64.c</file>
<file>wpopen.c</file>
<file>wstat.c</file>
<file>wstat64.c</file>
</directory>
<directory name="stdlib">
<file>_exit.c</file>
<file>abort.c</file>
<file>atexit.c</file>
<file>ecvt.c</file>
<file>errno.c</file>
<file>fcvt.c</file>
<file>fcvtbuf.c</file>
<file>fullpath.c</file>
<file>gcvt.c</file>
<file>getenv.c</file>
<file>makepath.c</file>
<file>makepath_s.c</file>
<file>mbtowc.c</file>
<file>mbstowcs.c</file>
<file>obsol.c</file>
<file>putenv.c</file>
<file>qsort.c</file>
<file>rot.c</file>
<file>senv.c</file>
<file>swab.c</file>
<file>wfulpath.c</file>
<file>wputenv.c</file>
<file>wsenv.c</file>
<file>wmakpath.c</file>
<file>wmakpath_s.c</file>
</directory>
<directory name="string">
<if property="ARCH" value="i386">
<directory name="i386">
<file>strcat_asm.s</file>
<file>strchr_asm.s</file>
<file>strcmp_asm.s</file>
<file>strcpy_asm.s</file>
<file>strlen_asm.s</file>
<file>strncat_asm.s</file>
<file>strncmp_asm.s</file>
<file>strncpy_asm.s</file>
<file>strnlen_asm.s</file>
<file>strrchr_asm.s</file>
<file>wcscat_asm.s</file>
<file>wcschr_asm.s</file>
<file>wcscmp_asm.s</file>
<file>wcscpy_asm.s</file>
<file>wcslen_asm.s</file>
<file>wcsncat_asm.s</file>
<file>wcsncmp_asm.s</file>
<file>wcsncpy_asm.s</file>
<file>wcsnlen_asm.s</file>
<file>wcsrchr_asm.s</file>
</directory>
</if>
<ifnot property="ARCH" value="i386">
<file>strcat.c</file>
<file>strchr.c</file>
<file>strcmp.c</file>
<file>strcpy.c</file>
<file>strlen.c</file>
<file>strncat.c</file>
<file>strncmp.c</file>
<file>strncpy.c</file>
<file>strnlen.c</file>
<file>strrchr.c</file>
<file>wcscat.c</file>
<file>wcschr.c</file>
<file>wcscmp.c</file>
<file>wcscpy.c</file>
<file>wcslen.c</file>
<file>wcsncat.c</file>
<file>wcsncmp.c</file>
<file>wcsncpy.c</file>
<file>wcsnlen.c</file>
<file>wcsrchr.c</file>
</ifnot>
<file>atof.c</file>
<file>atoi.c</file>
<file>atoi64.c</file>
<file>atol.c</file>
<file>ctype.c</file>
<file>itoa.c</file>
<file>itow.c</file>
<file>lasttok.c</file>
<file>scanf.c</file>
<file>splitp.c</file>
<file>strcoll.c</file>
<file>strcspn.c</file>
<file>strdup.c</file>
<file>strerror.c</file>
<file>stricmp.c</file>
<file>string.c</file>
<file>strlwr.c</file>
<file>strncoll.c</file>
<file>strnicmp.c</file>
<file>strpbrk.c</file>
<file>strrev.c</file>
<file>strset.c</file>
<file>strspn.c</file>
<file>strstr.c</file>
<file>strtod.c</file>
<file>strtoi64.c</file>
<file>strtok.c</file>
<file>strtol.c</file>
<file>strtoul.c</file>
<file>strtoull.c</file>
<file>strupr.c</file>
<file>strxfrm.c</file>
<file>wcs.c</file>
<file>wcstol.c</file>
<file>wcstoul.c</file>
<file>wsplitp.c</file>
<file>wtoi.c</file>
<file>wtoi64.c</file>
<file>wtol.c</file>
</directory>
<directory name="sys_stat">
<file>systime.c</file>
</directory>
<directory name="time">
<file>asctime.c</file>
<file>clock.c</file>
<file>ctime32.c</file>
<file>ctime64.c</file>
<file>ctime.c</file>
<file>difftime32.c</file>
<file>difftime64.c</file>
<file>difftime.c</file>
<file>ftime32.c</file>
<file>ftime64.c</file>
<file>ftime.c</file>
<file>futime32.c</file>
<file>futime64.c</file>
<file>futime.c</file>
<file>gmtime.c</file>
<file>localtime32.c</file>
<file>localtime64.c</file>
<file>localtime.c</file>
<file>mktime.c</file>
<file>strdate.c</file>
<file>strftime.c</file>
<file>strtime.c</file>
<file>time32.c</file>
<file>time64.c</file>
<file>time.c</file>
<file>timezone.c</file>
<file>tzname.c</file>
<file>utime32.c</file>
<file>utime64.c</file>
<file>utime.c</file>
<file>wasctime.c</file>
<file>wcsftime.c</file>
<file>wctime32.c</file>
<file>wctime64.c</file>
<file>wctime.c</file>
<file>wstrdate.c</file>
<file>wstrtime.c</file>
<file>wutime32.c</file>
<file>wutime64.c</file>
<file>wutime.c</file>
</directory>
<directory name="wstring">
<file>wcscoll.c</file>
<file>wcscspn.c</file>
<file>wcsicmp.c</file>
<file>wcslwr.c</file>
<file>wcsnicmp.c</file>
<file>wcsspn.c</file>
<file>wcsstr.c</file>
<file>wcstok.c</file>
<file>wcsupr.c</file>
<file>wcsxfrm.c</file>
<file>wlasttok.c</file>
</directory>
<directory name="wine">
<file>heap.c</file>
<file>undname.c</file>
</directory>
</module>
</group>

View file

@ -0,0 +1,27 @@
#include <precomp.h>
#include <ctype.h>
#include <direct.h>
#include <tchar.h>
/*
* @implemented
*/
int _tchdir(const _TCHAR* _path)
{
WCHAR newdir[MAX_PATH];
if (!SetCurrentDirectory(_path))
{
_dosmaperr(_path ? GetLastError() : 0);
return -1;
}
/* Update the drive-specific current directory variable */
if (GetCurrentDirectoryW(MAX_PATH, newdir) && newdir[1] == L':')
{
WCHAR envvar[4] = { L'=', towupper(newdir[0]), L':', L'\0' };
SetEnvironmentVariableW(envvar, newdir);
}
return 0;
}

View file

@ -0,0 +1,45 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/crt/chdrive.c
* PURPOSE: Change the current drive.
* PROGRAMER: WINE
* UPDATE HISTORY:
* 25/11/05: Added license header
*/
#include <precomp.h>
/*
* @implemented
*
* _chdrive (MSVCRT.@)
*
* Change the current drive.
*
* PARAMS
* newdrive [I] Drive number to change to (1 = 'A', 2 = 'B', ...)
*
* RETURNS
* Success: 0. The current drive is set to newdrive.
* Failure: -1. errno indicates the error.
*
* NOTES
* See SetCurrentDirectoryA.
*/
int _chdrive(int newdrive)
{
WCHAR buffer[] = L"A:";
buffer[0] += newdrive - 1;
if (!SetCurrentDirectoryW( buffer ))
{
_dosmaperr(GetLastError());
if (newdrive <= 0)
{
__set_errno(EACCES);
}
return -1;
}
return 0;
}

View file

@ -0,0 +1,33 @@
#include <precomp.h>
#include <direct.h>
#include <stdlib.h>
#include <tchar.h>
/*
* @implemented
*/
_TCHAR* _tgetcwd(_TCHAR* buf, int size)
{
_TCHAR dir[MAX_PATH];
DWORD dir_len = GetCurrentDirectory(MAX_PATH,dir);
if (dir_len == 0)
{
_dosmaperr(GetLastError());
return NULL; /* FIXME: Real return value untested */
}
if (!buf)
{
return _tcsdup(dir);
}
if (dir_len >= (DWORD)size)
{
__set_errno(ERANGE);
return NULL; /* buf too small */
}
_tcscpy(buf,dir);
return buf;
}

View file

@ -0,0 +1,62 @@
#include <precomp.h>
#include <direct.h>
#include <tchar.h>
/*
* @implemented
*
* _getdcwd (MSVCRT.@)
*
* Get the current working directory on a given disk.
*
* PARAMS
* drive [I] Drive letter to get the current working directory from.
* buf [O] Destination for the current working directory.
* size [I] Length of drive in characters.
*
* RETURNS
* Success: If drive is NULL, returns an allocated string containing the path.
* Otherwise populates drive with the path and returns it.
* Failure: NULL. errno indicates the error.
*/
_TCHAR* _tgetdcwd(int drive, _TCHAR * buf, int size)
{
static _TCHAR* dummy;
TRACE(":drive %d(%c), size %d\n",drive, drive + 'A' - 1, size);
if (!drive || drive == _getdrive())
return _tgetcwd(buf,size); /* current */
else
{
_TCHAR dir[MAX_PATH];
_TCHAR drivespec[] = _T("A:");
int dir_len;
drivespec[0] += drive - 1;
if (GetDriveType(drivespec) < DRIVE_REMOVABLE)
{
__set_errno(EACCES);
return NULL;
}
/* GetFullPathName for X: means "get working directory on drive X",
* just like passing X: to SetCurrentDirectory means "switch to working
* directory on drive X". -Gunnar */
dir_len = GetFullPathName(drivespec,MAX_PATH,dir,&dummy);
if (dir_len >= size || dir_len < 1)
{
__set_errno(ERANGE);
return NULL; /* buf too small */
}
TRACE(":returning '%s'\n", dir);
if (!buf)
return _tcsdup(dir); /* allocate */
_tcscpy(buf,dir);
}
return buf;
}

View file

@ -0,0 +1,23 @@
#include <precomp.h>
#include <ctype.h>
#include <direct.h>
/*
* @implemented
*/
unsigned int _getdiskfree(unsigned int _drive, struct _diskfree_t* _diskspace)
{
char RootPathName[10];
RootPathName[0] = toupper(_drive +'@');
RootPathName[1] = ':';
RootPathName[2] = '\\';
RootPathName[3] = 0;
if (_diskspace == NULL)
return 0;
if (!GetDiskFreeSpaceA(RootPathName,(LPDWORD)&_diskspace->sectors_per_cluster,(LPDWORD)&_diskspace->bytes_per_sector,
(LPDWORD )&_diskspace->avail_clusters,(LPDWORD )&_diskspace->total_clusters))
return 0;
return _diskspace->avail_clusters;
}

View file

@ -0,0 +1,35 @@
#include <precomp.h>
#include <ctype.h>
#include <direct.h>
/*
* @implemented
*
* _getdrive (MSVCRT.@)
*
* Get the current drive number.
*
* PARAMS
* None.
*
* RETURNS
* Success: The drive letter number from 1 to 26 ("A:" to "Z:").
* Failure: 0.
*/
int _getdrive(void)
{
WCHAR buffer[MAX_PATH];
if (GetCurrentDirectoryW( MAX_PATH, buffer ) &&
buffer[0] >= 'A' && buffer[0] <= 'z' && buffer[1] == ':')
return towupper(buffer[0]) - 'A' + 1;
return 0;
}
/*
* @implemented
*/
unsigned long _getdrives(void)
{
return GetLogicalDrives();
}

View file

@ -0,0 +1,15 @@
#include <precomp.h>
#include <direct.h>
#include <tchar.h>
/*
* @implemented
*/
int _tmkdir(const _TCHAR* _path)
{
if (!CreateDirectory(_path, NULL)) {
_dosmaperr(GetLastError());
return -1;
}
return 0;
}

View file

@ -0,0 +1,15 @@
#include <precomp.h>
#include <direct.h>
#include <tchar.h>
/*
* @implemented
*/
int _trmdir(const _TCHAR* _path)
{
if (!RemoveDirectory(_path)) {
_dosmaperr(GetLastError());
return -1;
}
return 0;
}

View file

@ -0,0 +1,4 @@
#define UNICODE
#define _UNICODE
#include "chdir.c"

View file

@ -0,0 +1,5 @@
#define UNICODE
#define _UNICODE
#include "getcwd.c"

View file

@ -0,0 +1,5 @@
#define UNICODE
#define _UNICODE
#include "getdcwd.c"

View file

@ -0,0 +1,4 @@
#define UNICODE
#define _UNICODE
#include "mkdir.c"

View file

@ -0,0 +1,4 @@
#define UNICODE
#define _UNICODE
#include "rmdir.c"

View file

@ -0,0 +1 @@
#include <precomp.h>

View file

@ -0,0 +1,30 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of _chkstk and _alloca_probe
* FILE: lib/sdk/crt/math/amd64/chkstk_asm.s
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
.intel_syntax noprefix
.global MsgUnimplemented
MsgUnimplemented:
.asciz "WARNING: %s at %s:%d is UNIMPLEMENTED!\n"
.proc _chkstk
UNIMPLEMENTED chkstk
ret
.endp
.proc _alloca_probe
UNIMPLEMENTED alloca_probe
ret
.endp
/* EOF */

View file

@ -0,0 +1,56 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CRT
* FILE: lib/crt/misc/i386/seh.S
* PURPOSE: SEH Support for the CRT
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <ndk/asm.h>
.intel_syntax noprefix
#define DISPOSITION_DISMISS 0
#define DISPOSITION_CONTINUE_SEARCH 1
#define DISPOSITION_COLLIDED_UNWIND 3
/* GLOBALS *******************************************************************/
.globl _global_unwind2
.globl _local_unwind2
.globl _abnormal_termination
.globl _except_handler2
.globl _except_handler3
/* FUNCTIONS *****************************************************************/
.func _unwind_handler
_unwind_handler:
ret
.endfunc
.func _global_unwind2
_global_unwind2:
ret
.endfunc
.func _abnormal_termination
_abnormal_termination:
ret
.endfunc
.func _local_unwind2
_local_unwind2:
ret
.endfunc
.func _except_handler2
_except_handler2:
ret
.endfunc
.func _except_handler3
_except_handler3:
ret
.endfunc

View file

@ -0,0 +1,35 @@
/*********************************************************************
* _chkesp (MSVCRT.@)
*
* Trap to a debugger if the value of the stack pointer has changed.
*
* PARAMS
* None.
*
* RETURNS
* Does not return.
*
* NOTES
* This function is available for iX86 only.
*
* When VC++ generates debug code, it stores the value of the stack pointer
* before calling any external function, and checks the value following
* the call. It then calls this function, which will trap if the values are
* not the same. Usually this means that the prototype used to call
* the function is incorrect. It can also mean that the .spec entry has
* the wrong calling convention or parameters.
*/
#ifdef __i386__
void _chkesp(void)
{
}
#else
void _chkesp(void)
{
}
#endif /* __i386__ */

1247
lib/sdk/crt/except/cpp.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,508 @@
/*
* msvcrt C++ exception handling
*
* Copyright 2002 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* NOTES
* A good reference is the article "How a C++ compiler implements
* exception handling" by Vishal Kochhar, available on
* www.thecodeproject.com.
*/
#define __WINE_DEBUG_CHANNEL__
#include <precomp.h>
#include <stdarg.h>
#include <wine/exception.h>
#include <internal/wine/msvcrt.h>
#include <internal/wine/cppexcept.h>
#ifdef __i386__ /* CxxFrameHandler is not supported on non-i386 */
WINE_DEFAULT_DEBUG_CHANNEL(seh);
DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame,
PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch,
const cxx_function_descr *descr,
EXCEPTION_REGISTRATION_RECORD* nested_frame, int nested_trylevel );
/* call a function with a given ebp */
static inline void *call_ebp_func( void *func, void *ebp )
{
void *ret;
int dummy;
__asm__ __volatile__ ("pushl %%ebx\n\t"
"pushl %%ebp\n\t"
"movl %4,%%ebp\n\t"
"call *%%eax\n\t"
"popl %%ebp\n\t"
"popl %%ebx"
: "=a" (ret), "=S" (dummy), "=D" (dummy)
: "0" (func), "1" (ebp) : "ecx", "edx", "memory" );
return ret;
}
/* call a copy constructor */
static inline void call_copy_ctor( void *func, void *this, void *src, int has_vbase )
{
TRACE( "calling copy ctor %p object %p src %p\n", func, this, src );
if (has_vbase)
/* in that case copy ctor takes an extra bool indicating whether to copy the base class */
__asm__ __volatile__("pushl $1; pushl %2; call *%0"
: : "r" (func), "c" (this), "r" (src) : "eax", "edx", "memory" );
else
__asm__ __volatile__("pushl %2; call *%0"
: : "r" (func), "c" (this), "r" (src) : "eax", "edx", "memory" );
}
/* call the destructor of the exception object */
static inline void call_dtor( void *func, void *object )
{
__asm__ __volatile__("call *%0" : : "r" (func), "c" (object) : "eax", "edx", "memory" );
}
/* continue execution to the specified address after exception is caught */
static inline void DECLSPEC_NORETURN continue_after_catch( cxx_exception_frame* frame, void *addr )
{
__asm__ __volatile__("movl -4(%0),%%esp; leal 12(%0),%%ebp; jmp *%1"
: : "r" (frame), "a" (addr) );
for (;;) ; /* unreached */
}
static inline void dump_type( const cxx_type_info *type )
{
TRACE( "flags %x type %p %s offsets %d,%d,%d size %d copy ctor %p\n",
type->flags, type->type_info, dbgstr_type_info(type->type_info),
type->offsets.this_offset, type->offsets.vbase_descr, type->offsets.vbase_offset,
type->size, type->copy_ctor );
}
static void dump_exception_type( const cxx_exception_type *type )
{
UINT i;
TRACE( "flags %x destr %p handler %p type info %p\n",
type->flags, type->destructor, type->custom_handler, type->type_info_table );
for (i = 0; i < type->type_info_table->count; i++)
{
TRACE( " %d: ", i );
dump_type( type->type_info_table->info[i] );
}
}
static void dump_function_descr( const cxx_function_descr *descr )
{
#ifndef WINE_NO_TRACE_MSGS
UINT i;
int j;
TRACE( "magic %x\n", descr->magic );
TRACE( "unwind table: %p %d\n", descr->unwind_table, descr->unwind_count );
for (i = 0; i < descr->unwind_count; i++)
{
TRACE( " %d: prev %d func %p\n", i,
descr->unwind_table[i].prev, descr->unwind_table[i].handler );
}
TRACE( "try table: %p %d\n", descr->tryblock, descr->tryblock_count );
for (i = 0; i < descr->tryblock_count; i++)
{
TRACE( " %d: start %d end %d catchlevel %d catch %p %d\n", i,
descr->tryblock[i].start_level, descr->tryblock[i].end_level,
descr->tryblock[i].catch_level, descr->tryblock[i].catchblock,
descr->tryblock[i].catchblock_count );
for (j = 0; j < descr->tryblock[i].catchblock_count; j++)
{
const catchblock_info *ptr = &descr->tryblock[i].catchblock[j];
TRACE( " %d: flags %x offset %d handler %p type %p %s\n",
j, ptr->flags, ptr->offset, ptr->handler,
ptr->type_info, dbgstr_type_info( ptr->type_info ) );
}
}
#endif
if (descr->magic <= CXX_FRAME_MAGIC_VC6) return;
TRACE( "expect list: %p\n", descr->expect_list );
if (descr->magic <= CXX_FRAME_MAGIC_VC7) return;
TRACE( "flags: %08x\n", descr->flags );
}
/* check if the exception type is caught by a given catch block, and return the type that matched */
static const cxx_type_info *find_caught_type( cxx_exception_type *exc_type,
const catchblock_info *catchblock )
{
UINT i;
for (i = 0; i < exc_type->type_info_table->count; i++)
{
const cxx_type_info *type = exc_type->type_info_table->info[i];
if (!catchblock->type_info) return type; /* catch(...) matches any type */
if (catchblock->type_info != type->type_info)
{
if (strcmp( catchblock->type_info->mangled, type->type_info->mangled )) continue;
}
/* type is the same, now check the flags */
if ((exc_type->flags & TYPE_FLAG_CONST) &&
!(catchblock->flags & TYPE_FLAG_CONST)) continue;
if ((exc_type->flags & TYPE_FLAG_VOLATILE) &&
!(catchblock->flags & TYPE_FLAG_VOLATILE)) continue;
return type; /* it matched */
}
return NULL;
}
/* copy the exception object where the catch block wants it */
static void copy_exception( void *object, cxx_exception_frame *frame,
const catchblock_info *catchblock, const cxx_type_info *type )
{
void **dest_ptr;
if (!catchblock->type_info || !catchblock->type_info->mangled[0]) return;
if (!catchblock->offset) return;
dest_ptr = (void **)((char *)&frame->ebp + catchblock->offset);
if (catchblock->flags & TYPE_FLAG_REFERENCE)
{
*dest_ptr = get_this_pointer( &type->offsets, object );
}
else if (type->flags & CLASS_IS_SIMPLE_TYPE)
{
memmove( dest_ptr, object, type->size );
/* if it is a pointer, adjust it */
if (type->size == sizeof(void *)) *dest_ptr = get_this_pointer( &type->offsets, *dest_ptr );
}
else /* copy the object */
{
if (type->copy_ctor)
call_copy_ctor( type->copy_ctor, dest_ptr, get_this_pointer(&type->offsets,object),
(type->flags & CLASS_HAS_VIRTUAL_BASE_CLASS) );
else
memmove( dest_ptr, get_this_pointer(&type->offsets,object), type->size );
}
}
/* unwind the local function up to a given trylevel */
static void cxx_local_unwind( cxx_exception_frame* frame, const cxx_function_descr *descr, int last_level)
{
void (*handler)(void);
int trylevel = frame->trylevel;
while (trylevel != last_level)
{
if (trylevel < 0 || trylevel >= descr->unwind_count)
{
ERR( "invalid trylevel %d\n", trylevel );
MSVCRT_terminate();
}
handler = descr->unwind_table[trylevel].handler;
if (handler)
{
TRACE( "calling unwind handler %p trylevel %d last %d ebp %p\n",
handler, trylevel, last_level, &frame->ebp );
call_ebp_func( handler, &frame->ebp );
}
trylevel = descr->unwind_table[trylevel].prev;
}
frame->trylevel = last_level;
}
/* exception frame for nested exceptions in catch block */
struct catch_func_nested_frame
{
EXCEPTION_REGISTRATION_RECORD frame; /* standard exception frame */
EXCEPTION_RECORD *prev_rec; /* previous record to restore in thread data */
cxx_exception_frame *cxx_frame; /* frame of parent exception */
const cxx_function_descr *descr; /* descriptor of parent exception */
int trylevel; /* current try level */
EXCEPTION_RECORD *rec; /* rec associated with frame */
};
/* handler for exceptions happening while calling a catch function */
static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame,
CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher )
{
struct catch_func_nested_frame *nested_frame = (struct catch_func_nested_frame *)frame;
if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
{
msvcrt_get_thread_data()->exc_record = nested_frame->prev_rec;
return ExceptionContinueSearch;
}
TRACE( "got nested exception in catch function\n" );
if(rec->ExceptionCode == CXX_EXCEPTION)
{
PEXCEPTION_RECORD prev_rec = nested_frame->rec;
if(rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0)
{
/* exception was rethrown */
rec->ExceptionInformation[1] = prev_rec->ExceptionInformation[1];
rec->ExceptionInformation[2] = prev_rec->ExceptionInformation[2];
TRACE("detect rethrow: re-propagate: obj: %lx, type: %lx\n",
rec->ExceptionInformation[1], rec->ExceptionInformation[2]);
}
else {
/* new exception in exception handler, destroy old */
void *object = (void*)prev_rec->ExceptionInformation[1];
cxx_exception_type *info = (cxx_exception_type*) prev_rec->ExceptionInformation[2];
TRACE("detect threw new exception in catch block - destroy old(obj: %p type: %p)\n",
object, info);
if(info && info->destructor)
call_dtor( info->destructor, object );
}
}
return cxx_frame_handler( rec, nested_frame->cxx_frame, context,
NULL, nested_frame->descr, &nested_frame->frame,
nested_frame->trylevel );
}
/* find and call the appropriate catch block for an exception */
/* returns the address to continue execution to after the catch block was called */
static inline void call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame *frame,
const cxx_function_descr *descr, int nested_trylevel,
cxx_exception_type *info )
{
UINT i;
int j;
void *addr, *object = (void *)rec->ExceptionInformation[1];
struct catch_func_nested_frame nested_frame;
int trylevel = frame->trylevel;
MSVCRT_thread_data *thread_data = msvcrt_get_thread_data();
DWORD save_esp = ((DWORD*)frame)[-1];
for (i = 0; i < descr->tryblock_count; i++)
{
const tryblock_info *tryblock = &descr->tryblock[i];
if (trylevel < tryblock->start_level) continue;
if (trylevel > tryblock->end_level) continue;
/* got a try block */
for (j = 0; j < tryblock->catchblock_count; j++)
{
const catchblock_info *catchblock = &tryblock->catchblock[j];
if(info)
{
const cxx_type_info *type = find_caught_type( info, catchblock );
if (!type) continue;
TRACE( "matched type %p in tryblock %d catchblock %d\n", type, i, j );
/* copy the exception to its destination on the stack */
copy_exception( object, frame, catchblock, type );
}
else
{
/* no CXX_EXCEPTION only proceed with a catch(...) block*/
if(catchblock->type_info)
continue;
TRACE("found catch(...) block\n");
}
/* unwind the stack */
RtlUnwind( frame, 0, rec, 0 );
cxx_local_unwind( frame, descr, tryblock->start_level );
frame->trylevel = tryblock->end_level + 1;
/* call the catch block */
TRACE( "calling catch block %p addr %p ebp %p\n",
catchblock, catchblock->handler, &frame->ebp );
/* setup an exception block for nested exceptions */
nested_frame.frame.Handler = (PEXCEPTION_ROUTINE)catch_function_nested_handler;
nested_frame.prev_rec = thread_data->exc_record;
nested_frame.cxx_frame = frame;
nested_frame.descr = descr;
nested_frame.trylevel = nested_trylevel + 1;
nested_frame.rec = rec;
__wine_push_frame( &nested_frame.frame );
thread_data->exc_record = rec;
addr = call_ebp_func( catchblock->handler, &frame->ebp );
thread_data->exc_record = nested_frame.prev_rec;
__wine_pop_frame( &nested_frame.frame );
((DWORD*)frame)[-1] = save_esp;
if (info && info->destructor) call_dtor( info->destructor, object );
TRACE( "done, continuing at %p\n", addr );
continue_after_catch( frame, addr );
}
}
}
/*********************************************************************
* cxx_frame_handler
*
* Implementation of __CxxFrameHandler.
*/
DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame,
PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch,
const cxx_function_descr *descr,
EXCEPTION_REGISTRATION_RECORD* nested_frame,
int nested_trylevel )
{
cxx_exception_type *exc_type;
if (descr->magic < CXX_FRAME_MAGIC_VC6 || descr->magic > CXX_FRAME_MAGIC_VC8)
{
ERR( "invalid frame magic %x\n", descr->magic );
return ExceptionContinueSearch;
}
if (descr->magic >= CXX_FRAME_MAGIC_VC8 &&
(descr->flags & FUNC_DESCR_SYNCHRONOUS) &&
(rec->ExceptionCode != CXX_EXCEPTION))
return ExceptionContinueSearch; /* handle only c++ exceptions */
if (rec->ExceptionFlags & (EH_UNWINDING|EH_EXIT_UNWIND))
{
if (descr->unwind_count && !nested_trylevel) cxx_local_unwind( frame, descr, -1 );
return ExceptionContinueSearch;
}
if (!descr->tryblock_count) return ExceptionContinueSearch;
if(rec->ExceptionCode == CXX_EXCEPTION)
{
exc_type = (cxx_exception_type *)rec->ExceptionInformation[2];
if (rec->ExceptionInformation[0] > CXX_FRAME_MAGIC_VC8 &&
exc_type->custom_handler)
{
return exc_type->custom_handler( rec, frame, context, dispatch,
descr, nested_trylevel, nested_frame, 0 );
}
if (TRACE_ON(seh))
{
TRACE("handling C++ exception rec %p frame %p trylevel %d descr %p nested_frame %p\n",
rec, frame, frame->trylevel, descr, nested_frame );
dump_exception_type( exc_type );
dump_function_descr( descr );
}
}
else
{
exc_type = NULL;
TRACE("handling C exception code %x rec %p frame %p trylevel %d descr %p nested_frame %p\n",
rec->ExceptionCode, rec, frame, frame->trylevel, descr, nested_frame );
}
call_catch_block( rec, frame, descr, frame->trylevel, exc_type );
return ExceptionContinueSearch;
}
/*********************************************************************
* __CxxFrameHandler (MSVCRT.@)
*/
extern DWORD CDECL __CxxFrameHandler( PEXCEPTION_RECORD rec, EXCEPTION_REGISTRATION_RECORD* frame,
PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch );
__ASM_GLOBAL_FUNC( __CxxFrameHandler,
"pushl $0\n\t" /* nested_trylevel */
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
"pushl $0\n\t" /* nested_frame */
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
"pushl %eax\n\t" /* descr */
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
"pushl 28(%esp)\n\t" /* dispatch */
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
"pushl 28(%esp)\n\t" /* context */
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
"pushl 28(%esp)\n\t" /* frame */
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
"pushl 28(%esp)\n\t" /* rec */
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
"call " __ASM_NAME("cxx_frame_handler") "\n\t"
"add $28,%esp\n\t"
__ASM_CFI(".cfi_adjust_cfa_offset -28\n\t")
"ret" )
/*********************************************************************
* __CxxLongjmpUnwind (MSVCRT.@)
*
* Callback meant to be used as UnwindFunc for setjmp/longjmp.
*/
void __stdcall __CxxLongjmpUnwind( const struct MSVCRT___JUMP_BUFFER *buf )
{
cxx_exception_frame *frame = (cxx_exception_frame *)buf->Registration;
const cxx_function_descr *descr = (const cxx_function_descr *)buf->UnwindData[0];
TRACE( "unwinding frame %p descr %p trylevel %ld\n", frame, descr, buf->TryLevel );
cxx_local_unwind( frame, descr, buf->TryLevel );
}
#endif /* __i386__ */
/*********************************************************************
* __CppXcptFilter (MSVCRT.@)
*/
int CDECL __CppXcptFilter(NTSTATUS ex, PEXCEPTION_POINTERS ptr)
{
/* only filter c++ exceptions */
if (ex != CXX_EXCEPTION) return EXCEPTION_CONTINUE_SEARCH;
return _XcptFilter( ex, ptr );
}
/*********************************************************************
* _CxxThrowException (MSVCRT.@)
*/
void CDECL _CxxThrowException( exception *object, const cxx_exception_type *type )
{
ULONG_PTR args[3];
args[0] = CXX_FRAME_MAGIC_VC6;
args[1] = (ULONG_PTR)object;
args[2] = (ULONG_PTR)type;
RaiseException( CXX_EXCEPTION, EH_NONCONTINUABLE, 3, args );
}
/*********************************************************************
* __CxxDetectRethrow (MSVCRT.@)
*/
BOOL CDECL __CxxDetectRethrow(PEXCEPTION_POINTERS ptrs)
{
PEXCEPTION_RECORD rec;
if (!ptrs)
return FALSE;
rec = ptrs->ExceptionRecord;
if (rec->ExceptionCode == CXX_EXCEPTION &&
rec->NumberParameters == 3 &&
rec->ExceptionInformation[0] == CXX_FRAME_MAGIC_VC6 &&
rec->ExceptionInformation[2])
{
ptrs->ExceptionRecord = msvcrt_get_thread_data()->exc_record;
return TRUE;
}
return (msvcrt_get_thread_data()->exc_record == rec);
}
/*********************************************************************
* __CxxQueryExceptionSize (MSVCRT.@)
*/
unsigned int CDECL __CxxQueryExceptionSize(void)
{
return sizeof(cxx_exception_type);
}

220
lib/sdk/crt/except/except.c Normal file
View file

@ -0,0 +1,220 @@
/*
* msvcrt.dll exception handling
*
* Copyright 2000 Jon Griffiths
* Copyright 2005 Juan Lang
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* FIXME: Incomplete support for nested exceptions/try block cleanup.
*/
#include <precomp.h>
#include "excpt.h"
#include <wine/exception.h>
void CDECL _global_unwind2(EXCEPTION_REGISTRATION_RECORD* frame);
/* VC++ extensions to Win32 SEH */
typedef struct _SCOPETABLE
{
int previousTryLevel;
int (*lpfnFilter)(PEXCEPTION_POINTERS);
int (*lpfnHandler)(void);
} SCOPETABLE, *PSCOPETABLE;
typedef struct _MSVCRT_EXCEPTION_FRAME
{
EXCEPTION_REGISTRATION_RECORD *prev;
void (*handler)(PEXCEPTION_RECORD, EXCEPTION_REGISTRATION_RECORD*,
PCONTEXT, PEXCEPTION_RECORD);
PSCOPETABLE scopetable;
int trylevel;
int _ebp;
PEXCEPTION_POINTERS xpointers;
} MSVCRT_EXCEPTION_FRAME;
typedef struct
{
int gs_cookie_offset;
ULONG gs_cookie_xor;
int eh_cookie_offset;
ULONG eh_cookie_xor;
SCOPETABLE entries[1];
} SCOPETABLE_V4;
#ifdef __i386__
static const SCOPETABLE_V4 *get_scopetable_v4( MSVCRT_EXCEPTION_FRAME *frame, ULONG_PTR cookie )
{
return (const SCOPETABLE_V4 *)((ULONG_PTR)frame->scopetable ^ cookie);
}
#if defined(__GNUC__)
static inline void call_finally_block( void *code_block, void *base_ptr )
{
__asm__ __volatile__ ("movl %1,%%ebp; call *%%eax"
: : "a" (code_block), "g" (base_ptr));
}
static inline int call_filter( int (*func)(PEXCEPTION_POINTERS), void *arg, void *ebp )
{
int ret;
__asm__ __volatile__ ("pushl %%ebp; pushl %3; movl %2,%%ebp; call *%%eax; popl %%ebp; popl %%ebp"
: "=a" (ret)
: "0" (func), "r" (ebp), "r" (arg)
: "ecx", "edx", "memory" );
return ret;
}
static inline int call_unwind_func( int (*func)(void), void *ebp )
{
int ret;
__asm__ __volatile__ ("pushl %%ebp\n\t"
"pushl %%ebx\n\t"
"pushl %%esi\n\t"
"pushl %%edi\n\t"
"movl %2,%%ebp\n\t"
"call *%0\n\t"
"popl %%edi\n\t"
"popl %%esi\n\t"
"popl %%ebx\n\t"
"popl %%ebp"
: "=a" (ret)
: "0" (func), "r" (ebp)
: "ecx", "edx", "memory" );
return ret;
}
#endif
static DWORD MSVCRT_nested_handler(PEXCEPTION_RECORD rec,
EXCEPTION_REGISTRATION_RECORD* frame,
PCONTEXT context,
EXCEPTION_REGISTRATION_RECORD** dispatch)
{
if (!(rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)))
return ExceptionContinueSearch;
*dispatch = frame;
return ExceptionCollidedUnwind;
}
void msvcrt_local_unwind4( ULONG *cookie, MSVCRT_EXCEPTION_FRAME* frame, int trylevel, void *ebp )
{
EXCEPTION_REGISTRATION_RECORD reg;
const SCOPETABLE_V4 *scopetable = get_scopetable_v4( frame, *cookie );
TRACE("(%p,%d,%d)\n",frame, frame->trylevel, trylevel);
/* Register a handler in case of a nested exception */
reg.Handler = (PEXCEPTION_ROUTINE)MSVCRT_nested_handler;
reg.Prev = NtCurrentTeb()->NtTib.ExceptionList;
__wine_push_frame(&reg);
while (frame->trylevel != -2 && frame->trylevel != trylevel)
{
int level = frame->trylevel;
frame->trylevel = scopetable->entries[level].previousTryLevel;
if (!scopetable->entries[level].lpfnFilter)
{
TRACE( "__try block cleanup level %d handler %p ebp %p\n",
level, scopetable->entries[level].lpfnHandler, ebp );
call_unwind_func( scopetable->entries[level].lpfnHandler, ebp );
}
}
__wine_pop_frame(&reg);
TRACE("unwound OK\n");
}
/*********************************************************************
* _except_handler4_common (MSVCRT.@)
*/
int CDECL _except_handler4_common( ULONG *cookie, void (*check_cookie)(void),
EXCEPTION_RECORD *rec, MSVCRT_EXCEPTION_FRAME *frame,
CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher )
{
int retval, trylevel;
EXCEPTION_POINTERS exceptPtrs;
const SCOPETABLE_V4 *scope_table = get_scopetable_v4( frame, *cookie );
TRACE( "exception %x flags=%x at %p handler=%p %p %p cookie=%x scope table=%p cookies=%d/%x,%d/%x\n",
rec->ExceptionCode, rec->ExceptionFlags, rec->ExceptionAddress,
frame->handler, context, dispatcher, *cookie, scope_table,
scope_table->gs_cookie_offset, scope_table->gs_cookie_xor,
scope_table->eh_cookie_offset, scope_table->eh_cookie_xor );
/* FIXME: no cookie validation yet */
if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
{
/* Unwinding the current frame */
msvcrt_local_unwind4( cookie, frame, -2, &frame->_ebp );
TRACE("unwound current frame, returning ExceptionContinueSearch\n");
return ExceptionContinueSearch;
}
else
{
/* Hunting for handler */
exceptPtrs.ExceptionRecord = rec;
exceptPtrs.ContextRecord = context;
*((DWORD *)frame-1) = (DWORD)&exceptPtrs;
trylevel = frame->trylevel;
while (trylevel != -2)
{
TRACE( "level %d prev %d filter %p\n", trylevel,
scope_table->entries[trylevel].previousTryLevel,
scope_table->entries[trylevel].lpfnFilter );
if (scope_table->entries[trylevel].lpfnFilter)
{
retval = call_filter( scope_table->entries[trylevel].lpfnFilter, &exceptPtrs, &frame->_ebp );
TRACE("filter returned %s\n", retval == EXCEPTION_CONTINUE_EXECUTION ?
"CONTINUE_EXECUTION" : retval == EXCEPTION_EXECUTE_HANDLER ?
"EXECUTE_HANDLER" : "CONTINUE_SEARCH");
if (retval == EXCEPTION_CONTINUE_EXECUTION)
return ExceptionContinueExecution;
if (retval == EXCEPTION_EXECUTE_HANDLER)
{
/* Unwind all higher frames, this one will handle the exception */
_global_unwind2((EXCEPTION_REGISTRATION_RECORD*)frame);
msvcrt_local_unwind4( cookie, frame, trylevel, &frame->_ebp );
/* Set our trylevel to the enclosing block, and call the __finally
* code, which won't return
*/
frame->trylevel = scope_table->entries[trylevel].previousTryLevel;
TRACE("__finally block %p\n",scope_table->entries[trylevel].lpfnHandler);
call_finally_block(scope_table->entries[trylevel].lpfnHandler, &frame->_ebp);
ERR("Returned from __finally block - expect crash!\n");
}
}
trylevel = scope_table->entries[trylevel].previousTryLevel;
}
}
TRACE("reached -2, returning ExceptionContinueSearch\n");
return ExceptionContinueSearch;
}
#endif
/******************************************************************
* __uncaught_exception
*/
BOOL CDECL __uncaught_exception(void)
{
return FALSE;
}

View file

@ -0,0 +1,66 @@
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Stack checker
* FILE: lib/ntdll/rtl/i386/chkstk.s
* PROGRAMER: KJK::Hyperion <noog@libero.it>
*/
.globl __chkstk
.globl __alloca_probe
/*
_chkstk() is called by all stack allocations of more than 4 KB. It grows the
stack in areas of 4 KB each, trying to access each area. This ensures that the
guard page for the stack is hit, and the stack growing triggered
*/
__chkstk:
__alloca_probe:
/* EAX = size to be allocated */
/* save the ECX register */
pushl %ecx
/* ECX = top of the previous stack frame */
leal 8(%esp), %ecx
/* probe the desired memory, page by page */
cmpl $0x1000, %eax
jge .l_MoreThanAPage
jmp .l_LessThanAPage
.l_MoreThanAPage:
/* raise the top of the stack by a page and probe */
subl $0x1000, %ecx
testl %eax, 0(%ecx)
/* loop if still more than a page must be probed */
subl $0x1000, %eax
cmpl $0x1000, %eax
jge .l_MoreThanAPage
.l_LessThanAPage:
/* raise the top of the stack by EAX bytes (size % 4096) and probe */
subl %eax, %ecx
testl %eax, 0(%ecx)
/* EAX = top of the stack */
movl %esp, %eax
/* allocate the memory */
movl %ecx, %esp
/* restore ECX */
movl 0(%eax), %ecx
/* restore the return address */
movl 4(%eax), %eax
pushl %eax
/* return */
ret
/* EOF */

View file

@ -0,0 +1,27 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CRT
* FILE: lib/crt/misc/i386/prolog.s
* PURPOSE: SEH Support for the CRT
* PROGRAMMERS: Wine Development Team
*/
/* INCLUDES ******************************************************************/
#include <ndk/asm.h>
/* GLOBALS *******************************************************************/
.globl __EH_prolog
// Copied from Wine.
__EH_prolog:
pushl $-1
pushl %eax
pushl %fs:0
movl %esp, %fs:0
movl 12(%esp), %eax
movl %ebp, 12(%esp)
leal 12(%esp), %ebp
pushl %eax
ret

View file

@ -0,0 +1,440 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CRT
* FILE: lib/crt/misc/i386/seh.S
* PURPOSE: SEH Support for the CRT
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <ndk/asm.h>
.intel_syntax noprefix
#define DISPOSITION_DISMISS 0
#define DISPOSITION_CONTINUE_SEARCH 1
#define DISPOSITION_COLLIDED_UNWIND 3
/* GLOBALS *******************************************************************/
.globl __global_unwind2
.globl __local_unwind2
.globl __abnormal_termination
.globl __except_handler2
.globl __except_handler3
/* FUNCTIONS *****************************************************************/
.func unwind_handler
_unwind_handler:
/* Check if we were unwinding and continue search if not */
mov ecx, [esp+4]
test dword ptr [ecx+4], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING
mov eax, DISPOSITION_CONTINUE_SEARCH
jz unwind_handler_return
/* We have a collision, do a local unwind */
mov eax, [esp+20]
push ebp
mov ebp, [eax+16]
mov edx, [eax+40]
push edx
mov edx, [eax+36]
push edx
call __local_unwind2
add esp, 8
pop ebp
/* Set new try level */
mov eax, [esp+8]
mov edx, [esp+16]
mov [edx], eax
/* Return collided unwind */
mov eax, DISPOSITION_COLLIDED_UNWIND
unwind_handler_return:
ret
.endfunc
.func _global_unwind2
__global_unwind2:
/* Create stack and save all registers */
push ebp
mov ebp, esp
push ebx
push esi
push edi
push ebp
/* Call unwind */
push 0
push 0
push glu_return
push [ebp+8]
call _RtlUnwind@16
glu_return:
/* Restore registers and return */
pop ebp
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
.endfunc
.func _abnormal_termination
__abnormal_termination:
/* Assume false */
xor eax, eax
/* Check if the handler is the unwind handler */
mov ecx, fs:0
cmp dword ptr [ecx+4], offset _unwind_handler
jne short ab_return
/* Get the try level */
mov edx, [ecx+12]
mov edx, [edx+12]
/* Compare it */
cmp [ecx+8], edx
jne ab_return
/* Return true */
mov eax, 1
/* Return */
ab_return:
ret
.endfunc
.func _local_unwind2
__local_unwind2:
/* Save volatiles */
push ebx
push esi
push edi
/* Get the exception registration */
mov eax, [esp+16]
/* Setup SEH to protect the unwind */
push ebp
push eax
push -2
push offset _unwind_handler
push fs:0
mov fs:0, esp
unwind_loop:
/* Get the exception registration and try level */
mov eax, [esp+36]
mov ebx, [eax+8]
mov esi, [eax+12]
/* Validate the unwind */
cmp esi, -1
je unwind_return
cmp dword ptr [esp+40], -1
je unwind_ok
cmp esi, [esp+40]
jbe unwind_return
unwind_ok:
/* Get the new enclosing level and save it */
lea esi, [esi+esi*2]
mov ecx, [ebx+esi*4]
mov [esp+8], ecx
mov [eax+12], ecx
/* Check the filter type */
cmp dword ptr [ebx+esi*4+4], 0
jnz __NLG_Return2
/* FIXME: NLG Notification */
/* Call the handler */
call dword ptr [ebx+esi*4+8]
__NLG_Return2:
/* Unwind again */
jmp unwind_loop
unwind_return:
/* Cleanup SEH */
pop fs:0
add esp, 16
pop edi
pop esi
pop ebx
ret
.endfunc
.func _except_handler2
__except_handler2:
/* Setup stack and save volatiles */
push ebp
mov ebp, esp
sub esp, 8
push ebx
push esi
push edi
push ebp
/* Clear direction flag */
cld
/* Get exception registration and record */
mov ebx, [ebp+12]
mov eax, [ebp+8]
/* Check if this is an unwind */
test dword ptr [eax+4], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING
jnz except_unwind2
/* Save exception pointers structure */
mov [ebp-8], eax
mov eax, [ebp+16]
mov [ebp-4], eax
lea eax, [ebp-8]
mov [ebx+20], eax
/* Get the try level and scope table */
mov esi, [ebx+12]
mov edi, [ebx+8]
except_loop2:
/* Validate try level */
cmp esi, -1
je except_search2
/* Check if this is the termination handler */
lea ecx, [esi+esi*2]
cmp dword ptr [edi+ecx*4+4], 0
jz except_continue2
/* Save registers and call filter, then restore them */
push esi
push ebp
mov ebp, [ebx+16]
call dword ptr [edi+ecx*4+4]
pop ebp
pop esi
/* Restore ebx and check the result */
mov ebx, [ebp+12]
or eax, eax
jz except_continue2
js except_dismiss2
/* So this is an accept, call the termination handlers */
mov edi, [ebx+8]
push ebx
call __global_unwind2
add esp, 4
/* Restore ebp */
mov ebp, [ebx+16]
/* Do local unwind */
push esi
push ebx
call __local_unwind2
add esp, 8
/* Set new try level */
lea ecx, [esi+esi*2]
mov eax, [edi+ecx*4]
mov [ebx+12], eax
/* Call except handler */
call [edi+ecx*4+8]
except_continue2:
/* Reload try level and except again */
mov edi, [ebx+8]
lea ecx, [esi+esi*2]
mov esi, [edi+ecx*4]
jmp except_loop2
except_dismiss2:
/* Dismiss it */
mov eax, DISPOSITION_DISMISS
jmp except_return2
except_search2:
/* Continue searching */
mov eax, DISPOSITION_CONTINUE_SEARCH
jmp except_return2
/* Do local unwind */
except_unwind2:
push ebp
mov ebp, [ebx+16]
push -1
push ebx
call __local_unwind2
add esp, 8
/* Retore EBP and set return disposition */
pop ebp
mov eax, DISPOSITION_CONTINUE_SEARCH
except_return2:
/* Restore registers and stack */
pop ebp
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
.endfunc
.func _except_handler3
__except_handler3:
/* Setup stack and save volatiles */
push ebp
mov ebp, esp
sub esp, 8
push ebx
push esi
push edi
push ebp
/* Clear direction flag */
cld
/* Get exception registration and record */
mov ebx, [ebp+12]
mov eax, [ebp+8]
/* Check if this is an unwind */
test dword ptr [eax+4], EXCEPTION_EXIT_UNWIND + EXCEPTION_UNWINDING
jnz except_unwind3
/* Save exception pointers structure */
mov [ebp-8], eax
mov eax, [ebp+16]
mov [ebp-4], eax
lea eax, [ebp-8]
mov [ebx-4], eax
/* Get the try level and scope table */
mov esi, [ebx+12]
mov edi, [ebx+8]
/* FIXME: Validate the SEH exception */
except_loop3:
/* Validate try level */
cmp esi, -1
je except_search3
/* Check if this is the termination handler */
lea ecx, [esi+esi*2]
mov eax, [edi+ecx*4+4]
or eax, eax
jz except_continue3
/* Save registers clear them all */
push esi
push ebp
lea ebp, [ebx+16]
xor ebx, ebx
xor ecx, ecx
xor edx, edx
xor esi, esi
xor edi, edi
/* Call the filter and restore our registers */
call eax
pop ebp
pop esi
/* Restore ebx and check the result */
mov ebx, [ebp+12]
or eax, eax
jz except_continue3
js except_dismiss3
/* So this is an accept, call the termination handlers */
mov edi, [ebx+8]
push ebx
call __global_unwind2
add esp, 4
/* Restore ebp */
lea ebp, [ebx+16]
/* Do local unwind */
push esi
push ebx
call __local_unwind2
add esp, 8
/* FIXME: Do NLG Notification */
/* Set new try level */
lea ecx, [esi+esi*2]
mov eax, [edi+ecx*4]
mov [ebx+12], eax
/* Clear registers and call except handler */
mov eax, [edi+ecx*4+8]
xor ebx, ebx
xor ecx, ecx
xor edx, edx
xor esi, esi
xor edi, edi
call eax
except_continue3:
/* Reload try level and except again */
mov edi, [ebx+8]
lea ecx, [esi+esi*2]
mov esi, [edi+ecx*4]
jmp except_loop3
except_dismiss3:
/* Dismiss it */
mov eax, DISPOSITION_DISMISS
jmp except_return3
except_search3:
/* Continue searching */
mov eax, DISPOSITION_CONTINUE_SEARCH
jmp except_return3
/* Do local unwind */
except_unwind3:
push ebp
mov ebp, [ebx+16]
push -1
push ebx
call __local_unwind2
add esp, 8
/* Retore EBP and set return disposition */
pop ebp
mov eax, DISPOSITION_CONTINUE_SEARCH
except_return3:
/* Restore registers and stack */
pop ebp
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
.endfunc

View file

@ -0,0 +1,56 @@
#define WIN32_NO_STATUS
#include <precomp.h>
#include <windows.h>
#define NTOS_MODE_USER
#include <ndk/umtypes.h>
#include <ndk/extypes.h>
#include <ndk/rtlfuncs.h>
/* VC++ extensions to Win32 SEH */
typedef struct _SCOPETABLE
{
int previousTryLevel;
int (*lpfnFilter)(PEXCEPTION_POINTERS);
int (*lpfnHandler)(void);
} SCOPETABLE, *PSCOPETABLE;
typedef struct _MSVCRT_EXCEPTION_FRAME
{
PEXCEPTION_REGISTRATION_RECORD *prev;
void (*handler)(PEXCEPTION_RECORD, PEXCEPTION_REGISTRATION_RECORD,
PCONTEXT, PEXCEPTION_RECORD);
PSCOPETABLE scopetable;
int trylevel;
int _ebp;
PEXCEPTION_POINTERS xpointers;
} MSVCRT_EXCEPTION_FRAME;
typedef struct __JUMP_BUFFER
{
unsigned long Ebp;
unsigned long Ebx;
unsigned long Edi;
unsigned long Esi;
unsigned long Esp;
unsigned long Eip;
unsigned long Registration;
unsigned long TryLevel;
/* Start of new struct members */
unsigned long Cookie;
unsigned long UnwindFunc;
unsigned long UnwindData[6];
} _JUMP_BUFFER;
void
_local_unwind2(MSVCRT_EXCEPTION_FRAME *RegistrationFrame,
LONG TryLevel);
/*
* @implemented
*/
void __stdcall _seh_longjmp_unwind(_JUMP_BUFFER *jmp)
{
_local_unwind2((MSVCRT_EXCEPTION_FRAME*) jmp->Registration, jmp->TryLevel);
}

View file

@ -0,0 +1,65 @@
#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);
}
#define _FPIEEE_RECORD void
/*
* @unimplemented
*/
int _fpieee_flt(
unsigned long exception_code,
struct _EXCEPTION_POINTERS* ExceptionPointer,
int (*handler)(_FPIEEE_RECORD*)
)
{
FIXME("Unimplemented!\n");
return 0;
}

View file

@ -0,0 +1,23 @@
/* $Id: chkstk_asm.s 26099 2007-03-14 20:30:32Z ion $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Stack checker
* FILE: lib/ntdll/rtl/i386/chkstk.s
* PROGRAMER: arty
*/
.globl _chkstk
.globl _alloca_probe
/*
_chkstk() is called by all stack allocations of more than 4 KB. It grows the
stack in areas of 4 KB each, trying to access each area. This ensures that the
guard page for the stack is hit, and the stack growing triggered
*/
_chkstk:
_alloca_probe:
/* return */
blr
/* EOF */

View file

@ -0,0 +1,75 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CRT
* FILE: lib/crt/misc/i386/seh.S
* PURPOSE: SEH Support for the CRT
* PROGRAMMERS: arty
*/
/* INCLUDES ******************************************************************/
#include <ndk/asm.h>
#define DISPOSITION_DISMISS 0
#define DISPOSITION_CONTINUE_SEARCH 1
#define DISPOSITION_COLLIDED_UNWIND 3
/* GLOBALS *******************************************************************/
.globl _global_unwind2
.globl _local_unwind2
.globl _abnormal_termination
.globl _except_handler2
.globl _except_handler3
/* FUNCTIONS *****************************************************************/
unwind_handler:
blr
_global_unwind2:
blr
_local_unwind2:
blr
_except_handler2:
blr
_except_handler3:
blr
//
//
// REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME
// sorry
//
//
.globl RtlpGetStackLimits
RtlpGetStackLimits:
stwu 1,16(1)
mflr 0
stw 0,4(1)
stw 3,8(1)
stw 4,12(1)
/* Get the current thread */
lwz 3,KPCR_CURRENT_THREAD(13)
/* Get the stack limits */
lwz 4,KTHREAD_STACK_LIMIT(3)
lwz 5,KTHREAD_INITIAL_STACK(3)
subi 5,5,SIZEOF_FX_SAVE_AREA
/* Return them */
lwz 3,8(1)
stw 4,0(3)
lwz 3,12(1)
stw 5,0(3)
addi 1,1,16
/* return */
blr

View file

@ -0,0 +1,98 @@
#include <precomp.h>
#include "internal/wine/msvcrt.h"
#include "internal/wine/cppexcept.h"
typedef void (*sighandler_t)(int);
static sighandler_t sighandlers[NSIG] = { SIG_DFL };
/* The exception codes are actually NTSTATUS values */
static const struct
{
NTSTATUS status;
int signal;
} float_exception_map[] = {
{ EXCEPTION_FLT_DENORMAL_OPERAND, _FPE_DENORMAL },
{ EXCEPTION_FLT_DIVIDE_BY_ZERO, _FPE_ZERODIVIDE },
{ EXCEPTION_FLT_INEXACT_RESULT, _FPE_INEXACT },
{ EXCEPTION_FLT_INVALID_OPERATION, _FPE_INVALID },
{ EXCEPTION_FLT_OVERFLOW, _FPE_OVERFLOW },
{ EXCEPTION_FLT_STACK_CHECK, _FPE_STACKOVERFLOW },
{ EXCEPTION_FLT_UNDERFLOW, _FPE_UNDERFLOW },
};
/*
* @implemented
*/
int CDECL
_XcptFilter(NTSTATUS ExceptionCode,
struct _EXCEPTION_POINTERS * except)
{
LONG ret = EXCEPTION_CONTINUE_SEARCH;
sighandler_t handler;
if (!except || !except->ExceptionRecord)
return EXCEPTION_CONTINUE_SEARCH;
switch (except->ExceptionRecord->ExceptionCode)
{
case EXCEPTION_ACCESS_VIOLATION:
if ((handler = sighandlers[SIGSEGV]) != SIG_DFL)
{
if (handler != SIG_IGN)
{
sighandlers[SIGSEGV] = SIG_DFL;
handler(SIGSEGV);
}
ret = EXCEPTION_CONTINUE_EXECUTION;
}
break;
/* According to msdn,
* the FPE signal handler takes as a second argument the type of
* floating point exception.
*/
case EXCEPTION_FLT_DENORMAL_OPERAND:
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
case EXCEPTION_FLT_INEXACT_RESULT:
case EXCEPTION_FLT_INVALID_OPERATION:
case EXCEPTION_FLT_OVERFLOW:
case EXCEPTION_FLT_STACK_CHECK:
case EXCEPTION_FLT_UNDERFLOW:
if ((handler = sighandlers[SIGFPE]) != SIG_DFL)
{
if (handler != SIG_IGN)
{
unsigned int i;
int float_signal = _FPE_INVALID;
sighandlers[SIGFPE] = SIG_DFL;
for (i = 0; i < sizeof(float_exception_map) /
sizeof(float_exception_map[0]); i++)
{
if (float_exception_map[i].status ==
except->ExceptionRecord->ExceptionCode)
{
float_signal = float_exception_map[i].signal;
break;
}
}
((float_handler)handler)(SIGFPE, float_signal);
}
ret = EXCEPTION_CONTINUE_EXECUTION;
}
break;
case EXCEPTION_ILLEGAL_INSTRUCTION:
case EXCEPTION_PRIV_INSTRUCTION:
if ((handler = sighandlers[SIGILL]) != SIG_DFL)
{
if (handler != SIG_IGN)
{
sighandlers[SIGILL] = SIG_DFL;
handler(SIGILL);
}
ret = EXCEPTION_CONTINUE_EXECUTION;
}
break;
}
return ret;
}

View file

@ -0,0 +1,33 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/crt/??????
* PURPOSE: Unknown
* PROGRAMER: Unknown
* UPDATE HISTORY:
* 25/11/05: Added license header
*/
#include <precomp.h>
#include <internal/ieee.h>
/*
* @implemented
*/
double _chgsign( double __x )
{
union
{
double* __x;
double_s *x;
} u;
u.__x = &__x;
if ( u.x->sign == 1 )
u.x->sign = 0;
else
u.x->sign = 1;
return __x;
}

View file

@ -0,0 +1,36 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/crt/??????
* PURPOSE: Unknown
* PROGRAMER: Unknown
* UPDATE HISTORY:
* 25/11/05: Added license header
*/
#include <precomp.h>
#include <internal/ieee.h>
/*
* @implemented
*/
double _copysign (double __d, double __s)
{
union
{
double* __d;
double_s* d;
} d;
union
{
double* __s;
double_s* s;
} s;
d.__d = &__d;
s.__s = &__s;
d.d->sign = s.s->sign;
return __d;
}

View file

@ -0,0 +1,86 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/crt/??????
* PURPOSE: Unknown
* PROGRAMER: Unknown
* UPDATE HISTORY:
* 25/11/05: Added license header
*/
#include <precomp.h>
#include <math.h>
#include <internal/ieee.h>
#define _FPCLASS_SNAN 0x0001 /* signaling NaN */
#define _FPCLASS_QNAN 0x0002 /* quiet NaN */
#define _FPCLASS_NINF 0x0004 /* negative infinity */
#define _FPCLASS_NN 0x0008 /* negative normal */
#define _FPCLASS_ND 0x0010 /* negative denormal */
#define _FPCLASS_NZ 0x0020 /* -0 */
#define _FPCLASS_PZ 0x0040 /* +0 */
#define _FPCLASS_PD 0x0080 /* positive denormal */
#define _FPCLASS_PN 0x0100 /* positive normal */
#define _FPCLASS_PINF 0x0200 /* positive infinity */
//#if __MINGW32_MAJOR_VERSION < 3 || __MINGW32_MINOR_VERSION < 3
#define FP_SNAN 0x0001 // signaling NaN
#define FP_QNAN 0x0002 // quiet NaN
#define FP_NINF 0x0004 // negative infinity
#define FP_PINF 0x0200 // positive infinity
#define FP_NDENORM 0x0008 // negative denormalized non-zero
#define FP_PDENORM 0x0010 // positive denormalized non-zero
#define FP_NZERO 0x0020 // negative zero
#define FP_PZERO 0x0040 // positive zero
#define FP_NNORM 0x0080 // negative normalized non-zero
#define FP_PNORM 0x0100 // positive normalized non-zero
//#endif
typedef int fpclass_t;
/*
* @implemented
*/
fpclass_t _fpclass(double __d)
{
union
{
double* __d;
double_s* d;
} d;
d.__d = &__d;
if ( d.d->exponent == 0 ) {
if ( d.d->mantissah == 0 && d.d->mantissal == 0 ) {
if ( d.d->sign ==0 )
return FP_NZERO;
else
return FP_PZERO;
} else {
if ( d.d->sign ==0 )
return FP_NDENORM;
else
return FP_PDENORM;
}
}
if (d.d->exponent == 0x7ff ) {
if ( d.d->mantissah == 0 && d.d->mantissal == 0 ) {
if ( d.d->sign ==0 )
return FP_NINF;
else
return FP_PINF;
}
else if ( d.d->mantissah == 0 && d.d->mantissal != 0 ) {
return FP_QNAN;
}
else if ( d.d->mantissah == 0 && d.d->mantissal != 0 ) {
return FP_SNAN;
}
}
return 0;
}

View file

@ -0,0 +1,20 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/crt/??????
* PURPOSE: Unknown
* PROGRAMER: Unknown
* UPDATE HISTORY:
* 25/11/05: Added license header
*/
#include <precomp.h>
#include <internal/tls.h>
/*
* @implemented
*/
int * __fpecode(void)
{
return(&(GetThreadData()->fpecode));
}

View file

@ -0,0 +1,28 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/crt/??????
* PURPOSE: Unknown
* PROGRAMER: Unknown
* UPDATE HISTORY:
* 25/11/05: Added license header
*/
#include <precomp.h>
unsigned int _statusfp( void );
/*********************************************************************
* _clearfp (MSVCRT.@)
*/
unsigned int CDECL _clearfp(void)
{
unsigned int retVal = _statusfp();
#if defined(__GNUC__)
__asm__ __volatile__( "fnclex" );
#else
__asm fnclex;
#endif
return retVal;
}

View file

@ -0,0 +1,128 @@
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#include <precomp.h>
#include <float.h>
#define X87_CW_IM (1<<0) /* Invalid operation mask */
#define X87_CW_DM (1<<1) /* Denormal operand mask */
#define X87_CW_ZM (1<<2) /* Zero divide mask */
#define X87_CW_OM (1<<3) /* Overflow mask */
#define X87_CW_UM (1<<4) /* Underflow mask */
#define X87_CW_PM (1<<5) /* Precision mask */
#define X87_CW_PC_MASK (3<<8) /* precision control mask */
#define X87_CW_PC24 (0<<8) /* 24 bit precision */
#define X87_CW_PC53 (2<<8) /* 53 bit precision */
#define X87_CW_PC64 (3<<8) /* 64 bit precision */
#define X87_CW_RC_MASK (3<<10) /* rounding control mask */
#define X87_CW_RC_NEAREST (0<<10) /* round to nearest */
#define X87_CW_RC_DOWN (1<<10) /* round down */
#define X87_CW_RC_UP (2<<10) /* round up */
#define X87_CW_RC_ZERO (3<<10) /* round toward zero (chop) */
#define X87_CW_IC (1<<12) /* infinity control flag */
/*
* @implemented
*/
unsigned int CDECL _controlfp(unsigned int newval, unsigned int mask)
{
return _control87( newval, mask & ~_EM_DENORMAL );
}
/*********************************************************************
* _control87 (MSVCRT.@)
*/
unsigned int CDECL _control87(unsigned int newval, unsigned int mask)
{
unsigned int fpword = 0;
unsigned int flags = 0;
TRACE("(%08x, %08x): Called\n", newval, mask);
/* Get fp control word */
#if defined(__GNUC__)
__asm__ __volatile__( "fstcw %0" : "=m" (fpword) : );
#else
__asm fstcw [fpword];
#endif
TRACE("Control word before : %08x\n", fpword);
/* Convert into mask constants */
if (fpword & 0x1) flags |= _EM_INVALID;
if (fpword & 0x2) flags |= _EM_DENORMAL;
if (fpword & 0x4) flags |= _EM_ZERODIVIDE;
if (fpword & 0x8) flags |= _EM_OVERFLOW;
if (fpword & 0x10) flags |= _EM_UNDERFLOW;
if (fpword & 0x20) flags |= _EM_INEXACT;
switch(fpword & 0xC00) {
case 0xC00: flags |= _RC_UP|_RC_DOWN; break;
case 0x800: flags |= _RC_UP; break;
case 0x400: flags |= _RC_DOWN; break;
}
switch(fpword & 0x300) {
case 0x0: flags |= _PC_24; break;
case 0x200: flags |= _PC_53; break;
case 0x300: flags |= _PC_64; break;
}
if (fpword & 0x1000) flags |= _IC_AFFINE;
/* Mask with parameters */
flags = (flags & ~mask) | (newval & mask);
/* Convert (masked) value back to fp word */
fpword = 0;
if (flags & _EM_INVALID) fpword |= 0x1;
if (flags & _EM_DENORMAL) fpword |= 0x2;
if (flags & _EM_ZERODIVIDE) fpword |= 0x4;
if (flags & _EM_OVERFLOW) fpword |= 0x8;
if (flags & _EM_UNDERFLOW) fpword |= 0x10;
if (flags & _EM_INEXACT) fpword |= 0x20;
switch(flags & (_RC_UP | _RC_DOWN)) {
case _RC_UP|_RC_DOWN: fpword |= 0xC00; break;
case _RC_UP: fpword |= 0x800; break;
case _RC_DOWN: fpword |= 0x400; break;
}
switch (flags & (_PC_24 | _PC_53)) {
case _PC_64: fpword |= 0x300; break;
case _PC_53: fpword |= 0x200; break;
case _PC_24: fpword |= 0x0; break;
}
if (flags & _IC_AFFINE) fpword |= 0x1000;
TRACE("Control word after : %08x\n", fpword);
/* Put fp control word */
#if defined(__GNUC__)
__asm__ __volatile__( "fldcw %0" : : "m" (fpword) );
#else
__asm fldcw [fpword];
#endif
return flags;
}
/*********************************************************************
* _controlfp_s (MSVCRT.@)
*/
int CDECL _controlfp_s(unsigned int *cur, unsigned int newval, unsigned int mask)
{
#ifdef __i386__
unsigned int flags;
FIXME("(%p %u %u) semi-stub\n", cur, newval, mask);
flags = _control87( newval, mask & ~_EM_DENORMAL );
if(cur)
*cur = flags;
return 0;
#else
FIXME(":Not Implemented!\n");
return 0;
#endif
}

View file

@ -0,0 +1,23 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/crt/??????
* PURPOSE: Unknown
* PROGRAMER: Unknown
* UPDATE HISTORY:
* 25/11/05: Added license header
*/
#include <precomp.h>
/*********************************************************************
* _fpreset (MSVCRT.@)
*/
void CDECL _fpreset(void)
{
#if defined(__GNUC__)
__asm__ __volatile__( "fninit" );
#else
__asm fninit;
#endif
}

View file

@ -0,0 +1,40 @@
/* Math functions for i387.
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by John C. Bowman <bowman@ipp-garching.mpg.de>, 1995.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <precomp.h>
double _logb (double __x)
{
register double __val;
#ifdef __GNUC__
register double __junk;
__asm __volatile__
("fxtract\n\t"
: "=t" (__junk), "=u" (__val) : "0" (__x));
#else
#error REVIEW ME
__asm fld [__x];
__asm fxtract;
__asm fstp st(0);
__asm fstp [__val];
#endif /*__GNUC__*/
return __val;
}

View file

@ -0,0 +1,41 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/crt/??????
* PURPOSE: Unknown
* PROGRAMER: Unknown
* UPDATE HISTORY:
* 25/11/05: Added license header
*/
#include <precomp.h>
#include "float.h"
//WTF IS HAPPENING WITH float.h !??!?!
#define _SW_INVALID 0x00000010 /* invalid */
#define _SW_ZERODIVIDE 0x00000008 /* zero divide */
#define _SW_UNDERFLOW 0x00000002 /* underflow */
#define _SW_OVERFLOW 0x00000004 /* overflow */
#define _SW_INEXACT 0x00000001 /* inexact (precision) */
#define _SW_DENORMAL 0x00080000 /* denormal status bit */
/**********************************************************************
* _statusfp (MSVCRT.@)
*/
unsigned int CDECL _statusfp(void)
{
unsigned int retVal = 0;
unsigned int fpword;
#if defined(__GNUC__)
__asm__ __volatile__( "fstsw %0" : "=m" (fpword) : );
#else
__asm fstsw [fpword];
#endif
if (fpword & 0x1) retVal |= _SW_INVALID;
if (fpword & 0x2) retVal |= _SW_DENORMAL;
if (fpword & 0x4) retVal |= _SW_ZERODIVIDE;
if (fpword & 0x8) retVal |= _SW_OVERFLOW;
if (fpword & 0x10) retVal |= _SW_UNDERFLOW;
if (fpword & 0x20) retVal |= _SW_INEXACT;
return retVal;
}

97
lib/sdk/crt/float/isnan.c Normal file
View file

@ -0,0 +1,97 @@
/* Copyright (C) 1991, 1992, 1995 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <precomp.h>
/*
* @implemented
*/
int _isnan(double __x)
{
union
{
double* __x;
double_s* x;
} x;
x.__x = &__x;
return ( x.x->exponent == 0x7ff && ( x.x->mantissah != 0 || x.x->mantissal != 0 ));
}
int _isnanl(long double __x)
{
/* Intel's extended format has the normally implicit 1 explicit
present. Sigh! */
union
{
long double* __x;
long_double_s* x;
} x;
x.__x = &__x;
/* IEEE 854 NaN's have the maximum possible
exponent and a nonzero mantissa. */
return (( x.x->exponent == 0x7fff)
&& ( (x.x->mantissah & 0x80000000) != 0)
&& ( (x.x->mantissah & (unsigned int)0x7fffffff) != 0 || x.x->mantissal != 0 ));
}
int _isinf(double __x)
{
union
{
double* __x;
double_s* x;
} x;
x.__x = &__x;
return ( x.x->exponent == 0x7ff && ( x.x->mantissah == 0 && x.x->mantissal == 0 ));
}
/*
* @implemented
*/
int _finite( double x )
{
return !_isinf(x);
}
int _isinfl(long double __x)
{
/* Intel's extended format has the normally implicit 1 explicit
present. Sigh! */
union
{
long double* __x;
long_double_s* x;
} x;
x.__x = &__x;
/* An IEEE 854 infinity has an exponent with the
maximum possible value and a zero mantissa. */
if ( x.x->exponent == 0x7fff && ( (x.x->mantissah == 0x80000000 ) && x.x->mantissal == 0 ))
return x.x->sign ? -1 : 1;
return 0;
}

View file

@ -0,0 +1,26 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/crt/??????
* PURPOSE: Unknown
* PROGRAMER: Unknown
* UPDATE HISTORY:
* 25/11/05: Added license header
*/
#include <precomp.h>
/*
* @implemented
*/
double _nextafter( double x, double y )
{
WARN("This function is not implemented correctly\n");
if ( x == y)
return x;
if ( _isnan(x) || _isnan(y) )
return x;
return x;
}

30
lib/sdk/crt/float/scalb.c Normal file
View file

@ -0,0 +1,30 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/crt/??????
* PURPOSE: Unknown
* PROGRAMER: Unknown
* UPDATE HISTORY:
* 25/11/05: Added license header
*/
#include <precomp.h>
#include <internal/ieee.h>
/*
* @implemented
*/
double _scalb( double __x, long e )
{
union
{
double* __x;
double_s* x;
} x;
x.__x = &__x;
x.x->exponent += e;
return __x;
}

176
lib/sdk/crt/include/float.h Normal file
View file

@ -0,0 +1,176 @@
/*
* float.h
* This file has no copyright assigned and is placed in the Public Domain.
* This file is a part of the mingw-runtime package.
* No warranty is given; refer to the file DISCLAIMER within the package.
*
* Constants related to floating point arithmetic.
*
* Also included here are some non-ANSI bits for accessing the floating
* point controller.
*
* NOTE: GCC provides float.h, but it doesn't include the non-standard
* stuff for accessing the fp controller. We include_next the
* GCC-supplied header and just define the MS-specific extensions
* here.
*
*/
#ifdef __GNUC__
#include_next <float.h>
#endif
#ifndef _MINGW_FLOAT_H_
#define _MINGW_FLOAT_H_
/* All the headers include this file. */
#ifdef __GNUC__
#include <_mingw.h>
#endif
/*
* Functions and definitions for controlling the FPU.
*/
#ifndef __STRICT_ANSI__
/* TODO: These constants are only valid for x86 machines */
/* Control word masks for unMask */
#define _MCW_EM 0x0008001F /* Error masks */
#define _MCW_IC 0x00040000 /* Infinity */
#define _MCW_RC 0x00000300 /* Rounding */
#define _MCW_PC 0x00030000 /* Precision */
/* Control word values for unNew (use with related unMask above) */
#define _EM_INVALID 0x00000010
#define _EM_DENORMAL 0x00080000
#define _EM_ZERODIVIDE 0x00000008
#define _EM_OVERFLOW 0x00000004
#define _EM_UNDERFLOW 0x00000002
#define _EM_INEXACT 0x00000001
#define _IC_AFFINE 0x00040000
#define _IC_PROJECTIVE 0x00000000
#define _RC_CHOP 0x00000300
#define _RC_UP 0x00000200
#define _RC_DOWN 0x00000100
#define _RC_NEAR 0x00000000
#define _PC_24 0x00020000
#define _PC_53 0x00010000
#define _PC_64 0x00000000
/* These are also defined in Mingw math.h, needed to work around
GCC build issues. */
/* Return values for fpclass. */
#ifndef __MINGW_FPCLASS_DEFINED
#define __MINGW_FPCLASS_DEFINED 1
#define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */
#define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */
#define _FPCLASS_NINF 0x0004 /* Negative Infinity */
#define _FPCLASS_NN 0x0008 /* Negative Normal */
#define _FPCLASS_ND 0x0010 /* Negative Denormal */
#define _FPCLASS_NZ 0x0020 /* Negative Zero */
#define _FPCLASS_PZ 0x0040 /* Positive Zero */
#define _FPCLASS_PD 0x0080 /* Positive Denormal */
#define _FPCLASS_PN 0x0100 /* Positive Normal */
#define _FPCLASS_PINF 0x0200 /* Positive Infinity */
#endif /* __MINGW_FPCLASS_DEFINED */
/* _statusfp bit flags */
#define _SW_INEXACT 0x00000001 /* inexact (precision) */
#define _SW_UNDERFLOW 0x00000002 /* underflow */
#define _SW_OVERFLOW 0x00000004 /* overflow */
#define _SW_ZERODIVIDE 0x00000008 /* zero divide */
#define _SW_INVALID 0x00000010 /* invalid */
#define _SW_DENORMAL 0x00080000 /* denormal status bit */
#define _SW_UNEMULATED 0x00000040 /* unemulated instruction */
#define _SW_SQRTNEG 0x00000080 /* square root of a neg number */
#define _SW_STACKOVERFLOW 0x00000200 /* FP stack overflow */
#define _SW_STACKUNDERFLOW 0x00000400 /* FP stack underflow */
/* Floating point error signals and return codes */
#define _FPE_INVALID 0x81
#define _FPE_DENORMAL 0x82
#define _FPE_ZERODIVIDE 0x83
#define _FPE_OVERFLOW 0x84
#define _FPE_UNDERFLOW 0x85
#define _FPE_INEXACT 0x86
#define _FPE_UNEMULATED 0x87
#define _FPE_SQRTNEG 0x88
#define _FPE_STACKOVERFLOW 0x8a
#define _FPE_STACKUNDERFLOW 0x8b
#define _FPE_EXPLICITGEN 0x8c /* raise( SIGFPE ); */
#ifndef DBL_MAX_10_EXP
#define DBL_MAX_10_EXP 308
#endif
#ifndef UINT64_MAX
#define UINT64_MAX 0xffffffffffffffff
#endif
#ifndef RC_INVOKED
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _CRTIMP
#ifdef _DLL
#define _CRTIMP __declspec(dllimport)
#else
#define _CRTIMP
#endif /* _DLL */
#endif
/* Set the FPU control word as cw = (cw & ~unMask) | (unNew & unMask),
* i.e. change the bits in unMask to have the values they have in unNew,
* leaving other bits unchanged. */
_CRTIMP unsigned int __cdecl _controlfp (unsigned int unNew, unsigned int unMask);
_CRTIMP unsigned int __cdecl _control87 (unsigned int unNew, unsigned int unMask);
_CRTIMP unsigned int __cdecl _clearfp (void); /* Clear the FPU status word */
_CRTIMP unsigned int __cdecl _statusfp (void); /* Report the FPU status word */
#define _clear87 _clearfp
#define _status87 _statusfp
/*
MSVCRT.dll _fpreset initializes the control register to 0x27f,
the status register to zero and the tag word to 0FFFFh.
This differs from asm instruction finit/fninit which set control
word to 0x37f (64 bit mantissa precison rather than 53 bit).
By default, the mingw version of _fpreset sets fp control as
per fninit. To use the MSVCRT.dll _fpreset, include CRT_fp8.o when
building your application.
*/
void __cdecl _fpreset (void);
void __cdecl fpreset (void);
/* Global 'variable' for the current floating point error code. */
_CRTIMP int * __cdecl __fpecode(void);
#define _fpecode (*(__fpecode()))
/*
* IEEE recommended functions. MS puts them in float.h
* but they really belong in math.h.
*/
_CRTIMP double __cdecl _chgsign (double);
_CRTIMP double __cdecl _copysign (double, double);
_CRTIMP double __cdecl _logb (double);
_CRTIMP double __cdecl _nextafter (double, double);
_CRTIMP double __cdecl _scalb (double, long);
_CRTIMP int __cdecl _finite (double);
_CRTIMP int __cdecl _fpclass (double);
_CRTIMP int __cdecl _isnan (double);
#ifdef __cplusplus
}
#endif
#endif /* Not RC_INVOKED */
#endif /* Not __STRICT_ANSI__ */
#endif /* _FLOAT_H_ */

View file

@ -0,0 +1,17 @@
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
#ifndef __CRT_INTERNAL_ATEXIT_H
#define __CRT_INTERNAL_ATEXIT_H
#ifndef _CRT_PRECOMP_H
#error DO NOT INCLUDE THIS HEADER DIRECTLY
#endif
struct __atexit {
struct __atexit* __next;
void (*__function)(void);
};
extern struct __atexit* __atexit_ptr;
#endif

View file

@ -0,0 +1,16 @@
/* console.h */
#ifndef __CRT_INTERNAL_CONSOLE_H
#define __CRT_INTERNAL_CONSOLE_H
#ifndef _CRT_PRECOMP_H
#error DO NOT INCLUDE THIS HEADER DIRECTLY
#endif
extern int char_avail;
extern int ungot_char;
#endif
/* EOF */

View file

@ -0,0 +1,179 @@
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
/*
* Some stuff taken from active perl: perl\win32.c (ioinfo stuff)
*
* (c) 1995 Microsoft Corporation. All rights reserved.
* Developed by hip communications inc., http://info.hip.com/info/
* Portions (c) 1993 Intergraph Corporation. All rights reserved.
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
*/
#ifndef __CRT_INTERNAL_FILE_H
#define __CRT_INTERNAL_FILE_H
#ifndef _CRT_PRECOMP_H
#error DO NOT INCLUDE THIS HEADER DIRECTLY
#endif
#include <stdarg.h>
#include <time.h>
#ifndef _IORMONCL
#define _IORMONCL 004000 /* remove on close, for temp files */
#endif
/* if _flag & _IORMONCL, ._name_to_remove needs freeing */
#ifndef _IOUNGETC
#define _IOUNGETC 010000 /* there is an ungetc'ed character in the buffer */
#endif
/* might need check for IO_APPEND aswell */
#define OPEN4WRITING(f) ((((f)->_flag & _IOWRT) == _IOWRT))
#define OPEN4READING(f) ((((f)->_flag & _IOREAD) == _IOREAD))
/* might need check for IO_APPEND aswell */
#define WRITE_STREAM(f) ((((f)->_flag & _IOWRT) == _IOWRT))
#define READ_STREAM(f) ((((f)->_flag & _IOREAD) == _IOREAD))
int __set_errno(int err);
int __set_doserrno(int error);
void* filehnd(int fn);
char __is_text_file(FILE*);
int _doprnt(const char* fmt, va_list args, FILE *);
int _doscan(FILE* iop, const char* fmt, va_list argp);
int __fileno_dup2(int handle1, int handle2);
char __fileno_getmode(int _fd);
int __fileno_setmode(int _fd, int _newmode);
void sigabort_handler(int sig);
void UnixTimeToFileTime(time_t unix_time, FILETIME* filetime, DWORD remainder);
#define __FILE_REC_MAX 20
typedef struct __file_rec
{
struct __file_rec* next;
int count;
FILE* files[__FILE_REC_MAX];
} __file_rec;
extern __file_rec* __file_rec_list;
typedef struct _FDINFO
{
HANDLE hFile;
char fdflags;
char pipechar; /* one char buffer for handles opened on pipes */
int lockinitflag;
CRITICAL_SECTION lock;
} FDINFO;
#define FDINFO_ENTRIES_PER_BUCKET_SHIFT 5 /* log2(32) = 5 */
#define FDINFO_BUCKETS 64
#define FDINFO_ENTRIES_PER_BUCKET 32
#define FDINFO_ENTRIES (FDINFO_BUCKETS * FDINFO_ENTRIES_PER_BUCKET)
/* pipech */
#define LF 10 /* line feed */
#define CR 13 /* carriage return */
#define CTRLZ 26 /* ctrl-z means eof for text */
/* mode */
#define FOPEN 0x01 /* file handle open */
#define FEOFLAG 0x02 /* end of file has been encountered */
#define FCRLF 0x04 /* CR-LF across read buffer (in text mode) */
#define FPIPE 0x08 /* file refers to a pipe */
#define FNOINHERIT 0x10 /* file handle opened _O_NOINHERIT */
#define FAPPEND 0x20 /* file opened O_APPEND */
#define FDEV 0x40 /* file refers to device */
#define FTEXT 0x80 /* file is in text mode (absence = binary) */
/* get bucket index (0-63) from an fd */
#define fdinfo_bucket_idx(i) ((i) >> FDINFO_ENTRIES_PER_BUCKET_SHIFT)
/* get position inside a bucket (0-31) from an fd */
#define fdinfo_bucket_entry_idx(i) ((i) & (FDINFO_ENTRIES_PER_BUCKET - 1))
/* get bucket ptr. (ptr. to first fdinfo inside a bucket) from an fd */
#define fdinfo_bucket(i) ( __pioinfo[fdinfo_bucket_idx(i)])
/* get fdinfo ptr. from an fd */
#define fdinfo(i) (fdinfo_bucket(i) + fdinfo_bucket_entry_idx(i))
//extern FDINFO* __pioinfo[];
void _dosmaperr(unsigned long oserrcode);
int access_dirA(const char *_path);
int access_dirW(const wchar_t *_path);
#ifdef _UNICODE
#define access_dirT access_dirW
#else
#define access_dirT access_dirA
#endif
#undef MB_CUR_MAX
#define MB_CUR_MAX __mb_cur_max
int _isnanl(long double x);
int _isinfl(long double x);
int _isnan(double x);
int _isinf(double x);
/* Flags for the iobuf structure (for reference) */
#if 0
#define _IOREAD 1 /* currently reading */
#define _IOWRT 2 /* currently writing */
#define _IORW 0x0080 /* opened as "r+w" */
#endif
#ifndef F_OK
#define F_OK 0 /* Check for file existence */
#endif
#ifndef W_OK
#define W_OK 2 /* Check for write permission */
#endif
/* internal FILE->_flag flags */
#define _IOMYBUF 0x0008 /* stdio malloc()'d buffer */
#define _IOEOF 0x0010 /* EOF reached on read */
#define _IOERR 0x0020 /* I/O error from system */
#define _IOSTRG 0x0040 /* Strange or no file descriptor */
#define _IOBINARY 0x040000
#define _IOTEXT 0x000000
#define _IOCOMMIT 0x100000
#define _IODIRTY 0x010000
#define _IOAHEAD 0x020000
/*
* The three possible buffering mode (nMode) values for setvbuf.
* NOTE: _IOFBF works, but _IOLBF seems to work like unbuffered...
* maybe I'm testing it wrong?
*/
#define _IOFBF 0x0000 /* full buffered */
#define _IOLBF 0x0040 /* line buffered */
#define _IONBF 0x0004 /* not buffered */
#define _IO_LBF 0x80000 /* this value is used insteat of _IOLBF within the
structure FILE as value for _flags,
because _IOLBF has the same value as _IOSTRG */
wint_t _filwbuf(FILE *f);
#if __MINGW32_MAJOR_VERSION < 3 || __MINGW32_MINOR_VERSION < 2
int __cdecl _filbuf (FILE*);
int __cdecl _flsbuf (int, FILE*);
#endif
#endif /* __dj_include_libc_file_h__ */

View file

@ -0,0 +1,25 @@
#ifndef __CRT_INTERNAL_IEEE_H
#define __CRT_INTERNAL_IEEE_H
typedef struct {
unsigned int mantissa:23;
unsigned int exponent:8;
unsigned int sign:1;
} float_s;
typedef struct {
unsigned int mantissal:32;
unsigned int mantissah:20;
unsigned int exponent:11;
unsigned int sign:1;
} double_s;
typedef struct {
unsigned int mantissal:32;
unsigned int mantissah:32;
unsigned int exponent:15;
unsigned int sign:1;
unsigned int empty:16;
} long_double_s;
#endif

View file

@ -0,0 +1,12 @@
#ifndef __CRT_INTERNAL_MATH_H
#define __CRT_INTERNAL_MATH_H
#ifndef _CRT_PRECOMP_H
#error DO NOT INCLUDE THIS HEADER DIRECTLY
#endif
int _isinf (double); /* not exported */
int _isnanl (long double); /* not exported */
int _isinfl (long double); /* not exported */
#endif

View file

@ -0,0 +1,61 @@
#ifndef __CRT_INTERNAL_MBSTRING_H
#define __CRT_INTERNAL_MBSTRING_H
#define _MALPHA 0x01
#define _MBLANK 0x02
#define _MDIGIT 0x04
#define _MKMOJI 0x08
#define _MKPNCT 0x10
#define _MLEAD 0x20
#define _MPUNCT 0x40
#define _MTRAIL 0x80
#define _MBALNUM (_MALPHA | _MDIGIT | _MKPNCT | _MKMOJI)
#define _MBALPHA (_MALPHA | _MKPNCT | _MKMOJI)
#define _MBGRAPH (_MALPHA | _MDIGIT | _MPUNCT | _MKPNCT | _MKMOJI)
#define _MBKANA (_MKPNCT | _MKMOJI)
#define _MBPRINT (_MALPHA | _MDIGIT | _MPUNCT | _MBLANK | _MKPNCT | _MKMOJI)
#define _MBPUNCT (_MPUNCT | _MKPNCT)
#define _MBLMASK(c) ((c) & 255)
#define _MBHMASK(c) ((c) & ~255)
#define _MBGETL(c) ((c) & 255)
#define _MBGETH(c) (((c) >> 8) & 255)
#define _MBIS16(c) ((c) & 0xff00)
/* Macros */
#define B _MBLANK
#define D _MDIGIT
#define P _MPUNCT
#define T _MTRAIL
/* Macros */
#define AT (_MALPHA | _MTRAIL)
#define GT (_MKPNCT | _MTRAIL)
#define KT (_MKMOJI | _MTRAIL)
#define LT (_MLEAD | _MTRAIL)
#define PT (_MPUNCT | _MTRAIL)
#define MAX_LOCALE_LENGTH 256
extern unsigned char _mbctype[257];
extern int MSVCRT___lc_codepage;
extern char MSVCRT_current_lc_all[MAX_LOCALE_LENGTH];
#if defined (_MSC_VER)
#undef _ismbbkana
#undef _ismbbkpunct
#undef _ismbbalpha
#undef _ismbbalnum
#undef _ismbbgraph
#undef _ismbbkalnum
#undef _ismbblead
#undef _ismbbprint
#undef _ismbbpunct
#undef _ismbbtrail
#endif
#endif

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2002, TransGaming Technologies Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __CRT_INTERNAL_WINE_MTDLL_H
#define __CRT_INTERNAL_WINE_MTDLL_H
#if defined(_MT)
#define _mlock(locknum) _lock(locknum)
#define _munlock(locknum) _unlock(locknum)
void _unlock( int locknum );
void _lock( int locknum );
#else
#define _mlock(locknum) do {} while(0)
#define _munlock(locknum) do {} while(0)
#endif
#define _SIGNAL_LOCK 1
#define _IOB_SCAN_LOCK 2
#define _TMPNAM_LOCK 3
#define _INPUT_LOCK 4
#define _OUTPUT_LOCK 5
#define _CSCANF_LOCK 6
#define _CPRINTF_LOCK 7
#define _CONIO_LOCK 8
#define _HEAP_LOCK 9
#define _BHEAP_LOCK 10 /* No longer used? */
#define _TIME_LOCK 11
#define _ENV_LOCK 12
#define _EXIT_LOCK1 13
#define _EXIT_LOCK2 14
#define _THREADDATA_LOCK 15 /* No longer used? */
#define _POPEN_LOCK 16
#define _LOCKTAB_LOCK 17
#define _OSFHND_LOCK 18
#define _SETLOCALE_LOCK 19
#define _LC_COLLATE_LOCK 20 /* No longer used? */
#define _LC_CTYPE_LOCK 21 /* No longer used? */
#define _LC_MONETARY_LOCK 22 /* No longer used? */
#define _LC_NUMERIC_LOCK 23 /* No longer used? */
#define _LC_TIME_LOCK 24 /* No longer used? */
#define _MB_CP_LOCK 25
#define _NLG_LOCK 26
#define _TYPEINFO_LOCK 27
#define _STREAM_LOCKS 28
/* Must match definition in msvcrt/stdio.h */
#define _IOB_ENTRIES 20
#define _LAST_STREAM_LOCK (_STREAM_LOCKS+_IOB_ENTRIES-1)
#define _TOTAL_LOCKS (_LAST_STREAM_LOCK+1)
#endif /* WINE_MTDLL_H */

View file

@ -0,0 +1,22 @@
#ifndef _CRT_PRINTF_H
#define _CRT_PRINTF_H
/* Implementation of a printf appropriated from Linux kernel */
int lnx_sprintf(char *str, const char *fmt, ...);
int lnx__vsprintf(char *str, const char *fmt, va_list ap);
int lnx__vswprintf(wchar_t *str, const wchar_t *fmt, va_list ap);
int lnx__vsnprintf(char *str, size_t maxlen, const char *fmt, va_list ap);
int lnx__vsnwprintf(wchar_t *str, size_t maxlen, const char *fmt, va_list ap);
int lnx_vfprintf(FILE* f, const char* fmt, va_list ap);
int lnx_vfwprintf(FILE *f, const wchar_t *fmt, va_list ap);
#ifdef _UNICODE
#define lnx_vftprintf lnx_vfwprintf
#define lnx__vstprintf lnx__vswprintf
#else
#define lnx_vftprintf lnx_vfprintf
#define lnx__vstprintf lnx__vsprintf
#endif
#endif /* _CRT_PRINTF_H */

View file

@ -0,0 +1,31 @@
/* rterror.h */
#ifndef __CRT_INTERNAL_RTERROR_H
#define __CRT_INTERNAL_RTERROR_H
#define _RT_STACK 0 /* stack overflow */
#define _RT_NULLPTR 1 /* null pointer assignment */
#define _RT_FLOAT 2 /* floating point not loaded */
#define _RT_INTDIV 3 /* integer divide by 0 */
#define _RT_SPACEARG 4 /* not enough space for arguments */
#define _RT_SPACEENV 5 /* not enough space for environment */
#define _RT_ABORT 6 /* abnormal program termination */
#define _RT_THREAD 7 /* not enough space for thread data */
#define _RT_LOCK 8 /* unexpected multi-thread lock error */
#define _RT_HEAP 9 /* unexpected heap error */
#define _RT_OPENCON 10 /* unable to open console device */
#define _RT_NONCONT 11 /* non-continuable exception */
#define _RT_INVALDISP 12 /* invalid disposition of exception */
#define _RT_ONEXIT 13 /* insufficient heap to allocate
* initial table of function pointers
* used by _onexit()/atexit(). */
#define _RT_PUREVIRT 14 /* pure virtual function call attempted
* (C++ error) */
#define _RT_STDIOINIT 15 /* not enough space for stdio initialization */
#define _RT_LOWIOINIT 16 /* not enough space for lowio initialization */
void _amsg_exit (int errnum);
#endif /* __MSVCRT_INTERNAL_RTERROR_H */

View file

@ -0,0 +1,10 @@
extern void * __pInvalidArgHandler;
void _invalid_parameter(
const wchar_t * expression,
const wchar_t * function,
const wchar_t * file,
unsigned int line,
uintptr_t pReserved);

View file

@ -0,0 +1,55 @@
#define DIFFTIME 0x19db1ded53e8000ULL
#define DIFFDAYS (3 * DAYSPER100YEARS + 17 * DAYSPER4YEARS + 1 * DAYSPERYEAR)
#define DAYSPERYEAR 365
#define DAYSPER4YEARS (4*DAYSPERYEAR+1)
#define DAYSPER100YEARS (25*DAYSPER4YEARS-1)
#define DAYSPER400YEARS (4*DAYSPER100YEARS+1)
#define SECONDSPERDAY (24*60*60)
#define SECONDSPERHOUR (60*60)
#define LEAPDAY 59
static __inline
time_t
FileTimeToUnixTime(const FILETIME *FileTime, USHORT *millitm)
{
ULARGE_INTEGER ULargeInt;
time_t time;
ULargeInt.LowPart = FileTime->dwLowDateTime;
ULargeInt.HighPart = FileTime->dwHighDateTime;
ULargeInt.QuadPart -= DIFFTIME;
time = ULargeInt.QuadPart / 10000000;
if (millitm)
*millitm = (ULargeInt.QuadPart % 10000000) / 10000;
return time;
}
static __inline
long leapyears_passed(long days)
{
long quadcenturies, centuries, quadyears;
quadcenturies = days / DAYSPER400YEARS;
days -= quadcenturies;
centuries = days / DAYSPER100YEARS;
days += centuries;
quadyears = days / DAYSPER4YEARS;
return quadyears - centuries + quadcenturies;
}
static __inline
long leapdays_passed(long days)
{
return leapyears_passed(days + DAYSPERYEAR - LEAPDAY + 1);
}
static __inline
long years_passed(long days)
{
return (days - leapdays_passed(days)) / 365;
}
extern long dst_begin;
extern long dst_end;

View file

@ -0,0 +1,48 @@
/* tls.h */
#ifndef __CRT_INTERNAL_TLS_H
#define __CRT_INTERNAL_TLS_H
#ifndef _CRT_PRECOMP_H
#error DO NOT INCLUDE THIS HEADER DIRECTLY
#endif
#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
#include <winnt.h>
#include <time.h>
#include <stddef.h>
typedef struct _ThreadData
{
int terrno; /* *nix error code */
unsigned long tdoserrno; /* Win32 error code (for I/O only) */
unsigned __int64 tnext; /* used by rand/srand */
char *lasttoken; /* used by strtok */
wchar_t *wlasttoken; /* used by wcstok */
int fpecode; /* fp exception code */
EXCEPTION_RECORD *exc_record; /* Head of exception record list */
struct tm tmbuf; /* Used by gmtime, mktime, mkgmtime, localtime */
char asctimebuf[26]; /* Buffer for asctime and ctime */
wchar_t wasctimebuf[26]; /* Buffer for wasctime and wctime */
} THREADDATA, *PTHREADDATA;
int CreateThreadData(void);
void DestroyThreadData(void);
void FreeThreadData(PTHREADDATA ptd);
PTHREADDATA GetThreadData(void);
#endif /* __MSVCRT_INTERNAL_TLS_H */
/* EOF */

View file

@ -0,0 +1,183 @@
/*
* msvcrt C++ exception handling
*
* Copyright 2002 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __MSVCRT_CPPEXCEPT_H
#define __MSVCRT_CPPEXCEPT_H
#include <pseh/pseh2.h>
#define CXX_FRAME_MAGIC_VC6 0x19930520
#define CXX_FRAME_MAGIC_VC7 0x19930521
#define CXX_FRAME_MAGIC_VC8 0x19930522
#define CXX_EXCEPTION 0xe06d7363
/* Macros to define assembler functions somewhat portably */
#define EH_NONCONTINUABLE 0x01
#define EH_UNWINDING 0x02
#define EH_EXIT_UNWIND 0x04
#define EH_STACK_INVALID 0x08
#define EH_NESTED_CALL 0x10
typedef void (*vtable_ptr)();
/* type_info object, see cpp.c for inplementation */
typedef struct __type_info
{
const vtable_ptr *vtable;
char *name; /* Unmangled name, allocated lazily */
char mangled[32]; /* Variable length, but we declare it large enough for static RTTI */
} type_info;
/* exception object */
typedef struct __exception
{
const vtable_ptr *vtable;
char *name; /* Name of this exception, always a new copy for each object */
int do_free; /* Whether to free 'name' in our dtor */
} exception;
/* the exception frame used by CxxFrameHandler */
typedef struct __cxx_exception_frame
{
EXCEPTION_REGISTRATION_RECORD frame; /* the standard exception frame */
int trylevel;
DWORD ebp;
} cxx_exception_frame;
/* info about a single catch {} block */
typedef struct __catchblock_info
{
UINT flags; /* flags (see below) */
const type_info *type_info; /* C++ type caught by this block */
int offset; /* stack offset to copy exception object to */
void (*handler)(void);/* catch block handler code */
} catchblock_info;
#define TYPE_FLAG_CONST 1
#define TYPE_FLAG_VOLATILE 2
#define TYPE_FLAG_REFERENCE 8
/* info about a single try {} block */
typedef struct __tryblock_info
{
int start_level; /* start trylevel of that block */
int end_level; /* end trylevel of that block */
int catch_level; /* initial trylevel of the catch block */
int catchblock_count; /* count of catch blocks in array */
const catchblock_info *catchblock; /* array of catch blocks */
} tryblock_info;
/* info about the unwind handler for a given trylevel */
typedef struct __unwind_info
{
int prev; /* prev trylevel unwind handler, to run after this one */
void (*handler)(void);/* unwind handler */
} unwind_info;
/* descriptor of all try blocks of a given function */
typedef struct __cxx_function_descr
{
UINT magic; /* must be CXX_FRAME_MAGIC */
UINT unwind_count; /* number of unwind handlers */
const unwind_info *unwind_table; /* array of unwind handlers */
UINT tryblock_count; /* number of try blocks */
const tryblock_info *tryblock; /* array of try blocks */
UINT ipmap_count;
const void *ipmap;
const void *expect_list; /* expected exceptions list when magic >= VC7 */
UINT flags; /* flags when magic >= VC8 */
} cxx_function_descr;
#define FUNC_DESCR_SYNCHRONOUS 1 /* synchronous exceptions only (built with /EHs) */
typedef void (*cxx_copy_ctor)(void);
/* offsets for computing the this pointer */
typedef struct
{
int this_offset; /* offset of base class this pointer from start of object */
int vbase_descr; /* offset of virtual base class descriptor */
int vbase_offset; /* offset of this pointer offset in virtual base class descriptor */
} this_ptr_offsets;
/* complete information about a C++ type */
typedef struct __cxx_type_info
{
UINT flags; /* flags (see CLASS_* flags below) */
const type_info *type_info; /* C++ type info */
this_ptr_offsets offsets; /* offsets for computing the this pointer */
unsigned int size; /* object size */
cxx_copy_ctor copy_ctor; /* copy constructor */
} cxx_type_info;
#define CLASS_IS_SIMPLE_TYPE 1
#define CLASS_HAS_VIRTUAL_BASE_CLASS 4
/* table of C++ types that apply for a given object */
typedef struct __cxx_type_info_table
{
UINT count; /* number of types */
const cxx_type_info *info[3]; /* variable length, we declare it large enough for static RTTI */
} cxx_type_info_table;
typedef DWORD (*cxx_exc_custom_handler)( PEXCEPTION_RECORD, cxx_exception_frame*,
PCONTEXT, EXCEPTION_REGISTRATION_RECORD**,
const cxx_function_descr*, int nested_trylevel,
EXCEPTION_REGISTRATION_RECORD *nested_frame, DWORD unknown3 );
/* type information for an exception object */
typedef struct __cxx_exception_type
{
UINT flags; /* TYPE_FLAG flags */
void (*destructor)(void);/* exception object destructor */
cxx_exc_custom_handler custom_handler; /* custom handler for this exception */
const cxx_type_info_table *type_info_table; /* list of types for this exception object */
} cxx_exception_type;
void CDECL _CxxThrowException(exception*,const cxx_exception_type*);
int CDECL _XcptFilter(NTSTATUS, PEXCEPTION_POINTERS);
int CDECL __CppXcptFilter(NTSTATUS, PEXCEPTION_POINTERS);
static inline const char *dbgstr_type_info( const type_info *info )
{
if (!info) return "{}";
return wine_dbg_sprintf( "{vtable=%p name=%s (%s)}",
info->vtable, info->mangled, info->name ? info->name : "" );
}
/* compute the this pointer for a base class of a given type */
static inline void *get_this_pointer( const this_ptr_offsets *off, void *object )
{
void *this_ptr;
int *offset_ptr;
if (!object) return NULL;
this_ptr = (char *)object + off->this_offset;
if (off->vbase_descr >= 0)
{
/* move this ptr to vbase descriptor */
this_ptr = (char *)this_ptr + off->vbase_descr;
/* and fetch additional offset from vbase descriptor */
offset_ptr = (int *)(*(char **)this_ptr + off->vbase_offset);
this_ptr = (char *)this_ptr + *offset_ptr;
}
return this_ptr;
}
#endif /* __MSVCRT_CPPEXCEPT_H */

View file

@ -0,0 +1,53 @@
/*
* C++ exception handling facility
*
* Copyright 2000 Francois Gouget.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __WINE_EH_H
#define __WINE_EH_H
#ifndef __WINE_USE_MSVCRT
#define __WINE_USE_MSVCRT
#endif
#if !defined(__cplusplus) && !defined(USE_MSVCRT_PREFIX)
#error "eh.h is meant only for C++ applications"
#endif
#ifndef MSVCRT
# ifdef USE_MSVCRT_PREFIX
# define MSVCRT(x) MSVCRT_##x
# else
# define MSVCRT(x) x
# endif
#endif
struct _EXCEPTION_POINTERS;
typedef void (*terminate_handler)();
typedef void (*terminate_function)();
typedef void (*unexpected_handler)();
typedef void (*unexpected_function)();
typedef void (*_se_translator_function)(unsigned int code, struct _EXCEPTION_POINTERS *info);
terminate_function MSVCRT(set_terminate)(terminate_function func);
unexpected_function MSVCRT(set_unexpected)(unexpected_function func);
_se_translator_function MSVCRT(_set_se_translator)(_se_translator_function func);
void MSVCRT(terminate)();
void MSVCRT(unexpected)();
#endif /* __WINE_EH_H */

View file

@ -0,0 +1,174 @@
/*
* Copyright 2001 Jon Griffiths
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef __WINE_MSVCRT_H
#define __WINE_MSVCRT_H
#include <stdarg.h>
#include <signal.h>
#include "windef.h"
#include "winbase.h"
#include "eh.h"
typedef unsigned short MSVCRT_wchar_t;
typedef unsigned short MSVCRT_wint_t;
typedef unsigned short MSVCRT_wctype_t;
typedef unsigned short MSVCRT__ino_t;
typedef unsigned long MSVCRT__fsize_t;
#ifdef _WIN64
typedef unsigned __int64 MSVCRT_size_t;
typedef __int64 MSVCRT_intptr_t;
typedef unsigned __int64 MSVCRT_uintptr_t;
#else
typedef unsigned int MSVCRT_size_t;
typedef int MSVCRT_intptr_t;
typedef unsigned int MSVCRT_uintptr_t;
#endif
typedef unsigned int MSVCRT__dev_t;
typedef int MSVCRT__off_t;
typedef long MSVCRT_clock_t;
typedef long MSVCRT_time_t;
typedef __int64 MSVCRT___time64_t;
typedef __int64 MSVCRT_fpos_t;
struct MSVCRT_tm {
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
/* TLS data */
extern DWORD MSVCRT_tls_index;
typedef struct __MSVCRT_thread_data
{
int thread_errno;
unsigned long thread_doserrno;
unsigned int random_seed; /* seed for rand() */
char *strtok_next; /* next ptr for strtok() */
unsigned char *mbstok_next; /* next ptr for mbstok() */
MSVCRT_wchar_t *wcstok_next; /* next ptr for wcstok() */
char *efcvt_buffer; /* buffer for ecvt/fcvt */
char *asctime_buffer; /* buffer for asctime */
MSVCRT_wchar_t *wasctime_buffer; /* buffer for wasctime */
struct MSVCRT_tm time_buffer; /* buffer for localtime/gmtime */
char *strerror_buffer; /* buffer for strerror */
int fpecode;
terminate_function terminate_handler;
unexpected_function unexpected_handler;
_se_translator_function se_translator;
EXCEPTION_RECORD *exc_record;
} MSVCRT_thread_data;
extern MSVCRT_thread_data *msvcrt_get_thread_data(void);
extern int MSVCRT_current_lc_all_cp;
void _purecall(void);
void MSVCRT__set_errno(int);
char* msvcrt_strndup(const char*,unsigned int);
#ifndef __REACTOS__
MSVCRT_wchar_t *msvcrt_wstrndup(const MSVCRT_wchar_t*, unsigned int);
#endif
void MSVCRT__amsg_exit(int errnum);
extern char **MSVCRT__environ;
#ifndef __REACTOS__
extern MSVCRT_wchar_t **MSVCRT__wenviron;
extern char ** msvcrt_SnapshotOfEnvironmentA(char **);
extern MSVCRT_wchar_t ** msvcrt_SnapshotOfEnvironmentW(MSVCRT_wchar_t **);
#endif
/* FIXME: This should be declared in new.h but it's not an extern "C" so
* it would not be much use anyway. Even for Winelib applications.
*/
int MSVCRT__set_new_mode(int mode);
void* MSVCRT_operator_new(unsigned long size);
void MSVCRT_operator_delete(void*);
#ifndef __REACTOS__
typedef void* (*MSVCRT_malloc_func)(MSVCRT_size_t);
#endif
typedef void (*MSVCRT_free_func)(void*);
#ifndef __REACTOS__
extern char* MSVCRT___unDName(int,const char*,int,MSVCRT_malloc_func,MSVCRT_free_func,unsigned int);
#endif
/* Setup and teardown multi threaded locks */
extern void msvcrt_init_mt_locks(void);
extern void msvcrt_free_mt_locks(void);
extern void msvcrt_init_io(void);
extern void msvcrt_free_io(void);
extern void msvcrt_init_console(void);
extern void msvcrt_free_console(void);
extern void msvcrt_init_args(void);
extern void msvcrt_free_args(void);
extern void msvcrt_init_signals(void);
extern void msvcrt_free_signals(void);
extern unsigned create_io_inherit_block(WORD*, BYTE**);
#define MSVCRT__OUT_TO_DEFAULT 0
#define MSVCRT__REPORT_ERRMODE 3
#ifdef __i386__
struct MSVCRT___JUMP_BUFFER {
unsigned long Ebp;
unsigned long Ebx;
unsigned long Edi;
unsigned long Esi;
unsigned long Esp;
unsigned long Eip;
unsigned long Registration;
unsigned long TryLevel;
/* Start of new struct members */
unsigned long Cookie;
unsigned long UnwindFunc;
unsigned long UnwindData[6];
};
#endif /* __i386__ */
typedef void (*float_handler)(int, int);
void _default_handler(int signal);
typedef struct _sig_element
{
int signal;
char *signame;
__p_sig_fn_t handler;
}sig_element;
typedef void* (*malloc_func_t)(size_t);
typedef void (*free_func_t)(void*);
#define MSVCRT_malloc malloc
#define MSVCRT_free free
char* _setlocale(int,const char*);
NTSYSAPI VOID NTAPI RtlAssert(PVOID FailedAssertion,PVOID FileName,ULONG LineNumber,PCHAR Message);
extern char* __unDName(char *,const char*,int,malloc_func_t,free_func_t,unsigned short int);
#endif /* __WINE_MSVCRT_H */

219
lib/sdk/crt/libcntpr.rbuild Normal file
View file

@ -0,0 +1,219 @@
<?xml version="1.0"?>
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
<module name="libcntpr" type="staticlibrary">
<include base="libcntpr">.</include>
<include base="libcntpr">include</include>
<define name="NO_RTL_INLINES" />
<define name="_NTSYSTEM_" />
<define name="_NTDLLBUILD_" />
<define name="_LIBCNT_" />
<define name="_CRTBLD" />
<define name="__CRT__NO_INLINE" />
<if property="ARCH" value="i386">
<define name="__MINGW_IMPORT">"extern __attribute__ ((dllexport))"</define>
</if>
<directory name="except">
<if property="ARCH" value="i386">
<directory name="i386">
<file>chkstk_asm.s</file>
<file>seh.s</file>
</directory>
</if>
<if property="ARCH" value="amd64">
<directory name="amd64">
<file>chkstk_asm.s</file>
<file>seh.s</file>
</directory>
</if>
<if property="ARCH" value="powerpc">
<directory name="powerpc">
<file>chkstk_asm.s</file>
<file>seh.s</file>
</directory>
</if>
</directory>
<directory name="math">
<if property="ARCH" value="i386">
<directory name="i386">
<file>alldiv_asm.s</file>
<file>alldvrm_asm.s</file>
<file>allmul_asm.s</file>
<file>allrem_asm.s</file>
<file>allshl_asm.s</file>
<file>allshr_asm.s</file>
<file>atan_asm.s</file>
<file>aulldiv_asm.s</file>
<file>aulldvrm_asm.s</file>
<file>aullrem_asm.s</file>
<file>aullshr_asm.s</file>
<file>ci.c</file>
<file>ceil_asm.s</file>
<file>cos_asm.s</file>
<file>fabs_asm.s</file>
<file>floor_asm.s</file>
<file>ftol_asm.s</file>
<file>log_asm.s</file>
<file>pow_asm.s</file>
<file>sin_asm.s</file>
<file>sqrt_asm.s</file>
<file>tan_asm.s</file>
</directory>
</if>
<if property="ARCH" value="amd64">
<file>cos.c</file>
<file>sin.c</file>
<directory name="amd64">
<file>alldiv.S</file>
<file>atan.S</file>
<file>atan2.S</file>
<file>ceil.S</file>
<file>exp.S</file>
<file>fabs.S</file>
<file>floor.S</file>
<file>fmod.S</file>
<file>ldexp.S</file>
<file>log.S</file>
<file>log10.S</file>
<file>pow.S</file>
<file>sqrt.S</file>
<file>tan.S</file>
</directory>
</if>
<file>abs.c</file>
<file>div.c</file>
<file>labs.c</file>
<file>rand_nt.c</file>
</directory>
<directory name="mem">
<if property="ARCH" value="i386">
<directory name="i386">
<file>memchr_asm.s</file>
<file>memcpy_asm.s</file>
<file>memmove_asm.s</file>
<file>memset_asm.s</file>
</directory>
</if>
<ifnot property="ARCH" value="i386">
<file>memchr.c</file>
<file>memcpy.c</file>
<file>memmove.c</file>
<file>memset.c</file>
</ifnot>
<file>memccpy.c</file>
<file>memcmp.c</file>
<file>memicmp.c</file>
</directory>
<directory name="search">
<file>bsearch.c</file>
<file>lfind.c</file>
</directory>
<directory name="setjmp">
<if property="ARCH" value="i386">
<directory name="i386">
<file>setjmp.s</file>
</directory>
</if>
<if property="ARCH" value="amd64">
<directory name="amd64">
<file>setjmp.s</file>
</directory>
</if>
</directory>
<directory name="stdlib">
<file>qsort.c</file>
</directory>
<directory name="string">
<if property="ARCH" value="i386">
<directory name="i386">
<file>strcat_asm.s</file>
<file>strchr_asm.s</file>
<file>strcmp_asm.s</file>
<file>strcpy_asm.s</file>
<file>strlen_asm.s</file>
<file>strncat_asm.s</file>
<file>strncmp_asm.s</file>
<file>strncpy_asm.s</file>
<file>strnlen_asm.s</file>
<file>strrchr_asm.s</file>
<file>wcscat_asm.s</file>
<file>wcschr_asm.s</file>
<file>wcscmp_asm.s</file>
<file>wcscpy_asm.s</file>
<file>wcslen_asm.s</file>
<file>wcsncat_asm.s</file>
<file>wcsncmp_asm.s</file>
<file>wcsncpy_asm.s</file>
<file>wcsnlen_asm.s</file>
<file>wcsrchr_asm.s</file>
</directory>
</if>
<ifnot property="ARCH" value="i386">
<file>strcat.c</file>
<file>strchr.c</file>
<file>strcmp.c</file>
<file>strcpy.c</file>
<file>strlen.c</file>
<file>strncat.c</file>
<file>strncmp.c</file>
<file>strncpy.c</file>
<file>strnlen.c</file>
<file>strrchr.c</file>
<file>wcscat.c</file>
<file>wcschr.c</file>
<file>wcscmp.c</file>
<file>wcscpy.c</file>
<file>wcslen.c</file>
<file>wcsncat.c</file>
<file>wcsncmp.c</file>
<file>wcsncpy.c</file>
<file>wcsnlen.c</file>
<file>wcsrchr.c</file>
</ifnot>
<file>ctype.c</file>
<file>scanf.c</file>
<file>strcspn.c</file>
<file>stricmp.c</file>
<file>strnicmp.c</file>
<file>strlwr.c</file>
<file>strrev.c</file>
<file>strset.c</file>
<file>strstr.c</file>
<file>strupr.c</file>
<file>strpbrk.c</file>
<file>strspn.c</file>
<file>atoi64.c</file>
<file>atoi.c</file>
<file>atol.c</file>
<file>itoa.c</file>
<file>itow.c</file>
<file>mbstowcs_nt.c</file>
<file>splitp.c</file>
<file>strtol.c</file>
<file>strtoul.c</file>
<file>strtoull.c</file>
<file>wcs.c</file>
<file>wcstol.c</file>
<file>wcstombs_nt.c</file>
<file>wcstoul.c</file>
<file>wsplitp.c</file>
<file>wtoi64.c</file>
<file>wtoi.c</file>
<file>wtol.c</file>
</directory>
<directory name="wstring">
<file>wcsicmp.c</file>
<file>wcslwr.c</file>
<file>wcsnicmp.c</file>
<file>wcsupr.c</file>
<file>wcscspn.c</file>
<file>wcsspn.c</file>
<file>wcsstr.c</file>
</directory>
</module>

918
lib/sdk/crt/locale/locale.c Normal file
View file

@ -0,0 +1,918 @@
/*
* Some stuff takem from wine msvcrt\locale.c
*
* Copyright 2000 Jon Griffiths
*/
#include <precomp.h>
#include <locale.h>
#include "mbctype.h"
// mtdll.h
#define _SETLOCALE_LOCK 19
// msvcrt.h
#define MSVCRT_LC_ALL 0
#define MSVCRT_LC_COLLATE 1
#define MSVCRT_LC_CTYPE 2
#define MSVCRT_LC_MONETARY 3
#define MSVCRT_LC_NUMERIC 4
#define MSVCRT_LC_TIME 5
#define MSVCRT_LC_MIN MSVCRT_LC_ALL
#define MSVCRT_LC_MAX MSVCRT_LC_TIME
/* FIXME: Need to hold locale for each LC_* type and aggregate
* string to produce lc_all.
*/
#define MAX_ELEM_LEN 64 /* Max length of country/language/CP string */
unsigned char _mbctype[257] = { 0 };
int g_mbcp_is_multibyte = 0;
/* It seems that the data about valid trail bytes is not available from kernel32
* so we have to store is here. The format is the same as for lead bytes in CPINFO */
struct cp_extra_info_t
{
int cp;
BYTE TrailBytes[MAX_LEADBYTES];
};
static struct cp_extra_info_t g_cpextrainfo[] =
{
{932, {0x40, 0x7e, 0x80, 0xfc, 0, 0}},
{936, {0x40, 0xfe, 0, 0}},
{949, {0x41, 0xfe, 0, 0}},
{950, {0x40, 0x7e, 0xa1, 0xfe, 0, 0}},
{1361, {0x31, 0x7e, 0x81, 0xfe, 0, 0}},
{20932, {1, 255, 0, 0}}, /* seems to give different results on different systems */
{0, {1, 255, 0, 0}} /* match all with FIXME */
};
char MSVCRT_current_lc_all[MAX_LOCALE_LENGTH] = { 0 };
LCID MSVCRT_current_lc_all_lcid = 0;
int MSVCRT___lc_codepage = 0;
int MSVCRT___lc_collate_cp = 0;
HANDLE MSVCRT___lc_handle[MSVCRT_LC_MAX - MSVCRT_LC_MIN + 1] = { 0 };
/* MT */
#define LOCK_LOCALE _mlock(_SETLOCALE_LOCK);
#define UNLOCK_LOCALE _munlock(_SETLOCALE_LOCK);
#define MSVCRT_LEADBYTE 0x8000
typedef struct {
char search_language[MAX_ELEM_LEN];
char search_country[MAX_ELEM_LEN];
char search_codepage[MAX_ELEM_LEN];
char found_language[MAX_ELEM_LEN];
char found_country[MAX_ELEM_LEN];
char found_codepage[MAX_ELEM_LEN];
unsigned int match_flags;
LANGID found_lang_id;
} locale_search_t;
unsigned int __setlc_active;
unsigned int __unguarded_readlc_active;
int _current_category; /* used by setlocale */
const char *_current_locale;
int parse_locale(const char *locale, char *lang, char *country, char *code_page);
#define _C_ _CONTROL
#define _S_ _SPACE
#define _P_ _PUNCT
#define _D_ _DIGIT
#define _H_ _HEX
#define _U_ _UPPER
#define _L_ _LOWER
WORD MSVCRT__ctype [257] = {
0, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _S_|_C_, _S_|_C_,
_S_|_C_, _S_|_C_, _S_|_C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_,
_C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _C_, _S_|_BLANK,
_P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _P_,
_P_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_, _D_|_H_,
_D_|_H_, _D_|_H_, _D_|_H_, _P_, _P_, _P_, _P_, _P_, _P_, _P_, _U_|_H_,
_U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_|_H_, _U_, _U_, _U_, _U_, _U_,
_U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_, _U_,
_U_, _P_, _P_, _P_, _P_, _P_, _P_, _L_|_H_, _L_|_H_, _L_|_H_, _L_|_H_,
_L_|_H_, _L_|_H_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_,
_L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _L_, _P_, _P_, _P_, _P_,
_C_, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* Internal: Current ctype table for locale */
WORD MSVCRT_current_ctype[257];
/* pctype is used by macros in the Win32 headers. It must point
* To a table of flags exactly like ctype. To allow locale
* changes to affect ctypes (i.e. isleadbyte), we use a second table
* and update its flags whenever the current locale changes.
*/
WORD* MSVCRT__pctype = MSVCRT_current_ctype + 1;
/* Friendly country strings & iso codes for synonym support.
* Based on MS documentation for setlocale().
*/
static const char * const _country_synonyms[] =
{
"Hong Kong","HK",
"Hong-Kong","HK",
"New Zealand","NZ",
"New-Zealand","NZ",
"PR China","CN",
"PR-China","CN",
"United Kingdom","GB",
"United-Kingdom","GB",
"Britain","GB",
"England","GB",
"Great Britain","GB",
"United States","US",
"United-States","US",
"America","US"
};
/* Note: Flags are weighted in order of matching importance */
#define FOUND_LANGUAGE 0x4
#define FOUND_COUNTRY 0x2
#define FOUND_CODEPAGE 0x1
/* INTERNAL: Map a synonym to an ISO code */
static void remap_synonym(char *name)
{
size_t i;
for (i = 0; i < sizeof(_country_synonyms)/sizeof(char*); i += 2 )
{
if (!_stricmp(_country_synonyms[i],name))
{
TRACE(":Mapping synonym %s to %s\n",name,_country_synonyms[i+1]);
name[0] = _country_synonyms[i+1][0];
name[1] = _country_synonyms[i+1][1];
name[2] = '\0';
return;
}
}
}
#define CONTINUE_LOOKING TRUE
#define STOP_LOOKING FALSE
/* INTERNAL: Get and compare locale info with a given string */
static int compare_info(LCID lcid, DWORD flags, char* buff, const char* cmp)
{
buff[0] = 0;
GetLocaleInfoA(lcid, flags|LOCALE_NOUSEROVERRIDE,buff, MAX_ELEM_LEN);
if (!buff[0] || !cmp[0])
return 0;
/* Partial matches are allowed, e.g. "Germ" matches "Germany" */
return !_strnicmp(cmp, buff, strlen(cmp));
}
static BOOL CALLBACK
find_best_locale_proc(HMODULE hModule, LPCSTR type, LPCSTR name, WORD LangID, LONG_PTR lParam)
{
locale_search_t *res = (locale_search_t *)lParam;
const LCID lcid = MAKELCID(LangID, SORT_DEFAULT);
char buff[MAX_ELEM_LEN];
unsigned int flags = 0;
if(PRIMARYLANGID(LangID) == LANG_NEUTRAL)
return CONTINUE_LOOKING;
/* Check Language */
if (compare_info(lcid,LOCALE_SISO639LANGNAME,buff,res->search_language) ||
compare_info(lcid,LOCALE_SABBREVLANGNAME,buff,res->search_language) ||
compare_info(lcid,LOCALE_SENGLANGUAGE,buff,res->search_language))
{
TRACE(":Found language: %s->%s\n", res->search_language, buff);
flags |= FOUND_LANGUAGE;
memcpy(res->found_language,res->search_language,MAX_ELEM_LEN);
}
else if (res->match_flags & FOUND_LANGUAGE)
{
return CONTINUE_LOOKING;
}
/* Check Country */
if (compare_info(lcid,LOCALE_SISO3166CTRYNAME,buff,res->search_country) ||
compare_info(lcid,LOCALE_SABBREVCTRYNAME,buff,res->search_country) ||
compare_info(lcid,LOCALE_SENGCOUNTRY,buff,res->search_country))
{
TRACE("Found country:%s->%s\n", res->search_country, buff);
flags |= FOUND_COUNTRY;
memcpy(res->found_country,res->search_country,MAX_ELEM_LEN);
}
else if (res->match_flags & FOUND_COUNTRY)
{
return CONTINUE_LOOKING;
}
/* Check codepage */
if (compare_info(lcid,LOCALE_IDEFAULTCODEPAGE,buff,res->search_codepage) ||
(compare_info(lcid,LOCALE_IDEFAULTANSICODEPAGE,buff,res->search_codepage)))
{
TRACE("Found codepage:%s->%s\n", res->search_codepage, buff);
flags |= FOUND_CODEPAGE;
memcpy(res->found_codepage,res->search_codepage,MAX_ELEM_LEN);
}
else if (res->match_flags & FOUND_CODEPAGE)
{
return CONTINUE_LOOKING;
}
if (flags > res->match_flags)
{
/* Found a better match than previously */
res->match_flags = flags;
res->found_lang_id = LangID;
}
if ((flags & (FOUND_LANGUAGE | FOUND_COUNTRY | FOUND_CODEPAGE)) ==
(FOUND_LANGUAGE | FOUND_COUNTRY | FOUND_CODEPAGE))
{
TRACE(":found exact locale match\n");
return STOP_LOOKING;
}
return CONTINUE_LOOKING;
}
/* Internal: Find the LCID for a locale specification */
static LCID MSVCRT_locale_to_LCID(locale_search_t* locale)
{
LCID lcid;
EnumResourceLanguagesA(GetModuleHandleA("KERNEL32"), (LPSTR)RT_STRING,
(LPCSTR)LOCALE_ILANGUAGE,find_best_locale_proc,
(LONG_PTR)locale);
if (!locale->match_flags)
return 0;
/* If we were given something that didn't match, fail */
if (locale->search_country[0] && !(locale->match_flags & FOUND_COUNTRY))
return 0;
lcid = MAKELCID(locale->found_lang_id, SORT_DEFAULT);
/* Populate partial locale, translating LCID to locale string elements */
if (!locale->found_codepage[0])
{
/* Even if a codepage is not enumerated for a locale
* it can be set if valid */
if (locale->search_codepage[0])
{
if (IsValidCodePage(atoi(locale->search_codepage)))
memcpy(locale->found_codepage,locale->search_codepage,MAX_ELEM_LEN);
else
{
/* Special codepage values: OEM & ANSI */
if (_stricmp(locale->search_codepage,"OCP"))
{
GetLocaleInfoA(lcid, LOCALE_IDEFAULTCODEPAGE,
locale->found_codepage, MAX_ELEM_LEN);
}
if (_stricmp(locale->search_codepage,"ACP"))
{
GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE,
locale->found_codepage, MAX_ELEM_LEN);
}
else
return 0;
if (!atoi(locale->found_codepage))
return 0;
}
}
else
{
/* Prefer ANSI codepages if present */
GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE,
locale->found_codepage, MAX_ELEM_LEN);
if (!locale->found_codepage[0] || !atoi(locale->found_codepage))
GetLocaleInfoA(lcid, LOCALE_IDEFAULTCODEPAGE,
locale->found_codepage, MAX_ELEM_LEN);
}
}
GetLocaleInfoA(lcid, LOCALE_SENGLANGUAGE|LOCALE_NOUSEROVERRIDE,
locale->found_language, MAX_ELEM_LEN);
GetLocaleInfoA(lcid, LOCALE_SENGCOUNTRY|LOCALE_NOUSEROVERRIDE,
locale->found_country, MAX_ELEM_LEN);
return lcid;
}
/* INTERNAL: Set ctype behaviour for a codepage */
static void msvcrt_set_ctype(unsigned int codepage, LCID lcid)
{
CPINFO cp;
memset(&cp, 0, sizeof(CPINFO));
if (GetCPInfo(codepage, &cp))
{
int i;
char str[3];
unsigned char *traverse = cp.LeadByte;
memset(MSVCRT_current_ctype, 0, sizeof(MSVCRT__ctype));
MSVCRT___lc_codepage = codepage;
MSVCRT___lc_collate_cp = codepage;
/* Switch ctype macros to MBCS if needed */
__mb_cur_max = cp.MaxCharSize;
/* Set remaining ctype flags: FIXME: faster way to do this? */
str[1] = str[2] = 0;
for (i = 0; i < 256; i++)
{
if (!(MSVCRT__pctype[i] & MSVCRT_LEADBYTE))
{
str[0] = i;
GetStringTypeA(lcid, CT_CTYPE1, str, 1, MSVCRT__pctype + i);
}
}
/* Set leadbyte flags */
while (traverse[0] || traverse[1])
{
for( i = traverse[0]; i <= traverse[1]; i++ )
MSVCRT_current_ctype[i+1] |= MSVCRT_LEADBYTE;
traverse += 2;
};
}
}
/*
* @implemented
*/
char *setlocale(int category, const char *locale)
{
LCID lcid = 0;
locale_search_t lc;
int haveLang, haveCountry, haveCP;
char* next;
int lc_all = 0;
TRACE("(%d %s)\n",category,locale);
if (category < MSVCRT_LC_MIN || category > MSVCRT_LC_MAX)
return NULL;
if (locale == NULL)
{
/* Report the current Locale */
return MSVCRT_current_lc_all;
}
LOCK_LOCALE;
if (locale[0] == 'L' && locale[1] == 'C' && locale[2] == '_')
{
WARN(":restore previous locale not implemented!\n");
/* FIXME: Easiest way to do this is parse the string and
* call this function recursively with its elements,
* Where they differ for each lc_ type.
*/
UNLOCK_LOCALE;
return MSVCRT_current_lc_all;
}
/* Default Locale: Special case handling */
if (!strlen(locale) || ((toupper(locale[0]) == 'C') && !locale[1]))
{
MSVCRT_current_lc_all[0] = 'C';
MSVCRT_current_lc_all[1] = '\0';
MSVCRT___lc_codepage = GetACP();
MSVCRT___lc_collate_cp = GetACP();
switch (category) {
case MSVCRT_LC_ALL:
lc_all = 1; /* Fall through all cases ... */
case MSVCRT_LC_COLLATE:
if (!lc_all) break;
case MSVCRT_LC_CTYPE:
/* Restore C locale ctype info */
__mb_cur_max = 1;
memcpy(MSVCRT_current_ctype, MSVCRT__ctype, sizeof(MSVCRT__ctype));
if (!lc_all) break;
case MSVCRT_LC_MONETARY:
if (!lc_all) break;
case MSVCRT_LC_NUMERIC:
if (!lc_all) break;
case MSVCRT_LC_TIME:
break;
}
UNLOCK_LOCALE;
return MSVCRT_current_lc_all;
}
/* Get locale elements */
haveLang = haveCountry = haveCP = 0;
memset(&lc,0,sizeof(lc));
next = strchr(locale,'_');
if (next && next != locale)
{
haveLang = 1;
memcpy(lc.search_language,locale,next-locale);
locale += next-locale+1;
}
next = strchr(locale,'.');
if (next)
{
haveCP = 1;
if (next == locale)
{
locale++;
lstrcpynA(lc.search_codepage, locale, MAX_ELEM_LEN);
}
else
{
if (haveLang)
{
haveCountry = 1;
memcpy(lc.search_country,locale,next-locale);
locale += next-locale+1;
}
else
{
haveLang = 1;
memcpy(lc.search_language,locale,next-locale);
locale += next-locale+1;
}
lstrcpynA(lc.search_codepage, locale, MAX_ELEM_LEN);
}
}
else
{
if (haveLang)
{
haveCountry = 1;
lstrcpynA(lc.search_country, locale, MAX_ELEM_LEN);
}
else
{
haveLang = 1;
lstrcpynA(lc.search_language, locale, MAX_ELEM_LEN);
}
}
if (haveCountry)
remap_synonym(lc.search_country);
if (haveCP && !haveCountry && !haveLang)
{
ERR(":Codepage only locale not implemented\n");
/* FIXME: Use default lang/country and skip locale_to_LCID()
* call below...
*/
UNLOCK_LOCALE;
return NULL;
}
lcid = MSVCRT_locale_to_LCID(&lc);
TRACE(":found LCID %d\n",lcid);
if (lcid == 0)
{
UNLOCK_LOCALE;
return NULL;
}
MSVCRT_current_lc_all_lcid = lcid;
_snprintf(MSVCRT_current_lc_all,MAX_LOCALE_LENGTH,"%s_%s.%s",
lc.found_language,lc.found_country,lc.found_codepage);
switch (category) {
case MSVCRT_LC_ALL:
lc_all = 1; /* Fall through all cases ... */
case MSVCRT_LC_COLLATE:
if (!lc_all) break;
case MSVCRT_LC_CTYPE:
msvcrt_set_ctype(atoi(lc.found_codepage),lcid);
if (!lc_all) break;
case MSVCRT_LC_MONETARY:
if (!lc_all) break;
case MSVCRT_LC_NUMERIC:
if (!lc_all) break;
case MSVCRT_LC_TIME:
break;
}
UNLOCK_LOCALE;
return MSVCRT_current_lc_all;
}
/*
* @unimplemented
*/
wchar_t* _wsetlocale(int category, const wchar_t* locale)
{
static wchar_t fake[] = {
'E','n','g','l','i','s','h','_','U','n','i','t','e','d',' ',
'S','t','a','t','e','s','.','1','2','5','2',0 };
TRACE("%d %S\n", category, locale);
return fake;
}
/*
locale "lang[_country[.code_page]]"
| ".code_page"
| ""
| NULL
*/
int parse_locale(const char *locale, char *lang, char *country, char *code_page)
{
while ( *locale != 0 && *locale != '.' && *locale != '_' )
{
*lang = *locale;
lang++;
locale++;
}
*lang = 0;
if ( *locale == '_' ) {
locale++;
while ( *locale != 0 && *locale != '.' )
{
*country = *locale;
country++;
locale++;
}
}
*country = 0;
if ( *locale == '.' ) {
locale++;
while ( *locale != 0 && *locale != '.' )
{
*code_page = *locale;
code_page++;
locale++;
}
}
*code_page = 0;
return 0;
}
const struct map_lcid2str {
short langid;
const char *langname;
const char *country;
} languages[]={
{0x0409,"English", "United States"},
{0x0809,"English", "United Kingdom"},
{0x0000,"Unknown", "Unknown"}
};
const struct map_cntr {
const char *abrev;
const char *country;
} abrev[] = {
{"britain", "united kingdom"},
{"england", "united kingdom"},
{"gbr", "united kingdom"},
{"great britain", "united kingdom"},
{"uk", "united kingdom"},
{"united kingdom", "united kingdom"},
{"united-kingdom", "united kingdom"},
{"america", "united states" },
{"united states", "united states"},
{"united-states", "united states"},
{"us", "united states"},
{"usa", "united states"}
};
struct lconv _lconv = {
".", // decimal_point
",", // thousands_sep
"", // grouping;
"DOL", // int_curr_symbol
"$", // currency_symbol
".", // mon_decimal_point
",", // mon_thousands_sep
"", // mon_grouping;
"+", // positive_sign
"-", // negative_sign
127, // int_frac_digits
127, // frac_digits
127, // p_cs_precedes
127, // p_sep_by_space
127, // n_cs_precedes
127, // n_sep_by_space
127, // p_sign_posn;
127 // n_sign_posn;
};
/*
* @implemented
*/
struct lconv *localeconv(void)
{
return (struct lconv *) &_lconv;
}
/*********************************************************************
* _setmbcp (MSVCRT.@)
* @implemented
*/
int CDECL _setmbcp(int cp)
{
int newcp;
CPINFO cpi;
BYTE *bytes;
WORD chartypes[256];
WORD *curr_type;
char bufA[256];
WCHAR bufW[256];
int charcount;
int ret;
int i;
TRACE("_setmbcp %d\n",cp);
switch (cp)
{
case _MB_CP_ANSI:
newcp = GetACP();
break;
case _MB_CP_OEM:
newcp = GetOEMCP();
break;
case _MB_CP_LOCALE:
newcp = MSVCRT___lc_codepage;
break;
case _MB_CP_SBCS:
newcp = 20127; /* ASCII */
break;
default:
newcp = cp;
break;
}
if (!GetCPInfo(newcp, &cpi))
{
ERR("Codepage %d not found\n", newcp);
__set_errno(EINVAL);
return -1;
}
/* setup the _mbctype */
memset(_mbctype, 0, sizeof(_mbctype));
bytes = cpi.LeadByte;
while (bytes[0] || bytes[1])
{
for (i = bytes[0]; i <= bytes[1]; i++)
_mbctype[i + 1] |= _M1;
bytes += 2;
}
if (cpi.MaxCharSize > 1)
{
/* trail bytes not available through kernel32 but stored in a structure in msvcrt */
struct cp_extra_info_t *cpextra = g_cpextrainfo;
g_mbcp_is_multibyte = 1;
while (TRUE)
{
if (cpextra->cp == 0 || cpextra->cp == newcp)
{
if (cpextra->cp == 0)
ERR("trail bytes data not available for DBCS codepage %d - assuming all bytes\n", newcp);
bytes = cpextra->TrailBytes;
while (bytes[0] || bytes[1])
{
for (i = bytes[0]; i <= bytes[1]; i++)
_mbctype[i + 1] |= _M2;
bytes += 2;
}
break;
}
cpextra++;
}
}
else
g_mbcp_is_multibyte = 0;
/* we can't use GetStringTypeA directly because we don't have a locale - only a code page
*/
charcount = 0;
for (i = 0; i < 256; i++)
if (!(_mbctype[i + 1] & _M1))
bufA[charcount++] = i;
ret = MultiByteToWideChar(newcp, 0, bufA, charcount, bufW, charcount);
if (ret != charcount)
ERR("MultiByteToWideChar of chars failed for cp %d, ret=%d (exp %d), error=%d\n", newcp, ret, charcount, GetLastError());
GetStringTypeW(CT_CTYPE1, bufW, charcount, chartypes);
curr_type = chartypes;
for (i = 0; i < 256; i++)
if (!(_mbctype[i + 1] & _M1))
{
if ((*curr_type) & C1_UPPER)
_mbctype[i + 1] |= _SBUP;
if ((*curr_type) & C1_LOWER)
_mbctype[i + 1] |= _SBLOW;
curr_type++;
}
if (newcp == 932) /* CP932 only - set _MP and _MS */
{
/* On Windows it's possible to calculate the _MP and _MS from CT_CTYPE1
* and CT_CTYPE3. But as of Wine 0.9.43 we return wrong values what makes
* it hard. As this is set only for codepage 932 we hardcode it what gives
* also faster execution.
*/
for (i = 161; i <= 165; i++)
_mbctype[i + 1] |= _MP;
for (i = 166; i <= 223; i++)
_mbctype[i + 1] |= _MS;
}
MSVCRT___lc_collate_cp = MSVCRT___lc_codepage = newcp;
TRACE("(%d) -> %d\n", cp, MSVCRT___lc_codepage);
return 0;
}
/*********************************************************************
* __lc_collate_cp (MSVCRT.@)
*
* @unimplemented
*/
void __lc_collate_cp(int cp)
{
FIXME("__lc_collate_cp - stub\n");
return;
}
/*********************************************************************
* __lc_handle (MSVCRT.@)
*
* @unimplemented
*/
void __lc_handle(void)
{
FIXME("__lc_handle - stub\n");
return;
}
/*********************************************************************
* __lc_codepage (MSVCRT.@)
*
* @unimplemented
*/
void __lc_codepage(void)
{
FIXME("__lc_codepage - stub\n");
return;
}
/*********************************************************************
* _Gettnames (MSVCRT.@)
*/
void *_Gettnames(void)
{
FIXME("(void), stub!\n");
return NULL;
}
/*********************************************************************
* __lconv_init (MSVCRT.@)
*/
void __lconv_init(void)
{
char Char = (char) UCHAR_MAX;
TRACE("__lconv_init()\n");
_lconv.int_frac_digits = Char;
_lconv.frac_digits = Char;
_lconv.p_sep_by_space = _lconv.n_sep_by_space = Char;
_lconv.p_cs_precedes = _lconv.n_cs_precedes = Char;
_lconv.p_sign_posn = _lconv.n_sign_posn = Char;
}
/*********************************************************************
* _Strftime (MSVCRT.@)
*/
const char* _Strftime(char *out, unsigned int len, const char *fmt,
const void *tm, void *foo)
{
/* FIXME: */
FIXME("(%p %d %s %p %p) stub\n", out, len, fmt, tm, foo);
return "";
}
/*********************************************************************
* _Getdays (MSVCRT.@)
*/
const char* _Getdays(void)
{
static const char *MSVCRT_days = ":Sun:Sunday:Mon:Monday:Tue:Tuesday:Wed:"
"Wednesday:Thu:Thursday:Fri:Friday:Sat:Saturday";
/* FIXME: Use locale */
FIXME("(void) semi-stub\n");
return MSVCRT_days;
}
/*********************************************************************
* _Getmonths (MSVCRT.@)
*/
const char* _Getmonths(void)
{
static const char *MSVCRT_months = ":Jan:January:Feb:February:Mar:March:Apr:"
"April:May:May:Jun:June:Jul:July:Aug:August:Sep:September:Oct:"
"October:Nov:November:Dec:December";
/* FIXME: Use locale */
FIXME("(void) semi-stub\n");
return MSVCRT_months;
}
/*********************************************************************
* __crtLCMapStringA (MSVCRT.@)
*/
int __crtLCMapStringA(
LCID lcid, DWORD mapflags, const char* src, int srclen, char* dst,
int dstlen, unsigned int codepage, int xflag
) {
TRACE("(lcid %lx, flags %lx, %s(%d), %p(%d), %x, %d), partial stub!\n",
lcid,mapflags,src,srclen,dst,dstlen,codepage,xflag);
/* FIXME: A bit incorrect. But msvcrt itself just converts its
* arguments to wide strings and then calls LCMapStringW
*/
return LCMapStringA(lcid,mapflags,src,srclen,dst,dstlen);
}
/*********************************************************************
* __crtLCMapStringW (MSVCRT.@)
*/
int __crtLCMapStringW(
LCID lcid, DWORD mapflags, LPCWSTR src, int srclen, LPWSTR dst,
int dstlen, unsigned int codepage, int xflag
) {
TRACE("(lcid %lx, flags %lx, %s(%d), %p(%d), %x, %d), partial stub!\n",
lcid,mapflags,src,srclen,dst,dstlen,codepage,xflag);
return LCMapStringW(lcid,mapflags,src,srclen,dst,dstlen);
}
int CDECL _getmbcp(void)
{
return MSVCRT___lc_codepage;
}
/*********************************************************************
* ___unguarded_readlc_active_add_func (MSVCRT.@)
*/
unsigned int * CDECL ___unguarded_readlc_active_add_func(void)
{
return &__unguarded_readlc_active;
}
/*********************************************************************
* ___setlc_active_func (MSVCRT.@)
*/
unsigned int CDECL ___setlc_active_func(void)
{
return __setlc_active;
}
/*********************************************************************
* __crtGetStringTypeW(MSVCRT.@)
*
* This function was accepting different number of arguments in older
* versions of msvcrt.
*/
BOOL CDECL __crtGetStringTypeW(DWORD unk, DWORD type,
wchar_t *buffer, int len, WORD *out)
{
FIXME("(unk %x, type %x, wstr %p(%d), %p) partial stub\n",
unk, type, buffer, len, out);
return GetStringTypeW(type, buffer, len, out);
}

10
lib/sdk/crt/math/abs.c Normal file
View file

@ -0,0 +1,10 @@
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
/*
* @implemented
*/
int
abs(int j)
{
return j<0 ? -j : j;
}

28
lib/sdk/crt/math/acos.c Normal file
View file

@ -0,0 +1,28 @@
/* Math functions for i387.
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by John C. Bowman <bowman@ipp-garching.mpg.de>, 1995.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <math.h>
double acos(double __x)
{
return atan2(sqrt(1.0 - __x * __x), __x);
}

View file

@ -0,0 +1,7 @@
/* $Id$
*
*/
int _adjust_fdiv = 0;
/* EOF */

View file

@ -0,0 +1,28 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of alldiv
* FILE: lib/sdk/crt/math/amd64/alldiv.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
#include <ndk/amd64/asm.h>
/* DATA *********************************************************************/
PUBLIC _fltused
_fltused:
.long 0x9875
/* FUNCTIONS ****************************************************************/
.code64
.proc alldiv
UNIMPLEMENTED alldiv
ret
.endp alldiv

View file

@ -0,0 +1,21 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of atan
* FILE: lib/sdk/crt/math/amd64/atan.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
#include <ndk/amd64/asm.h>
/* FUNCTIONS ****************************************************************/
.code64
PUBLIC atan
atan:
UNIMPLEMENTED atan
ret

View file

@ -0,0 +1,21 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of atan2
* FILE: lib/sdk/crt/math/amd64/atan2.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
#include <ndk/amd64/asm.h>
/* FUNCTIONS ****************************************************************/
.code64
PUBLIC atan2
atan2:
UNIMPLEMENTED atan2
ret

View file

@ -0,0 +1,22 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of ceil
* FILE: lib/sdk/crt/math/amd64/ceil.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
#include <ndk/amd64/asm.h>
/* FUNCTIONS ****************************************************************/
.code64
PUBLIC ceil
ceil:
UNIMPLEMENTED ceil
ret

View file

@ -0,0 +1,40 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of tan
* FILE: lib/sdk/crt/math/amd64/ceilf.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
#include <ndk/amd64/asm.h>
/* FUNCTIONS ****************************************************************/
.code64
PUBLIC ceilf
ceilf:
/* Put parameter on the stack */
movss [rsp - 0x10], xmm0
fld dword ptr [rsp]
/* Change fpu control word to round up */
fstcw [rsp - 0x10]
mov eax, [rsp - 0x10]
or eax, 0x00800
and eax, 0x0fbff
mov [rsp - 0x08], eax
fldcw [rsp - 0x08]
/* Round to integer */
frndint
/* Restore fpu control word */
fldcw [rsp - 0x10]
fstp dword ptr [rsp - 0x10]
movss xmm0, [rsp - 0x10]
ret

View file

@ -0,0 +1,22 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of exp
* FILE: lib/sdk/crt/math/amd64/exp.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
#include <ndk/amd64/asm.h>
/* FUNCTIONS ****************************************************************/
.code64
PUBLIC exp
exp:
UNIMPLEMENTED exp
ret

View file

@ -0,0 +1,22 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of fabs
* FILE: lib/sdk/crt/math/amd64/fabs.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
#include <ndk/amd64/asm.h>
/* FUNCTIONS ****************************************************************/
.code64
PUBLIC fabs
fabs:
UNIMPLEMENTED fabs
ret

View file

@ -0,0 +1,21 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of floor
* FILE: lib/sdk/crt/math/amd64/floor.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
#include <ndk/amd64/asm.h>
/* FUNCTIONS ****************************************************************/
.code64
PUBLIC floor
floor:
UNIMPLEMENTED floor
ret

View file

@ -0,0 +1,40 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of tan
* FILE: lib/sdk/crt/math/amd64/floorf.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
#include <ndk/amd64/asm.h>
/* FUNCTIONS ****************************************************************/
.code64
PUBLIC floorf
floorf:
/* Put parameter on the stack */
movss [rsp - 0x10], xmm0
fld dword ptr [rsp]
/* Change fpu control word to round down */
fstcw [rsp - 0x10]
mov eax, [rsp - 0x10]
or eax, 0x00400
and eax, 0x0f7ff
mov [rsp - 0x08], eax
fldcw [rsp - 0x08]
/* Round to integer */
frndint
/* Restore fpu control word */
fldcw [rsp - 0x10]
fstp dword ptr [rsp - 0x10]
movss xmm0, [rsp - 0x10]
ret

View file

@ -0,0 +1,19 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of fmod
* FILE: lib/sdk/crt/math/amd64/fmod.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
#include <ndk/amd64/asm.h>
/* DATA *********************************************************************/
PUBLIC fmod
fmod:
UNIMPLEMENTED fmod
ret

View file

@ -0,0 +1,19 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of fmodf
* FILE: lib/sdk/crt/math/amd64/fmodf.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
#include <ndk/amd64/asm.h>
/* DATA *********************************************************************/
PUBLIC fmodf
fmodf:
UNIMPLEMENTED fmodf
ret

View file

@ -0,0 +1,19 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of ldexp
* FILE: lib/sdk/crt/math/amd64/ldexp.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
#include <ndk/amd64/asm.h>
/* DATA *********************************************************************/
PUBLIC ldexp
ldexp:
UNIMPLEMENTED ldexp
ret

View file

@ -0,0 +1,19 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of log
* FILE: lib/sdk/crt/math/amd64/log.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
#include <ndk/amd64/asm.h>
/* DATA *********************************************************************/
PUBLIC log
log:
UNIMPLEMENTED log
ret

View file

@ -0,0 +1,20 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of log10
* FILE: lib/sdk/crt/math/amd64/log10.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
#include <ndk/amd64/asm.h>
/* DATA *********************************************************************/
PUBLIC log10
log10:
UNIMPLEMENTED log10
ret

View file

@ -0,0 +1,20 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of pow
* FILE: lib/sdk/crt/math/amd64/pow.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
#include <ndk/amd64/asm.h>
/* DATA *********************************************************************/
PUBLIC pow
pow:
UNIMPLEMENTED pow
ret

View file

@ -0,0 +1,19 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of sqrt
* FILE: lib/sdk/crt/math/amd64/sqrt.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
#include <ndk/amd64/asm.h>
/* DATA *********************************************************************/
PUBLIC sqrt
sqrt:
UNIMPLEMENTED sqrt
ret

View file

@ -0,0 +1,19 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of tan
* FILE: lib/sdk/crt/math/amd64/sqrtf.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
#include <ndk/amd64/asm.h>
/* DATA *********************************************************************/
PUBLIC sqrtf
sqrtf:
sqrtss xmm0, xmm0
ret

View file

@ -0,0 +1,19 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* PURPOSE: Implementation of tan
* FILE: lib/sdk/crt/math/amd64/tan.S
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
/* INCLUDES ******************************************************************/
#include <reactos/asm.h>
#include <ndk/amd64/asm.h>
/* DATA *********************************************************************/
PUBLIC tan
tan:
UNIMPLEMENTED tan
ret

28
lib/sdk/crt/math/asin.c Normal file
View file

@ -0,0 +1,28 @@
/* Math functions for i387.
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by John C. Bowman <bowman@ipp-garching.mpg.de>, 1995.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <math.h>
double asin(double __x)
{
return atan2(__x, sqrt(1.0 - __x * __x));
}

14
lib/sdk/crt/math/cabs.c Normal file
View file

@ -0,0 +1,14 @@
#include <math.h>
/*
* @implemented
*/
double _cabs( struct _complex z )
{
return sqrt( z.x*z.x + z.y*z.y );
// return hypot(z.x,z.y);
}

89
lib/sdk/crt/math/cos.c Normal file
View file

@ -0,0 +1,89 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS CRT
* FILE: lib/crt/math/cos.c
* PURPOSE: Generic C Implementation of cos
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
*/
#define PRECISION 9
#define M_PI 3.141592653589793238462643
static double cos_off_tbl[] = {0.0, -M_PI/2., 0, -M_PI/2.};
static double cos_sign_tbl[] = {1,-1,-1,1};
double
cos(double x)
{
int quadrant;
double x2, result;
/* Calculate the quadrant */
quadrant = x * (2./M_PI);
/* Get offset inside quadrant */
x = x - quadrant * (M_PI/2.);
/* Normalize quadrant to [0..3] */
quadrant = quadrant & 0x3;
/* Fixup value for the generic function */
x += cos_off_tbl[quadrant];
/* Calculate the negative of the square of x */
x2 = - (x * x);
/* This is an unrolled taylor series using <PRECISION> iterations
* Example with 4 iterations:
* result = 1 - x^2/2! + x^4/4! - x^6/6! + x^8/8!
* To save multiplications and to keep the precision high, it's performed
* like this:
* result = 1 - x^2 * (1/2! - x^2 * (1/4! - x^2 * (1/6! - x^2 * (1/8!))))
*/
/* Start with 0, compiler will optimize this away */
result = 0;
#if (PRECISION >= 10)
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18*19*20);
result *= x2;
#endif
#if (PRECISION >= 9)
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16*17*18);
result *= x2;
#endif
#if (PRECISION >= 8)
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14*15*16);
result *= x2;
#endif
#if (PRECISION >= 7)
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12*13*14);
result *= x2;
#endif
#if (PRECISION >= 6)
result += 1./(1.*2*3*4*5*6*7*8*9*10*11*12);
result *= x2;
#endif
#if (PRECISION >= 5)
result += 1./(1.*2*3*4*5*6*7*8*9*10);
result *= x2;
#endif
result += 1./(1.*2*3*4*5*6*7*8);
result *= x2;
result += 1./(1.*2*3*4*5*6);
result *= x2;
result += 1./(1.*2*3*4);
result *= x2;
result += 1./(1.*2);
result *= x2;
result += 1;
/* Apply correct sign */
result *= cos_sign_tbl[quadrant];
return result;
}

11
lib/sdk/crt/math/cosf.c Normal file
View file

@ -0,0 +1,11 @@
/**
* 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 <math.h>
float cosf(float _X)
{
return ((float)cos((double)_X));
}

12
lib/sdk/crt/math/cosh.c Normal file
View file

@ -0,0 +1,12 @@
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <math.h>
/*
* @implemented
*/
double cosh(double x)
{
const double ebig = exp(fabs(x));
return (ebig + 1.0/ebig) / 2.0;
}

27
lib/sdk/crt/math/div.c Normal file
View file

@ -0,0 +1,27 @@
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <precomp.h>
/*
* @implemented
*/
div_t
div(int num, int denom)
{
div_t r;
if (num > 0 && denom < 0) {
num = -num;
denom = -denom;
}
r.quot = num / denom;
r.rem = num % denom;
if (num < 0 && denom > 0)
{
if (r.rem > 0)
{
r.quot++;
r.rem -= denom;
}
}
return r;
}

View file

@ -0,0 +1,89 @@
#include <precomp.h>
#include <math.h>
/* The following functions are likely workarounds for the pentium fdiv bug */
void __stdcall _adj_fdiv_m32( unsigned int arg )
{
FIXME("_adj_fdiv_m32 stub\n");
}
void __stdcall _adj_fdiv_m32i( int arg )
{
FIXME("_adj_fdiv_m32i stub\n");
}
void __stdcall _adj_fdiv_m64( unsigned __int64 arg )
{
FIXME("_adj_fdiv_m64 stub\n");
}
void _adj_fdiv_r(void)
{
FIXME("_adj_fdiv_r stub\n");
}
void __stdcall _adj_fdivr_m32( unsigned int arg )
{
FIXME("_adj_fdivr_m32i stub\n");
}
void __stdcall _adj_fdivr_m32i( int arg )
{
FIXME("_adj_fdivr_m32i stub\n");
}
void __stdcall _adj_fdivr_m64( unsigned __int64 arg )
{
FIXME("_adj_fdivr_m64 stub\n");
}
void _adj_fpatan(void)
{
FIXME("_adj_fpatan stub\n");
}
void __stdcall _adj_fdiv_m16i( short arg )
{
FIXME("_adj_fdiv_m16i stub\n");
}
void __stdcall _adj_fdivr_m16i( short arg )
{
FIXME("_adj_fdivr_m16i stub\n");
}
void _adj_fprem(void)
{
FIXME("_adj_fprem stub\n");
}
void _adj_fprem1(void)
{
FIXME("_adj_fprem1 stub\n");
}
void _adj_fptan(void)
{
FIXME("_adj_fptan stub\n");
}
void _safe_fdiv(void)
{
FIXME("_safe_fdiv stub\n");
}
void _safe_fdivr(void)
{
FIXME("_safe_fdivr stub\n");
}
void _safe_fprem(void)
{
FIXME("_safe_fprem stub\n");
}
void _safe_fprem1(void)
{
FIXME("_safe_fprem1 stub\n");
}

29
lib/sdk/crt/math/frexp.c Normal file
View file

@ -0,0 +1,29 @@
#include <math.h>
#include <stdlib.h>
#include <internal/ieee.h>
/*
* @implemented
*/
double
frexp(double __x, int *exptr)
{
union
{
double* __x;
double_s* x;
} x;
x.__x = &__x;
if ( exptr != NULL )
*exptr = x.x->exponent - 0x3FE;
x.x->exponent = 0x3FE;
return __x;
}

View file

@ -0,0 +1,6 @@
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <internal/ieee.h>
#undef _HUGE
double_s _HUGE = { 0x00000, 0x00000, 0x7ff, 0x0 };

98
lib/sdk/crt/math/hypot.c Normal file
View file

@ -0,0 +1,98 @@
/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
/*
* hypot() function for DJGPP.
*
* hypot() computes sqrt(x^2 + y^2). The problem with the obvious
* naive implementation is that it might fail for very large or
* very small arguments. For instance, for large x or y the result
* might overflow even if the value of the function should not,
* because squaring a large number might trigger an overflow. For
* very small numbers, their square might underflow and will be
* silently replaced by zero; this won't cause an exception, but might
* have an adverse effect on the accuracy of the result.
*
* This implementation tries to avoid the above pitfals, without
* inflicting too much of a performance hit.
*
*/
#include <precomp.h>
/* Approximate square roots of DBL_MAX and DBL_MIN. Numbers
between these two shouldn't neither overflow nor underflow
when squared. */
#define __SQRT_DBL_MAX 1.3e+154
#define __SQRT_DBL_MIN 2.3e-162
/*
* @implemented
*/
double
_hypot(double x, double y)
{
double abig = fabs(x), asmall = fabs(y);
double ratio;
/* Make abig = max(|x|, |y|), asmall = min(|x|, |y|). */
if (abig < asmall)
{
double temp = abig;
abig = asmall;
asmall = temp;
}
/* Trivial case. */
if (asmall == 0.)
return abig;
/* Scale the numbers as much as possible by using its ratio.
For example, if both ABIG and ASMALL are VERY small, then
X^2 + Y^2 might be VERY inaccurate due to loss of
significant digits. Dividing ASMALL by ABIG scales them
to a certain degree, so that accuracy is better. */
if ((ratio = asmall / abig) > __SQRT_DBL_MIN && abig < __SQRT_DBL_MAX)
return abig * sqrt(1.0 + ratio*ratio);
else
{
/* Slower but safer algorithm due to Moler and Morrison. Never
produces any intermediate result greater than roughly the
larger of X and Y. Should converge to machine-precision
accuracy in 3 iterations. */
double r = ratio*ratio, t, s, p = abig, q = asmall;
do {
t = 4. + r;
if (t == 4.)
break;
s = r / t;
p += 2. * s * p;
q *= s;
r = (q / p) * (q / p);
} while (1);
return p;
}
}
#ifdef TEST
#include <msvcrt/stdio.h>
int
main(void)
{
printf("hypot(3, 4) =\t\t\t %25.17e\n", _hypot(3., 4.));
printf("hypot(3*10^150, 4*10^150) =\t %25.17g\n", _hypot(3.e+150, 4.e+150));
printf("hypot(3*10^306, 4*10^306) =\t %25.17g\n", _hypot(3.e+306, 4.e+306));
printf("hypot(3*10^-320, 4*10^-320) =\t %25.17g\n",_hypot(3.e-320, 4.e-320));
printf("hypot(0.7*DBL_MAX, 0.7*DBL_MAX) =%25.17g\n",_hypot(0.7*DBL_MAX, 0.7*DBL_MAX));
printf("hypot(DBL_MAX, 1.0) =\t\t %25.17g\n", _hypot(DBL_MAX, 1.0));
printf("hypot(1.0, DBL_MAX) =\t\t %25.17g\n", _hypot(1.0, DBL_MAX));
printf("hypot(0.0, DBL_MAX) =\t\t %25.17g\n", _hypot(0.0, DBL_MAX));
return 0;
}
#endif

View file

@ -0,0 +1,224 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* PURPOSE: Run-Time Library
* FILE: lib/rtl/i386/alldiv_asm.S
* PROGRAMER: Alex Ionescu (alex@relsoft.net)
*
* Copyright (C) 2002 Michael Ringgaard.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS 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 OWNER OR CONTRIBUTORS 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.
*/
.globl __alldiv
.globl __fltused
/* DATA ********************************************************************/
__fltused:
.long 0x9875
.intel_syntax noprefix
/* FUNCTIONS ***************************************************************/
//
// lldiv - signed long divide
//
// Purpose:
// Does a signed long divide of the arguments. Arguments are
// not changed.
//
// Entry:
// Arguments are passed on the stack:
// 1st pushed: divisor (QWORD)
// 2nd pushed: dividend (QWORD)
//
// Exit:
// EDX:EAX contains the quotient (dividend/divisor)
// NOTE: this routine removes the parameters from the stack.
//
// Uses:
// ECX
//
__alldiv:
push edi
push esi
push ebx
// Set up the local stack and save the index registers. When this is done
// the stack frame will look as follows (assuming that the expression a/b will
// generate a call to lldiv(a, b)):
//
// -----------------
// | |
// |---------------|
// | |
// |--divisor (b)--|
// | |
// |---------------|
// | |
// |--dividend (a)-|
// | |
// |---------------|
// | return addr** |
// |---------------|
// | EDI |
// |---------------|
// | ESI |
// |---------------|
// ESP---->| EBX |
// -----------------
//
#define DVNDLO [esp + 16] // stack address of dividend (a)
#define DVNDHI [esp + 20] // stack address of dividend (a)
#define DVSRLO [esp + 24] // stack address of divisor (b)
#define DVSRHI [esp + 28] // stack address of divisor (b)
// Determine sign of the result (edi = 0 if result is positive, non-zero
// otherwise) and make operands positive.
xor edi,edi // result sign assumed positive
mov eax,DVNDHI // hi word of a
or eax,eax // test to see if signed
jge short L1 // skip rest if a is already positive
inc edi // complement result sign flag
mov edx,DVNDLO // lo word of a
neg eax // make a positive
neg edx
sbb eax,0
mov DVNDHI,eax // save positive value
mov DVNDLO,edx
L1:
mov eax,DVSRHI // hi word of b
or eax,eax // test to see if signed
jge short L2 // skip rest if b is already positive
inc edi // complement the result sign flag
mov edx,DVSRLO // lo word of a
neg eax // make b positive
neg edx
sbb eax,0
mov DVSRHI,eax // save positive value
mov DVSRLO,edx
L2:
//
// Now do the divide. First look to see if the divisor is less than 4194304K.
// If so, then we can use a simple algorithm with word divides, otherwise
// things get a little more complex.
//
// NOTE - eax currently contains the high order word of DVSR
//
or eax,eax // check to see if divisor < 4194304K
jnz short L3 // nope, gotta do this the hard way
mov ecx,DVSRLO // load divisor
mov eax,DVNDHI // load high word of dividend
xor edx,edx
div ecx // eax <- high order bits of quotient
mov ebx,eax // save high bits of quotient
mov eax,DVNDLO // edx:eax <- remainder:lo word of dividend
div ecx // eax <- low order bits of quotient
mov edx,ebx // edx:eax <- quotient
jmp short L4 // set sign, restore stack and return
//
// Here we do it the hard way. Remember, eax contains the high word of DVSR
//
L3:
mov ebx,eax // ebx:ecx <- divisor
mov ecx,DVSRLO
mov edx,DVNDHI // edx:eax <- dividend
mov eax,DVNDLO
L5:
shr ebx,1 // shift divisor right one bit
rcr ecx,1
shr edx,1 // shift dividend right one bit
rcr eax,1
or ebx,ebx
jnz short L5 // loop until divisor < 4194304K
div ecx // now divide, ignore remainder
mov esi,eax // save quotient
//
// We may be off by one, so to check, we will multiply the quotient
// by the divisor and check the result against the orignal dividend
// Note that we must also check for overflow, which can occur if the
// dividend is close to 2**64 and the quotient is off by 1.
//
mul dword ptr DVSRHI // QUOT * DVSRHI
mov ecx,eax
mov eax,DVSRLO
mul esi // QUOT * DVSRLO
add edx,ecx // EDX:EAX = QUOT * DVSR
jc short L6 // carry means Quotient is off by 1
//
// do long compare here between original dividend and the result of the
// multiply in edx:eax. If original is larger or equal, we are ok, otherwise
// subtract one (1) from the quotient.
//
cmp edx,DVNDHI // compare hi words of result and original
ja short L6 // if result > original, do subtract
jb short L7 // if result < original, we are ok
cmp eax,DVNDLO // hi words are equal, compare lo words
jbe short L7 // if less or equal we are ok, else subtract
L6:
dec esi // subtract 1 from quotient
L7:
xor edx,edx // edx:eax <- quotient
mov eax,esi
//
// Just the cleanup left to do. edx:eax contains the quotient. Set the sign
// according to the save value, cleanup the stack, and return.
//
L4:
dec edi // check to see if result is negative
jnz short L8 // if EDI == 0, result should be negative
neg edx // otherwise, negate the result
neg eax
sbb edx,0
//
// Restore the saved registers and return.
//
L8:
pop ebx
pop esi
pop edi
ret 16

Some files were not shown because too many files have changed in this diff Show more