Mercurial > projects > ldc
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 } |