mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-03-15 00:21:50 +01:00
Merged DMD 1.042.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
|
||||
// Copyright (c) 1999-2006 by Digital Mars
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// www.digitalmars.com
|
||||
|
||||
177
dmd/root/async.c
Normal file
177
dmd/root/async.c
Normal file
@@ -0,0 +1,177 @@
|
||||
|
||||
#define _MT 1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <process.h>
|
||||
|
||||
#include "root.h"
|
||||
#include "rmem.h"
|
||||
|
||||
static unsigned __stdcall startthread(void *p);
|
||||
|
||||
struct FileData
|
||||
{
|
||||
File *file;
|
||||
int result;
|
||||
HANDLE event;
|
||||
};
|
||||
|
||||
struct AsyncRead
|
||||
{
|
||||
static AsyncRead *create(size_t nfiles);
|
||||
void addFile(File *file);
|
||||
void start();
|
||||
int read(size_t i);
|
||||
static void dispose(AsyncRead *);
|
||||
|
||||
HANDLE hThread;
|
||||
|
||||
size_t filesdim;
|
||||
size_t filesmax;
|
||||
FileData files[1];
|
||||
};
|
||||
|
||||
|
||||
AsyncRead *AsyncRead::create(size_t nfiles)
|
||||
{
|
||||
AsyncRead *aw = (AsyncRead *)mem.calloc(1, sizeof(AsyncRead) +
|
||||
(nfiles - 1) * sizeof(FileData));
|
||||
aw->filesmax = nfiles;
|
||||
return aw;
|
||||
}
|
||||
|
||||
void AsyncRead::addFile(File *file)
|
||||
{
|
||||
//printf("addFile(file = %p)\n", file);
|
||||
//printf("filesdim = %d, filesmax = %d\n", filesdim, filesmax);
|
||||
assert(filesdim < filesmax);
|
||||
files[filesdim].file = file;
|
||||
files[filesdim].event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
ResetEvent(files[filesdim].event);
|
||||
filesdim++;
|
||||
}
|
||||
|
||||
void AsyncRead::start()
|
||||
{
|
||||
unsigned threadaddr;
|
||||
hThread = (HANDLE) _beginthreadex(NULL,
|
||||
0,
|
||||
&startthread,
|
||||
this,
|
||||
0,
|
||||
(unsigned *)&threadaddr);
|
||||
|
||||
if (hThread)
|
||||
{
|
||||
SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
int AsyncRead::read(size_t i)
|
||||
{
|
||||
FileData *f = &files[i];
|
||||
WaitForSingleObject(f->event, INFINITE);
|
||||
Sleep(0); // give up time slice
|
||||
return f->result;
|
||||
}
|
||||
|
||||
void AsyncRead::dispose(AsyncRead *aw)
|
||||
{
|
||||
delete aw;
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned __stdcall startthread(void *p)
|
||||
{
|
||||
AsyncRead *aw = (AsyncRead *)p;
|
||||
|
||||
for (size_t i = 0; i < aw->filesdim; i++)
|
||||
{ FileData *f = &aw->files[i];
|
||||
|
||||
f->result = f->file->read();
|
||||
SetEvent(f->event);
|
||||
}
|
||||
_endthreadex(EXIT_SUCCESS);
|
||||
return EXIT_SUCCESS; // if skidding
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "root.h"
|
||||
#include "rmem.h"
|
||||
|
||||
struct FileData
|
||||
{
|
||||
File *file;
|
||||
int result;
|
||||
//HANDLE event;
|
||||
};
|
||||
|
||||
struct AsyncRead
|
||||
{
|
||||
static AsyncRead *create(size_t nfiles);
|
||||
void addFile(File *file);
|
||||
void start();
|
||||
int read(size_t i);
|
||||
static void dispose(AsyncRead *);
|
||||
|
||||
//HANDLE hThread;
|
||||
|
||||
size_t filesdim;
|
||||
size_t filesmax;
|
||||
FileData files[1];
|
||||
};
|
||||
|
||||
|
||||
AsyncRead *AsyncRead::create(size_t nfiles)
|
||||
{
|
||||
AsyncRead *aw = (AsyncRead *)mem.calloc(1, sizeof(AsyncRead) +
|
||||
(nfiles - 1) * sizeof(FileData));
|
||||
aw->filesmax = nfiles;
|
||||
return aw;
|
||||
}
|
||||
|
||||
void AsyncRead::addFile(File *file)
|
||||
{
|
||||
//printf("addFile(file = %p)\n", file);
|
||||
//printf("filesdim = %d, filesmax = %d\n", filesdim, filesmax);
|
||||
assert(filesdim < filesmax);
|
||||
files[filesdim].file = file;
|
||||
//files[filesdim].event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
//ResetEvent(files[filesdim].event);
|
||||
filesdim++;
|
||||
}
|
||||
|
||||
void AsyncRead::start()
|
||||
{
|
||||
}
|
||||
|
||||
int AsyncRead::read(size_t i)
|
||||
{
|
||||
FileData *f = &files[i];
|
||||
f->result = f->file->read();
|
||||
return f->result;
|
||||
}
|
||||
|
||||
void AsyncRead::dispose(AsyncRead *aw)
|
||||
{
|
||||
delete aw;
|
||||
}
|
||||
|
||||
#endif
|
||||
33
dmd/root/async.h
Normal file
33
dmd/root/async.h
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
// Copyright (c) 2009-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef ASYNC_H
|
||||
#define ASYNC_H
|
||||
|
||||
#if __DMC__
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
/*******************
|
||||
* Simple interface to read files asynchronously in another
|
||||
* thread.
|
||||
*/
|
||||
|
||||
struct AsyncRead
|
||||
{
|
||||
static AsyncRead *create(size_t nfiles);
|
||||
void addFile(File *file);
|
||||
void start();
|
||||
int read(size_t i);
|
||||
static void dispose(AsyncRead *);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
754
dmd/root/port.c
Normal file
754
dmd/root/port.c
Normal file
@@ -0,0 +1,754 @@
|
||||
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
|
||||
#include "port.h"
|
||||
|
||||
#if __DMC__
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <fp.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
double Port::nan = NAN;
|
||||
double Port::infinity = INFINITY;
|
||||
double Port::dbl_max = DBL_MAX;
|
||||
double Port::dbl_min = DBL_MIN;
|
||||
|
||||
int Port::isNan(double r)
|
||||
{
|
||||
return ::isnan(r);
|
||||
}
|
||||
|
||||
int Port::isNan(long double r)
|
||||
{
|
||||
return ::isnan(r);
|
||||
}
|
||||
|
||||
int Port::isSignallingNan(double r)
|
||||
{
|
||||
/* A signalling NaN is a NaN with 0 as the most significant bit of
|
||||
* its significand, which is bit 51 of 0..63 for 64 bit doubles.
|
||||
*/
|
||||
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
|
||||
}
|
||||
|
||||
int Port::isSignallingNan(long double r)
|
||||
{
|
||||
/* A signalling NaN is a NaN with 0 as the most significant bit of
|
||||
* its significand, which is bit 62 of 0..79 for 80 bit reals.
|
||||
*/
|
||||
return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40);
|
||||
}
|
||||
|
||||
int Port::isFinite(double r)
|
||||
{
|
||||
return ::isfinite(r);
|
||||
}
|
||||
|
||||
int Port::isInfinity(double r)
|
||||
{
|
||||
return (::fpclassify(r) == FP_INFINITE);
|
||||
}
|
||||
|
||||
int Port::Signbit(double r)
|
||||
{
|
||||
return ::signbit(r);
|
||||
}
|
||||
|
||||
double Port::floor(double d)
|
||||
{
|
||||
return ::floor(d);
|
||||
}
|
||||
|
||||
double Port::pow(double x, double y)
|
||||
{
|
||||
return ::pow(x, y);
|
||||
}
|
||||
|
||||
unsigned long long Port::strtoull(const char *p, char **pend, int base)
|
||||
{
|
||||
return ::strtoull(p, pend, base);
|
||||
}
|
||||
|
||||
char *Port::ull_to_string(char *buffer, ulonglong ull)
|
||||
{
|
||||
sprintf(buffer, "%llu", ull);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull)
|
||||
{
|
||||
swprintf(buffer, sizeof(ulonglong) * 3 + 1, L"%llu", ull);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
double Port::ull_to_double(ulonglong ull)
|
||||
{
|
||||
return (double) ull;
|
||||
}
|
||||
|
||||
const char *Port::list_separator()
|
||||
{
|
||||
// LOCALE_SLIST for Windows
|
||||
return ",";
|
||||
}
|
||||
|
||||
const wchar_t *Port::wlist_separator()
|
||||
{
|
||||
// LOCALE_SLIST for Windows
|
||||
return L",";
|
||||
}
|
||||
|
||||
char *Port::strupr(char *s)
|
||||
{
|
||||
return ::strupr(s);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if _MSC_VER
|
||||
|
||||
// Disable useless warnings about unreferenced functions
|
||||
#pragma warning (disable : 4514)
|
||||
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static unsigned long nanarray[2]= { 0xFFFFFFFF, 0x7FFFFFFF };
|
||||
//static unsigned long nanarray[2] = {0,0x7FF80000 };
|
||||
double Port::nan = (*(double *)nanarray);
|
||||
|
||||
//static unsigned long infinityarray[2] = {0,0x7FF00000 };
|
||||
static double zero = 0;
|
||||
double Port::infinity = 1 / zero;
|
||||
|
||||
double Port::dbl_max = DBL_MAX;
|
||||
double Port::dbl_min = DBL_MIN;
|
||||
|
||||
struct PortInitializer
|
||||
{
|
||||
PortInitializer();
|
||||
};
|
||||
|
||||
static PortInitializer portinitializer;
|
||||
|
||||
PortInitializer::PortInitializer()
|
||||
{
|
||||
Port::infinity = std::numeric_limits<long double>::infinity();
|
||||
}
|
||||
|
||||
int Port::isNan(double r)
|
||||
{
|
||||
return ::_isnan(r);
|
||||
}
|
||||
|
||||
int Port::isNan(long double r)
|
||||
{
|
||||
return ::_isnan(r);
|
||||
}
|
||||
|
||||
int Port::isSignallingNan(double r)
|
||||
{
|
||||
/* A signalling NaN is a NaN with 0 as the most significant bit of
|
||||
* its significand, which is bit 51 of 0..63 for 64 bit doubles.
|
||||
*/
|
||||
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
|
||||
}
|
||||
|
||||
int Port::isSignallingNan(long double r)
|
||||
{
|
||||
/* MSVC doesn't have 80 bit long doubles
|
||||
*/
|
||||
return isSignallingNan((double) r);
|
||||
}
|
||||
|
||||
int Port::isFinite(double r)
|
||||
{
|
||||
return ::_finite(r);
|
||||
}
|
||||
|
||||
int Port::isInfinity(double r)
|
||||
{
|
||||
return (::_fpclass(r) & (_FPCLASS_NINF | _FPCLASS_PINF));
|
||||
}
|
||||
|
||||
int Port::Signbit(double r)
|
||||
{
|
||||
return (long)(((long *)&(r))[1] & 0x80000000);
|
||||
}
|
||||
|
||||
double Port::floor(double d)
|
||||
{
|
||||
return ::floor(d);
|
||||
}
|
||||
|
||||
double Port::pow(double x, double y)
|
||||
{
|
||||
if (y == 0)
|
||||
return 1; // even if x is NAN
|
||||
return ::pow(x, y);
|
||||
}
|
||||
|
||||
unsigned _int64 Port::strtoull(const char *p, char **pend, int base)
|
||||
{
|
||||
unsigned _int64 number = 0;
|
||||
int c;
|
||||
int error;
|
||||
#define ULLONG_MAX ((unsigned _int64)~0I64)
|
||||
|
||||
while (isspace(*p)) /* skip leading white space */
|
||||
p++;
|
||||
if (*p == '+')
|
||||
p++;
|
||||
switch (base)
|
||||
{ case 0:
|
||||
base = 10; /* assume decimal base */
|
||||
if (*p == '0')
|
||||
{ base = 8; /* could be octal */
|
||||
p++;
|
||||
switch (*p)
|
||||
{ case 'x':
|
||||
case 'X':
|
||||
base = 16; /* hex */
|
||||
p++;
|
||||
break;
|
||||
#if BINARY
|
||||
case 'b':
|
||||
case 'B':
|
||||
base = 2; /* binary */
|
||||
p++;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 16: /* skip over '0x' and '0X' */
|
||||
if (*p == '0' && (p[1] == 'x' || p[1] == 'X'))
|
||||
p += 2;
|
||||
break;
|
||||
#if BINARY
|
||||
case 2: /* skip over '0b' and '0B' */
|
||||
if (*p == '0' && (p[1] == 'b' || p[1] == 'B'))
|
||||
p += 2;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
error = 0;
|
||||
for (;;)
|
||||
{ c = *p;
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c = (c & ~0x20) - ('A' - 10);
|
||||
else /* unrecognized character */
|
||||
break;
|
||||
if (c >= base) /* not in number base */
|
||||
break;
|
||||
if ((ULLONG_MAX - c) / base < number)
|
||||
error = 1;
|
||||
number = number * base + c;
|
||||
p++;
|
||||
}
|
||||
if (pend)
|
||||
*pend = (char *)p;
|
||||
if (error)
|
||||
{ number = ULLONG_MAX;
|
||||
errno = ERANGE;
|
||||
}
|
||||
return number;
|
||||
}
|
||||
|
||||
char *Port::ull_to_string(char *buffer, ulonglong ull)
|
||||
{
|
||||
_ui64toa(ull, buffer, 10);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull)
|
||||
{
|
||||
_ui64tow(ull, buffer, 10);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
double Port::ull_to_double(ulonglong ull)
|
||||
{ double d;
|
||||
|
||||
if ((__int64) ull < 0)
|
||||
{
|
||||
// MSVC doesn't implement the conversion
|
||||
d = (double) (__int64)(ull - 0x8000000000000000i64);
|
||||
d += (double)(signed __int64)(0x7FFFFFFFFFFFFFFFi64) + 1.0;
|
||||
}
|
||||
else
|
||||
d = (double)(__int64)ull;
|
||||
return d;
|
||||
}
|
||||
|
||||
const char *Port::list_separator()
|
||||
{
|
||||
// LOCALE_SLIST for Windows
|
||||
return ",";
|
||||
}
|
||||
|
||||
const wchar_t *Port::wlist_separator()
|
||||
{
|
||||
// LOCALE_SLIST for Windows
|
||||
return L",";
|
||||
}
|
||||
|
||||
char *Port::strupr(char *s)
|
||||
{
|
||||
return ::strupr(s);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if linux || __APPLE__ || __FreeBSD__
|
||||
|
||||
#include <math.h>
|
||||
#if linux
|
||||
#include <bits/nan.h>
|
||||
#include <bits/mathdef.h>
|
||||
#endif
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static double zero = 0;
|
||||
double Port::nan = NAN;
|
||||
double Port::infinity = 1 / zero;
|
||||
double Port::dbl_max = 1.7976931348623157e308;
|
||||
double Port::dbl_min = 5e-324;
|
||||
|
||||
struct PortInitializer
|
||||
{
|
||||
PortInitializer();
|
||||
};
|
||||
|
||||
static PortInitializer portinitializer;
|
||||
|
||||
PortInitializer::PortInitializer()
|
||||
{
|
||||
// gcc nan's have the sign bit set by default, so turn it off
|
||||
// Need the volatile to prevent gcc from doing incorrect
|
||||
// constant folding.
|
||||
volatile long double foo;
|
||||
foo = NAN;
|
||||
if (signbit(foo)) // signbit sometimes, not always, set
|
||||
foo = -foo; // turn off sign bit
|
||||
Port::nan = foo;
|
||||
}
|
||||
|
||||
#undef isnan
|
||||
int Port::isNan(double r)
|
||||
{
|
||||
#if __APPLE__
|
||||
return __inline_isnan(r);
|
||||
#else
|
||||
return ::isnan(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
int Port::isNan(long double r)
|
||||
{
|
||||
#if __APPLE__
|
||||
return __inline_isnan(r);
|
||||
#else
|
||||
return ::isnan(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
int Port::isSignallingNan(double r)
|
||||
{
|
||||
/* A signalling NaN is a NaN with 0 as the most significant bit of
|
||||
* its significand, which is bit 51 of 0..63 for 64 bit doubles.
|
||||
*/
|
||||
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
|
||||
}
|
||||
|
||||
int Port::isSignallingNan(long double r)
|
||||
{
|
||||
/* A signalling NaN is a NaN with 0 as the most significant bit of
|
||||
* its significand, which is bit 62 of 0..79 for 80 bit reals.
|
||||
*/
|
||||
return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40);
|
||||
}
|
||||
|
||||
#undef isfinite
|
||||
int Port::isFinite(double r)
|
||||
{
|
||||
return ::finite(r);
|
||||
}
|
||||
|
||||
#undef isinf
|
||||
int Port::isInfinity(double r)
|
||||
{
|
||||
#if __APPLE__
|
||||
return fpclassify(r) == FP_INFINITE;
|
||||
#else
|
||||
return ::isinf(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef signbit
|
||||
int Port::Signbit(double r)
|
||||
{
|
||||
return (long)(((long *)&r)[1] & 0x80000000);
|
||||
}
|
||||
|
||||
double Port::floor(double d)
|
||||
{
|
||||
return ::floor(d);
|
||||
}
|
||||
|
||||
double Port::pow(double x, double y)
|
||||
{
|
||||
return ::pow(x, y);
|
||||
}
|
||||
|
||||
unsigned long long Port::strtoull(const char *p, char **pend, int base)
|
||||
{
|
||||
return ::strtoull(p, pend, base);
|
||||
}
|
||||
|
||||
char *Port::ull_to_string(char *buffer, ulonglong ull)
|
||||
{
|
||||
sprintf(buffer, "%llu", ull);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull)
|
||||
{
|
||||
swprintf(buffer, sizeof(ulonglong) * 3 + 1, L"%llu", ull);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
double Port::ull_to_double(ulonglong ull)
|
||||
{
|
||||
return (double) ull;
|
||||
}
|
||||
|
||||
const char *Port::list_separator()
|
||||
{
|
||||
return ",";
|
||||
}
|
||||
|
||||
const wchar_t *Port::wlist_separator()
|
||||
{
|
||||
return L",";
|
||||
}
|
||||
|
||||
char *Port::strupr(char *s)
|
||||
{
|
||||
char *t = s;
|
||||
|
||||
while (*s)
|
||||
{
|
||||
*s = toupper(*s);
|
||||
s++;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined (__SVR4) && defined (__sun)
|
||||
|
||||
#define __C99FEATURES__ 1 // Needed on Solaris for NaN and more
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static double zero = 0;
|
||||
double Port::nan = NAN;
|
||||
double Port::infinity = 1 / zero;
|
||||
double Port::dbl_max = 1.7976931348623157e308;
|
||||
double Port::dbl_min = 5e-324;
|
||||
|
||||
struct PortInitializer
|
||||
{
|
||||
PortInitializer();
|
||||
};
|
||||
|
||||
static PortInitializer portinitializer;
|
||||
|
||||
PortInitializer::PortInitializer()
|
||||
{
|
||||
// gcc nan's have the sign bit set by default, so turn it off
|
||||
// Need the volatile to prevent gcc from doing incorrect
|
||||
// constant folding.
|
||||
volatile long double foo;
|
||||
foo = NAN;
|
||||
if (signbit(foo)) // signbit sometimes, not always, set
|
||||
foo = -foo; // turn off sign bit
|
||||
Port::nan = foo;
|
||||
}
|
||||
|
||||
#undef isnan
|
||||
int Port::isNan(double r)
|
||||
{
|
||||
#if __APPLE__
|
||||
return __inline_isnan(r);
|
||||
#else
|
||||
return ::isnan(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
int Port::isNan(long double r)
|
||||
{
|
||||
#if __APPLE__
|
||||
return __inline_isnan(r);
|
||||
#else
|
||||
return ::isnan(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
int Port::isSignallingNan(double r)
|
||||
{
|
||||
/* A signalling NaN is a NaN with 0 as the most significant bit of
|
||||
* its significand, which is bit 51 of 0..63 for 64 bit doubles.
|
||||
*/
|
||||
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
|
||||
}
|
||||
|
||||
int Port::isSignallingNan(long double r)
|
||||
{
|
||||
/* A signalling NaN is a NaN with 0 as the most significant bit of
|
||||
* its significand, which is bit 62 of 0..79 for 80 bit reals.
|
||||
*/
|
||||
return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40);
|
||||
}
|
||||
|
||||
#undef isfinite
|
||||
int Port::isFinite(double r)
|
||||
{
|
||||
return ::finite(r);
|
||||
}
|
||||
|
||||
#undef isinf
|
||||
int Port::isInfinity(double r)
|
||||
{
|
||||
return ::isinf(r);
|
||||
}
|
||||
|
||||
#undef signbit
|
||||
int Port::Signbit(double r)
|
||||
{
|
||||
return (long)(((long *)&r)[1] & 0x80000000);
|
||||
}
|
||||
|
||||
double Port::floor(double d)
|
||||
{
|
||||
return ::floor(d);
|
||||
}
|
||||
|
||||
double Port::pow(double x, double y)
|
||||
{
|
||||
return ::pow(x, y);
|
||||
}
|
||||
|
||||
unsigned long long Port::strtoull(const char *p, char **pend, int base)
|
||||
{
|
||||
return ::strtoull(p, pend, base);
|
||||
}
|
||||
|
||||
char *Port::ull_to_string(char *buffer, ulonglong ull)
|
||||
{
|
||||
sprintf(buffer, "%llu", ull);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull)
|
||||
{
|
||||
swprintf(buffer, sizeof(ulonglong) * 3 + 1, L"%llu", ull);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
double Port::ull_to_double(ulonglong ull)
|
||||
{
|
||||
return (double) ull;
|
||||
}
|
||||
|
||||
const char *Port::list_separator()
|
||||
{
|
||||
return ",";
|
||||
}
|
||||
|
||||
const wchar_t *Port::wlist_separator()
|
||||
{
|
||||
return L",";
|
||||
}
|
||||
|
||||
char *Port::strupr(char *s)
|
||||
{
|
||||
char *t = s;
|
||||
|
||||
while (*s)
|
||||
{
|
||||
*s = toupper(*s);
|
||||
s++;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if IN_GCC
|
||||
|
||||
#include <math.h>
|
||||
#include <bits/nan.h>
|
||||
#include <bits/mathdef.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static double zero = 0;
|
||||
double Port::nan = NAN;
|
||||
double Port::infinity = 1 / zero;
|
||||
double Port::dbl_max = 1.7976931348623157e308;
|
||||
double Port::dbl_min = 5e-324;
|
||||
|
||||
#include "d-gcc-real.h"
|
||||
extern "C" bool real_isnan (const real_t *);
|
||||
|
||||
struct PortInitializer
|
||||
{
|
||||
PortInitializer();
|
||||
};
|
||||
|
||||
static PortInitializer portinitializer;
|
||||
|
||||
PortInitializer::PortInitializer()
|
||||
{
|
||||
Port::infinity = real_t::getinfinity();
|
||||
Port::nan = real_t::getnan(real_t::LongDouble);
|
||||
}
|
||||
|
||||
#undef isnan
|
||||
int Port::isNan(double r)
|
||||
{
|
||||
#if __APPLE__
|
||||
return __inline_isnan(r);
|
||||
#else
|
||||
return ::isnan(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
int Port::isNan(long double r)
|
||||
{
|
||||
return real_isnan(&r);
|
||||
}
|
||||
|
||||
int Port::isSignallingNan(double r)
|
||||
{
|
||||
/* A signalling NaN is a NaN with 0 as the most significant bit of
|
||||
* its significand, which is bit 51 of 0..63 for 64 bit doubles.
|
||||
*/
|
||||
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
|
||||
}
|
||||
|
||||
int Port::isSignallingNan(long double r)
|
||||
{
|
||||
/* A signalling NaN is a NaN with 0 as the most significant bit of
|
||||
* its significand, which is bit 62 of 0..79 for 80 bit reals.
|
||||
*/
|
||||
return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40);
|
||||
}
|
||||
|
||||
#undef isfinite
|
||||
int Port::isFinite(double r)
|
||||
{
|
||||
return ::finite(r);
|
||||
}
|
||||
|
||||
#undef isinf
|
||||
int Port::isInfinity(double r)
|
||||
{
|
||||
return ::isinf(r);
|
||||
}
|
||||
|
||||
#undef signbit
|
||||
int Port::Signbit(double r)
|
||||
{
|
||||
return (long)(((long *)&r)[1] & 0x80000000);
|
||||
}
|
||||
|
||||
double Port::floor(double d)
|
||||
{
|
||||
return ::floor(d);
|
||||
}
|
||||
|
||||
double Port::pow(double x, double y)
|
||||
{
|
||||
return ::pow(x, y);
|
||||
}
|
||||
|
||||
unsigned long long Port::strtoull(const char *p, char **pend, int base)
|
||||
{
|
||||
return ::strtoull(p, pend, base);
|
||||
}
|
||||
|
||||
char *Port::ull_to_string(char *buffer, ulonglong ull)
|
||||
{
|
||||
sprintf(buffer, "%llu", ull);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull)
|
||||
{
|
||||
swprintf(buffer, L"%llu", ull);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
double Port::ull_to_double(ulonglong ull)
|
||||
{
|
||||
return (double) ull;
|
||||
}
|
||||
|
||||
const char *Port::list_separator()
|
||||
{
|
||||
return ",";
|
||||
}
|
||||
|
||||
const wchar_t *Port::wlist_separator()
|
||||
{
|
||||
return L",";
|
||||
}
|
||||
|
||||
char *Port::strupr(char *s)
|
||||
{
|
||||
char *t = s;
|
||||
|
||||
while (*s)
|
||||
{
|
||||
*s = toupper(*s);
|
||||
s++;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
// Copyright (c) 1999-2002 by Digital Mars
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// www.digitalmars.com
|
||||
// http://www.digitalmars.com
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
@@ -42,6 +42,11 @@ struct Port
|
||||
#undef signbit
|
||||
#endif
|
||||
static int isNan(double);
|
||||
static int isNan(long double);
|
||||
|
||||
static int isSignallingNan(double);
|
||||
static int isSignallingNan(long double);
|
||||
|
||||
static int isFinite(double);
|
||||
static int isInfinity(double);
|
||||
static int Signbit(double);
|
||||
@@ -58,8 +63,10 @@ struct Port
|
||||
static double ull_to_double(ulonglong ull);
|
||||
|
||||
// Get locale-dependent list separator
|
||||
static char *list_separator();
|
||||
static wchar_t *wlist_separator();
|
||||
static const char *list_separator();
|
||||
static const wchar_t *wlist_separator();
|
||||
|
||||
static char *strupr(char *);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -583,9 +583,17 @@ char *FileName::name(const char *str)
|
||||
return e + 1;
|
||||
|
||||
#if _WIN32
|
||||
case '/':
|
||||
case '\\':
|
||||
case ':':
|
||||
return e + 1;
|
||||
case ':':
|
||||
/* The ':' is a drive letter only if it is the second
|
||||
* character or the last character,
|
||||
* otherwise it is an ADS (Alternate Data Stream) separator.
|
||||
* Consider ADS separators as part of the file name.
|
||||
*/
|
||||
if (e == str + 1 || e == str + len - 1)
|
||||
return e + 1;
|
||||
#endif
|
||||
default:
|
||||
if (e == str)
|
||||
@@ -620,7 +628,7 @@ char *FileName::path(const char *str)
|
||||
n--;
|
||||
|
||||
#if _WIN32
|
||||
if (n[-1] == '\\')
|
||||
if (n[-1] == '\\' || n[-1] == '/')
|
||||
n--;
|
||||
#endif
|
||||
}
|
||||
@@ -822,8 +830,8 @@ void FileName::ensurePathExists(const char *path)
|
||||
if (*p)
|
||||
{
|
||||
#if _WIN32
|
||||
size_t len = strlen(p);
|
||||
if (len > 2 && p[-1] == ':')
|
||||
size_t len = strlen(path);
|
||||
if (len > 2 && p[-1] == ':' && path + 2 == p)
|
||||
{ mem.free(p);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user