comparison runtime/internal/switch.d @ 443:44f08170f4ef

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