comparison druntime/src/compiler/dmd/switch_.d @ 759:d3eb054172f9

Added copy of druntime from DMD 2.020 modified for LDC.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Tue, 11 Nov 2008 01:52:37 +0100
parents
children
comparison
equal deleted inserted replaced
758:f04dde6e882c 759:d3eb054172f9
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 for use with the D Runtime Project
26 */
27
28 module rt.switch_;
29
30 private import stdc.string;
31
32 /******************************************************
33 * Support for switch statements switching on strings.
34 * Input:
35 * table[] sorted array of strings generated by compiler
36 * ca string to look up in table
37 * Output:
38 * result index of match in table[]
39 * -1 if not in table
40 */
41
42 extern (C):
43
44 int _d_switch_string(char[][] table, char[] ca)
45 in
46 {
47 //printf("in _d_switch_string()\n");
48 assert(table.length >= 0);
49 assert(ca.length >= 0);
50
51 // Make sure table[] is sorted correctly
52 int j;
53
54 for (j = 1; j < table.length; j++)
55 {
56 int len1 = table[j - 1].length;
57 int len2 = table[j].length;
58
59 assert(len1 <= len2);
60 if (len1 == len2)
61 {
62 int ci;
63
64 ci = memcmp(table[j - 1].ptr, table[j].ptr, len1);
65 assert(ci < 0); // ci==0 means a duplicate
66 }
67 }
68 }
69 out (result)
70 {
71 int i;
72 int cj;
73
74 //printf("out _d_switch_string()\n");
75 if (result == -1)
76 {
77 // Not found
78 for (i = 0; i < table.length; i++)
79 {
80 if (table[i].length == ca.length)
81 { cj = memcmp(table[i].ptr, ca.ptr, ca.length);
82 assert(cj != 0);
83 }
84 }
85 }
86 else
87 {
88 assert(0 <= result && result < table.length);
89 for (i = 0; 1; i++)
90 {
91 assert(i < table.length);
92 if (table[i].length == ca.length)
93 {
94 cj = memcmp(table[i].ptr, ca.ptr, ca.length);
95 if (cj == 0)
96 {
97 assert(i == result);
98 break;
99 }
100 }
101 }
102 }
103 }
104 body
105 {
106 //printf("body _d_switch_string(%.*s)\n", ca);
107 int low;
108 int high;
109 int mid;
110 int c;
111 char[] pca;
112
113 low = 0;
114 high = table.length;
115
116 version (none)
117 {
118 // Print table
119 printf("ca[] = '%s'\n", cast(char *)ca);
120 for (mid = 0; mid < high; mid++)
121 {
122 pca = table[mid];
123 printf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca);
124 }
125 }
126 if (high &&
127 ca.length >= table[0].length &&
128 ca.length <= table[high - 1].length)
129 {
130 // Looking for 0 length string, which would only be at the beginning
131 if (ca.length == 0)
132 return 0;
133
134 char c1 = ca[0];
135
136 // Do binary search
137 while (low < high)
138 {
139 mid = (low + high) >> 1;
140 pca = table[mid];
141 c = ca.length - pca.length;
142 if (c == 0)
143 {
144 c = cast(ubyte)c1 - cast(ubyte)pca[0];
145 if (c == 0)
146 {
147 c = memcmp(ca.ptr, pca.ptr, ca.length);
148 if (c == 0)
149 { //printf("found %d\n", mid);
150 return mid;
151 }
152 }
153 }
154 if (c < 0)
155 {
156 high = mid;
157 }
158 else
159 {
160 low = mid + 1;
161 }
162 }
163 }
164
165 //printf("not found\n");
166 return -1; // not found
167 }
168
169 unittest
170 {
171 switch (cast(char []) "c")
172 {
173 case "coo":
174 default:
175 break;
176 }
177 }
178
179 /**********************************
180 * Same thing, but for wide chars.
181 */
182
183 int _d_switch_ustring(wchar[][] table, wchar[] ca)
184 in
185 {
186 //printf("in _d_switch_ustring()\n");
187 assert(table.length >= 0);
188 assert(ca.length >= 0);
189
190 // Make sure table[] is sorted correctly
191 int j;
192
193 for (j = 1; j < table.length; j++)
194 {
195 int len1 = table[j - 1].length;
196 int len2 = table[j].length;
197
198 assert(len1 <= len2);
199 if (len1 == len2)
200 {
201 int c;
202
203 c = memcmp(table[j - 1].ptr, table[j].ptr, len1 * wchar.sizeof);
204 assert(c < 0); // c==0 means a duplicate
205 }
206 }
207 }
208 out (result)
209 {
210 int i;
211 int c;
212
213 //printf("out _d_switch_string()\n");
214 if (result == -1)
215 {
216 // Not found
217 for (i = 0; i < table.length; i++)
218 {
219 if (table[i].length == ca.length)
220 { c = memcmp(table[i].ptr, ca.ptr, ca.length * wchar.sizeof);
221 assert(c != 0);
222 }
223 }
224 }
225 else
226 {
227 assert(0 <= result && result < table.length);
228 for (i = 0; 1; i++)
229 {
230 assert(i < table.length);
231 if (table[i].length == ca.length)
232 {
233 c = memcmp(table[i].ptr, ca.ptr, ca.length * wchar.sizeof);
234 if (c == 0)
235 {
236 assert(i == result);
237 break;
238 }
239 }
240 }
241 }
242 }
243 body
244 {
245 //printf("body _d_switch_ustring()\n");
246 int low;
247 int high;
248 int mid;
249 int c;
250 wchar[] pca;
251
252 low = 0;
253 high = table.length;
254
255 /*
256 // Print table
257 wprintf("ca[] = '%.*s'\n", ca);
258 for (mid = 0; mid < high; mid++)
259 {
260 pca = table[mid];
261 wprintf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca);
262 }
263 */
264
265 // Do binary search
266 while (low < high)
267 {
268 mid = (low + high) >> 1;
269 pca = table[mid];
270 c = ca.length - pca.length;
271 if (c == 0)
272 {
273 c = memcmp(ca.ptr, pca.ptr, ca.length * wchar.sizeof);
274 if (c == 0)
275 { //printf("found %d\n", mid);
276 return mid;
277 }
278 }
279 if (c < 0)
280 {
281 high = mid;
282 }
283 else
284 {
285 low = mid + 1;
286 }
287 }
288 //printf("not found\n");
289 return -1; // not found
290 }
291
292
293 unittest
294 {
295 switch (cast(wchar []) "c")
296 {
297 case "coo":
298 default:
299 break;
300 }
301 }
302
303
304 /**********************************
305 * Same thing, but for wide chars.
306 */
307
308 int _d_switch_dstring(dchar[][] table, dchar[] ca)
309 in
310 {
311 //printf("in _d_switch_dstring()\n");
312 assert(table.length >= 0);
313 assert(ca.length >= 0);
314
315 // Make sure table[] is sorted correctly
316 int j;
317
318 for (j = 1; j < table.length; j++)
319 {
320 int len1 = table[j - 1].length;
321 int len2 = table[j].length;
322
323 assert(len1 <= len2);
324 if (len1 == len2)
325 {
326 int c;
327
328 c = memcmp(table[j - 1].ptr, table[j].ptr, len1 * dchar.sizeof);
329 assert(c < 0); // c==0 means a duplicate
330 }
331 }
332 }
333 out (result)
334 {
335 int i;
336 int c;
337
338 //printf("out _d_switch_string()\n");
339 if (result == -1)
340 {
341 // Not found
342 for (i = 0; i < table.length; i++)
343 {
344 if (table[i].length == ca.length)
345 { c = memcmp(table[i].ptr, ca.ptr, ca.length * dchar.sizeof);
346 assert(c != 0);
347 }
348 }
349 }
350 else
351 {
352 assert(0 <= result && result < table.length);
353 for (i = 0; 1; i++)
354 {
355 assert(i < table.length);
356 if (table[i].length == ca.length)
357 {
358 c = memcmp(table[i].ptr, ca.ptr, ca.length * dchar.sizeof);
359 if (c == 0)
360 {
361 assert(i == result);
362 break;
363 }
364 }
365 }
366 }
367 }
368 body
369 {
370 //printf("body _d_switch_ustring()\n");
371 int low;
372 int high;
373 int mid;
374 int c;
375 dchar[] pca;
376
377 low = 0;
378 high = table.length;
379
380 /*
381 // Print table
382 wprintf("ca[] = '%.*s'\n", ca);
383 for (mid = 0; mid < high; mid++)
384 {
385 pca = table[mid];
386 wprintf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca);
387 }
388 */
389
390 // Do binary search
391 while (low < high)
392 {
393 mid = (low + high) >> 1;
394 pca = table[mid];
395 c = ca.length - pca.length;
396 if (c == 0)
397 {
398 c = memcmp(ca.ptr, pca.ptr, ca.length * dchar.sizeof);
399 if (c == 0)
400 { //printf("found %d\n", mid);
401 return mid;
402 }
403 }
404 if (c < 0)
405 {
406 high = mid;
407 }
408 else
409 {
410 low = mid + 1;
411 }
412 }
413 //printf("not found\n");
414 return -1; // not found
415 }
416
417
418 unittest
419 {
420 switch (cast(dchar []) "c")
421 {
422 case "coo":
423 default:
424 break;
425 }
426 }