Mercurial > projects > ldc
comparison tango/lib/compiler/llvmdc/switch.d @ 132:1700239cab2e trunk
[svn r136] MAJOR UNSTABLE UPDATE!!!
Initial commit after moving to Tango instead of Phobos.
Lots of bugfixes...
This build is not suitable for most things.
author | lindquist |
---|---|
date | Fri, 11 Jan 2008 17:57:40 +0100 |
parents | |
children | 1e6e2b5d5bfe |
comparison
equal
deleted
inserted
replaced
131:5825d48b27d1 | 132:1700239cab2e |
---|---|
1 /* | |
2 * Copyright (C) 2004-2007 by Digital Mars, www.digitalmars.com | |
3 * Written by Walter Bright | |
4 * | |
5 * This software is provided 'as-is', without any express or implied | |
6 * warranty. In no event will the authors be held liable for any damages | |
7 * arising from the use of this software. | |
8 * | |
9 * Permission is granted to anyone to use this software for any purpose, | |
10 * including commercial applications, and to alter it and redistribute it | |
11 * freely, in both source and binary form, subject to the following | |
12 * restrictions: | |
13 * | |
14 * o The origin of this software must not be misrepresented; you must not | |
15 * claim that you wrote the original software. If you use this software | |
16 * in a product, an acknowledgment in the product documentation would be | |
17 * appreciated but is not required. | |
18 * o Altered source versions must be plainly marked as such, and must not | |
19 * be misrepresented as being the original software. | |
20 * o This notice may not be removed or altered from any source | |
21 * distribution. | |
22 */ | |
23 | |
24 /* | |
25 * Modified by Sean Kelly <sean@f4.ca> for use with Tango. | |
26 */ | |
27 | |
28 private import tango.stdc.string; | |
29 | |
30 /****************************************************** | |
31 * Support for switch statements switching on strings. | |
32 * Input: | |
33 * table[] sorted array of strings generated by compiler | |
34 * ca string to look up in table | |
35 * Output: | |
36 * result index of match in table[] | |
37 * -1 if not in table | |
38 */ | |
39 | |
40 extern (C): | |
41 | |
42 int _d_switch_string(char[][] table, char[] ca) | |
43 in | |
44 { | |
45 //printf("in _d_switch_string()\n"); | |
46 assert(table.length >= 0); | |
47 assert(ca.length >= 0); | |
48 | |
49 // Make sure table[] is sorted correctly | |
50 int j; | |
51 | |
52 for (j = 1; j < table.length; j++) | |
53 { | |
54 size_t len1 = table[j - 1].length; | |
55 size_t len2 = table[j].length; | |
56 | |
57 assert(len1 <= len2); | |
58 if (len1 == len2) | |
59 { | |
60 int ci; | |
61 | |
62 ci = memcmp(table[j - 1].ptr, table[j].ptr, len1); | |
63 assert(ci < 0); // ci==0 means a duplicate | |
64 } | |
65 } | |
66 } | |
67 out (result) | |
68 { | |
69 int i; | |
70 int cj; | |
71 | |
72 //printf("out _d_switch_string()\n"); | |
73 if (result == -1) | |
74 { | |
75 // Not found | |
76 for (i = 0; i < table.length; i++) | |
77 { | |
78 if (table[i].length == ca.length) | |
79 { cj = memcmp(table[i].ptr, ca.ptr, ca.length); | |
80 assert(cj != 0); | |
81 } | |
82 } | |
83 } | |
84 else | |
85 { | |
86 assert(0 <= result && result < table.length); | |
87 for (i = 0; 1; i++) | |
88 { | |
89 assert(i < table.length); | |
90 if (table[i].length == ca.length) | |
91 { | |
92 cj = memcmp(table[i].ptr, ca.ptr, ca.length); | |
93 if (cj == 0) | |
94 { | |
95 assert(i == result); | |
96 break; | |
97 } | |
98 } | |
99 } | |
100 } | |
101 } | |
102 body | |
103 { | |
104 //printf("body _d_switch_string(%.*s)\n", ca); | |
105 size_t low; | |
106 size_t high; | |
107 size_t mid; | |
108 size_t c; | |
109 char[] pca; | |
110 | |
111 low = 0; | |
112 high = table.length; | |
113 | |
114 version (none) | |
115 { | |
116 // Print table | |
117 printf("ca[] = '%s'\n", cast(char *)ca); | |
118 for (mid = 0; mid < high; mid++) | |
119 { | |
120 pca = table[mid]; | |
121 printf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca); | |
122 } | |
123 } | |
124 if (high && | |
125 ca.length >= table[0].length && | |
126 ca.length <= table[high - 1].length) | |
127 { | |
128 // Looking for 0 length string, which would only be at the beginning | |
129 if (ca.length == 0) | |
130 return 0; | |
131 | |
132 char c1 = ca[0]; | |
133 | |
134 // Do binary search | |
135 while (low < high) | |
136 { | |
137 mid = (low + high) >> 1; | |
138 pca = table[mid]; | |
139 c = ca.length - pca.length; | |
140 if (c == 0) | |
141 { | |
142 c = cast(ubyte)c1 - cast(ubyte)pca[0]; | |
143 if (c == 0) | |
144 { | |
145 c = memcmp(ca.ptr, pca.ptr, ca.length); | |
146 if (c == 0) | |
147 { //printf("found %d\n", mid); | |
148 return cast(int)mid; | |
149 } | |
150 } | |
151 } | |
152 if (c < 0) | |
153 { | |
154 high = mid; | |
155 } | |
156 else | |
157 { | |
158 low = mid + 1; | |
159 } | |
160 } | |
161 } | |
162 | |
163 //printf("not found\n"); | |
164 return -1; // not found | |
165 } | |
166 | |
167 unittest | |
168 { | |
169 switch (cast(char []) "c") | |
170 { | |
171 case "coo": | |
172 default: | |
173 break; | |
174 } | |
175 } | |
176 | |
177 /********************************** | |
178 * Same thing, but for wide chars. | |
179 */ | |
180 | |
181 int _d_switch_ustring(wchar[][] table, wchar[] ca) | |
182 in | |
183 { | |
184 //printf("in _d_switch_ustring()\n"); | |
185 assert(table.length >= 0); | |
186 assert(ca.length >= 0); | |
187 | |
188 // Make sure table[] is sorted correctly | |
189 int j; | |
190 | |
191 for (j = 1; j < table.length; j++) | |
192 { | |
193 size_t len1 = table[j - 1].length; | |
194 size_t len2 = table[j].length; | |
195 | |
196 assert(len1 <= len2); | |
197 if (len1 == len2) | |
198 { | |
199 int c; | |
200 | |
201 c = memcmp(table[j - 1].ptr, table[j].ptr, len1 * wchar.sizeof); | |
202 assert(c < 0); // c==0 means a duplicate | |
203 } | |
204 } | |
205 } | |
206 out (result) | |
207 { | |
208 int i; | |
209 int c; | |
210 | |
211 //printf("out _d_switch_string()\n"); | |
212 if (result == -1) | |
213 { | |
214 // Not found | |
215 for (i = 0; i < table.length; i++) | |
216 { | |
217 if (table[i].length == ca.length) | |
218 { c = memcmp(table[i].ptr, ca.ptr, ca.length * wchar.sizeof); | |
219 assert(c != 0); | |
220 } | |
221 } | |
222 } | |
223 else | |
224 { | |
225 assert(0 <= result && result < table.length); | |
226 for (i = 0; 1; i++) | |
227 { | |
228 assert(i < table.length); | |
229 if (table[i].length == ca.length) | |
230 { | |
231 c = memcmp(table[i].ptr, ca.ptr, ca.length * wchar.sizeof); | |
232 if (c == 0) | |
233 { | |
234 assert(i == result); | |
235 break; | |
236 } | |
237 } | |
238 } | |
239 } | |
240 } | |
241 body | |
242 { | |
243 //printf("body _d_switch_ustring()\n"); | |
244 size_t low; | |
245 size_t high; | |
246 size_t mid; | |
247 size_t c; | |
248 wchar[] pca; | |
249 | |
250 low = 0; | |
251 high = table.length; | |
252 | |
253 /* | |
254 // Print table | |
255 wprintf("ca[] = '%.*s'\n", ca); | |
256 for (mid = 0; mid < high; mid++) | |
257 { | |
258 pca = table[mid]; | |
259 wprintf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca); | |
260 } | |
261 */ | |
262 | |
263 // Do binary search | |
264 while (low < high) | |
265 { | |
266 mid = (low + high) >> 1; | |
267 pca = table[mid]; | |
268 c = ca.length - pca.length; | |
269 if (c == 0) | |
270 { | |
271 c = memcmp(ca.ptr, pca.ptr, ca.length * wchar.sizeof); | |
272 if (c == 0) | |
273 { //printf("found %d\n", mid); | |
274 return cast(int)mid; | |
275 } | |
276 } | |
277 if (c < 0) | |
278 { | |
279 high = mid; | |
280 } | |
281 else | |
282 { | |
283 low = mid + 1; | |
284 } | |
285 } | |
286 //printf("not found\n"); | |
287 return -1; // not found | |
288 } | |
289 | |
290 | |
291 unittest | |
292 { | |
293 switch (cast(wchar []) "c") | |
294 { | |
295 case "coo": | |
296 default: | |
297 break; | |
298 } | |
299 } | |
300 | |
301 | |
302 /********************************** | |
303 * Same thing, but for wide chars. | |
304 */ | |
305 | |
306 int _d_switch_dstring(dchar[][] table, dchar[] ca) | |
307 in | |
308 { | |
309 //printf("in _d_switch_dstring()\n"); | |
310 assert(table.length >= 0); | |
311 assert(ca.length >= 0); | |
312 | |
313 // Make sure table[] is sorted correctly | |
314 int j; | |
315 | |
316 for (j = 1; j < table.length; j++) | |
317 { | |
318 size_t len1 = table[j - 1].length; | |
319 size_t len2 = table[j].length; | |
320 | |
321 assert(len1 <= len2); | |
322 if (len1 == len2) | |
323 { | |
324 int c; | |
325 | |
326 c = memcmp(table[j - 1].ptr, table[j].ptr, len1 * dchar.sizeof); | |
327 assert(c < 0); // c==0 means a duplicate | |
328 } | |
329 } | |
330 } | |
331 out (result) | |
332 { | |
333 int i; | |
334 int c; | |
335 | |
336 //printf("out _d_switch_string()\n"); | |
337 if (result == -1) | |
338 { | |
339 // Not found | |
340 for (i = 0; i < table.length; i++) | |
341 { | |
342 if (table[i].length == ca.length) | |
343 { c = memcmp(table[i].ptr, ca.ptr, ca.length * dchar.sizeof); | |
344 assert(c != 0); | |
345 } | |
346 } | |
347 } | |
348 else | |
349 { | |
350 assert(0 <= result && result < table.length); | |
351 for (i = 0; 1; i++) | |
352 { | |
353 assert(i < table.length); | |
354 if (table[i].length == ca.length) | |
355 { | |
356 c = memcmp(table[i].ptr, ca.ptr, ca.length * dchar.sizeof); | |
357 if (c == 0) | |
358 { | |
359 assert(i == result); | |
360 break; | |
361 } | |
362 } | |
363 } | |
364 } | |
365 } | |
366 body | |
367 { | |
368 //printf("body _d_switch_ustring()\n"); | |
369 size_t low; | |
370 size_t high; | |
371 size_t mid; | |
372 size_t c; | |
373 dchar[] pca; | |
374 | |
375 low = 0; | |
376 high = table.length; | |
377 | |
378 /* | |
379 // Print table | |
380 wprintf("ca[] = '%.*s'\n", ca); | |
381 for (mid = 0; mid < high; mid++) | |
382 { | |
383 pca = table[mid]; | |
384 wprintf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca); | |
385 } | |
386 */ | |
387 | |
388 // Do binary search | |
389 while (low < high) | |
390 { | |
391 mid = (low + high) >> 1; | |
392 pca = table[mid]; | |
393 c = ca.length - pca.length; | |
394 if (c == 0) | |
395 { | |
396 c = memcmp(ca.ptr, pca.ptr, ca.length * dchar.sizeof); | |
397 if (c == 0) | |
398 { //printf("found %d\n", mid); | |
399 return cast(int)mid; | |
400 } | |
401 } | |
402 if (c < 0) | |
403 { | |
404 high = mid; | |
405 } | |
406 else | |
407 { | |
408 low = mid + 1; | |
409 } | |
410 } | |
411 //printf("not found\n"); | |
412 return -1; // not found | |
413 } | |
414 | |
415 | |
416 unittest | |
417 { | |
418 switch (cast(dchar []) "c") | |
419 { | |
420 case "coo": | |
421 default: | |
422 break; | |
423 } | |
424 } |