Created
April 1, 2015 12:14
-
-
Save yebblies/09c20c74c71c3e1fe5ab to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import std.stdio; | |
import std.process; | |
import std.random; | |
import std.exception; | |
import std.uuid; | |
import std.range; | |
import std.string; | |
abstract | |
class Value | |
{ | |
void writeCheckCpp(ref File f, string prefix, size_t i); | |
void writeCheckD(ref File f, string prefix, size_t i); | |
void writeStructCpp(ref File f); | |
void writeStructD(ref File f); | |
void writeMemberCpp(ref File f, size_t i); | |
void writeMemberD(ref File f, size_t i); | |
} | |
class Struct : Value | |
{ | |
string name; | |
Value[] members; | |
this(string name) | |
{ | |
this.name = name; | |
} | |
override void writeCheckCpp(ref File f, string prefix, size_t i) | |
{ | |
auto m = "val_%d".format(i); | |
f.writefln("\tprintf(\"%s: %%p\\n\", (char*)&%s.%s - (char*)&%s);", m, prefix, m, prefix); | |
} | |
override void writeCheckD(ref File f, string prefix, size_t i) | |
{ | |
auto m = "val_%d".format(i); | |
f.writefln("\tprintf(\"%s: %%p\\n\", cast(char*)&%s.%s - cast(char*)&%s);", m, prefix, m, prefix); | |
} | |
override void writeStructCpp(ref File f) | |
{ | |
foreach(i, m; members) | |
m.writeStructCpp(f); | |
f.writefln("struct %s {", name); | |
foreach(i, m; members) | |
m.writeMemberCpp(f, i); | |
f.writefln("};"); | |
f.writefln(""); | |
} | |
override void writeStructD(ref File f) | |
{ | |
foreach(i, m; members) | |
m.writeStructD(f); | |
f.writefln("struct %s {", name); | |
foreach(i, m; members) | |
m.writeMemberD(f, i); | |
f.writefln("}"); | |
f.writefln(""); | |
} | |
override void writeMemberCpp(ref File f, size_t i) | |
{ | |
auto mname = "val_%d".format(i); | |
f.writefln("\t%s %s;", name, mname); | |
} | |
override void writeMemberD(ref File f, size_t i) | |
{ | |
auto mname = "val_%d".format(i); | |
f.writefln("\t%s %s;", name, mname); | |
} | |
} | |
class Basic : Value | |
{ | |
string dname; | |
string cname; | |
this(string dname, string cname) | |
{ | |
this.dname = dname; | |
this.cname = cname; | |
} | |
override void writeCheckCpp(ref File f, string prefix, size_t i) | |
{ | |
auto m = "val_%d".format(i); | |
f.writefln("\tprintf(\"%s: %%p\\n\", (char*)&%s.%s - (char*)&%s);", m, prefix, m, prefix); | |
} | |
override void writeCheckD(ref File f, string prefix, size_t i) | |
{ | |
auto m = "val_%d".format(i); | |
f.writefln("\tprintf(\"%s: %%p\\n\", cast(char*)&%s.%s - cast(char*)&%s);", m, prefix, m, prefix); | |
} | |
override void writeStructCpp(ref File f) | |
{ | |
} | |
override void writeStructD(ref File f) | |
{ | |
} | |
override void writeMemberCpp(ref File f, size_t i) | |
{ | |
auto mname = "val_%d".format(i); | |
f.writefln("\t%s %s;", cname, mname); | |
} | |
override void writeMemberD(ref File f, size_t i) | |
{ | |
auto mname = "val_%d".format(i); | |
f.writefln("\t%s %s;", dname, mname); | |
} | |
} | |
static immutable string[2][] basics = | |
[ | |
["byte", "signed char"], | |
["ubyte", "unsigned char"], | |
["char", "char"], | |
["int", "int"], | |
["uint", "unsigned"], | |
["long", "long long"], | |
["ulong", "unsigned long long"], | |
["float", "float"], | |
["double", "double"], | |
["real", "long double"], | |
["bool", "bool"], | |
["void*", "void*"], | |
]; | |
Value genValue() | |
{ | |
auto p = uniform(0, basics.length + 1); | |
if (p == basics.length) | |
{ | |
return genStruct("S" ~ randomUUID().toString().replace("-", "_")); | |
} | |
else | |
{ | |
return new Basic(basics[p][0], basics[p][1]); | |
} | |
} | |
Struct genStruct(string name) | |
{ | |
auto s = new Struct(name); | |
foreach(i; 0..uniform(0, 20)) | |
{ | |
s.members ~= genValue(); | |
} | |
return s; | |
} | |
void main() | |
{ | |
Lrestart: | |
auto testname = "test_struct_" ~ randomUUID().toString().replace("-", "_"); | |
while(true) | |
{ | |
auto s = genStruct("Test"); | |
auto cf = File(testname ~ "_cpp.cpp", "wb"); | |
auto df = File(testname ~ "_d.d", "wb"); | |
cf.writeln("#include <stdio.h>"); | |
df.writeln("import core.stdc.stdio;"); | |
s.writeStructCpp(cf); | |
s.writeStructD(df); | |
cf.writeln("int main(void) {"); | |
cf.writeln("\tTest s;"); | |
foreach(i, m; s.members) | |
m.writeCheckCpp(cf, "s", i); | |
cf.writefln("printf(\"size: %%d\\n\", sizeof(s));"); | |
cf.writeln("\treturn 0;"); | |
cf.writeln("}"); | |
df.writeln("void main() {"); | |
df.writeln("\tTest s;"); | |
foreach(i, m; s.members) | |
m.writeCheckD(df, "s", i); | |
df.writefln("printf(\"size: %%d\\n\", s.sizeof);"); | |
df.writeln("}"); | |
cf.close(); | |
df.close(); | |
version(Windows) | |
{ | |
auto dmcres = executeShell("dmc %s_cpp.cpp".format(testname)); | |
// writeln(dmcres.output); | |
enforce(dmcres.status == 0); | |
enforce(executeShell("dmd %s_d.d".format(testname)).status == 0); | |
auto cout = executeShell("%s_cpp".format(testname)); | |
auto dout = executeShell("%s_d".format(testname)); | |
} | |
else | |
{ | |
enforce(executeShell("g++ %s.cpp -o %s_cpp".format(testname, testname)).status == 0); | |
enforce(executeShell("./dmd %s.d -of%s_d".format(testname, testname)).status == 0); | |
auto cout = executeShell("./%s_cpp".format(testname)); | |
auto dout = executeShell("./%s_d".format(testname)); | |
} | |
// writeln(cout); | |
enforce(cout.status == 0); | |
enforce(dout.status == 0); | |
if (cout.output != dout.output) | |
{ | |
writeln("Output mismatch in ", testname); | |
goto Lrestart; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment