comparison tangotests/vararg3.d @ 214:629cfc1e7b77 trunk

[svn r230] Added vararg3 sample tangotest.
author lindquist
date Fri, 30 May 2008 19:32:56 +0200
parents
children a58d8f4b84df
comparison
equal deleted inserted replaced
213:7816aafeea3c 214:629cfc1e7b77
1 // tries to implement a fairly complete variadic print function
2 module tangotests.vararg3;
3
4 extern(C) int printf(char*, ...);
5
6 struct User
7 {
8 char[] name;
9 char[] nick;
10 uint age;
11
12 char[] toString()
13 {
14 return nick ~ "(" ~ name ~ ")";
15 }
16 }
17
18 struct Infidel
19 {
20 char[] whocares;
21 }
22
23 class Obj
24 {
25 private char[] ty;
26
27 this(char[] t)
28 {
29 ty = t;
30 }
31
32 char[] toString()
33 {
34 return "Obj(" ~ ty ~ ")";
35 }
36 }
37
38 void main()
39 {
40 User user = User("Bob Doe", "bd", 47);
41 char[] str = user.toString();
42 printf("Direct call:\n%.*s\nBy typeinfo:\n", str.length, str.ptr);
43 print(user, '\n');
44
45 print("Without toString:\n");
46 Infidel inf = Infidel("not me");
47 print(inf, '\n');
48
49 print("Character arrays:\n");
50 print("hello world\n");
51
52 print("Signed integers:\n");
53 print(cast(byte)byte.max,' ',cast(short)short.max,' ',cast(int)int.max,' ',cast(long)long.max,'\n');
54
55 print("Unsigned integers:\n");
56 print(cast(ubyte)ubyte.max,' ',cast(ushort)ushort.max,' ',cast(uint)uint.max,' ',cast(ulong)ulong.max,'\n');
57
58 print("Floating point:\n");
59 print(cast(float)1.273f, ' ', cast(double)3.412367, ' ', cast(real)142.96731112, '\n');
60
61 print("Arrays:\n");
62 int[] ia1 = [1,2,3,4,5,6,7,8,9];
63 print(ia1, '\n');
64 float[] fa1 = [0.1f, 0.15f, 0.2f, 0.25f, 0.3f];
65 print(fa1, '\n');
66
67 print("Pointers:\n");
68 print(&user,'\n');
69 print(&inf,'\n');
70 print(&ia1,'\n');
71 print(&fa1,'\n');
72
73 print("Static arrays:\n");
74 int[5] isa1 = [1,2,4,8,16];
75 print(isa1,'\n');
76
77 print("Classes:\n");
78 Obj o = new Obj("foo");
79 print(o, '\n');
80
81 print("Mixed:\n");
82 print(123, ' ', 42.536f, " foobar ", ia1, ' ', user, '\n');
83 print(42, ' ', cast(byte)12, ' ', user, ' ', cast(short)1445, " foo\n");
84 }
85
86 private void* get_va_arg(TypeInfo ti, ref void* vp)
87 {
88 auto tisize = ti.tsize;
89 assert(tisize);
90 size_t size = tisize > size_t.sizeof ? size_t.sizeof : tisize;
91 void* vptmp = cast(void*)((cast(size_t)vp + size - 1) & ~(size - 1));
92 vp = vptmp + tisize;
93 return vptmp;
94 }
95
96 void print(TypeInfo ti, void* arg)
97 {
98 if (ti == typeid(byte))
99 printf("%d", *cast(byte*)arg);
100 else if (ti == typeid(short))
101 printf("%d", *cast(short*)arg);
102 else if (ti == typeid(int))
103 printf("%d", *cast(int*)arg);
104 else if (ti == typeid(long))
105 printf("%lld", *cast(long*)arg);
106
107 else if (ti == typeid(ubyte))
108 printf("%u", *cast(ubyte*)arg);
109 else if (ti == typeid(ushort))
110 printf("%u", *cast(ushort*)arg);
111 else if (ti == typeid(uint))
112 printf("%u", *cast(uint*)arg);
113 else if (ti == typeid(ulong))
114 printf("%llu", *cast(ulong*)arg);
115
116 else if (ti == typeid(float))
117 printf("%f", *cast(float*)arg);
118 else if (ti == typeid(double))
119 printf("%f", *cast(double*)arg);
120 else if (ti == typeid(real)) // FIXME: 80bit?
121 printf("%f", *cast(real*)arg);
122
123 else if (ti == typeid(char))
124 printf("%.*s", 1, arg);
125 else if (ti == typeid(wchar))
126 printf("%.*s", 2, arg);
127 else if (ti == typeid(dchar))
128 printf("%.*s", 4, arg);
129
130 else if (ti == typeid(char[]))
131 {
132 char[] str = *cast(char[]*)arg;
133 printf("%.*s", str.length, str.ptr);
134 }
135 else if (ti == typeid(wchar[]))
136 {
137 wchar[] str = *cast(wchar[]*)arg;
138 printf("%.*s", str.length*2, str.ptr);
139 }
140 else if (ti == typeid(dchar[]))
141 {
142 dchar[] str = *cast(dchar[]*)arg;
143 printf("%.*s", str.length*4, str.ptr);
144 }
145
146 else if (auto pti = cast(TypeInfo_Pointer)ti)
147 {
148 printf("%p", *cast(void**)arg);
149 }
150
151 else if (auto sti = cast(TypeInfo_Struct)ti)
152 {
153 if (sti.xtoString !is null)
154 {
155 char[] str = sti.xtoString(arg);
156 printf("%.*s", str.length, str.ptr);
157 }
158 else
159 {
160 char[] str = sti.toString();
161 printf("%.*s", str.length, str.ptr);
162 }
163 }
164
165 else if (auto ati = cast(TypeInfo_Array)ti)
166 {
167 auto tnext = ati.next;
168 size_t len = *cast(size_t*)arg;
169 void* ptr = *(cast(void**)arg + 1);
170 printf("[");
171 for(auto i=0; i<len; ++i)
172 {
173 print(tnext, get_va_arg(tnext, ptr));
174 if (i < len-1)
175 printf(",");
176 }
177 printf("]");
178 }
179
180 else if (auto cti = cast(TypeInfo_Class)ti)
181 {
182 auto o = *cast(Object*)arg;
183 char[] str = o.toString();
184 printf("%.*s", str.length, str.ptr);
185 }
186
187 // static arrays are converted to dynamic arrays when passed to variadic functions
188 else if (auto sati = cast(TypeInfo_StaticArray)ti)
189 {
190 assert(0, "static arrays not supported");
191 }
192
193 else if (auto aati = cast(TypeInfo_AssociativeArray)ti)
194 {
195 assert(0, "associative array not supported");
196 }
197
198 else
199 {
200 char[] str = ti.toString();
201 printf("typeinfo: %.*s\n", str.length, str.ptr);
202 str = ti.classinfo.name;
203 printf("typeinfo.classinfo: %.*s\n", str.length, str.ptr);
204 assert(0, "unsupported type ^");
205 }
206 }
207
208 void print(...)
209 {
210 void* argptr = _argptr;
211 assert(argptr);
212
213 foreach(i,ti; _arguments)
214 {
215 void* arg = get_va_arg(ti, argptr);
216 assert(arg);
217 print(ti, arg);
218 }
219 }