mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-15 20:33:14 +01:00
Removed a few D1 leftovers.
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
[Environment]
|
||||
DFLAGS=-I@RUNTIME_DIR@ -I@RUNTIME_DIR@/lib/common -L-L@CMAKE_INSTALL_LIBDIR@ -d-version=Tango -defaultlib=@RUNTIME_AIO@ -debuglib=@RUNTIME_AIO@
|
||||
@@ -1,18 +0,0 @@
|
||||
// This configuration file uses libconfig.
|
||||
// See http://www.hyperrealm.com/libconfig/ for syntax details.
|
||||
|
||||
// The default group is required
|
||||
default:
|
||||
{
|
||||
// 'switches' holds array of string that are appends to the command line
|
||||
// arguments before they are parsed.
|
||||
switches = [
|
||||
"-I@INCLUDE_INSTALL_DIR@/@RUNTIME_AIO@",
|
||||
"-I@INCLUDE_INSTALL_DIR@/@RUNTIME_AIO@/core/vendor",
|
||||
"-I@INCLUDE_INSTALL_DIR@",
|
||||
"-L-L@CMAKE_INSTALL_LIBDIR@",
|
||||
"-d-version=Tango",
|
||||
"-defaultlib=@RUNTIME_AIO@",
|
||||
"-debuglib=@RUNTIME_AIO@"
|
||||
];
|
||||
};
|
||||
@@ -57,15 +57,6 @@ endif()
|
||||
get_directory_property(PROJECT_PARENT_DIR DIRECTORY ${PROJECT_SOURCE_DIR} PARENT_DIRECTORY)
|
||||
set(RUNTIME_DIR ${PROJECT_SOURCE_DIR}/druntime CACHE PATH "runtime source dir")
|
||||
|
||||
if(D_VERSION EQUAL 1)
|
||||
set(RUNTIME_AIO tango)
|
||||
configure_file(${PROJECT_PARENT_DIR}/${LDC_EXE}_install.conf.in ${PROJECT_BINARY_DIR}/../bin/${LDC_EXE}_install.conf)
|
||||
configure_file(${PROJECT_PARENT_DIR}/${LDC_EXE}.rebuild.conf.in ${PROJECT_BINARY_DIR}/../bin/${LDC_EXE}_install.rebuild.conf)
|
||||
|
||||
message(STATUS "Note: Tango is no longer included in D1 builds, please compile and install it separately using its own build infrastructure (bob).")
|
||||
return()
|
||||
endif()
|
||||
|
||||
#
|
||||
# Gather source files.
|
||||
#
|
||||
|
||||
6
tests/d1/.gitignore
vendored
6
tests/d1/.gitignore
vendored
@@ -1,6 +0,0 @@
|
||||
/dstress
|
||||
/findregressions
|
||||
/makewebstatistics
|
||||
/*.o
|
||||
/testincludes/*.a
|
||||
/testincludes/*.o
|
||||
@@ -1,15 +0,0 @@
|
||||
We have two different test sets. For the test drivers
|
||||
you need do compile the .d files in this folder with
|
||||
a Phobos D compiler.
|
||||
|
||||
To run the 'mini' test suite run
|
||||
./runminitests
|
||||
|
||||
To run the DStress based tests execute
|
||||
./runtest tmp-sensible-name
|
||||
and then use
|
||||
./findregressions old-results new-results
|
||||
to display a list of regressions. You can
|
||||
download old result files from
|
||||
http://www.incasoftware.de/~kamm/ldc/reference
|
||||
|
||||
@@ -1,367 +0,0 @@
|
||||
// Based on DSTRESS code by Thomas Kühne
|
||||
|
||||
module findregressions;
|
||||
|
||||
private import std.string;
|
||||
private import std.conv;
|
||||
private import std.stdio;
|
||||
private import std.stream;
|
||||
private import std.file;
|
||||
private import std.c.stdlib;
|
||||
private import std.date;
|
||||
|
||||
|
||||
enum Result{
|
||||
UNTESTED = 0,
|
||||
PASS = 1 << 2,
|
||||
XFAIL = 2 << 2,
|
||||
XPASS = 3 << 2,
|
||||
FAIL = 4 << 2,
|
||||
ERROR = 5 << 2,
|
||||
BASE_MASK = 7 << 2,
|
||||
|
||||
EXT_MASK = 3,
|
||||
BAD_MSG = 1,
|
||||
BAD_GDB = 2,
|
||||
|
||||
MAX = BAD_GDB + BASE_MASK
|
||||
}
|
||||
|
||||
char[] toString(Result r){
|
||||
switch(r & Result.BASE_MASK){
|
||||
case Result.PASS: return "PASS";
|
||||
case Result.XPASS: return "XPASS";
|
||||
case Result.FAIL: return "FAIL";
|
||||
case Result.XFAIL: return "XFAIL";
|
||||
case Result.ERROR: return "ERROR";
|
||||
case Result.UNTESTED: return "UNTESTED";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
throw new Exception(format("unhandled Result value %s", cast(int)r));
|
||||
}
|
||||
|
||||
char[] dateString(){
|
||||
static char[] date;
|
||||
if(date is null){
|
||||
auto time = getUTCtime();
|
||||
auto year = YearFromTime(time);
|
||||
auto month = MonthFromTime(time);
|
||||
auto day = DateFromTime(time);
|
||||
date = format("%d-%02d-%02d", year, month+1, day);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
char[][] unique(char[][] a){
|
||||
char[][] b = a.sort;
|
||||
char[][] back;
|
||||
|
||||
back ~= b[0];
|
||||
|
||||
size_t ii=0;
|
||||
for(size_t i=0; i<b.length; i++){
|
||||
if(back[ii]!=b[i]){
|
||||
back~=b[i];
|
||||
ii++;
|
||||
}
|
||||
}
|
||||
|
||||
return back;
|
||||
}
|
||||
|
||||
private{
|
||||
version(Windows){
|
||||
import std.c.windows.windows;
|
||||
extern(Windows) BOOL GetFileTime(HANDLE hFile, LPFILETIME lpCreationTime, LPFILETIME lpLastAccessTime, LPFILETIME lpLastWriteTime);
|
||||
}else version(linux){
|
||||
import std.c.linux.linux;
|
||||
version = Posix;
|
||||
}else version(Posix){
|
||||
import std.c.posix.posix;
|
||||
}else{
|
||||
static assert(0);
|
||||
}
|
||||
|
||||
alias ulong FStime;
|
||||
|
||||
FStime getFStime(char[] fileName){
|
||||
version(Windows){
|
||||
HANDLE h;
|
||||
|
||||
if (useWfuncs){
|
||||
wchar* namez = std.utf.toUTF16z(fileName);
|
||||
h = CreateFileW(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null);
|
||||
}else{
|
||||
char* namez = toMBSz(fileName);
|
||||
h = CreateFileA(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null);
|
||||
}
|
||||
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
goto err;
|
||||
|
||||
FILETIME creationTime;
|
||||
FILETIME accessTime;
|
||||
FILETIME writeTime;
|
||||
|
||||
BOOL b = GetFileTime(h, &creationTime, &accessTime, &writeTime);
|
||||
if(b==1){
|
||||
long modA = writeTime.dwLowDateTime;
|
||||
long modB = writeTime.dwHighDateTime;
|
||||
return modA | (modB << (writeTime.dwHighDateTime.sizeof*8));
|
||||
}
|
||||
|
||||
err:
|
||||
CloseHandle(h);
|
||||
throw new Exception("failed to query file modification : "~fileName);
|
||||
}else version(Posix){
|
||||
char* namez = toStringz(fileName);
|
||||
struct_stat statbuf;
|
||||
|
||||
if(stat(namez, &statbuf)){
|
||||
throw new FileException(fileName, getErrno());
|
||||
}
|
||||
|
||||
version(linux){
|
||||
return statbuf.st_mtime;
|
||||
}else version(OSX){
|
||||
return statbuf.st_mtimespec.tv_sec;
|
||||
}
|
||||
}else{
|
||||
static assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char[] cleanFileName(char[] file){
|
||||
char[] back;
|
||||
bool hadSep;
|
||||
|
||||
foreach(char c; file){
|
||||
if(c == '/' || c == '\\'){
|
||||
if(!hadSep){
|
||||
back ~= '/';
|
||||
hadSep = true;
|
||||
}
|
||||
}else{
|
||||
back ~= c;
|
||||
hadSep = false;
|
||||
}
|
||||
}
|
||||
|
||||
size_t start = 0;
|
||||
while(back[start] <= ' ' && start < back.length){
|
||||
start++;
|
||||
}
|
||||
|
||||
size_t end = back.length-1;
|
||||
while(back[end] <= ' ' && end >= start){
|
||||
end--;
|
||||
}
|
||||
|
||||
back = back[start .. end+1];
|
||||
|
||||
return back;
|
||||
}
|
||||
|
||||
class Test{
|
||||
char[] name;
|
||||
char[] file;
|
||||
Result r;
|
||||
|
||||
this(char[] file){
|
||||
this.file = file;
|
||||
|
||||
int start = rfind(file, "/");
|
||||
if(start<0){
|
||||
start = 0;
|
||||
}else{
|
||||
start += 1;
|
||||
}
|
||||
|
||||
int end = rfind(file, ".");
|
||||
if(end < start){
|
||||
end = file.length;
|
||||
}
|
||||
|
||||
name = file[start .. end];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Log{
|
||||
Test[char[]] tests;
|
||||
|
||||
char[] id;
|
||||
|
||||
this(char[] id){
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
||||
void dropBogusResults(FStime recordTime, char[] testRoot){
|
||||
uint totalCount = tests.length;
|
||||
|
||||
char[][] sourcesTests = tests.keys;
|
||||
foreach(char[] source; sourcesTests){
|
||||
if(find(source, "complex/") < 0){
|
||||
try{
|
||||
FStime caseTime = getFStime(testRoot~std.path.sep~source);
|
||||
if(caseTime > recordTime){
|
||||
debug(drop) fwritefln(stderr, "dropped: %s", source);
|
||||
tests.remove(source);
|
||||
}
|
||||
}catch(Exception e){
|
||||
debug(drop) fwritefln(stderr, "dropped: %s", source);
|
||||
tests.remove(source);
|
||||
}
|
||||
}
|
||||
// asm-filter
|
||||
int i = find(source, "asm_p");
|
||||
if(i >= 0){
|
||||
tests.remove(source);
|
||||
}
|
||||
}
|
||||
tests.rehash;
|
||||
|
||||
writefln("dropped %s outdated tests (%s remaining)", totalCount - tests.length, tests.length);
|
||||
}
|
||||
|
||||
|
||||
bool add(char[] line){
|
||||
const char[] SUB = "Torture-Sub-";
|
||||
const char[] TORTURE = "Torture:";
|
||||
|
||||
line = strip(line);
|
||||
int id = -1;
|
||||
Result r = Result.UNTESTED;
|
||||
|
||||
if(line.length > SUB.length && line[0 .. SUB.length] == SUB){
|
||||
line = line[SUB.length .. $];
|
||||
id = 0;
|
||||
while(line[id] >= '0' && line[id] <= '9'){
|
||||
id++;
|
||||
}
|
||||
int start = id;
|
||||
id = std.conv.toUint(line[0 .. id]);
|
||||
|
||||
while(line[start] != '-'){
|
||||
start++;
|
||||
}
|
||||
line = line[start+1 .. $];
|
||||
}
|
||||
|
||||
char[][] token = split(line);
|
||||
if(token.length < 2){
|
||||
return false;
|
||||
}
|
||||
char[] file = strip(token[1]);
|
||||
|
||||
switch(token[0]){
|
||||
case "PASS:":
|
||||
r = Result.PASS; break;
|
||||
case "FAIL:":
|
||||
r = Result.FAIL; break;
|
||||
case "XPASS:":
|
||||
r = Result.XPASS; break;
|
||||
case "XFAIL:":
|
||||
r = Result.XFAIL; break;
|
||||
case "ERROR:":
|
||||
r = Result.ERROR; break;
|
||||
default:{
|
||||
if(token[0] == TORTURE){
|
||||
throw new Exception("not yet handled: "~line);
|
||||
}else if(id > -1){
|
||||
throw new Exception(format("bug in SUB line: (%s) %s", id, line));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(r != Result.UNTESTED){
|
||||
if(std.string.find(line, "bad error message") > -1){
|
||||
r |= Result.BAD_MSG;
|
||||
}
|
||||
if(std.string.find(line, "bad debugger message") > -1){
|
||||
r |= Result.BAD_MSG;
|
||||
}
|
||||
|
||||
file = cleanFileName(file);
|
||||
|
||||
if(id >= 0){
|
||||
// update sub
|
||||
id--;
|
||||
|
||||
Test* test = file in tests;
|
||||
|
||||
if(test is null){
|
||||
Test t = new Test(file);
|
||||
tests[file] = t;
|
||||
t.r = r;
|
||||
}else{
|
||||
if(test.r != Result.UNTESTED){
|
||||
test.r = Result.UNTESTED;
|
||||
}
|
||||
test.r = r;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(char[][] args){
|
||||
|
||||
if(args.length < 2){
|
||||
fwritefln(stderr, "%s <old log> <new log>", args[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
Log[] logs;
|
||||
|
||||
foreach(size_t id, char[] file; args[1 .. $]){
|
||||
writefln("parsing: %s", file);
|
||||
FStime logTime = getFStime(file);
|
||||
debug fwritefln(stderr, "sourceTime: %s", logTime);
|
||||
|
||||
Log l= new Log(file);
|
||||
Stream source = new BufferedFile(file, FileMode.In);
|
||||
while(!source.eof()){
|
||||
l.add(source.readLine());
|
||||
}
|
||||
|
||||
l.dropBogusResults(logTime, "dstress");
|
||||
|
||||
logs ~= l;
|
||||
}
|
||||
|
||||
Log oldLog = logs[0];
|
||||
Log newLog = logs[1];
|
||||
|
||||
foreach(Test t; newLog.tests.values){
|
||||
Test* oldT = t.file in oldLog.tests;
|
||||
|
||||
if(oldT !is null){
|
||||
if(oldT.r == t.r)
|
||||
continue;
|
||||
else if(t.r >= Result.XPASS && oldT.r && oldT.r <= Result.XFAIL){
|
||||
writef("Regression ");
|
||||
}
|
||||
else if(t.r && t.r <= Result.XFAIL && oldT.r >= Result.XPASS){
|
||||
writef("Improvement ");
|
||||
}
|
||||
else {
|
||||
writef("Change ");
|
||||
}
|
||||
writefln(toString(oldT.r), " -> ", toString(t.r), " : ", t.name, " in ", t.file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,705 +0,0 @@
|
||||
// Based on DSTRESS code by Thomas Kühne
|
||||
|
||||
module findregressions;
|
||||
|
||||
private import std.string;
|
||||
private import std.conv;
|
||||
private import std.stdio;
|
||||
private import std.stream;
|
||||
private import std.file;
|
||||
private import std.c.stdlib;
|
||||
private import std.date;
|
||||
private import std.path;
|
||||
|
||||
|
||||
enum Result{
|
||||
UNTESTED = 0,
|
||||
PASS = 1 << 2,
|
||||
XFAIL = 2 << 2,
|
||||
XPASS = 3 << 2,
|
||||
FAIL = 4 << 2,
|
||||
ERROR = 5 << 2,
|
||||
BASE_MASK = 7 << 2,
|
||||
|
||||
EXT_MASK = 3,
|
||||
BAD_MSG = 1,
|
||||
BAD_GDB = 2,
|
||||
|
||||
MAX = BAD_GDB + BASE_MASK
|
||||
}
|
||||
|
||||
char[] toString(Result r){
|
||||
switch(r & Result.BASE_MASK){
|
||||
case Result.PASS: return "PASS";
|
||||
case Result.XPASS: return "XPASS";
|
||||
case Result.FAIL: return "FAIL";
|
||||
case Result.XFAIL: return "XFAIL";
|
||||
case Result.ERROR: return "ERROR";
|
||||
case Result.UNTESTED: return "UNTESTED";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
throw new Exception(format("unhandled Result value %s", cast(int)r));
|
||||
}
|
||||
|
||||
char[] dateString(){
|
||||
static char[] date;
|
||||
if(date is null){
|
||||
auto time = getUTCtime();
|
||||
auto year = YearFromTime(time);
|
||||
auto month = MonthFromTime(time);
|
||||
auto day = DateFromTime(time);
|
||||
date = format("%d-%02d-%02d", year, month+1, day);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
char[][] unique(char[][] a){
|
||||
char[][] b = a.sort;
|
||||
char[][] back;
|
||||
|
||||
back ~= b[0];
|
||||
|
||||
size_t ii=0;
|
||||
for(size_t i=0; i<b.length; i++){
|
||||
if(back[ii]!=b[i]){
|
||||
back~=b[i];
|
||||
ii++;
|
||||
}
|
||||
}
|
||||
|
||||
return back;
|
||||
}
|
||||
|
||||
private{
|
||||
version(Windows){
|
||||
import std.c.windows.windows;
|
||||
extern(Windows) BOOL GetFileTime(HANDLE hFile, LPFILETIME lpCreationTime, LPFILETIME lpLastAccessTime, LPFILETIME lpLastWriteTime);
|
||||
}else version(linux){
|
||||
import std.c.linux.linux;
|
||||
version = Posix;
|
||||
}else version(Posix){
|
||||
import std.c.posix.posix;
|
||||
}else{
|
||||
static assert(0);
|
||||
}
|
||||
|
||||
alias ulong FStime;
|
||||
|
||||
FStime getFStime(char[] fileName){
|
||||
version(Windows){
|
||||
HANDLE h;
|
||||
|
||||
if (useWfuncs){
|
||||
wchar* namez = std.utf.toUTF16z(fileName);
|
||||
h = CreateFileW(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null);
|
||||
}else{
|
||||
char* namez = toMBSz(fileName);
|
||||
h = CreateFileA(namez,GENERIC_WRITE,0,null,OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,cast(HANDLE)null);
|
||||
}
|
||||
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
goto err;
|
||||
|
||||
FILETIME creationTime;
|
||||
FILETIME accessTime;
|
||||
FILETIME writeTime;
|
||||
|
||||
BOOL b = GetFileTime(h, &creationTime, &accessTime, &writeTime);
|
||||
if(b==1){
|
||||
long modA = writeTime.dwLowDateTime;
|
||||
long modB = writeTime.dwHighDateTime;
|
||||
return modA | (modB << (writeTime.dwHighDateTime.sizeof*8));
|
||||
}
|
||||
|
||||
err:
|
||||
CloseHandle(h);
|
||||
throw new Exception("failed to query file modification : "~fileName);
|
||||
}else version(Posix){
|
||||
char* namez = toStringz(fileName);
|
||||
struct_stat statbuf;
|
||||
|
||||
if(stat(namez, &statbuf)){
|
||||
throw new FileException(fileName, getErrno());
|
||||
}
|
||||
|
||||
version(linux){
|
||||
return statbuf.st_mtime;
|
||||
}else version(OSX){
|
||||
return statbuf.st_mtimespec.tv_sec;
|
||||
}
|
||||
|
||||
}else{
|
||||
static assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char[] cleanFileName(char[] file){
|
||||
char[] back;
|
||||
bool hadSep;
|
||||
|
||||
foreach(char c; file){
|
||||
if(c == '/' || c == '\\'){
|
||||
if(!hadSep){
|
||||
back ~= '/';
|
||||
hadSep = true;
|
||||
}
|
||||
}else{
|
||||
back ~= c;
|
||||
hadSep = false;
|
||||
}
|
||||
}
|
||||
|
||||
size_t start = 0;
|
||||
while(back[start] <= ' ' && start < back.length){
|
||||
start++;
|
||||
}
|
||||
|
||||
size_t end = back.length-1;
|
||||
while(back[end] <= ' ' && end >= start){
|
||||
end--;
|
||||
}
|
||||
|
||||
back = back[start .. end+1];
|
||||
|
||||
return back;
|
||||
}
|
||||
|
||||
class Test{
|
||||
char[] name;
|
||||
char[] file;
|
||||
Result r;
|
||||
|
||||
this(char[] file){
|
||||
this.file = file;
|
||||
|
||||
int start = rfind(file, "/");
|
||||
if(start<0){
|
||||
start = 0;
|
||||
}else{
|
||||
start += 1;
|
||||
}
|
||||
|
||||
int end = rfind(file, ".");
|
||||
if(end < start){
|
||||
end = file.length;
|
||||
}
|
||||
|
||||
name = file[start .. end];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Log{
|
||||
Test[char[]] tests;
|
||||
|
||||
char[] id;
|
||||
|
||||
int[Result] counts;
|
||||
|
||||
this(char[] id, char[] file){
|
||||
this.id = id;
|
||||
counts = [
|
||||
Result.PASS: 0,
|
||||
Result.FAIL: 0,
|
||||
Result.XPASS: 0,
|
||||
Result.XFAIL: 0,
|
||||
Result.ERROR: 0 ];
|
||||
|
||||
writefln("parsing: %s", file);
|
||||
FStime logTime = getFStime(file);
|
||||
Stream source = new BufferedFile(file, FileMode.In);
|
||||
while(!source.eof()){
|
||||
add(source.readLine());
|
||||
}
|
||||
dropBogusResults(logTime, "dstress");
|
||||
}
|
||||
|
||||
|
||||
void dropBogusResults(FStime recordTime, char[] testRoot){
|
||||
uint totalCount = tests.length;
|
||||
|
||||
char[][] sourcesTests = tests.keys;
|
||||
foreach(char[] source; sourcesTests){
|
||||
if(find(source, "complex/") < 0){
|
||||
try{
|
||||
FStime caseTime = getFStime(testRoot~std.path.sep~source);
|
||||
if(caseTime > recordTime){
|
||||
debug(drop) fwritefln(stderr, "dropped: %s", source);
|
||||
counts[tests[source].r & Result.BASE_MASK]--;
|
||||
tests.remove(source);
|
||||
continue;
|
||||
}
|
||||
}catch(Exception e){
|
||||
debug(drop) fwritefln(stderr, "dropped: %s", source);
|
||||
counts[tests[source].r & Result.BASE_MASK]--;
|
||||
tests.remove(source);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// asm-filter
|
||||
int i = find(source, "asm_p");
|
||||
if(i >= 0){
|
||||
counts[tests[source].r & Result.BASE_MASK]--;
|
||||
tests.remove(source);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
tests.rehash;
|
||||
|
||||
writefln("dropped %s outdated tests (%s remaining)", totalCount - tests.length, tests.length);
|
||||
}
|
||||
|
||||
|
||||
bool add(char[] line){
|
||||
const char[] SUB = "Torture-Sub-";
|
||||
const char[] TORTURE = "Torture:";
|
||||
|
||||
line = strip(line);
|
||||
int id = -1;
|
||||
Result r = Result.UNTESTED;
|
||||
|
||||
if(line.length > SUB.length && line[0 .. SUB.length] == SUB){
|
||||
line = line[SUB.length .. $];
|
||||
id = 0;
|
||||
while(line[id] >= '0' && line[id] <= '9'){
|
||||
id++;
|
||||
}
|
||||
int start = id;
|
||||
id = std.conv.toUint(line[0 .. id]);
|
||||
|
||||
while(line[start] != '-'){
|
||||
start++;
|
||||
}
|
||||
line = line[start+1 .. $];
|
||||
}
|
||||
|
||||
char[][] token = split(line);
|
||||
if(token.length < 2){
|
||||
return false;
|
||||
}
|
||||
char[] file = strip(token[1]);
|
||||
|
||||
switch(token[0]){
|
||||
case "PASS:":
|
||||
r = Result.PASS; break;
|
||||
case "FAIL:":
|
||||
r = Result.FAIL; break;
|
||||
case "XPASS:":
|
||||
r = Result.XPASS; break;
|
||||
case "XFAIL:":
|
||||
r = Result.XFAIL; break;
|
||||
case "ERROR:":
|
||||
r = Result.ERROR; break;
|
||||
default:{
|
||||
if(token[0] == TORTURE){
|
||||
throw new Exception("not yet handled: "~line);
|
||||
}else if(id > -1){
|
||||
throw new Exception(format("bug in SUB line: (%s) %s", id, line));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(r != Result.UNTESTED){
|
||||
if(std.string.find(line, "bad error message") > -1){
|
||||
r |= Result.BAD_MSG;
|
||||
}
|
||||
if(std.string.find(line, "bad debugger message") > -1){
|
||||
r |= Result.BAD_MSG;
|
||||
}
|
||||
|
||||
file = cleanFileName(file);
|
||||
|
||||
if(id >= 0){
|
||||
// update sub
|
||||
id--;
|
||||
|
||||
Test* test = file in tests;
|
||||
|
||||
if(test is null){
|
||||
Test t = new Test(file);
|
||||
tests[file] = t;
|
||||
t.r = r;
|
||||
counts[r & Result.BASE_MASK]++;
|
||||
}else{
|
||||
if(test.r != Result.UNTESTED){
|
||||
test.r = Result.UNTESTED;
|
||||
}
|
||||
test.r = r;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char[] basedir = "web";
|
||||
bool regenerate = false;
|
||||
|
||||
int main(char[][] args){
|
||||
|
||||
if(args.length < 3 || (args[1] == "--regenerate" && args.length < 4)){
|
||||
fwritefln(stderr, "%s [--regenerate] <reference-log> <log> <log> ...", args[0]);
|
||||
fwritefln(stderr, "bash example: %s reference/dmd-something $(ls reference/ldc*)", args[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char[] reference;
|
||||
char[][] files;
|
||||
if(args[1] == "--regenerate") {
|
||||
regenerate = true;
|
||||
reference = args[2];
|
||||
files = args[3..$] ~ reference;
|
||||
} else {
|
||||
reference = args[1];
|
||||
files = args[2..$] ~ reference;
|
||||
}
|
||||
|
||||
// make sure base path exists
|
||||
if(std.file.exists(basedir) && !std.file.isdir(basedir))
|
||||
throw new Exception(basedir ~ " is not a directory!");
|
||||
else if(!std.file.exists(basedir))
|
||||
std.file.mkdir(basedir);
|
||||
|
||||
|
||||
Log[char[]] logs;
|
||||
|
||||
// emit per-log data
|
||||
foreach(char[] file; files)
|
||||
generateLogStatistics(file, logs);
|
||||
|
||||
// differences between logs
|
||||
foreach(int i, char[] file; files[1 .. $])
|
||||
generateChangeStatistics(files[1+i], files[1+i-1], logs);
|
||||
|
||||
// differences between reference and logs
|
||||
foreach(char[] file; files[0..$-1])
|
||||
generateChangeStatistics(file, reference, logs);
|
||||
|
||||
// collect all the stats.base files into a large table
|
||||
BufferedFile index = new BufferedFile(std.path.join(basedir, "index.html"), FileMode.OutNew);
|
||||
scope(exit) index.close();
|
||||
index.writefln(`
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>DStress results for x86-32 Linux</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
border-bottom: 1px dotted blue;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
tr {
|
||||
border-bottom: 1px solid #CCC;
|
||||
}
|
||||
tr.odd {
|
||||
background: #e0e0e0;
|
||||
}
|
||||
tr.head {
|
||||
border-bottom: none;
|
||||
}
|
||||
td,th {
|
||||
padding: 2px 10px 2px 10px;
|
||||
}
|
||||
.result:hover {
|
||||
background: #C3DFFF;
|
||||
}
|
||||
.pass,.xfail,.xpass,.fail,.xpass,.error,.generic {
|
||||
text-align: center;
|
||||
}
|
||||
.generic {
|
||||
background: #EEE;
|
||||
color: gray;
|
||||
}
|
||||
.pass {
|
||||
background: #98FF90;
|
||||
color: green;
|
||||
}
|
||||
tr:hover .pass {
|
||||
background: #83E67B;
|
||||
}
|
||||
.xfail {
|
||||
background: #BDFFB8;
|
||||
color: #0CAE00;
|
||||
}
|
||||
tr:hover .xfail {
|
||||
background: #98FF90;
|
||||
}
|
||||
.fail {
|
||||
background: #FF6E7A;
|
||||
color: maroon;
|
||||
}
|
||||
.xpass {
|
||||
background: #FF949D;
|
||||
color: maroon;
|
||||
}
|
||||
.error {
|
||||
background: #FFB3B9;
|
||||
color: maroon;
|
||||
}
|
||||
.borderleft {
|
||||
border-left: 1px solid #CCC;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>DStress results for x86-32 Linux</h1>
|
||||
|
||||
<h2>Legend</h2>
|
||||
<table id="legend">
|
||||
<tr>
|
||||
<th>Color</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr class="result">
|
||||
<td class="pass">PASS</td>
|
||||
<td>Test passed and was expected to pass</td>
|
||||
</tr>
|
||||
<tr class="result">
|
||||
<td class="xfail">XFAIL</td>
|
||||
<td>Test failed and expected to fail</td>
|
||||
</tr>
|
||||
<tr class="result">
|
||||
<td class="fail">FAIL</td>
|
||||
<td>Test failed but was expected to pass</td>
|
||||
</tr>
|
||||
<tr class="result">
|
||||
<td class="xpass">XPASS</td>
|
||||
<td>Test passed but was expected to fail</td>
|
||||
</tr>
|
||||
<tr class="result">
|
||||
<td class="error">ERROR</td>
|
||||
<td>The compiler, linker or the test segfaulted</td>
|
||||
</tr>
|
||||
<tr class="result">
|
||||
<td class="generic">+</td>
|
||||
<td>Changes from FAIL, XPASS or ERROR to PASS or XFAIL</td>
|
||||
</tr>
|
||||
<tr class="result">
|
||||
<td class="generic">-</td>
|
||||
<td>Changes from PASS or XFAIL to FAIL, XPASS or ERROR</td>
|
||||
</tr>
|
||||
<tr class="result">
|
||||
<td class="generic">chg</td>
|
||||
<td>Changed within the good or bad group without crossing over</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Results</h2>
|
||||
<table>
|
||||
<tr class="head">
|
||||
<th></th>
|
||||
<th colspan="5" class="borderleft">Test results</th>
|
||||
<th colspan="3" class="borderleft">Diff to previous</th>
|
||||
<th colspan="3" class="borderleft">Diff to ` ~ std.path.getBaseName(reference) ~ `</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th class="borderleft">PASS</th>
|
||||
<th>XFAIL</th>
|
||||
<th>FAIL</th>
|
||||
<th>XPASS</th>
|
||||
<th>ERROR</th>
|
||||
<th class="borderleft">+</th>
|
||||
<th>-</th>
|
||||
<th>chg</th>
|
||||
<th class="borderleft">+</th>
|
||||
<th>-</th>
|
||||
<th>chg</th>
|
||||
</tr>
|
||||
`);
|
||||
|
||||
for(int i = files.length - 1; i >= 0; --i) {
|
||||
auto file = files[i];
|
||||
index.writefln(`<tr class="` ~ (i%2 ? `result` : `odd result`) ~ `">`);
|
||||
char[] id = std.path.getBaseName(file);
|
||||
char[] statsname = std.path.join(std.path.join(basedir, id), "stats.base");
|
||||
index.writef(cast(char[])std.file.read(statsname));
|
||||
|
||||
if(i != 0) {
|
||||
char[] newid = std.path.getBaseName(files[i-1]);
|
||||
statsname = std.path.join(std.path.join(basedir, newid ~ "-to-" ~ id), "stats.base");
|
||||
index.writef(cast(char[])std.file.read(statsname));
|
||||
} else {
|
||||
index.writefln(`<td class="borderleft"></td><td></td><td></td>`);
|
||||
}
|
||||
|
||||
if(i != files.length - 1) {
|
||||
char[] refid = std.path.getBaseName(reference);
|
||||
statsname = std.path.join(std.path.join(basedir, refid ~ "-to-" ~ id), "stats.base");
|
||||
index.writef(cast(char[])std.file.read(statsname));
|
||||
} else {
|
||||
index.writefln(`<td class="borderleft"></td><td></td><td></td>`);
|
||||
}
|
||||
|
||||
index.writefln(`</tr>`);
|
||||
}
|
||||
|
||||
index.writefln(`</table></body></html>`);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void generateLogStatistics(char[] file, ref Log[char[]] logs)
|
||||
{
|
||||
char[] id = std.path.getBaseName(file);
|
||||
char[] dirname = std.path.join(basedir, id);
|
||||
|
||||
if(std.file.exists(dirname)) {
|
||||
if(std.file.isdir(dirname)) {
|
||||
if(!regenerate) {
|
||||
writefln("Directory ", dirname, " already exists, skipping...");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new Exception(dirname ~ " is not a directory!");
|
||||
}
|
||||
else
|
||||
std.file.mkdir(dirname);
|
||||
|
||||
// parse etc.
|
||||
Log log = new Log(id, file);
|
||||
logs[id] = log;
|
||||
|
||||
// write status
|
||||
{
|
||||
BufferedFile makeFile(char[] name) {
|
||||
return new BufferedFile(std.path.join(dirname, name), FileMode.OutNew);
|
||||
}
|
||||
BufferedFile[Result] resultsfile = [
|
||||
Result.PASS: makeFile("pass.html"),
|
||||
Result.FAIL: makeFile("fail.html"),
|
||||
Result.XPASS: makeFile("xpass.html"),
|
||||
Result.XFAIL: makeFile("xfail.html"),
|
||||
Result.ERROR: makeFile("error.html") ];
|
||||
|
||||
scope(exit) {
|
||||
foreach(file; resultsfile)
|
||||
file.close();
|
||||
}
|
||||
|
||||
foreach(file; resultsfile)
|
||||
file.writefln(`<html><body>`);
|
||||
|
||||
foreach(tkey; log.tests.keys.sort) {
|
||||
auto test = log.tests[tkey];
|
||||
auto result = test.r & Result.BASE_MASK;
|
||||
resultsfile[result].writefln(test.name, " in ", test.file, "<br>");
|
||||
}
|
||||
|
||||
foreach(file; resultsfile)
|
||||
file.writefln(`</body></html>`);
|
||||
}
|
||||
|
||||
BufferedFile stats = new BufferedFile(std.path.join(dirname, "stats.base"), FileMode.OutNew);
|
||||
scope(exit) stats.close();
|
||||
stats.writefln(`<td>`, id, `</td>`);
|
||||
stats.writefln(`<td class="pass borderleft"><a href="`, std.path.join(log.id, "pass.html"), `">`, log.counts[Result.PASS], `</a></td>`);
|
||||
stats.writefln(`<td class="xfail"><a href="`, std.path.join(log.id, "xfail.html"), `">`, log.counts[Result.XFAIL], `</a></td>`);
|
||||
stats.writefln(`<td class="fail"><a href="`, std.path.join(log.id, "fail.html"), `">`, log.counts[Result.FAIL], `</a></td>`);
|
||||
stats.writefln(`<td class="xpass"><a href="`, std.path.join(log.id, "xpass.html"), `">`, log.counts[Result.XPASS], `</a></td>`);
|
||||
stats.writefln(`<td class="error"><a href="`, std.path.join(log.id, "error.html"), `">`, log.counts[Result.ERROR], `</a></td>`);
|
||||
}
|
||||
|
||||
void generateChangeStatistics(char[] file1, char[] file2, ref Log[char[]] logs)
|
||||
{
|
||||
char[] newid = std.path.getBaseName(file1);
|
||||
char[] oldid = std.path.getBaseName(file2);
|
||||
|
||||
char[] dirname = std.path.join(basedir, oldid ~ "-to-" ~ newid);
|
||||
|
||||
if(std.file.exists(dirname)) {
|
||||
if(std.file.isdir(dirname)) {
|
||||
if(!regenerate) {
|
||||
writefln("Directory ", dirname, " already exists, skipping...");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
throw new Exception(dirname ~ " is not a directory!");
|
||||
}
|
||||
else
|
||||
std.file.mkdir(dirname);
|
||||
|
||||
// parse etc.
|
||||
Log newLog, oldLog;
|
||||
Log getOrParse(char[] id, char[] file) {
|
||||
if(id in logs)
|
||||
return logs[id];
|
||||
else {
|
||||
Log tmp = new Log(id, file);
|
||||
logs[id] = tmp;
|
||||
return tmp;
|
||||
}
|
||||
}
|
||||
newLog = getOrParse(newid, file1);
|
||||
oldLog = getOrParse(oldid, file2);
|
||||
|
||||
int nRegressions, nImprovements, nChanges;
|
||||
|
||||
{
|
||||
auto regressionsFile = new BufferedFile(std.path.join(dirname, "regressions.html"), FileMode.OutNew);
|
||||
scope(exit) regressionsFile.close();
|
||||
regressionsFile.writefln(`<html><body>`);
|
||||
|
||||
auto improvementsFile = new BufferedFile(std.path.join(dirname, "improvements.html"), FileMode.OutNew);
|
||||
scope(exit) improvementsFile.close();
|
||||
improvementsFile.writefln(`<html><body>`);
|
||||
|
||||
auto changesFile = new BufferedFile(std.path.join(dirname, "changes.html"), FileMode.OutNew);
|
||||
scope(exit) changesFile.close();
|
||||
changesFile.writefln(`<html><body>`);
|
||||
|
||||
BufferedFile targetFile;
|
||||
|
||||
foreach(file; newLog.tests.keys.sort){
|
||||
Test* t = file in newLog.tests;
|
||||
Test* oldT = file in oldLog.tests;
|
||||
|
||||
if(oldT !is null){
|
||||
if(oldT.r == t.r)
|
||||
continue;
|
||||
else if(t.r >= Result.XPASS && oldT.r && oldT.r <= Result.XFAIL){
|
||||
targetFile = regressionsFile;
|
||||
nRegressions++;
|
||||
}
|
||||
else if(t.r && t.r <= Result.XFAIL && oldT.r >= Result.XPASS){
|
||||
targetFile = improvementsFile;
|
||||
nImprovements++;
|
||||
}
|
||||
else {
|
||||
targetFile = changesFile;
|
||||
nChanges++;
|
||||
}
|
||||
targetFile.writefln(toString(oldT.r), " -> ", toString(t.r), " : ", t.name, " in ", t.file, "<br>");
|
||||
}
|
||||
}
|
||||
|
||||
regressionsFile.writefln(`</body></html>`);
|
||||
improvementsFile.writefln(`</body></html>`);
|
||||
changesFile.writefln(`</body></html>`);
|
||||
}
|
||||
|
||||
BufferedFile stats = new BufferedFile(std.path.join(dirname, "stats.base"), FileMode.OutNew);
|
||||
scope(exit) stats.close();
|
||||
auto dir = oldid ~ "-to-" ~ newid;
|
||||
stats.writefln(`<td class="borderleft"><a href="`, std.path.join(dir, "improvements.html"), `">`, nImprovements, `</a></td>`);
|
||||
stats.writefln(`<td><a href="`, std.path.join(dir, "regressions.html"), `">`, nRegressions, `</a></td>`);
|
||||
stats.writefln(`<td><a href="`, std.path.join(dir, "changes.html"), `">`, nChanges, `</a></td>`);
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
module tangotests.arrays1;
|
||||
|
||||
import tango.stdc.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
real[] arr;
|
||||
print(arr);
|
||||
main2();
|
||||
}
|
||||
|
||||
void main2()
|
||||
{
|
||||
real[] arr = void;
|
||||
fill(arr);
|
||||
print(arr);
|
||||
main3();
|
||||
}
|
||||
|
||||
void main3()
|
||||
{
|
||||
}
|
||||
|
||||
void print(real[] arr)
|
||||
{
|
||||
printf("len=%u ; ptr=%p\n", arr.length, arr.ptr);
|
||||
}
|
||||
|
||||
void fill(ref real[] arr)
|
||||
{
|
||||
auto ptr = cast(void**)&arr;
|
||||
*ptr++ = cast(void*)0xbeefc0de;
|
||||
*ptr = cast(void*)0xbeefc0de;
|
||||
}
|
||||
|
||||
void dg1(void delegate(int[]) dg)
|
||||
{
|
||||
dg2(dg);
|
||||
}
|
||||
|
||||
void dg2(void delegate(int[]) dg)
|
||||
{
|
||||
dg(null);
|
||||
}
|
||||
|
||||
void sarr1(int[16] sa)
|
||||
{
|
||||
sarr1(sa);
|
||||
}
|
||||
|
||||
struct Str
|
||||
{
|
||||
size_t length;
|
||||
char* ptr;
|
||||
}
|
||||
|
||||
void str1(Str str)
|
||||
{
|
||||
str1(str);
|
||||
}
|
||||
|
||||
void str2(ref Str str)
|
||||
{
|
||||
str2(str);
|
||||
}
|
||||
|
||||
void str3(out Str str)
|
||||
{
|
||||
str3(str);
|
||||
}
|
||||
|
||||
void str4(Str* str)
|
||||
{
|
||||
str4(str);
|
||||
}
|
||||
|
||||
void str5(Str);
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
module constructors;
|
||||
|
||||
import tango.io.Console;
|
||||
|
||||
class C
|
||||
{
|
||||
this()
|
||||
{
|
||||
Cout("C()").newline;
|
||||
}
|
||||
this(char[] str)
|
||||
{
|
||||
Cout("C(")(str)(")").newline;
|
||||
}
|
||||
}
|
||||
|
||||
class D : C
|
||||
{
|
||||
this()
|
||||
{
|
||||
super("D");
|
||||
Cout("D()").newline;
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
auto c1 = new C();
|
||||
auto c2 = new C("C");
|
||||
auto d = new D();
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
module tangotests.files1;
|
||||
|
||||
//import tango.io.Stdout;
|
||||
import tango.io.File;
|
||||
|
||||
void main()
|
||||
{
|
||||
auto file = new File("files1.output");
|
||||
char[] str = "hello world from files1 test\n";
|
||||
void[] data = cast(void[])str;
|
||||
file.write(str);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
module tangotests.gc2;
|
||||
|
||||
import tango.core.Memory;
|
||||
|
||||
void main()
|
||||
{
|
||||
char[] tmp = new char[2500];
|
||||
GC.collect();
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
module tangotests.ina1;
|
||||
|
||||
import tango.stdc.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
int alder;
|
||||
printf("Hvor gammel er du?\n");
|
||||
scanf("%d", &alder);
|
||||
printf("om 10 år er du %d\n", alder + 10);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
import tango.io.Console;
|
||||
|
||||
void main()
|
||||
{
|
||||
Cout("Hi, says LDC + Tango").newline;
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
module tangotests.mem1;
|
||||
|
||||
import tango.stdc.stdio;
|
||||
|
||||
void main()
|
||||
{
|
||||
printf("new int;\n");
|
||||
int* i = new int;
|
||||
assert(*i == 0);
|
||||
|
||||
printf("new int[3];\n");
|
||||
int[] ar = new int[3];
|
||||
ar[0] = 1;
|
||||
ar[1] = 56;
|
||||
assert(ar.length == 3);
|
||||
assert(ar[0] == 1);
|
||||
assert(ar[1] == 56);
|
||||
assert(ar[2] == 0);
|
||||
|
||||
printf("array ~= elem;\n");
|
||||
int[] ar2;
|
||||
ar2 ~= 22;
|
||||
assert(ar2.length == 1);
|
||||
assert(ar2[0] == 22);
|
||||
|
||||
printf("array ~= array;\n");
|
||||
ar2 ~= ar;
|
||||
assert(ar2.length == 4);
|
||||
assert(ar2[0] == 22);
|
||||
assert(ar2[1] == 1);
|
||||
printf("%d %d %d %d\n", ar2[0], ar2[1], ar2[2], ar2[3]);
|
||||
assert(ar2[2] == 56);
|
||||
assert(ar2[3] == 0);
|
||||
|
||||
printf("array ~ array;\n");
|
||||
int[] ar5 = ar ~ ar2;
|
||||
assert(ar5.length == 7);
|
||||
assert(ar5[0] == 1);
|
||||
assert(ar5[1] == 56);
|
||||
assert(ar5[2] == 0);
|
||||
assert(ar5[3] == 22);
|
||||
assert(ar5[4] == 1);
|
||||
assert(ar5[5] == 56);
|
||||
assert(ar5[6] == 0);
|
||||
|
||||
printf("array ~ elem;\n");
|
||||
int[] ar4 = ar2 ~ 123;
|
||||
assert(ar4.length == 5);
|
||||
assert(ar4[0] == 22);
|
||||
assert(ar4[1] == 1);
|
||||
assert(ar4[2] == 56);
|
||||
assert(ar4[3] == 0);
|
||||
assert(ar4[4] == 123);
|
||||
|
||||
printf("elem ~ array;\n");
|
||||
int[] ar3 = 123 ~ ar2;
|
||||
assert(ar3.length == 5);
|
||||
assert(ar3[0] == 123);
|
||||
assert(ar3[1] == 22);
|
||||
assert(ar3[2] == 1);
|
||||
assert(ar3[3] == 56);
|
||||
assert(ar3[4] == 0);
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
module tangotests.mem4;
|
||||
|
||||
import tango.stdc.stdio;
|
||||
|
||||
class C {
|
||||
int* ptr;
|
||||
this() {
|
||||
printf("this()\n");
|
||||
ptr = new int;
|
||||
}
|
||||
~this() {
|
||||
printf("~this()\n");
|
||||
delete ptr;
|
||||
assert(ptr is null);
|
||||
}
|
||||
final void check()
|
||||
{
|
||||
printf("check()\n");
|
||||
assert(ptr !is null);
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
C c = new C();
|
||||
c.check();
|
||||
delete c;
|
||||
assert(c is null);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import tango.io.Stdout;
|
||||
|
||||
void main()
|
||||
{
|
||||
Stdout("Hello World").newline;
|
||||
Stdout.formatln("{} {}", "Hello", "World");
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
module tangotests.stdout2;
|
||||
|
||||
import tango.io.Stdout;
|
||||
|
||||
void main()
|
||||
{
|
||||
Stdout.formatln("{} {} {}", "a", "b", 1.0);
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
module tangotests.templ1;
|
||||
|
||||
import Util = tango.text.Util;
|
||||
|
||||
extern(C) int printf(char*, ...);
|
||||
|
||||
void main()
|
||||
{
|
||||
foreach (line; Util.lines("a\nb\nc"))
|
||||
{
|
||||
printf("%.*s\n", line.length, line.ptr);
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import tango.io.Console;
|
||||
void main()
|
||||
{
|
||||
Cout("getting name std").newline;
|
||||
Cerr("getting name err").newline;
|
||||
auto s = Cin.get();
|
||||
Cout("putting name").newline;
|
||||
Cout (s).newline;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
module tangotests.vararg1;
|
||||
|
||||
import tango.stdc.stdio;
|
||||
|
||||
void func(int[] arr...)
|
||||
{
|
||||
printf("1,2,4,5,6 == %d,%d,%d,%d,%d\n", arr[0],arr[1],arr[2],arr[3],arr[4]);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
func(1,2,4,5,6);
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
module tangotests.vararg2;
|
||||
|
||||
extern(C) int printf(char*, ...);
|
||||
|
||||
import tango.core.Vararg;
|
||||
|
||||
void main()
|
||||
{
|
||||
func(0xf00, 1, " ", 2, " ", 3, "\n", 0.3, "\n");
|
||||
}
|
||||
|
||||
void func(int foo, ...)
|
||||
{
|
||||
foreach(t; _arguments)
|
||||
{
|
||||
if (t == typeid(char[]))
|
||||
{
|
||||
char[] str = va_arg!(char[])(_argptr);
|
||||
printf("%.*s", str.length, str.ptr);
|
||||
}
|
||||
else if (t == typeid(int))
|
||||
{
|
||||
printf("%d", va_arg!(int)(_argptr));
|
||||
}
|
||||
else if (t == typeid(float))
|
||||
{
|
||||
printf("%f", va_arg!(float)(_argptr));
|
||||
}
|
||||
else if (t == typeid(double))
|
||||
{
|
||||
printf("%f", va_arg!(double)(_argptr));
|
||||
}
|
||||
else if (t == typeid(real))
|
||||
{
|
||||
printf("%f", va_arg!(real)(_argptr));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0, "not int");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
module tangotests.volatile1;
|
||||
|
||||
import tango.stdc.stdlib;
|
||||
|
||||
void main()
|
||||
{
|
||||
int var = rand();
|
||||
{
|
||||
int i = var;
|
||||
volatile;
|
||||
int j = i;
|
||||
}
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
module runminitest;
|
||||
|
||||
import tango.sys.Environment,
|
||||
tango.io.Stdout,
|
||||
tango.io.vfs.FileFolder;
|
||||
import Path = tango.io.Path;
|
||||
import Util = tango.text.Util;
|
||||
import tango.text.convert.Format;
|
||||
import tango.stdc.stdlib,
|
||||
tango.stdc.stringz;
|
||||
|
||||
int main(char[][] args)
|
||||
{
|
||||
enum : int
|
||||
{
|
||||
COMPILE,
|
||||
NOCOMPILE,
|
||||
RUN,
|
||||
NORUN
|
||||
}
|
||||
|
||||
char[][] compilefailed;
|
||||
char[][] nocompilefailed;
|
||||
char[][] runfailed;
|
||||
char[][] norunfailed;
|
||||
|
||||
Environment.cwd("mini");
|
||||
|
||||
if (!Path.exists("obj"))
|
||||
Path.createFolder("obj");
|
||||
|
||||
foreach(f; Path.children("./obj"))
|
||||
{
|
||||
Path.remove(f.path ~ f.name);
|
||||
}
|
||||
|
||||
static int classify(char[] name)
|
||||
{
|
||||
char[] tail;
|
||||
char[] desc = Util.head(name, "_", tail);
|
||||
if ("compile" == desc)
|
||||
return COMPILE;
|
||||
else if ("nocompile" == desc)
|
||||
return NOCOMPILE;
|
||||
else if ("run" == desc)
|
||||
return RUN;
|
||||
else if ("norun" == desc)
|
||||
return NORUN;
|
||||
return RUN;
|
||||
}
|
||||
|
||||
auto scan = new FileFolder (".");
|
||||
auto contents = scan.tree.catalog("*.d");
|
||||
foreach(c; contents) {
|
||||
auto testname = Path.parse(c.name).name;
|
||||
Stdout.formatln("TEST NAME: {}", testname);
|
||||
|
||||
char[] cmd = Format.convert("ldc {} -quiet -L-s -ofobj/{}", c, testname);
|
||||
foreach(v; args[1..$]) {
|
||||
cmd ~= ' ';
|
||||
cmd ~= v;
|
||||
}
|
||||
int cl = classify(testname);
|
||||
if (cl == COMPILE || cl == NOCOMPILE)
|
||||
cmd ~= " -c";
|
||||
Stdout(cmd).newline;
|
||||
if (system(toStringz(cmd)) != 0) {
|
||||
if (cl != NOCOMPILE)
|
||||
compilefailed ~= c.toString;
|
||||
}
|
||||
else if (cl == RUN || cl == NORUN) {
|
||||
if (system(toStringz(Path.native("obj/" ~ testname))) != 0) {
|
||||
if (cl == RUN)
|
||||
runfailed ~= c.toString;
|
||||
}
|
||||
else {
|
||||
if (cl == NORUN)
|
||||
norunfailed ~= c.toString;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (cl == NOCOMPILE)
|
||||
nocompilefailed ~= c.toString;
|
||||
}
|
||||
}
|
||||
|
||||
size_t nerrors = 0;
|
||||
|
||||
if (compilefailed.length > 0)
|
||||
{
|
||||
Stdout.formatln("{}{}{}{}", compilefailed.length, '/', contents.files, " of the tests failed to compile:");
|
||||
foreach(b; compilefailed) {
|
||||
Stdout.formatln(" {}",b);
|
||||
}
|
||||
nerrors += compilefailed.length;
|
||||
}
|
||||
|
||||
if (nocompilefailed.length > 0)
|
||||
{
|
||||
Stdout.formatln("{}{}{}{}", nocompilefailed.length, '/', contents.files, " of the tests failed to NOT compile:");
|
||||
foreach(b; nocompilefailed) {
|
||||
Stdout.formatln(" {}",b);
|
||||
}
|
||||
nerrors += nocompilefailed.length;
|
||||
}
|
||||
|
||||
if (runfailed.length > 0)
|
||||
{
|
||||
Stdout.formatln("{}{}{}{}", runfailed.length, '/', contents.files, " of the tests failed to run:");
|
||||
foreach(b; runfailed) {
|
||||
Stdout.formatln(" {}",b);
|
||||
}
|
||||
nerrors += runfailed.length;
|
||||
}
|
||||
|
||||
if (norunfailed.length > 0)
|
||||
{
|
||||
Stdout.formatln("{}{}{}{}", norunfailed.length, '/', contents.files, " of the tests failed to NOT run:");
|
||||
foreach(b; norunfailed) {
|
||||
Stdout.formatln(" {}",b);
|
||||
}
|
||||
nerrors += norunfailed.length;
|
||||
}
|
||||
|
||||
Stdout.formatln("{}{}{}{}", contents.files - nerrors, '/', contents.files, " of the tests passed");
|
||||
|
||||
return nerrors ? 1 : 0;
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# check for command line arguments
|
||||
if [ -z "$1" ] ; then
|
||||
echo "Usage: `basename $0` <test result file>"
|
||||
exit
|
||||
fi
|
||||
TARGETFILE=$1
|
||||
|
||||
# build libtangobos-partial
|
||||
echo "Building libtangobos-partial.a"
|
||||
cd testincludes
|
||||
make
|
||||
cd ..
|
||||
|
||||
# check for dstress
|
||||
if ! [ -d dstress ] ; then
|
||||
echo "Testing requires DStress to be checked out into dstress/"
|
||||
exit
|
||||
fi
|
||||
|
||||
BASEPATH=`pwd`
|
||||
cd dstress
|
||||
|
||||
# remove excessive tests
|
||||
sed -i -e 's/torture-//g' Makefile
|
||||
|
||||
# make sure only .d files in 'run' tests are run
|
||||
sed -i -e 's/find run -type f |/find run -type f -name "*\\\\.d" |/' Makefile
|
||||
sed -i -e 's/find norun -type f |/find norun -type f -name "*\\\\.d" |/' Makefile
|
||||
|
||||
# impose more conservative constraints (10s and 256 MB)
|
||||
sed -i -e 's/crashRun 30 1000/crashRun 10 256/' dstress.c
|
||||
|
||||
echo
|
||||
echo "Running new test and storing result in $TARGETFILE ..."
|
||||
echo
|
||||
echo "Remember to make sure you have an up to date runtime!"
|
||||
echo
|
||||
|
||||
if [ -z "$DMD" ] ; then
|
||||
echo "Testing with LDC. Set DMD environment variable to select compiler."
|
||||
DMD="ldmd -I$BASEPATH/testincludes -L$BASEPATH/testincludes/libtangobos-partial.a"
|
||||
echo "Default is $DMD"
|
||||
else
|
||||
echo "Using compiler given by DMD environment variable: $DMD"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "This will take a while, try 'tail -f $TARGETFILE' to follow progress."
|
||||
echo "Note that aborting is tricky. Try killing the processes by the name of"
|
||||
echo "run.sh, compile.sh, nocompile.sh and norun.sh as well as this one."
|
||||
echo
|
||||
|
||||
DMD=$DMD make compile nocompile run norun > ../$TARGETFILE
|
||||
cd ..
|
||||
|
||||
echo
|
||||
echo "Cleanup... (removing all .o and .exe files)"
|
||||
echo
|
||||
|
||||
find dstress -name "*\.o" -o -name "*\.exe" -delete
|
||||
@@ -1,51 +0,0 @@
|
||||
# Copied from tango runtime makefile.
|
||||
# Designed to work with GNU make
|
||||
# Targets:
|
||||
# make
|
||||
# Same as make all
|
||||
# make lib
|
||||
# Build the common library
|
||||
# make doc
|
||||
# Generate documentation
|
||||
# make clean
|
||||
# Delete unneeded files created by build process
|
||||
|
||||
LIB_TARGET=libtangobos-partial.a
|
||||
LIB_MASK=libtangobos-partial.*
|
||||
|
||||
CP=cp -f
|
||||
RM=rm -f
|
||||
MD=mkdir -p
|
||||
|
||||
ADD_CFLAGS=
|
||||
ADD_DFLAGS=
|
||||
|
||||
#CFLAGS=-O3 $(ADD_CFLAGS)
|
||||
CFLAGS=-g $(ADD_CFLAGS)
|
||||
|
||||
#DFLAGS=-release -O3 -inline -w $(ADD_DFLAGS)
|
||||
DFLAGS=-g -w -noasm $(ADD_DFLAGS)
|
||||
|
||||
DC=ldc
|
||||
|
||||
targets : lib
|
||||
all : lib
|
||||
lib : tangobos.lib
|
||||
|
||||
SOURCE= \
|
||||
std/gc.d \
|
||||
std/outofmemory.d \
|
||||
std/IEEE.d \
|
||||
std/stdarg.d \
|
||||
# std/asserterror.d \
|
||||
# std/format.d \
|
||||
|
||||
tangobos.lib : $(LIB_TARGET)
|
||||
|
||||
$(LIB_TARGET) : $(ALL_OBJS)
|
||||
$(DC) -lib -of$(LIB_TARGET) $(DFLAGS) $(SOURCE)
|
||||
|
||||
clean :
|
||||
$(RM) $(ALL_OBJS)
|
||||
find . -name "$(LIB_MASK)" | xargs $(RM)
|
||||
|
||||
@@ -1,320 +0,0 @@
|
||||
// A copy of the object.di from Tango, with std.compat publically included to
|
||||
// to make sure the Phobos compatibilty aliases are always available (DStress
|
||||
// depends on Phobos).
|
||||
module object;
|
||||
|
||||
public import std.compat;
|
||||
|
||||
/// unsigned integer type of the size of a pointer
|
||||
alias typeof(int.sizeof) size_t;
|
||||
/// signed integer type of the size of a pointer
|
||||
alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t;
|
||||
|
||||
/// type of hashes used in associative arrays
|
||||
alias size_t hash_t;
|
||||
/// type returned by equality comparisons
|
||||
alias int equals_t;
|
||||
|
||||
/// root class for all objects in D
|
||||
class Object
|
||||
{
|
||||
void dispose();
|
||||
/// returns a string representation of the object (for debugging purposes)
|
||||
char[] toString();
|
||||
/// returns a hash
|
||||
hash_t toHash();
|
||||
/// compares two objects, returns a number ret, such (a op b) is rewritten as (a.opCmp(b) op 0)
|
||||
/// thus if a>b a.opCmp(b)>0
|
||||
int opCmp(Object o);
|
||||
/// returns 0 if this==o
|
||||
equals_t opEquals(Object o);
|
||||
|
||||
interface Monitor
|
||||
{
|
||||
void lock();
|
||||
void unlock();
|
||||
}
|
||||
}
|
||||
|
||||
/// interface, if COM objects (IUnknown) they might not be casted to Object
|
||||
struct Interface
|
||||
{
|
||||
/// class info of the interface
|
||||
ClassInfo classinfo;
|
||||
void*[] vtbl;
|
||||
/// offset to Interface 'this' from Object 'this'
|
||||
ptrdiff_t offset;
|
||||
}
|
||||
|
||||
struct PointerMap
|
||||
{
|
||||
// Conservative pointer mask (one word, scan it, we don't know if it's
|
||||
// really a pointer)
|
||||
size_t[] bits = [1, 1, 0];
|
||||
|
||||
size_t size();
|
||||
bool mustScanWordAt(size_t offset);
|
||||
bool isPointerAt(size_t offset);
|
||||
bool canUpdatePointers();
|
||||
}
|
||||
|
||||
struct PointerMapBuilder
|
||||
{
|
||||
private size_t[] m_bits = null;
|
||||
private size_t m_size = 0;
|
||||
|
||||
void size(size_t bytes);
|
||||
void mustScanWordAt(size_t offset);
|
||||
void inlineAt(size_t offset, PointerMap pm);
|
||||
PointerMap convertToPointerMap();
|
||||
}
|
||||
|
||||
/// class information
|
||||
class ClassInfo : Object
|
||||
{
|
||||
byte[] init; // class static initializer
|
||||
char[] name; /// class name
|
||||
void*[] vtbl; // virtual function pointer table
|
||||
Interface[] interfaces; /// implemented interfaces
|
||||
ClassInfo base; /// base class
|
||||
void* destructor; /// compiler dependent storage of destructor function pointer
|
||||
void* classInvariant; /// compiler dependent storage of classInvariant function pointer
|
||||
/// flags
|
||||
/// 1: IUnknown
|
||||
/// 2: has no possible pointers into GC memory
|
||||
/// 4: has offTi[] member
|
||||
/// 8: has constructors
|
||||
// 32: has typeinfo
|
||||
uint flags;
|
||||
void* deallocator;
|
||||
OffsetTypeInfo[] offTi; /// offsets of its members (not supported by all compilers)
|
||||
void* defaultConstructor; /// compiler dependent storage of constructor function pointer
|
||||
/// TypeInfo information about this class
|
||||
TypeInfo typeinfo;
|
||||
version (D_HavePointerMap) {
|
||||
PointerMap pointermap;
|
||||
}
|
||||
/// finds the classinfo of the class with the given name
|
||||
static ClassInfo find(char[] classname);
|
||||
/// creates an instance of this class (works only if there is a constructor without arguments)
|
||||
Object create();
|
||||
}
|
||||
|
||||
/// offset of the different fields (at the moment works only with ldc)
|
||||
struct OffsetTypeInfo
|
||||
{
|
||||
size_t offset;
|
||||
TypeInfo ti;
|
||||
}
|
||||
|
||||
/// information on a type
|
||||
class TypeInfo
|
||||
{
|
||||
/// returns the hash of the type of this TypeInfo at p
|
||||
hash_t getHash(void *p);
|
||||
/// returns 0 if the types of this TypeInfo stored at p1 and p2 are different
|
||||
equals_t equals(void *p1, void *p2);
|
||||
/// compares the types of this TypeInfo stored at p1 and p2
|
||||
int compare(void *p1, void *p2);
|
||||
/// Return alignment of type
|
||||
size_t talign() { return tsize(); }
|
||||
/// returns the size of a type with the current TypeInfo
|
||||
size_t tsize();
|
||||
/// swaps the two types stored at p1 and p2
|
||||
void swap(void *p1, void *p2);
|
||||
/// "next" TypeInfo (for an array its elements, for a pointer what it is pointed to,...)
|
||||
TypeInfo next();
|
||||
void[] init();
|
||||
/// flags, 1: has possible pointers into GC memory
|
||||
uint flags();
|
||||
PointerMap pointermap();
|
||||
/// offsets of the various elements
|
||||
OffsetTypeInfo[] offTi();
|
||||
|
||||
/** Return internal info on arguments fitting into 8byte.
|
||||
* See X86-64 ABI 3.2.3
|
||||
*/
|
||||
version (X86_64) int argTypes(out TypeInfo arg1, out TypeInfo arg2);
|
||||
}
|
||||
|
||||
class TypeInfo_Typedef : TypeInfo
|
||||
{
|
||||
TypeInfo base;
|
||||
char[] name;
|
||||
void[] m_init;
|
||||
}
|
||||
|
||||
class TypeInfo_Enum : TypeInfo_Typedef
|
||||
{
|
||||
}
|
||||
|
||||
class TypeInfo_Pointer : TypeInfo
|
||||
{
|
||||
TypeInfo m_next;
|
||||
}
|
||||
|
||||
class TypeInfo_Array : TypeInfo
|
||||
{
|
||||
/// typeinfo of the elements, might be null for basic arrays, it is safer to use next()
|
||||
TypeInfo value;
|
||||
|
||||
//ensure derived array TypeInfos use correct method
|
||||
//if this declaration is forgotten, e.g. TypeInfo_Ai will have a wrong vtbl entry
|
||||
PointerMap pointermap();
|
||||
}
|
||||
|
||||
class TypeInfo_StaticArray : TypeInfo
|
||||
{
|
||||
TypeInfo value;
|
||||
size_t len;
|
||||
}
|
||||
|
||||
class TypeInfo_AssociativeArray : TypeInfo
|
||||
{
|
||||
TypeInfo value;
|
||||
TypeInfo key;
|
||||
}
|
||||
|
||||
class TypeInfo_Function : TypeInfo
|
||||
{
|
||||
TypeInfo next;
|
||||
}
|
||||
|
||||
class TypeInfo_Delegate : TypeInfo
|
||||
{
|
||||
TypeInfo next;
|
||||
}
|
||||
|
||||
class TypeInfo_Class : TypeInfo
|
||||
{
|
||||
ClassInfo info;
|
||||
}
|
||||
|
||||
class TypeInfo_Interface : TypeInfo
|
||||
{
|
||||
ClassInfo info;
|
||||
}
|
||||
|
||||
class TypeInfo_Struct : TypeInfo
|
||||
{
|
||||
char[] name;
|
||||
void[] m_init;
|
||||
|
||||
hash_t function() xtoHash;
|
||||
int function(void*) xopEquals;
|
||||
int function(void*) xopCmp;
|
||||
char[] function() xtoString;
|
||||
|
||||
uint m_flags;
|
||||
|
||||
version (D_HavePointerMap) {
|
||||
PointerMap m_pointermap;
|
||||
}
|
||||
}
|
||||
|
||||
class TypeInfo_Tuple : TypeInfo
|
||||
{
|
||||
TypeInfo[] elements;
|
||||
}
|
||||
|
||||
/// information about a module (can be used for example to get its unittests)
|
||||
class ModuleInfo
|
||||
{
|
||||
/// name of the module
|
||||
char[] name;
|
||||
///
|
||||
ModuleInfo[] importedModules;
|
||||
///
|
||||
ClassInfo[] localClasses;
|
||||
uint flags;
|
||||
|
||||
void function() ctor;
|
||||
void function() dtor;
|
||||
/// unit tests of the module
|
||||
void function() unitTest;
|
||||
|
||||
version(GNU){}
|
||||
else{
|
||||
void* xgetMembers;
|
||||
void function() ictor;
|
||||
}
|
||||
|
||||
/// loops on all the modules loaded
|
||||
static int opApply( int delegate( ref ModuleInfo ) );
|
||||
}
|
||||
|
||||
/// base class for all exceptions/errors
|
||||
/// it is a good practice to pass line and file to the exception, which can be obtained with
|
||||
/// __FILE__ and __LINE__, and then passed to the exception constructor
|
||||
class Exception : Object
|
||||
{
|
||||
/// Information about a frame in the stack
|
||||
struct FrameInfo{
|
||||
/// line number in the source of the most likely start adress (0 if not available)
|
||||
long line;
|
||||
/// number of the stack frame (starting at 0 for the top frame)
|
||||
ptrdiff_t iframe;
|
||||
/// offset from baseSymb: within the function, or from the closest symbol
|
||||
ptrdiff_t offsetSymb;
|
||||
/// adress of the symbol in this execution
|
||||
size_t baseSymb;
|
||||
/// offset within the image (from this you can use better methods to get line number
|
||||
/// a posteriory)
|
||||
ptrdiff_t offsetImg;
|
||||
/// base adress of the image (will be dependent on randomization schemes)
|
||||
size_t baseImg;
|
||||
/// adress of the function, or at which the ipc will return
|
||||
/// (which most likely is the one after the adress where it started)
|
||||
/// this is the raw adress returned by the backtracing function
|
||||
size_t address;
|
||||
/// file (image) of the current adress
|
||||
char[] file;
|
||||
/// name of the function, if possible demangled
|
||||
char[] func;
|
||||
/// extra information (for example calling arguments)
|
||||
char[] extra;
|
||||
/// if the address is exact or it is the return address
|
||||
bool exactAddress;
|
||||
/// if this function is an internal functions (for example the backtracing function itself)
|
||||
/// if true by default the frame is not printed
|
||||
bool internalFunction;
|
||||
alias void function(FrameInfo*,void delegate(char[])) FramePrintHandler;
|
||||
/// the default printing function
|
||||
static FramePrintHandler defaultFramePrintingFunction;
|
||||
/// writes out the current frame info
|
||||
void writeOut(void delegate(char[])sink);
|
||||
/// clears the frame information stored
|
||||
void clear();
|
||||
}
|
||||
/// trace information has the following interface
|
||||
interface TraceInfo
|
||||
{
|
||||
int opApply( int delegate( ref FrameInfo fInfo) );
|
||||
void writeOut(void delegate(char[])sink);
|
||||
}
|
||||
/// message of the exception
|
||||
char[] msg;
|
||||
/// file name
|
||||
char[] file;
|
||||
/// line number
|
||||
size_t line; // long would be better to be consistent
|
||||
/// trace of where the exception was raised
|
||||
TraceInfo info;
|
||||
/// next exception (if an exception made an other exception raise)
|
||||
Exception next;
|
||||
|
||||
/// designated constructor (breakpoint this if you want to catch all explict Exception creations,
|
||||
/// special exception just allocate and init the structure directly)
|
||||
this(char[] msg, char[] file, long line, Exception next, TraceInfo info );
|
||||
this(char[] msg, Exception next=null);
|
||||
this(char[] msg, char[] file, long line, Exception next = null);
|
||||
/// returns the message of the exception, should not be used (because it should not allocate,
|
||||
/// and thus only a small message is returned)
|
||||
char[] toString();
|
||||
/// writes out the message of the exception, by default writes toString
|
||||
/// override this is you have a better message for the exception
|
||||
void writeOutMsg(void delegate(char[]) sink);
|
||||
/// writes out the exception message, file, line number, stacktrace (if available) and any
|
||||
/// subexceptions
|
||||
void writeOut(void delegate(char[]) sink);
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
// Written in the D programming language
|
||||
/*
|
||||
* Authors:
|
||||
* Walter Bright, Don Clugston
|
||||
* Copyright:
|
||||
* Copyright (c) 2001-2005 by Digital Mars,
|
||||
* All Rights Reserved,
|
||||
* www.digitalmars.com
|
||||
* License:
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* <ul>
|
||||
* <li> The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* </li>
|
||||
* <li> Altered source versions must be plainly marked as such, and must not
|
||||
* be misrepresented as being the original software.
|
||||
* </li>
|
||||
* <li> This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
/* Cut down version for libtangobos-partial/dstress */
|
||||
|
||||
module tango.math.IEEE;
|
||||
|
||||
|
||||
private:
|
||||
/*
|
||||
* The following IEEE 'real' formats are currently supported:
|
||||
* 64 bit Big-endian 'double' (eg PowerPC)
|
||||
* 128 bit Big-endian 'quadruple' (eg SPARC)
|
||||
* 64 bit Little-endian 'double' (eg x86-SSE2)
|
||||
* 80 bit Little-endian, with implied bit 'real80' (eg x87, Itanium).
|
||||
* 128 bit Little-endian 'quadruple' (not implemented on any known processor!)
|
||||
*
|
||||
* Non-IEEE 128 bit Big-endian 'doubledouble' (eg PowerPC) has partial support
|
||||
*/
|
||||
version(LittleEndian) {
|
||||
static assert(real.mant_dig == 53 || real.mant_dig==64
|
||||
|| real.mant_dig == 113,
|
||||
"Only 64-bit, 80-bit, and 128-bit reals"
|
||||
" are supported for LittleEndian CPUs");
|
||||
} else {
|
||||
static assert(real.mant_dig == 53 || real.mant_dig==106
|
||||
|| real.mant_dig == 113,
|
||||
"Only 64-bit and 128-bit reals are supported for BigEndian CPUs."
|
||||
" double-double reals have partial support");
|
||||
}
|
||||
|
||||
// Constants used for extracting the components of the representation.
|
||||
// They supplement the built-in floating point properties.
|
||||
template floatTraits(T) {
|
||||
// EXPMASK is a ushort mask to select the exponent portion (without sign)
|
||||
// POW2MANTDIG = pow(2, real.mant_dig) is the value such that
|
||||
// (smallest_denormal)*POW2MANTDIG == real.min
|
||||
// EXPPOS_SHORT is the index of the exponent when represented as a ushort array.
|
||||
// SIGNPOS_BYTE is the index of the sign when represented as a ubyte array.
|
||||
static if (T.mant_dig == 24) { // float
|
||||
const ushort EXPMASK = 0x7F80;
|
||||
const ushort EXPBIAS = 0x3F00;
|
||||
const uint EXPMASK_INT = 0x7F80_0000;
|
||||
const uint MANTISSAMASK_INT = 0x007F_FFFF;
|
||||
const real POW2MANTDIG = 0x1p+24;
|
||||
version(LittleEndian) {
|
||||
const EXPPOS_SHORT = 1;
|
||||
} else {
|
||||
const EXPPOS_SHORT = 0;
|
||||
}
|
||||
} else static if (T.mant_dig == 53) { // double, or real==double
|
||||
const ushort EXPMASK = 0x7FF0;
|
||||
const ushort EXPBIAS = 0x3FE0;
|
||||
const uint EXPMASK_INT = 0x7FF0_0000;
|
||||
const uint MANTISSAMASK_INT = 0x000F_FFFF; // for the MSB only
|
||||
const real POW2MANTDIG = 0x1p+53;
|
||||
version(LittleEndian) {
|
||||
const EXPPOS_SHORT = 3;
|
||||
const SIGNPOS_BYTE = 7;
|
||||
} else {
|
||||
const EXPPOS_SHORT = 0;
|
||||
const SIGNPOS_BYTE = 0;
|
||||
}
|
||||
} else static if (T.mant_dig == 64) { // real80
|
||||
const ushort EXPMASK = 0x7FFF;
|
||||
const ushort EXPBIAS = 0x3FFE;
|
||||
const real POW2MANTDIG = 0x1p+63;
|
||||
version(LittleEndian) {
|
||||
const EXPPOS_SHORT = 4;
|
||||
const SIGNPOS_BYTE = 9;
|
||||
} else {
|
||||
const EXPPOS_SHORT = 0;
|
||||
const SIGNPOS_BYTE = 0;
|
||||
}
|
||||
} else static if (real.mant_dig == 113){ // quadruple
|
||||
const ushort EXPMASK = 0x7FFF;
|
||||
const real POW2MANTDIG = 0x1p+113;
|
||||
version(LittleEndian) {
|
||||
const EXPPOS_SHORT = 7;
|
||||
const SIGNPOS_BYTE = 15;
|
||||
} else {
|
||||
const EXPPOS_SHORT = 0;
|
||||
const SIGNPOS_BYTE = 0;
|
||||
}
|
||||
} else static if (real.mant_dig == 106) { // doubledouble
|
||||
const ushort EXPMASK = 0x7FF0;
|
||||
const real POW2MANTDIG = 0x1p+53; // doubledouble denormals are strange
|
||||
// and the exponent byte is not unique
|
||||
version(LittleEndian) {
|
||||
const EXPPOS_SHORT = 7; // [3] is also an exp short
|
||||
const SIGNPOS_BYTE = 15;
|
||||
} else {
|
||||
const EXPPOS_SHORT = 0; // [4] is also an exp short
|
||||
const SIGNPOS_BYTE = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
/*********************************
|
||||
* Return 1 if sign bit of e is set, 0 if not.
|
||||
*/
|
||||
|
||||
int signbit(real x)
|
||||
{
|
||||
return ((cast(ubyte *)&x)[floatTraits!(real).SIGNPOS_BYTE] & 0x80) != 0;
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
module std.compat;
|
||||
|
||||
extern (C) int printf(char *, ...);
|
||||
|
||||
alias char[] string;
|
||||
alias wchar[] wstring;
|
||||
alias dchar[] dstring;
|
||||
|
||||
alias Exception Error;
|
||||
alias bool bit;
|
||||
@@ -1,250 +0,0 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) 1999-2006 by Digital Mars, www.digitalmars.com
|
||||
* Written by Walter Bright
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* o The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* o Altered source versions must be plainly marked as such, and must not
|
||||
* be misrepresented as being the original software.
|
||||
* o This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* The garbage collector normally works behind the scenes without needing any
|
||||
* specific interaction. These functions are for advanced applications that
|
||||
* benefit from tuning the operation of the collector.
|
||||
* Macros:
|
||||
* WIKI=Phobos/StdGc
|
||||
*/
|
||||
|
||||
module std.gc;
|
||||
|
||||
import tango.core.Memory;
|
||||
|
||||
/**
|
||||
* Add p to list of roots. Roots are references to memory allocated by the
|
||||
collector that are maintained in memory outside the collector pool. The garbage
|
||||
collector will by default look for roots in the stacks of each thread, the
|
||||
registers, and the default static data segment. If roots are held elsewhere,
|
||||
use addRoot() or addRange() to tell the collector not to free the memory it
|
||||
points to.
|
||||
*/
|
||||
void addRoot(void *p) // add p to list of roots
|
||||
{
|
||||
GC.addRoot(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove p from list of roots.
|
||||
*/
|
||||
void removeRoot(void *p) // remove p from list of roots
|
||||
{
|
||||
GC.removeRoot(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add range to scan for roots.
|
||||
*/
|
||||
void addRange(void *pbot, void *ptop) // add range to scan for roots
|
||||
{
|
||||
GC.addRange(pbot, ptop-pbot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove range.
|
||||
*/
|
||||
void removeRange(void *pbot) // remove range
|
||||
{
|
||||
GC.removeRange(pbot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a gc allocated block of memory as possibly containing pointers.
|
||||
*/
|
||||
void hasPointers(void* p)
|
||||
{
|
||||
GC.clrAttr(p, GC.BlkAttr.NO_SCAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a gc allocated block of memory as definitely NOT containing pointers.
|
||||
*/
|
||||
void hasNoPointers(void* p)
|
||||
{
|
||||
GC.setAttr(p, GC.BlkAttr.NO_SCAN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark a gc allocated block of memory pointed to by p as being populated with
|
||||
* an array of TypeInfo ti (as many as will fit).
|
||||
*/
|
||||
//void setTypeInfo(TypeInfo ti, void* p);
|
||||
|
||||
/**
|
||||
* Allocate nbytes of uninitialized data.
|
||||
* The allocated memory will be scanned for pointers during
|
||||
* a gc collection cycle, unless
|
||||
* it is followed by a call to hasNoPointers().
|
||||
*/
|
||||
void[] malloc(size_t nbytes)
|
||||
{
|
||||
void* p = GC.malloc(nbytes);
|
||||
if (p is null)
|
||||
return null;
|
||||
else
|
||||
return p[0..nbytes];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize allocated memory block pointed to by p to be at least nbytes long.
|
||||
* It will try to resize the memory block in place.
|
||||
* If nbytes is 0, the memory block is free'd.
|
||||
* If p is null, the memory block is allocated using malloc.
|
||||
* The returned array may not be at the same location as the original
|
||||
* memory block.
|
||||
* The allocated memory will be scanned for pointers during
|
||||
* a gc collection cycle, unless
|
||||
* it is followed by a call to hasNoPointers().
|
||||
*/
|
||||
void[] realloc(void* p, size_t nbytes)
|
||||
{
|
||||
p = GC.realloc(p, nbytes);
|
||||
if (p is null)
|
||||
return null;
|
||||
else
|
||||
return p[0..nbytes];
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to enlarge the memory block pointed to by p
|
||||
* by at least minbytes beyond its current capacity,
|
||||
* up to a maximum of maxbytes.
|
||||
* Returns:
|
||||
* 0 if could not extend p,
|
||||
* total size of entire memory block if successful.
|
||||
*/
|
||||
size_t extend(void* p, size_t minbytes, size_t maxbytes)
|
||||
{
|
||||
return GC.extend(p, maxbytes, minbytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns capacity (size of the memory block) that p
|
||||
* points to the beginning of.
|
||||
* If p does not point into the gc memory pool, or does
|
||||
* not point to the beginning of an allocated memory block,
|
||||
* 0 is returned.
|
||||
*/
|
||||
size_t capacity(void* p)
|
||||
{
|
||||
return GC.sizeOf(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set gc behavior to match that of 1.0.
|
||||
*/
|
||||
void setV1_0()
|
||||
{
|
||||
}
|
||||
|
||||
/***********************************
|
||||
* Run a full garbage collection cycle.
|
||||
*
|
||||
* The collector normally runs synchronously with a storage allocation request
|
||||
(i.e. it never happens when in code that does not allocate memory). In some
|
||||
circumstances, for example when a particular task is finished, it is convenient
|
||||
to explicitly run the collector and free up all memory used by that task. It
|
||||
can also be helpful to run a collection before starting a new task that would
|
||||
be annoying if it ran a collection in the middle of that task. Explicitly
|
||||
running a collection can also be done in a separate very low priority thread,
|
||||
so that if the program is idly waiting for input, memory can be cleaned up.
|
||||
*/
|
||||
|
||||
void fullCollect()
|
||||
{
|
||||
GC.collect();
|
||||
}
|
||||
|
||||
/***********************************
|
||||
* Run a generational garbage collection cycle.
|
||||
* Takes less time than a fullcollect(), but isn't
|
||||
* as effective.
|
||||
*/
|
||||
|
||||
void genCollect()
|
||||
{
|
||||
GC.collect();
|
||||
}
|
||||
|
||||
//void genCollectNoStack();
|
||||
|
||||
/**
|
||||
* Minimizes physical memory usage
|
||||
*/
|
||||
void minimize()
|
||||
{
|
||||
GC.collect();
|
||||
}
|
||||
|
||||
/***************************************
|
||||
* disable() temporarily disables garbage collection cycle, enable()
|
||||
* then reenables them.
|
||||
*
|
||||
* This is used for brief time critical sections of code, so the amount of time
|
||||
* it will take is predictable.
|
||||
* If the collector runs out of memory while it is disabled, it will throw an
|
||||
* std.outofmemory.OutOfMemoryException.
|
||||
* The disable() function calls can be nested, but must be
|
||||
* matched with corresponding enable() calls.
|
||||
* By default collections are enabled.
|
||||
*/
|
||||
|
||||
void disable()
|
||||
{
|
||||
GC.disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* ditto
|
||||
*/
|
||||
void enable()
|
||||
{
|
||||
GC.enable();
|
||||
}
|
||||
|
||||
//void getStats(out GCStats stats);
|
||||
|
||||
/***************************************
|
||||
* Get handle to the collector.
|
||||
*/
|
||||
|
||||
//void* getGCHandle();
|
||||
|
||||
/***************************************
|
||||
* Set handle to the collector.
|
||||
*/
|
||||
|
||||
//void setGCHandle(void* p);
|
||||
|
||||
//void endGCHandle();
|
||||
|
||||
/*
|
||||
extern (C)
|
||||
{
|
||||
void gc_init();
|
||||
void gc_term();
|
||||
}
|
||||
*/
|
||||
@@ -1,11 +0,0 @@
|
||||
module std.outofmemory;
|
||||
import std.compat;
|
||||
|
||||
public import tango.core.Exception;
|
||||
|
||||
extern (C) void _d_OutOfMemory()
|
||||
{
|
||||
throw cast(OutOfMemoryException)
|
||||
cast(void *)
|
||||
OutOfMemoryException.classinfo.init;
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
|
||||
/*
|
||||
* Placed in public domain.
|
||||
* Written by Hauke Duden and Walter Bright
|
||||
*/
|
||||
|
||||
/* This is for use with variable argument lists with extern(D) linkage. */
|
||||
|
||||
module std.stdarg;
|
||||
|
||||
version(LDC)
|
||||
{
|
||||
public import ldc.vararg;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
alias void* va_list;
|
||||
|
||||
template va_arg(T)
|
||||
{
|
||||
T va_arg(inout va_list _argptr)
|
||||
{
|
||||
T arg = *cast(T*)_argptr;
|
||||
_argptr = _argptr + ((T.sizeof + int.sizeof - 1) & ~(int.sizeof - 1));
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user