Merged DMD 1.042.

This commit is contained in:
Tomas Lindquist Olsen
2009-04-03 17:59:34 +02:00
parent 57bf95cb42
commit 3d1f8cc565
38 changed files with 6504 additions and 5232 deletions

View File

@@ -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
View 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
View 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
View 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

View File

@@ -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

View File

@@ -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;
}