Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

root/runtime/internal/aApplyR.d

Revision 486:a34078905d01, 24.4 kB (checked in by Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>, 4 years ago)

Added pragma(llvmdc, "string") for misc per-module compiler configuration, currently "string" can only be "verbose" which forces -vv for module it appears in.
Reimplemented support for nested functions/class using a new approach.
Added error on taking address of intrinsic.
Fixed problems with the ->syntaxCopy of TypeFunction? delegate exp.
Removed DtoDType and replaced all uses with ->toBasetype() instead.
Removed unused inplace stuff.
Fixed a bunch of issues in the runtime unittests, not complete yet.
Added mini tests.

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