Mercurial > projects > ldc
changeset 214:629cfc1e7b77 trunk
[svn r230] Added vararg3 sample tangotest.
author | lindquist |
---|---|
date | Fri, 30 May 2008 19:32:56 +0200 |
parents | 7816aafeea3c |
children | a58d8f4b84df |
files | tangotests/vararg3.d |
diffstat | 1 files changed, 219 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tangotests/vararg3.d Fri May 30 19:32:56 2008 +0200 @@ -0,0 +1,219 @@ +// 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 ~ ")"; + } +} + +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"); +} + +private void* get_va_arg(TypeInfo ti, ref void* vp) +{ + auto tisize = ti.tsize; + assert(tisize); + size_t size = tisize > size_t.sizeof ? size_t.sizeof : tisize; + void* vptmp = cast(void*)((cast(size_t)vp + size - 1) & ~(size - 1)); + vp = vptmp + tisize; + return vptmp; +} + +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? + 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); + } +}