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 }