Mercurial > projects > ldc
comparison druntime/src/compiler/dmd/aApplyR.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 * Part of the D programming language runtime library. | |
3 */ | |
4 | |
5 /* | |
6 * Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com | |
7 * Written by Walter Bright | |
8 * | |
9 * This software is provided 'as-is', without any express or implied | |
10 * warranty. In no event will the authors be held liable for any damages | |
11 * arising from the use of this software. | |
12 * | |
13 * Permission is granted to anyone to use this software for any purpose, | |
14 * including commercial applications, and to alter it and redistribute it | |
15 * freely, in both source and binary form, subject to the following | |
16 * restrictions: | |
17 * | |
18 * o The origin of this software must not be misrepresented; you must not | |
19 * claim that you wrote the original software. If you use this software | |
20 * in a product, an acknowledgment in the product documentation would be | |
21 * appreciated but is not required. | |
22 * o Altered source versions must be plainly marked as such, and must not | |
23 * be misrepresented as being the original software. | |
24 * o This notice may not be removed or altered from any source | |
25 * distribution. | |
26 */ | |
27 | |
28 /* | |
29 * Modified by Sean Kelly for use with the D Runtime Project | |
30 */ | |
31 | |
32 module rt.aApplyR; | |
33 | |
34 /* This code handles decoding UTF strings for foreach_reverse loops. | |
35 * There are 6 combinations of conversions between char, wchar, | |
36 * and dchar, and 2 of each of those. | |
37 */ | |
38 | |
39 private import util.utf; | |
40 | |
41 /**********************************************/ | |
42 /* 1 argument versions */ | |
43 | |
44 // dg is D, but _aApplyRcd() is C | |
45 extern (D) typedef int delegate(void *) dg_t; | |
46 | |
47 extern (C) int _aApplyRcd1(in char[] aa, dg_t dg) | |
48 { int result; | |
49 | |
50 debug(apply) printf("_aApplyRcd1(), len = %d\n", aa.length); | |
51 for (size_t i = aa.length; i != 0; ) | |
52 { dchar d; | |
53 | |
54 i--; | |
55 d = aa[i]; | |
56 if (d & 0x80) | |
57 { char c = cast(char)d; | |
58 uint j; | |
59 uint m = 0x3F; | |
60 d = 0; | |
61 while ((c & 0xC0) != 0xC0) | |
62 { if (i == 0) | |
63 onUnicodeError("Invalid UTF-8 sequence", 0); | |
64 i--; | |
65 d |= (c & 0x3F) << j; | |
66 j += 6; | |
67 m >>= 1; | |
68 c = aa[i]; | |
69 } | |
70 d |= (c & m) << j; | |
71 } | |
72 result = dg(cast(void *)&d); | |
73 if (result) | |
74 break; | |
75 } | |
76 return result; | |
77 } | |
78 | |
79 unittest | |
80 { | |
81 debug(apply) printf("_aApplyRcd1.unittest\n"); | |
82 | |
83 auto s = "hello"c; | |
84 int i; | |
85 | |
86 foreach_reverse(dchar d; s) | |
87 { | |
88 switch (i) | |
89 { | |
90 case 0: assert(d == 'o'); break; | |
91 case 1: assert(d == 'l'); break; | |
92 case 2: assert(d == 'l'); break; | |
93 case 3: assert(d == 'e'); break; | |
94 case 4: assert(d == 'h'); break; | |
95 default: assert(0); | |
96 } | |
97 i++; | |
98 } | |
99 assert(i == 5); | |
100 | |
101 s = "a\u1234\U00100456b"; | |
102 i = 0; | |
103 foreach_reverse(dchar d; s) | |
104 { | |
105 //printf("i = %d, d = %x\n", i, d); | |
106 switch (i) | |
107 { | |
108 case 0: assert(d == 'b'); break; | |
109 case 1: assert(d == '\U00100456'); break; | |
110 case 2: assert(d == '\u1234'); break; | |
111 case 3: assert(d == 'a'); break; | |
112 default: assert(0); | |
113 } | |
114 i++; | |
115 } | |
116 assert(i == 4); | |
117 } | |
118 | |
119 /*****************************/ | |
120 | |
121 extern (C) int _aApplyRwd1(in wchar[] aa, dg_t dg) | |
122 { int result; | |
123 | |
124 debug(apply) printf("_aApplyRwd1(), len = %d\n", aa.length); | |
125 for (size_t i = aa.length; i != 0; ) | |
126 { dchar d; | |
127 | |
128 i--; | |
129 d = aa[i]; | |
130 if (d >= 0xDC00 && d <= 0xDFFF) | |
131 { if (i == 0) | |
132 onUnicodeError("Invalid UTF-16 sequence", 0); | |
133 i--; | |
134 d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00); | |
135 } | |
136 result = dg(cast(void *)&d); | |
137 if (result) | |
138 break; | |
139 } | |
140 return result; | |
141 } | |
142 | |
143 unittest | |
144 { | |
145 debug(apply) printf("_aApplyRwd1.unittest\n"); | |
146 | |
147 auto s = "hello"w; | |
148 int i; | |
149 | |
150 foreach_reverse(dchar d; s) | |
151 { | |
152 switch (i) | |
153 { | |
154 case 0: assert(d == 'o'); break; | |
155 case 1: assert(d == 'l'); break; | |
156 case 2: assert(d == 'l'); break; | |
157 case 3: assert(d == 'e'); break; | |
158 case 4: assert(d == 'h'); break; | |
159 default: assert(0); | |
160 } | |
161 i++; | |
162 } | |
163 assert(i == 5); | |
164 | |
165 s = "a\u1234\U00100456b"; | |
166 i = 0; | |
167 foreach_reverse(dchar d; s) | |
168 { | |
169 //printf("i = %d, d = %x\n", i, d); | |
170 switch (i) | |
171 { | |
172 case 0: assert(d == 'b'); break; | |
173 case 1: assert(d == '\U00100456'); break; | |
174 case 2: assert(d == '\u1234'); break; | |
175 case 3: assert(d == 'a'); break; | |
176 default: assert(0); | |
177 } | |
178 i++; | |
179 } | |
180 assert(i == 4); | |
181 } | |
182 | |
183 /*****************************/ | |
184 | |
185 extern (C) int _aApplyRcw1(in char[] aa, dg_t dg) | |
186 { int result; | |
187 | |
188 debug(apply) printf("_aApplyRcw1(), len = %d\n", aa.length); | |
189 for (size_t i = aa.length; i != 0; ) | |
190 { dchar d; | |
191 wchar w; | |
192 | |
193 i--; | |
194 w = aa[i]; | |
195 if (w & 0x80) | |
196 { char c = cast(char)w; | |
197 uint j; | |
198 uint m = 0x3F; | |
199 d = 0; | |
200 while ((c & 0xC0) != 0xC0) | |
201 { if (i == 0) | |
202 onUnicodeError("Invalid UTF-8 sequence", 0); | |
203 i--; | |
204 d |= (c & 0x3F) << j; | |
205 j += 6; | |
206 m >>= 1; | |
207 c = aa[i]; | |
208 } | |
209 d |= (c & m) << j; | |
210 | |
211 if (d <= 0xFFFF) | |
212 w = cast(wchar) d; | |
213 else | |
214 { | |
215 w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800); | |
216 result = dg(cast(void *)&w); | |
217 if (result) | |
218 break; | |
219 w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00); | |
220 } | |
221 } | |
222 result = dg(cast(void *)&w); | |
223 if (result) | |
224 break; | |
225 } | |
226 return result; | |
227 } | |
228 | |
229 unittest | |
230 { | |
231 debug(apply) printf("_aApplyRcw1.unittest\n"); | |
232 | |
233 auto s = "hello"c; | |
234 int i; | |
235 | |
236 foreach_reverse(wchar d; s) | |
237 { | |
238 switch (i) | |
239 { | |
240 case 0: assert(d == 'o'); break; | |
241 case 1: assert(d == 'l'); break; | |
242 case 2: assert(d == 'l'); break; | |
243 case 3: assert(d == 'e'); break; | |
244 case 4: assert(d == 'h'); break; | |
245 default: assert(0); | |
246 } | |
247 i++; | |
248 } | |
249 assert(i == 5); | |
250 | |
251 s = "a\u1234\U00100456b"; | |
252 i = 0; | |
253 foreach_reverse(wchar d; s) | |
254 { | |
255 //printf("i = %d, d = %x\n", i, d); | |
256 switch (i) | |
257 { | |
258 case 0: assert(d == 'b'); break; | |
259 case 1: assert(d == 0xDBC1); break; | |
260 case 2: assert(d == 0xDC56); break; | |
261 case 3: assert(d == 0x1234); break; | |
262 case 4: assert(d == 'a'); break; | |
263 default: assert(0); | |
264 } | |
265 i++; | |
266 } | |
267 assert(i == 5); | |
268 } | |
269 | |
270 /*****************************/ | |
271 | |
272 extern (C) int _aApplyRwc1(in wchar[] aa, dg_t dg) | |
273 { int result; | |
274 | |
275 debug(apply) printf("_aApplyRwc1(), len = %d\n", aa.length); | |
276 for (size_t i = aa.length; i != 0; ) | |
277 { dchar d; | |
278 char c; | |
279 | |
280 i--; | |
281 d = aa[i]; | |
282 if (d >= 0xDC00 && d <= 0xDFFF) | |
283 { if (i == 0) | |
284 onUnicodeError("Invalid UTF-16 sequence", 0); | |
285 i--; | |
286 d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00); | |
287 } | |
288 | |
289 if (d & ~0x7F) | |
290 { | |
291 char[4] buf; | |
292 | |
293 auto b = toUTF8(buf, d); | |
294 foreach (char c2; b) | |
295 { | |
296 result = dg(cast(void *)&c2); | |
297 if (result) | |
298 return result; | |
299 } | |
300 continue; | |
301 } | |
302 c = cast(char)d; | |
303 result = dg(cast(void *)&c); | |
304 if (result) | |
305 break; | |
306 } | |
307 return result; | |
308 } | |
309 | |
310 unittest | |
311 { | |
312 debug(apply) printf("_aApplyRwc1.unittest\n"); | |
313 | |
314 auto s = "hello"w; | |
315 int i; | |
316 | |
317 foreach_reverse(char d; s) | |
318 { | |
319 switch (i) | |
320 { | |
321 case 0: assert(d == 'o'); break; | |
322 case 1: assert(d == 'l'); break; | |
323 case 2: assert(d == 'l'); break; | |
324 case 3: assert(d == 'e'); break; | |
325 case 4: assert(d == 'h'); break; | |
326 default: assert(0); | |
327 } | |
328 i++; | |
329 } | |
330 assert(i == 5); | |
331 | |
332 s = "a\u1234\U00100456b"; | |
333 i = 0; | |
334 foreach_reverse(char d; s) | |
335 { | |
336 //printf("i = %d, d = %x\n", i, d); | |
337 switch (i) | |
338 { | |
339 case 0: assert(d == 'b'); break; | |
340 case 1: assert(d == 0xF4); break; | |
341 case 2: assert(d == 0x80); break; | |
342 case 3: assert(d == 0x91); break; | |
343 case 4: assert(d == 0x96); break; | |
344 case 5: assert(d == 0xE1); break; | |
345 case 6: assert(d == 0x88); break; | |
346 case 7: assert(d == 0xB4); break; | |
347 case 8: assert(d == 'a'); break; | |
348 default: assert(0); | |
349 } | |
350 i++; | |
351 } | |
352 assert(i == 9); | |
353 } | |
354 | |
355 /*****************************/ | |
356 | |
357 extern (C) int _aApplyRdc1(in dchar[] aa, dg_t dg) | |
358 { int result; | |
359 | |
360 debug(apply) printf("_aApplyRdc1(), len = %d\n", aa.length); | |
361 for (size_t i = aa.length; i != 0;) | |
362 { dchar d = aa[--i]; | |
363 char c; | |
364 | |
365 if (d & ~0x7F) | |
366 { | |
367 char[4] buf; | |
368 | |
369 auto b = toUTF8(buf, d); | |
370 foreach (char c2; b) | |
371 { | |
372 result = dg(cast(void *)&c2); | |
373 if (result) | |
374 return result; | |
375 } | |
376 continue; | |
377 } | |
378 else | |
379 { | |
380 c = cast(char)d; | |
381 } | |
382 result = dg(cast(void *)&c); | |
383 if (result) | |
384 break; | |
385 } | |
386 return result; | |
387 } | |
388 | |
389 unittest | |
390 { | |
391 debug(apply) printf("_aApplyRdc1.unittest\n"); | |
392 | |
393 auto s = "hello"d; | |
394 int i; | |
395 | |
396 foreach_reverse(char d; s) | |
397 { | |
398 switch (i) | |
399 { | |
400 case 0: assert(d == 'o'); break; | |
401 case 1: assert(d == 'l'); break; | |
402 case 2: assert(d == 'l'); break; | |
403 case 3: assert(d == 'e'); break; | |
404 case 4: assert(d == 'h'); break; | |
405 default: assert(0); | |
406 } | |
407 i++; | |
408 } | |
409 assert(i == 5); | |
410 | |
411 s = "a\u1234\U00100456b"; | |
412 i = 0; | |
413 foreach_reverse(char d; s) | |
414 { | |
415 //printf("i = %d, d = %x\n", i, d); | |
416 switch (i) | |
417 { | |
418 case 0: assert(d == 'b'); break; | |
419 case 1: assert(d == 0xF4); break; | |
420 case 2: assert(d == 0x80); break; | |
421 case 3: assert(d == 0x91); break; | |
422 case 4: assert(d == 0x96); break; | |
423 case 5: assert(d == 0xE1); break; | |
424 case 6: assert(d == 0x88); break; | |
425 case 7: assert(d == 0xB4); break; | |
426 case 8: assert(d == 'a'); break; | |
427 default: assert(0); | |
428 } | |
429 i++; | |
430 } | |
431 assert(i == 9); | |
432 } | |
433 | |
434 /*****************************/ | |
435 | |
436 extern (C) int _aApplyRdw1(in dchar[] aa, dg_t dg) | |
437 { int result; | |
438 | |
439 debug(apply) printf("_aApplyRdw1(), len = %d\n", aa.length); | |
440 for (size_t i = aa.length; i != 0; ) | |
441 { dchar d = aa[--i]; | |
442 wchar w; | |
443 | |
444 if (d <= 0xFFFF) | |
445 w = cast(wchar) d; | |
446 else | |
447 { | |
448 w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800); | |
449 result = dg(cast(void *)&w); | |
450 if (result) | |
451 break; | |
452 w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00); | |
453 } | |
454 result = dg(cast(void *)&w); | |
455 if (result) | |
456 break; | |
457 } | |
458 return result; | |
459 } | |
460 | |
461 unittest | |
462 { | |
463 debug(apply) printf("_aApplyRdw1.unittest\n"); | |
464 | |
465 auto s = "hello"d; | |
466 int i; | |
467 | |
468 foreach_reverse(wchar d; s) | |
469 { | |
470 switch (i) | |
471 { | |
472 case 0: assert(d == 'o'); break; | |
473 case 1: assert(d == 'l'); break; | |
474 case 2: assert(d == 'l'); break; | |
475 case 3: assert(d == 'e'); break; | |
476 case 4: assert(d == 'h'); break; | |
477 default: assert(0); | |
478 } | |
479 i++; | |
480 } | |
481 assert(i == 5); | |
482 | |
483 s = "a\u1234\U00100456b"; | |
484 i = 0; | |
485 foreach_reverse(wchar d; s) | |
486 { | |
487 //printf("i = %d, d = %x\n", i, d); | |
488 switch (i) | |
489 { | |
490 case 0: assert(d == 'b'); break; | |
491 case 1: assert(d == 0xDBC1); break; | |
492 case 2: assert(d == 0xDC56); break; | |
493 case 3: assert(d == 0x1234); break; | |
494 case 4: assert(d == 'a'); break; | |
495 default: assert(0); | |
496 } | |
497 i++; | |
498 } | |
499 assert(i == 5); | |
500 } | |
501 | |
502 | |
503 /****************************************************************************/ | |
504 /* 2 argument versions */ | |
505 | |
506 // dg is D, but _aApplyRcd2() is C | |
507 extern (D) typedef int delegate(void *, void *) dg2_t; | |
508 | |
509 extern (C) int _aApplyRcd2(in char[] aa, dg2_t dg) | |
510 { int result; | |
511 size_t i; | |
512 size_t len = aa.length; | |
513 | |
514 debug(apply) printf("_aApplyRcd2(), len = %d\n", len); | |
515 for (i = len; i != 0; ) | |
516 { dchar d; | |
517 | |
518 i--; | |
519 d = aa[i]; | |
520 if (d & 0x80) | |
521 { char c = cast(char)d; | |
522 uint j; | |
523 uint m = 0x3F; | |
524 d = 0; | |
525 while ((c & 0xC0) != 0xC0) | |
526 { if (i == 0) | |
527 onUnicodeError("Invalid UTF-8 sequence", 0); | |
528 i--; | |
529 d |= (c & 0x3F) << j; | |
530 j += 6; | |
531 m >>= 1; | |
532 c = aa[i]; | |
533 } | |
534 d |= (c & m) << j; | |
535 } | |
536 result = dg(&i, cast(void *)&d); | |
537 if (result) | |
538 break; | |
539 } | |
540 return result; | |
541 } | |
542 | |
543 unittest | |
544 { | |
545 debug(apply) printf("_aApplyRcd2.unittest\n"); | |
546 | |
547 auto s = "hello"c; | |
548 int i; | |
549 | |
550 foreach_reverse(k, dchar d; s) | |
551 { | |
552 assert(k == 4 - i); | |
553 switch (i) | |
554 { | |
555 case 0: assert(d == 'o'); break; | |
556 case 1: assert(d == 'l'); break; | |
557 case 2: assert(d == 'l'); break; | |
558 case 3: assert(d == 'e'); break; | |
559 case 4: assert(d == 'h'); break; | |
560 default: assert(0); | |
561 } | |
562 i++; | |
563 } | |
564 assert(i == 5); | |
565 | |
566 s = "a\u1234\U00100456b"; | |
567 i = 0; | |
568 foreach_reverse(k, dchar d; s) | |
569 { | |
570 //printf("i = %d, k = %d, d = %x\n", i, k, d); | |
571 switch (i) | |
572 { | |
573 case 0: assert(d == 'b'); assert(k == 8); break; | |
574 case 1: assert(d == '\U00100456'); assert(k == 4); break; | |
575 case 2: assert(d == '\u1234'); assert(k == 1); break; | |
576 case 3: assert(d == 'a'); assert(k == 0); break; | |
577 default: assert(0); | |
578 } | |
579 i++; | |
580 } | |
581 assert(i == 4); | |
582 } | |
583 | |
584 /*****************************/ | |
585 | |
586 extern (C) int _aApplyRwd2(in wchar[] aa, dg2_t dg) | |
587 { int result; | |
588 | |
589 debug(apply) printf("_aApplyRwd2(), len = %d\n", aa.length); | |
590 for (size_t i = aa.length; i != 0; ) | |
591 { dchar d; | |
592 | |
593 i--; | |
594 d = aa[i]; | |
595 if (d >= 0xDC00 && d <= 0xDFFF) | |
596 { if (i == 0) | |
597 onUnicodeError("Invalid UTF-16 sequence", 0); | |
598 i--; | |
599 d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00); | |
600 } | |
601 result = dg(&i, cast(void *)&d); | |
602 if (result) | |
603 break; | |
604 } | |
605 return result; | |
606 } | |
607 | |
608 unittest | |
609 { | |
610 debug(apply) printf("_aApplyRwd2.unittest\n"); | |
611 | |
612 auto s = "hello"w; | |
613 int i; | |
614 | |
615 foreach_reverse(k, dchar d; s) | |
616 { | |
617 //printf("i = %d, k = %d, d = %x\n", i, k, d); | |
618 assert(k == 4 - i); | |
619 switch (i) | |
620 { | |
621 case 0: assert(d == 'o'); break; | |
622 case 1: assert(d == 'l'); break; | |
623 case 2: assert(d == 'l'); break; | |
624 case 3: assert(d == 'e'); break; | |
625 case 4: assert(d == 'h'); break; | |
626 default: assert(0); | |
627 } | |
628 i++; | |
629 } | |
630 assert(i == 5); | |
631 | |
632 s = "a\u1234\U00100456b"; | |
633 i = 0; | |
634 foreach_reverse(k, dchar d; s) | |
635 { | |
636 //printf("i = %d, k = %d, d = %x\n", i, k, d); | |
637 switch (i) | |
638 { | |
639 case 0: assert(k == 4); assert(d == 'b'); break; | |
640 case 1: assert(k == 2); assert(d == '\U00100456'); break; | |
641 case 2: assert(k == 1); assert(d == '\u1234'); break; | |
642 case 3: assert(k == 0); assert(d == 'a'); break; | |
643 default: assert(0); | |
644 } | |
645 i++; | |
646 } | |
647 assert(i == 4); | |
648 } | |
649 | |
650 /*****************************/ | |
651 | |
652 extern (C) int _aApplyRcw2(in char[] aa, dg2_t dg) | |
653 { int result; | |
654 | |
655 debug(apply) printf("_aApplyRcw2(), len = %d\n", aa.length); | |
656 for (size_t i = aa.length; i != 0; ) | |
657 { dchar d; | |
658 wchar w; | |
659 | |
660 i--; | |
661 w = aa[i]; | |
662 if (w & 0x80) | |
663 { char c = cast(char)w; | |
664 uint j; | |
665 uint m = 0x3F; | |
666 d = 0; | |
667 while ((c & 0xC0) != 0xC0) | |
668 { if (i == 0) | |
669 onUnicodeError("Invalid UTF-8 sequence", 0); | |
670 i--; | |
671 d |= (c & 0x3F) << j; | |
672 j += 6; | |
673 m >>= 1; | |
674 c = aa[i]; | |
675 } | |
676 d |= (c & m) << j; | |
677 | |
678 if (d <= 0xFFFF) | |
679 w = cast(wchar) d; | |
680 else | |
681 { | |
682 w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800); | |
683 result = dg(&i, cast(void *)&w); | |
684 if (result) | |
685 break; | |
686 w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00); | |
687 } | |
688 } | |
689 result = dg(&i, cast(void *)&w); | |
690 if (result) | |
691 break; | |
692 } | |
693 return result; | |
694 } | |
695 | |
696 unittest | |
697 { | |
698 debug(apply) printf("_aApplyRcw2.unittest\n"); | |
699 | |
700 auto s = "hello"c; | |
701 int i; | |
702 | |
703 foreach_reverse(k, wchar d; s) | |
704 { | |
705 //printf("i = %d, k = %d, d = %x\n", i, k, d); | |
706 assert(k == 4 - i); | |
707 switch (i) | |
708 { | |
709 case 0: assert(d == 'o'); break; | |
710 case 1: assert(d == 'l'); break; | |
711 case 2: assert(d == 'l'); break; | |
712 case 3: assert(d == 'e'); break; | |
713 case 4: assert(d == 'h'); break; | |
714 default: assert(0); | |
715 } | |
716 i++; | |
717 } | |
718 assert(i == 5); | |
719 | |
720 s = "a\u1234\U00100456b"; | |
721 i = 0; | |
722 foreach_reverse(k, wchar d; s) | |
723 { | |
724 //printf("i = %d, k = %d, d = %x\n", i, k, d); | |
725 switch (i) | |
726 { | |
727 case 0: assert(k == 8); assert(d == 'b'); break; | |
728 case 1: assert(k == 4); assert(d == 0xDBC1); break; | |
729 case 2: assert(k == 4); assert(d == 0xDC56); break; | |
730 case 3: assert(k == 1); assert(d == 0x1234); break; | |
731 case 4: assert(k == 0); assert(d == 'a'); break; | |
732 default: assert(0); | |
733 } | |
734 i++; | |
735 } | |
736 assert(i == 5); | |
737 } | |
738 | |
739 /*****************************/ | |
740 | |
741 extern (C) int _aApplyRwc2(in wchar[] aa, dg2_t dg) | |
742 { int result; | |
743 | |
744 debug(apply) printf("_aApplyRwc2(), len = %d\n", aa.length); | |
745 for (size_t i = aa.length; i != 0; ) | |
746 { dchar d; | |
747 char c; | |
748 | |
749 i--; | |
750 d = aa[i]; | |
751 if (d >= 0xDC00 && d <= 0xDFFF) | |
752 { if (i == 0) | |
753 onUnicodeError("Invalid UTF-16 sequence", 0); | |
754 i--; | |
755 d = ((aa[i] - 0xD7C0) << 10) + (d - 0xDC00); | |
756 } | |
757 | |
758 if (d & ~0x7F) | |
759 { | |
760 char[4] buf; | |
761 | |
762 auto b = toUTF8(buf, d); | |
763 foreach (char c2; b) | |
764 { | |
765 result = dg(&i, cast(void *)&c2); | |
766 if (result) | |
767 return result; | |
768 } | |
769 continue; | |
770 } | |
771 c = cast(char)d; | |
772 result = dg(&i, cast(void *)&c); | |
773 if (result) | |
774 break; | |
775 } | |
776 return result; | |
777 } | |
778 | |
779 unittest | |
780 { | |
781 debug(apply) printf("_aApplyRwc2.unittest\n"); | |
782 | |
783 auto s = "hello"w; | |
784 int i; | |
785 | |
786 foreach_reverse(k, char d; s) | |
787 { | |
788 //printf("i = %d, k = %d, d = %x\n", i, k, d); | |
789 assert(k == 4 - i); | |
790 switch (i) | |
791 { | |
792 case 0: assert(d == 'o'); break; | |
793 case 1: assert(d == 'l'); break; | |
794 case 2: assert(d == 'l'); break; | |
795 case 3: assert(d == 'e'); break; | |
796 case 4: assert(d == 'h'); break; | |
797 default: assert(0); | |
798 } | |
799 i++; | |
800 } | |
801 assert(i == 5); | |
802 | |
803 s = "a\u1234\U00100456b"; | |
804 i = 0; | |
805 foreach_reverse(k, char d; s) | |
806 { | |
807 //printf("i = %d, k = %d, d = %x\n", i, k, d); | |
808 switch (i) | |
809 { | |
810 case 0: assert(k == 4); assert(d == 'b'); break; | |
811 case 1: assert(k == 2); assert(d == 0xF4); break; | |
812 case 2: assert(k == 2); assert(d == 0x80); break; | |
813 case 3: assert(k == 2); assert(d == 0x91); break; | |
814 case 4: assert(k == 2); assert(d == 0x96); break; | |
815 case 5: assert(k == 1); assert(d == 0xE1); break; | |
816 case 6: assert(k == 1); assert(d == 0x88); break; | |
817 case 7: assert(k == 1); assert(d == 0xB4); break; | |
818 case 8: assert(k == 0); assert(d == 'a'); break; | |
819 default: assert(0); | |
820 } | |
821 i++; | |
822 } | |
823 assert(i == 9); | |
824 } | |
825 | |
826 /*****************************/ | |
827 | |
828 extern (C) int _aApplyRdc2(in dchar[] aa, dg2_t dg) | |
829 { int result; | |
830 | |
831 debug(apply) printf("_aApplyRdc2(), len = %d\n", aa.length); | |
832 for (size_t i = aa.length; i != 0; ) | |
833 { dchar d = aa[--i]; | |
834 char c; | |
835 | |
836 if (d & ~0x7F) | |
837 { | |
838 char[4] buf; | |
839 | |
840 auto b = toUTF8(buf, d); | |
841 foreach (char c2; b) | |
842 { | |
843 result = dg(&i, cast(void *)&c2); | |
844 if (result) | |
845 return result; | |
846 } | |
847 continue; | |
848 } | |
849 else | |
850 { c = cast(char)d; | |
851 } | |
852 result = dg(&i, cast(void *)&c); | |
853 if (result) | |
854 break; | |
855 } | |
856 return result; | |
857 } | |
858 | |
859 unittest | |
860 { | |
861 debug(apply) printf("_aApplyRdc2.unittest\n"); | |
862 | |
863 auto s = "hello"d; | |
864 int i; | |
865 | |
866 foreach_reverse(k, char d; s) | |
867 { | |
868 //printf("i = %d, k = %d, d = %x\n", i, k, d); | |
869 assert(k == 4 - i); | |
870 switch (i) | |
871 { | |
872 case 0: assert(d == 'o'); break; | |
873 case 1: assert(d == 'l'); break; | |
874 case 2: assert(d == 'l'); break; | |
875 case 3: assert(d == 'e'); break; | |
876 case 4: assert(d == 'h'); break; | |
877 default: assert(0); | |
878 } | |
879 i++; | |
880 } | |
881 assert(i == 5); | |
882 | |
883 s = "a\u1234\U00100456b"; | |
884 i = 0; | |
885 foreach_reverse(k, char d; s) | |
886 { | |
887 //printf("i = %d, k = %d, d = %x\n", i, k, d); | |
888 switch (i) | |
889 { | |
890 case 0: assert(k == 3); assert(d == 'b'); break; | |
891 case 1: assert(k == 2); assert(d == 0xF4); break; | |
892 case 2: assert(k == 2); assert(d == 0x80); break; | |
893 case 3: assert(k == 2); assert(d == 0x91); break; | |
894 case 4: assert(k == 2); assert(d == 0x96); break; | |
895 case 5: assert(k == 1); assert(d == 0xE1); break; | |
896 case 6: assert(k == 1); assert(d == 0x88); break; | |
897 case 7: assert(k == 1); assert(d == 0xB4); break; | |
898 case 8: assert(k == 0); assert(d == 'a'); break; | |
899 default: assert(0); | |
900 } | |
901 i++; | |
902 } | |
903 assert(i == 9); | |
904 } | |
905 | |
906 /*****************************/ | |
907 | |
908 extern (C) int _aApplyRdw2(in dchar[] aa, dg2_t dg) | |
909 { int result; | |
910 | |
911 debug(apply) printf("_aApplyRdw2(), len = %d\n", aa.length); | |
912 for (size_t i = aa.length; i != 0; ) | |
913 { dchar d = aa[--i]; | |
914 wchar w; | |
915 | |
916 if (d <= 0xFFFF) | |
917 w = cast(wchar) d; | |
918 else | |
919 { | |
920 w = cast(wchar) ((((d - 0x10000) >> 10) & 0x3FF) + 0xD800); | |
921 result = dg(&i, cast(void *)&w); | |
922 if (result) | |
923 break; | |
924 w = cast(wchar) (((d - 0x10000) & 0x3FF) + 0xDC00); | |
925 } | |
926 result = dg(&i, cast(void *)&w); | |
927 if (result) | |
928 break; | |
929 } | |
930 return result; | |
931 } | |
932 | |
933 unittest | |
934 { | |
935 debug(apply) printf("_aApplyRdw2.unittest\n"); | |
936 | |
937 auto s = "hello"d; | |
938 int i; | |
939 | |
940 foreach_reverse(k, wchar d; s) | |
941 { | |
942 //printf("i = %d, k = %d, d = %x\n", i, k, d); | |
943 assert(k == 4 - i); | |
944 switch (i) | |
945 { | |
946 case 0: assert(d == 'o'); break; | |
947 case 1: assert(d == 'l'); break; | |
948 case 2: assert(d == 'l'); break; | |
949 case 3: assert(d == 'e'); break; | |
950 case 4: assert(d == 'h'); break; | |
951 default: assert(0); | |
952 } | |
953 i++; | |
954 } | |
955 assert(i == 5); | |
956 | |
957 s = "a\u1234\U00100456b"; | |
958 i = 0; | |
959 foreach_reverse(k, wchar d; s) | |
960 { | |
961 //printf("i = %d, k = %d, d = %x\n", i, k, d); | |
962 switch (i) | |
963 { | |
964 case 0: assert(k == 3); assert(d == 'b'); break; | |
965 case 1: assert(k == 2); assert(d == 0xDBC1); break; | |
966 case 2: assert(k == 2); assert(d == 0xDC56); break; | |
967 case 3: assert(k == 1); assert(d == 0x1234); break; | |
968 case 4: assert(k == 0); assert(d == 'a'); break; | |
969 default: assert(0); | |
970 } | |
971 i++; | |
972 } | |
973 assert(i == 5); | |
974 } |