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);
+    }
+}