Skip to content

Instantly share code, notes, and snippets.

@yebblies
Created April 1, 2015 12:14
Show Gist options
  • Save yebblies/09c20c74c71c3e1fe5ab to your computer and use it in GitHub Desktop.
Save yebblies/09c20c74c71c3e1fe5ab to your computer and use it in GitHub Desktop.
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