Mercurial > projects > ldc
annotate tangotests/vararg3.d @ 283:9bb48fb57a7d trunk
[svn r304] Fix associative array literals by always reserving a zero inited temporary for them.
author | ChristianK |
---|---|
date | Sat, 21 Jun 2008 00:54:55 +0200 |
parents | 23d0d9855cad |
children |
rev | line source |
---|---|
214 | 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 | |
215
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
38 struct TLA |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
39 { |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
40 char[3] acronym; |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
41 |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
42 char[] toString() |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
43 { |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
44 return acronym; |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
45 } |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
46 } |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
47 |
214 | 48 void main() |
49 { | |
50 User user = User("Bob Doe", "bd", 47); | |
51 char[] str = user.toString(); | |
52 printf("Direct call:\n%.*s\nBy typeinfo:\n", str.length, str.ptr); | |
53 print(user, '\n'); | |
54 | |
55 print("Without toString:\n"); | |
56 Infidel inf = Infidel("not me"); | |
57 print(inf, '\n'); | |
58 | |
59 print("Character arrays:\n"); | |
60 print("hello world\n"); | |
61 | |
62 print("Signed integers:\n"); | |
63 print(cast(byte)byte.max,' ',cast(short)short.max,' ',cast(int)int.max,' ',cast(long)long.max,'\n'); | |
64 | |
65 print("Unsigned integers:\n"); | |
66 print(cast(ubyte)ubyte.max,' ',cast(ushort)ushort.max,' ',cast(uint)uint.max,' ',cast(ulong)ulong.max,'\n'); | |
67 | |
68 print("Floating point:\n"); | |
69 print(cast(float)1.273f, ' ', cast(double)3.412367, ' ', cast(real)142.96731112, '\n'); | |
70 | |
71 print("Arrays:\n"); | |
72 int[] ia1 = [1,2,3,4,5,6,7,8,9]; | |
73 print(ia1, '\n'); | |
74 float[] fa1 = [0.1f, 0.15f, 0.2f, 0.25f, 0.3f]; | |
75 print(fa1, '\n'); | |
76 | |
77 print("Pointers:\n"); | |
78 print(&user,'\n'); | |
79 print(&inf,'\n'); | |
80 print(&ia1,'\n'); | |
81 print(&fa1,'\n'); | |
82 | |
83 print("Static arrays:\n"); | |
84 int[5] isa1 = [1,2,4,8,16]; | |
85 print(isa1,'\n'); | |
86 | |
87 print("Classes:\n"); | |
88 Obj o = new Obj("foo"); | |
89 print(o, '\n'); | |
90 | |
91 print("Mixed:\n"); | |
92 print(123, ' ', 42.536f, " foobar ", ia1, ' ', user, '\n'); | |
93 print(42, ' ', cast(byte)12, ' ', user, ' ', cast(short)1445, " foo\n"); | |
215
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
94 |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
95 print("International:\n"); |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
96 print('æ','ø','å','\n'); |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
97 print('Æ','Ø','Å','\n'); |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
98 print("rød grød med fløde\n"); |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
99 print("Heiße\n"); |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
100 |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
101 print("TLAs:\n"); |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
102 TLA tla1 = TLA("FBI"); |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
103 TLA tla2 = TLA("CIA"); |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
104 TLA tla3 = TLA("TLA"); |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
105 print(tla1); |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
106 print(tla2); |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
107 print(tla3, '\n'); |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
108 print(tla1, tla2, tla3, '\n'); |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
109 print(TLA("FBI"), TLA("CIA"), TLA("TLA"), '\n'); |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
110 |
a58d8f4b84df
[svn r231] Changed: warnings are no longer treated as an error.
lindquist
parents:
214
diff
changeset
|
111 print("Done!\n"); |
214 | 112 } |
113 | |
114 private void* get_va_arg(TypeInfo ti, ref void* vp) | |
115 { | |
264
a9dae3da4e87
[svn r285] Fixed D -> bool LLVM helper for floating point values.
lindquist
parents:
215
diff
changeset
|
116 void* arg = vp; |
a9dae3da4e87
[svn r285] Fixed D -> bool LLVM helper for floating point values.
lindquist
parents:
215
diff
changeset
|
117 vp = vp + ( ( ti.tsize + size_t.sizeof - 1 ) & ~( size_t.sizeof - 1 ) ); |
a9dae3da4e87
[svn r285] Fixed D -> bool LLVM helper for floating point values.
lindquist
parents:
215
diff
changeset
|
118 return arg; |
214 | 119 } |
120 | |
121 void print(TypeInfo ti, void* arg) | |
122 { | |
123 if (ti == typeid(byte)) | |
124 printf("%d", *cast(byte*)arg); | |
125 else if (ti == typeid(short)) | |
126 printf("%d", *cast(short*)arg); | |
127 else if (ti == typeid(int)) | |
128 printf("%d", *cast(int*)arg); | |
129 else if (ti == typeid(long)) | |
130 printf("%lld", *cast(long*)arg); | |
131 | |
132 else if (ti == typeid(ubyte)) | |
133 printf("%u", *cast(ubyte*)arg); | |
134 else if (ti == typeid(ushort)) | |
135 printf("%u", *cast(ushort*)arg); | |
136 else if (ti == typeid(uint)) | |
137 printf("%u", *cast(uint*)arg); | |
138 else if (ti == typeid(ulong)) | |
139 printf("%llu", *cast(ulong*)arg); | |
140 | |
141 else if (ti == typeid(float)) | |
142 printf("%f", *cast(float*)arg); | |
143 else if (ti == typeid(double)) | |
144 printf("%f", *cast(double*)arg); | |
145 else if (ti == typeid(real)) // FIXME: 80bit? | |
268
23d0d9855cad
[svn r289] Fixed: right shift >> was broken for unsigned types.
lindquist
parents:
264
diff
changeset
|
146 { |
23d0d9855cad
[svn r289] Fixed: right shift >> was broken for unsigned types.
lindquist
parents:
264
diff
changeset
|
147 version(LLVM_X86_FP80) |
23d0d9855cad
[svn r289] Fixed: right shift >> was broken for unsigned types.
lindquist
parents:
264
diff
changeset
|
148 printf("%llf", *cast(real*)arg); |
23d0d9855cad
[svn r289] Fixed: right shift >> was broken for unsigned types.
lindquist
parents:
264
diff
changeset
|
149 else |
23d0d9855cad
[svn r289] Fixed: right shift >> was broken for unsigned types.
lindquist
parents:
264
diff
changeset
|
150 printf("%f", *cast(real*)arg); |
23d0d9855cad
[svn r289] Fixed: right shift >> was broken for unsigned types.
lindquist
parents:
264
diff
changeset
|
151 } |
214 | 152 |
153 else if (ti == typeid(char)) | |
154 printf("%.*s", 1, arg); | |
155 else if (ti == typeid(wchar)) | |
156 printf("%.*s", 2, arg); | |
157 else if (ti == typeid(dchar)) | |
158 printf("%.*s", 4, arg); | |
159 | |
160 else if (ti == typeid(char[])) | |
161 { | |
162 char[] str = *cast(char[]*)arg; | |
163 printf("%.*s", str.length, str.ptr); | |
164 } | |
165 else if (ti == typeid(wchar[])) | |
166 { | |
167 wchar[] str = *cast(wchar[]*)arg; | |
168 printf("%.*s", str.length*2, str.ptr); | |
169 } | |
170 else if (ti == typeid(dchar[])) | |
171 { | |
172 dchar[] str = *cast(dchar[]*)arg; | |
173 printf("%.*s", str.length*4, str.ptr); | |
174 } | |
175 | |
176 else if (auto pti = cast(TypeInfo_Pointer)ti) | |
177 { | |
178 printf("%p", *cast(void**)arg); | |
179 } | |
180 | |
181 else if (auto sti = cast(TypeInfo_Struct)ti) | |
182 { | |
183 if (sti.xtoString !is null) | |
184 { | |
185 char[] str = sti.xtoString(arg); | |
186 printf("%.*s", str.length, str.ptr); | |
187 } | |
188 else | |
189 { | |
190 char[] str = sti.toString(); | |
191 printf("%.*s", str.length, str.ptr); | |
192 } | |
193 } | |
194 | |
195 else if (auto ati = cast(TypeInfo_Array)ti) | |
196 { | |
197 auto tnext = ati.next; | |
198 size_t len = *cast(size_t*)arg; | |
199 void* ptr = *(cast(void**)arg + 1); | |
200 printf("["); | |
201 for(auto i=0; i<len; ++i) | |
202 { | |
203 print(tnext, get_va_arg(tnext, ptr)); | |
204 if (i < len-1) | |
205 printf(","); | |
206 } | |
207 printf("]"); | |
208 } | |
209 | |
210 else if (auto cti = cast(TypeInfo_Class)ti) | |
211 { | |
212 auto o = *cast(Object*)arg; | |
213 char[] str = o.toString(); | |
214 printf("%.*s", str.length, str.ptr); | |
215 } | |
216 | |
217 // static arrays are converted to dynamic arrays when passed to variadic functions | |
218 else if (auto sati = cast(TypeInfo_StaticArray)ti) | |
219 { | |
220 assert(0, "static arrays not supported"); | |
221 } | |
222 | |
223 else if (auto aati = cast(TypeInfo_AssociativeArray)ti) | |
224 { | |
225 assert(0, "associative array not supported"); | |
226 } | |
227 | |
228 else | |
229 { | |
230 char[] str = ti.toString(); | |
231 printf("typeinfo: %.*s\n", str.length, str.ptr); | |
232 str = ti.classinfo.name; | |
233 printf("typeinfo.classinfo: %.*s\n", str.length, str.ptr); | |
234 assert(0, "unsupported type ^"); | |
235 } | |
236 } | |
237 | |
238 void print(...) | |
239 { | |
240 void* argptr = _argptr; | |
241 assert(argptr); | |
242 | |
243 foreach(i,ti; _arguments) | |
244 { | |
245 void* arg = get_va_arg(ti, argptr); | |
246 assert(arg); | |
247 print(ti, arg); | |
248 } | |
249 } |