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