Files
ldc/tests/mini/vararg6.d

250 lines
5.7 KiB
D

// tries to implement a fairly complete variadic print function
module tangotests.vararg3;
extern(C) int printf(char*, ...);
struct User
{
char[] name;
char[] nick;
uint age;
char[] toString()
{
return nick ~ "(" ~ name ~ ")";
}
}
struct Infidel
{
char[] whocares;
}
class Obj
{
private char[] ty;
this(char[] t)
{
ty = t;
}
char[] toString()
{
return "Obj(" ~ ty ~ ")";
}
}
struct TLA
{
char[3] acronym;
char[] toString()
{
return acronym;
}
}
void main()
{
User user = User("Bob Doe", "bd", 47);
char[] str = user.toString();
printf("Direct call:\n%.*s\nBy typeinfo:\n", str.length, str.ptr);
print(user, '\n');
print("Without toString:\n");
Infidel inf = Infidel("not me");
print(inf, '\n');
print("Character arrays:\n");
print("hello world\n");
print("Signed integers:\n");
print(cast(byte)byte.max,' ',cast(short)short.max,' ',cast(int)int.max,' ',cast(long)long.max,'\n');
print("Unsigned integers:\n");
print(cast(ubyte)ubyte.max,' ',cast(ushort)ushort.max,' ',cast(uint)uint.max,' ',cast(ulong)ulong.max,'\n');
print("Floating point:\n");
print(cast(float)1.273f, ' ', cast(double)3.412367, ' ', cast(real)142.96731112, '\n');
print("Arrays:\n");
int[] ia1 = [1,2,3,4,5,6,7,8,9];
print(ia1, '\n');
float[] fa1 = [0.1f, 0.15f, 0.2f, 0.25f, 0.3f];
print(fa1, '\n');
print("Pointers:\n");
print(&user,'\n');
print(&inf,'\n');
print(&ia1,'\n');
print(&fa1,'\n');
print("Static arrays:\n");
int[5] isa1 = [1,2,4,8,16];
print(isa1,'\n');
print("Classes:\n");
Obj o = new Obj("foo");
print(o, '\n');
print("Mixed:\n");
print(123, ' ', 42.536f, " foobar ", ia1, ' ', user, '\n');
print(42, ' ', cast(byte)12, ' ', user, ' ', cast(short)1445, " foo\n");
print("International:\n");
print('æ','ø','å','\n');
print('Æ','Ø','Å','\n');
print("rød grød med fløde\n");
print("Heiße\n");
print("TLAs:\n");
TLA tla1 = TLA("FBI");
TLA tla2 = TLA("CIA");
TLA tla3 = TLA("TLA");
print(tla1);
print(tla2);
print(tla3, '\n');
print(tla1, tla2, tla3, '\n');
print(TLA("FBI"), TLA("CIA"), TLA("TLA"), '\n');
print("Done!\n");
}
private void* get_va_arg(TypeInfo ti, ref void* vp)
{
void* arg = vp;
vp = vp + ( ( ti.tsize + size_t.sizeof - 1 ) & ~( size_t.sizeof - 1 ) );
return arg;
}
void print(TypeInfo ti, void* arg)
{
if (ti == typeid(byte))
printf("%d", *cast(byte*)arg);
else if (ti == typeid(short))
printf("%d", *cast(short*)arg);
else if (ti == typeid(int))
printf("%d", *cast(int*)arg);
else if (ti == typeid(long))
printf("%lld", *cast(long*)arg);
else if (ti == typeid(ubyte))
printf("%u", *cast(ubyte*)arg);
else if (ti == typeid(ushort))
printf("%u", *cast(ushort*)arg);
else if (ti == typeid(uint))
printf("%u", *cast(uint*)arg);
else if (ti == typeid(ulong))
printf("%llu", *cast(ulong*)arg);
else if (ti == typeid(float))
printf("%f", *cast(float*)arg);
else if (ti == typeid(double))
printf("%f", *cast(double*)arg);
else if (ti == typeid(real)) // FIXME: 80bit?
{
version(LLVM_X86_FP80)
printf("%llf", *cast(real*)arg);
else
printf("%f", *cast(real*)arg);
}
else if (ti == typeid(char))
printf("%.*s", 1, arg);
else if (ti == typeid(wchar))
printf("%.*s", 2, arg);
else if (ti == typeid(dchar))
printf("%.*s", 4, arg);
else if (ti == typeid(char[]))
{
char[] str = *cast(char[]*)arg;
printf("%.*s", str.length, str.ptr);
}
else if (ti == typeid(wchar[]))
{
wchar[] str = *cast(wchar[]*)arg;
printf("%.*s", str.length*2, str.ptr);
}
else if (ti == typeid(dchar[]))
{
dchar[] str = *cast(dchar[]*)arg;
printf("%.*s", str.length*4, str.ptr);
}
else if (auto pti = cast(TypeInfo_Pointer)ti)
{
printf("%p", *cast(void**)arg);
}
else if (auto sti = cast(TypeInfo_Struct)ti)
{
if (sti.xtoString !is null)
{
char[] str = sti.xtoString(arg);
printf("%.*s", str.length, str.ptr);
}
else
{
char[] str = sti.toString();
printf("%.*s", str.length, str.ptr);
}
}
else if (auto ati = cast(TypeInfo_Array)ti)
{
auto tnext = ati.next;
size_t len = *cast(size_t*)arg;
void* ptr = *(cast(void**)arg + 1);
printf("[");
for(auto i=0; i<len; ++i)
{
print(tnext, get_va_arg(tnext, ptr));
if (i < len-1)
printf(",");
}
printf("]");
}
else if (auto cti = cast(TypeInfo_Class)ti)
{
auto o = *cast(Object*)arg;
char[] str = o.toString();
printf("%.*s", str.length, str.ptr);
}
// static arrays are converted to dynamic arrays when passed to variadic functions
else if (auto sati = cast(TypeInfo_StaticArray)ti)
{
assert(0, "static arrays not supported");
}
else if (auto aati = cast(TypeInfo_AssociativeArray)ti)
{
assert(0, "associative array not supported");
}
else
{
char[] str = ti.toString();
printf("typeinfo: %.*s\n", str.length, str.ptr);
str = ti.classinfo.name;
printf("typeinfo.classinfo: %.*s\n", str.length, str.ptr);
assert(0, "unsupported type ^");
}
}
void print(...)
{
void* argptr = _argptr;
assert(argptr);
foreach(i,ti; _arguments)
{
void* arg = get_va_arg(ti, argptr);
assert(arg);
print(ti, arg);
}
}