132
|
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 }
|