Annotation of src/usr.bin/mklocale/yacc.y, Revision 1.4
1.4 ! nicm 1: /* $OpenBSD: yacc.y,v 1.3 2009/08/08 19:37:14 sobrado Exp $ */
1.1 espie 2: /* $NetBSD: yacc.y,v 1.24 2004/01/05 23:23:36 jmmv Exp $ */
3:
4: %{
5: /*-
6: * Copyright (c) 1993
7: * The Regents of the University of California. All rights reserved.
8: *
9: * This code is derived from software contributed to Berkeley by
10: * Paul Borman at Krystal Technologies.
11: *
12: * Redistribution and use in source and binary forms, with or without
13: * modification, are permitted provided that the following conditions
14: * are met:
15: * 1. Redistributions of source code must retain the above copyright
16: * notice, this list of conditions and the following disclaimer.
17: * 2. Redistributions in binary form must reproduce the above copyright
18: * notice, this list of conditions and the following disclaimer in the
19: * documentation and/or other materials provided with the distribution.
20: * 3. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: */
36:
37: #include <sys/cdefs.h>
38:
39: #include <sys/types.h>
40: #include <netinet/in.h> /* Needed by <arpa/inet.h> on NetBSD 1.5. */
41: #include <arpa/inet.h> /* Needed for htonl on POSIX systems. */
42:
43: #include <err.h>
44: #include "locale/runetype.h"
45: #include <stddef.h>
46: #include <stdio.h>
47: #include <stdlib.h>
48: #include <string.h>
49: #include <unistd.h>
50: #include <ctype.h>
51:
52: #include "ldef.h"
53:
54: const char *locale_file = "<stdout>";
55:
56: rune_map maplower = { { 0, }, };
57: rune_map mapupper = { { 0, }, };
58: rune_map types = { { 0, }, };
59:
60: _RuneLocale new_locale = { { 0, }, };
61:
62: rune_t charsetbits = (rune_t)0x00000000;
63: #if 0
64: rune_t charsetmask = (rune_t)0x0000007f;
65: #endif
66: rune_t charsetmask = (rune_t)0xffffffff;
67:
68: void set_map(rune_map *, rune_list *, u_int32_t);
69: void set_digitmap(rune_map *, rune_list *);
70: void add_map(rune_map *, rune_list *, u_int32_t);
71:
72: int main(int, char *[]);
73: int yyerror(const char *s);
74: void *xmalloc(size_t sz);
75: u_int32_t *xlalloc(size_t sz);
76: u_int32_t *xrelalloc(u_int32_t *old, size_t sz);
77: void dump_tables(void);
78: int yyparse(void);
79: extern int yylex(void);
80: %}
81:
82: %union {
83: rune_t rune;
84: int i;
85: char *str;
86:
87: rune_list *list;
88: }
89:
90: %token <rune> RUNE
91: %token LBRK
92: %token RBRK
93: %token THRU
94: %token MAPLOWER
95: %token MAPUPPER
96: %token DIGITMAP
97: %token <i> LIST
98: %token <str> VARIABLE
99: %token CHARSET
100: %token ENCODING
101: %token INVALID
102: %token <str> STRING
103:
104: %type <list> list
105: %type <list> map
106:
107:
108: %%
109:
110: locale : /* empty */
111: | table
112: { dump_tables(); }
113: ;
114:
115: table : entry
116: | table entry
117: ;
118:
119: entry : ENCODING STRING
120: { strncpy(new_locale.rl_encoding, $2, sizeof(new_locale.rl_encoding)); }
121: | VARIABLE
122: { new_locale.rl_variable_len = strlen($1) + 1;
123: new_locale.rl_variable = strdup($1);
124: }
125: | CHARSET RUNE
126: { charsetbits = $2; charsetmask = 0x0000007f; }
127: | CHARSET RUNE RUNE
128: { charsetbits = $2; charsetmask = $3; }
129: | CHARSET STRING
130: { int final = $2[strlen($2) - 1] & 0x7f;
131: charsetbits = final << 24;
132: if ($2[0] == '$') {
133: charsetmask = 0x00007f7f;
134: if (strchr(",-./", $2[1]))
135: charsetbits |= 0x80;
136: if (0xd0 <= final && final <= 0xdf)
137: charsetmask |= 0x007f0000;
138: } else {
139: charsetmask = 0x0000007f;
140: if (strchr(",-./", $2[0]))
141: charsetbits |= 0x80;
142: if (strlen($2) == 2 && $2[0] == '!')
143: charsetbits |= ((0x80 | $2[0]) << 16);
144: }
145:
146: /*
147: * special rules
148: */
149: if (charsetbits == ('B' << 24)
150: && charsetmask == 0x0000007f) {
151: /*ASCII: 94B*/
152: charsetbits = 0;
153: charsetmask = 0x0000007f;
154: } else if (charsetbits == (('A' << 24) | 0x80)
155: && charsetmask == 0x0000007f) {
156: /*Latin1: 96A*/
157: charsetbits = 0x80;
158: charsetmask = 0x0000007f;
159: }
160: }
161: | INVALID RUNE
162: { new_locale.rl_invalid_rune = $2; }
163: | LIST list
164: { set_map(&types, $2, $1); }
165: | MAPLOWER map
166: { set_map(&maplower, $2, 0); }
167: | MAPUPPER map
168: { set_map(&mapupper, $2, 0); }
169: | DIGITMAP map
170: { set_digitmap(&types, $2); }
171: ;
172:
173: list : RUNE
174: {
1.4 ! nicm 175: $$ = (rune_list *)xmalloc(sizeof(rune_list));
1.1 espie 176: $$->min = ($1 & charsetmask) | charsetbits;
177: $$->max = ($1 & charsetmask) | charsetbits;
1.4 ! nicm 178: $$->map = 0;
1.1 espie 179: $$->next = 0;
180: }
181: | RUNE THRU RUNE
182: {
1.4 ! nicm 183: $$ = (rune_list *)xmalloc(sizeof(rune_list));
1.1 espie 184: $$->min = ($1 & charsetmask) | charsetbits;
185: $$->max = ($3 & charsetmask) | charsetbits;
1.4 ! nicm 186: $$->map = 0;
1.1 espie 187: $$->next = 0;
188: }
189: | list RUNE
190: {
1.4 ! nicm 191: $$ = (rune_list *)xmalloc(sizeof(rune_list));
1.1 espie 192: $$->min = ($2 & charsetmask) | charsetbits;
193: $$->max = ($2 & charsetmask) | charsetbits;
1.4 ! nicm 194: $$->map = 0;
1.1 espie 195: $$->next = $1;
196: }
197: | list RUNE THRU RUNE
198: {
1.4 ! nicm 199: $$ = (rune_list *)xmalloc(sizeof(rune_list));
1.1 espie 200: $$->min = ($2 & charsetmask) | charsetbits;
201: $$->max = ($4 & charsetmask) | charsetbits;
1.4 ! nicm 202: $$->map = 0;
1.1 espie 203: $$->next = $1;
204: }
205: ;
206:
207: map : LBRK RUNE RUNE RBRK
208: {
1.4 ! nicm 209: $$ = (rune_list *)xmalloc(sizeof(rune_list));
1.1 espie 210: $$->min = ($2 & charsetmask) | charsetbits;
211: $$->max = ($2 & charsetmask) | charsetbits;
212: $$->map = $3;
213: $$->next = 0;
214: }
215: | map LBRK RUNE RUNE RBRK
216: {
1.4 ! nicm 217: $$ = (rune_list *)xmalloc(sizeof(rune_list));
1.1 espie 218: $$->min = ($3 & charsetmask) | charsetbits;
219: $$->max = ($3 & charsetmask) | charsetbits;
220: $$->map = $4;
221: $$->next = $1;
222: }
223: | LBRK RUNE THRU RUNE ':' RUNE RBRK
224: {
1.4 ! nicm 225: $$ = (rune_list *)xmalloc(sizeof(rune_list));
1.1 espie 226: $$->min = ($2 & charsetmask) | charsetbits;
227: $$->max = ($4 & charsetmask) | charsetbits;
228: $$->map = $6;
229: $$->next = 0;
230: }
231: | map LBRK RUNE THRU RUNE ':' RUNE RBRK
232: {
1.4 ! nicm 233: $$ = (rune_list *)xmalloc(sizeof(rune_list));
1.1 espie 234: $$->min = ($3 & charsetmask) | charsetbits;
235: $$->max = ($5 & charsetmask) | charsetbits;
236: $$->map = $7;
237: $$->next = $1;
238: }
239: ;
240: %%
241:
242: int debug = 0;
243: FILE *ofile;
244:
245: int
246: main(int ac, char *av[])
247: {
248: int x;
249:
250: extern char *optarg;
251: extern int optind;
252:
1.2 deraadt 253: while ((x = getopt(ac, av, "do:")) != -1) {
1.1 espie 254: switch(x) {
255: case 'd':
256: debug = 1;
257: break;
258: case 'o':
259: locale_file = optarg;
260: if ((ofile = fopen(locale_file, "w")) == 0)
261: err(1, "unable to open output file %s", locale_file);
262: break;
263: default:
264: usage:
1.3 sobrado 265: fprintf(stderr,
266: "usage: mklocale [-d] [src-file] language/LC_CTYPE\n"
267: " mklocale [-d] -o language/LC_CTYPE src-file\n");
1.1 espie 268: exit(1);
269: }
270: }
271:
272: switch (ac - optind) {
273: case 0:
274: break;
275: case 1:
276: if (freopen(av[optind], "r", stdin) == 0)
277: err(1, "unable to open input file %s", av[optind]);
278: break;
279: default:
280: goto usage;
281: }
282: for (x = 0; x < _CACHED_RUNES; ++x) {
283: mapupper.map[x] = x;
284: maplower.map[x] = x;
285: }
286: new_locale.rl_invalid_rune = _DEFAULT_INVALID_RUNE;
287: memcpy(new_locale.rl_magic, _RUNE_MAGIC_1, sizeof(new_locale.rl_magic));
288:
289: yyparse();
290:
291: return 0;
292: }
293:
294: int
295: yyerror(const char *s)
296: {
297: fprintf(stderr, "%s\n", s);
298:
299: return 0;
300: }
301:
302: void *
303: xmalloc(size_t sz)
304: {
305: void *r = malloc(sz);
306: if (!r) {
307: perror("xmalloc");
308: abort();
309: }
310: return(r);
311: }
312:
313: u_int32_t *
314: xlalloc(size_t sz)
315: {
316: u_int32_t *r = (u_int32_t *)malloc(sz * sizeof(u_int32_t));
317: if (!r) {
318: perror("xlalloc");
319: abort();
320: }
321: return(r);
322: }
323:
324: u_int32_t *
325: xrelalloc(u_int32_t *old, size_t sz)
326: {
327: u_int32_t *r = (u_int32_t *)realloc(old, sz * sizeof(u_int32_t));
328: if (!r) {
329: perror("xrelalloc");
330: abort();
331: }
332: return(r);
333: }
334:
335: void
336: set_map(rune_map *map, rune_list *list, u_int32_t flag)
337: {
338: list->map &= charsetmask;
339: list->map |= charsetbits;
340: while (list) {
341: rune_list *nlist = list->next;
342: add_map(map, list, flag);
343: list = nlist;
344: }
345: }
346:
347: void
348: set_digitmap(rune_map *map, rune_list *list)
349: {
350: rune_t i;
351:
352: while (list) {
353: rune_list *nlist = list->next;
354: for (i = list->min; i <= list->max; ++i) {
355: if (list->map + (i - list->min)) {
356: rune_list *tmp = (rune_list *)xmalloc(sizeof(rune_list));
357: tmp->min = i;
358: tmp->max = i;
359: add_map(map, tmp, list->map + (i - list->min));
360: }
361: }
362: free(list);
363: list = nlist;
364: }
365: }
366:
367: void
368: add_map(rune_map *map, rune_list *list, u_int32_t flag)
369: {
370: rune_t i;
371: rune_list *lr = 0;
372: rune_list *r;
373: rune_t run;
374:
375: while (list->min < _CACHED_RUNES && list->min <= list->max) {
376: if (flag)
377: map->map[list->min++] |= flag;
378: else
379: map->map[list->min++] = list->map++;
380: }
381:
382: if (list->min > list->max) {
383: free(list);
384: return;
385: }
386:
387: run = list->max - list->min + 1;
388:
389: if (!(r = map->root) || (list->max < r->min - 1)
390: || (!flag && list->max == r->min - 1)) {
391: if (flag) {
392: list->types = xlalloc(run);
393: for (i = 0; i < run; ++i)
394: list->types[i] = flag;
395: }
396: list->next = map->root;
397: map->root = list;
398: return;
399: }
400:
401: for (r = map->root; r && r->max + 1 < list->min; r = r->next)
402: lr = r;
403:
404: if (!r) {
405: /*
406: * We are off the end.
407: */
408: if (flag) {
409: list->types = xlalloc(run);
410: for (i = 0; i < run; ++i)
411: list->types[i] = flag;
412: }
413: list->next = 0;
414: lr->next = list;
415: return;
416: }
417:
418: if (list->max < r->min - 1) {
419: /*
420: * We come before this range and we do not intersect it.
421: * We are not before the root node, it was checked before the loop
422: */
423: if (flag) {
424: list->types = xlalloc(run);
425: for (i = 0; i < run; ++i)
426: list->types[i] = flag;
427: }
428: list->next = lr->next;
429: lr->next = list;
430: return;
431: }
432:
433: /*
434: * At this point we have found that we at least intersect with
435: * the range pointed to by `r', we might intersect with one or
436: * more ranges beyond `r' as well.
437: */
438:
439: if (!flag && list->map - list->min != r->map - r->min) {
440: /*
441: * There are only two cases when we are doing case maps and
442: * our maps needn't have the same offset. When we are adjoining
443: * but not intersecting.
444: */
445: if (list->max + 1 == r->min) {
446: lr->next = list;
447: list->next = r;
448: return;
449: }
450: if (list->min - 1 == r->max) {
451: list->next = r->next;
452: r->next = list;
453: return;
454: }
455: fprintf(stderr, "Error: conflicting map entries\n");
456: exit(1);
457: }
458:
459: if (list->min >= r->min && list->max <= r->max) {
460: /*
461: * Subset case.
462: */
463:
464: if (flag) {
465: for (i = list->min; i <= list->max; ++i)
466: r->types[i - r->min] |= flag;
467: }
468: free(list);
469: return;
470: }
471: if (list->min <= r->min && list->max >= r->max) {
472: /*
473: * Superset case. Make him big enough to hold us.
474: * We might need to merge with the guy after him.
475: */
476: if (flag) {
477: list->types = xlalloc(list->max - list->min + 1);
478:
479: for (i = list->min; i <= list->max; ++i)
480: list->types[i - list->min] = flag;
481:
482: for (i = r->min; i <= r->max; ++i)
483: list->types[i - list->min] |= r->types[i - r->min];
484:
485: free(r->types);
486: r->types = list->types;
487: } else {
488: r->map = list->map;
489: }
490: r->min = list->min;
491: r->max = list->max;
492: free(list);
493: } else if (list->min < r->min) {
494: /*
495: * Our tail intersects his head.
496: */
497: if (flag) {
498: list->types = xlalloc(r->max - list->min + 1);
499:
500: for (i = r->min; i <= r->max; ++i)
501: list->types[i - list->min] = r->types[i - r->min];
502:
503: for (i = list->min; i < r->min; ++i)
504: list->types[i - list->min] = flag;
505:
506: for (i = r->min; i <= list->max; ++i)
507: list->types[i - list->min] |= flag;
508:
509: free(r->types);
510: r->types = list->types;
511: } else {
512: r->map = list->map;
513: }
514: r->min = list->min;
515: free(list);
516: return;
517: } else {
518: /*
519: * Our head intersects his tail.
520: * We might need to merge with the guy after him.
521: */
522: if (flag) {
523: r->types = xrelalloc(r->types, list->max - r->min + 1);
524:
525: for (i = list->min; i <= r->max; ++i)
526: r->types[i - r->min] |= flag;
527:
528: for (i = r->max+1; i <= list->max; ++i)
529: r->types[i - r->min] = flag;
530: }
531: r->max = list->max;
532: free(list);
533: }
534:
535: /*
536: * Okay, check to see if we grew into the next guy(s)
537: */
538: while ((lr = r->next) && r->max >= lr->min) {
539: if (flag) {
540: if (r->max >= lr->max) {
541: /*
542: * Good, we consumed all of him.
543: */
544: for (i = lr->min; i <= lr->max; ++i)
545: r->types[i - r->min] |= lr->types[i - lr->min];
546: } else {
547: /*
548: * "append" him on to the end of us.
549: */
550: r->types = xrelalloc(r->types, lr->max - r->min + 1);
551:
552: for (i = lr->min; i <= r->max; ++i)
553: r->types[i - r->min] |= lr->types[i - lr->min];
554:
555: for (i = r->max+1; i <= lr->max; ++i)
556: r->types[i - r->min] = lr->types[i - lr->min];
557:
558: r->max = lr->max;
559: }
560: } else {
561: if (lr->max > r->max)
562: r->max = lr->max;
563: }
564:
565: r->next = lr->next;
566:
567: if (flag)
568: free(lr->types);
569: free(lr);
570: }
571: }
572:
573: void
574: dump_tables()
575: {
576: int x, n;
577: rune_list *list;
578: _FileRuneLocale file_new_locale;
579: FILE *fp = (ofile ? ofile : stdout);
580:
581: memset(&file_new_locale, 0, sizeof(file_new_locale));
582:
583: /*
584: * See if we can compress some of the istype arrays
585: */
586: for(list = types.root; list; list = list->next) {
587: list->map = list->types[0];
588: for (x = 1; x < list->max - list->min + 1; ++x) {
589: if (list->types[x] != list->map) {
590: list->map = 0;
591: break;
592: }
593: }
594: }
595:
596: memcpy(&file_new_locale.frl_magic, new_locale.rl_magic,
597: sizeof(file_new_locale.frl_magic));
598: memcpy(&file_new_locale.frl_encoding, new_locale.rl_encoding,
599: sizeof(file_new_locale.frl_encoding));
600:
601: file_new_locale.frl_invalid_rune = htonl(new_locale.rl_invalid_rune);
602:
603: /*
604: * Fill in our tables. Do this in network order so that
605: * diverse machines have a chance of sharing data.
606: * (Machines like Crays cannot share with little machines due to
607: * word size. Sigh. We tried.)
608: */
609: for (x = 0; x < _CACHED_RUNES; ++x) {
610: file_new_locale.frl_runetype[x] = htonl(types.map[x]);
611: file_new_locale.frl_maplower[x] = htonl(maplower.map[x]);
612: file_new_locale.frl_mapupper[x] = htonl(mapupper.map[x]);
613: }
614:
615: /*
616: * Count up how many ranges we will need for each of the extents.
617: */
618: list = types.root;
619:
620: while (list) {
621: new_locale.rl_runetype_ext.rr_nranges++;
622: list = list->next;
623: }
624: file_new_locale.frl_runetype_ext.frr_nranges =
625: htonl(new_locale.rl_runetype_ext.rr_nranges);
626:
627: list = maplower.root;
628:
629: while (list) {
630: new_locale.rl_maplower_ext.rr_nranges++;
631: list = list->next;
632: }
633: file_new_locale.frl_maplower_ext.frr_nranges =
634: htonl(new_locale.rl_maplower_ext.rr_nranges);
635:
636: list = mapupper.root;
637:
638: while (list) {
639: new_locale.rl_mapupper_ext.rr_nranges++;
640: list = list->next;
641: }
642: file_new_locale.frl_mapupper_ext.frr_nranges =
643: htonl(new_locale.rl_mapupper_ext.rr_nranges);
644:
645: file_new_locale.frl_variable_len = htonl(new_locale.rl_variable_len);
646:
647: /*
648: * Okay, we are now ready to write the new locale file.
649: */
650:
651: /*
652: * PART 1: The _RuneLocale structure
653: */
654: if (fwrite((char *)&file_new_locale, sizeof(file_new_locale), 1, fp) != 1)
655: err(1, "writing _RuneLocale to %s", locale_file);
656: /*
657: * PART 2: The runetype_ext structures (not the actual tables)
658: */
659: for (list = types.root, n = 0; list != NULL; list = list->next, n++) {
660: _FileRuneEntry re;
661:
662: memset(&re, 0, sizeof(re));
663: re.fre_min = htonl(list->min);
664: re.fre_max = htonl(list->max);
665: re.fre_map = htonl(list->map);
666:
667: if (fwrite((char *)&re, sizeof(re), 1, fp) != 1)
668: err(1, "writing runetype_ext #%d to %s", n, locale_file);
669: }
670: /*
671: * PART 3: The maplower_ext structures
672: */
673: for (list = maplower.root, n = 0; list != NULL; list = list->next, n++) {
674: _FileRuneEntry re;
675:
676: memset(&re, 0, sizeof(re));
677: re.fre_min = htonl(list->min);
678: re.fre_max = htonl(list->max);
679: re.fre_map = htonl(list->map);
680:
681: if (fwrite((char *)&re, sizeof(re), 1, fp) != 1)
682: err(1, "writing maplower_ext #%d to %s", n, locale_file);
683: }
684: /*
685: * PART 4: The mapupper_ext structures
686: */
687: for (list = mapupper.root, n = 0; list != NULL; list = list->next, n++) {
688: _FileRuneEntry re;
689:
690: memset(&re, 0, sizeof(re));
691: re.fre_min = htonl(list->min);
692: re.fre_max = htonl(list->max);
693: re.fre_map = htonl(list->map);
694:
695: if (fwrite((char *)&re, sizeof(re), 1, fp) != 1)
696: err(1, "writing mapupper_ext #%d to %s", n, locale_file);
697: }
698: /*
699: * PART 5: The runetype_ext tables
700: */
701: for (list = types.root, n = 0; list != NULL; list = list->next, n++) {
702: for (x = 0; x < list->max - list->min + 1; ++x)
703: list->types[x] = htonl(list->types[x]);
704:
705: if (!list->map) {
706: if (fwrite((char *)list->types,
707: (list->max - list->min + 1) * sizeof(u_int32_t),
708: 1, fp) != 1)
709: err(1, "writing runetype_ext table #%d to %s", n, locale_file);
710: }
711: }
712: /*
713: * PART 5: And finally the variable data
714: */
715: if (new_locale.rl_variable_len != 0 &&
716: fwrite((char *)new_locale.rl_variable,
717: new_locale.rl_variable_len, 1, fp) != 1)
718: err(1, "writing variable data to %s", locale_file);
719: fclose(fp);
720:
721: if (!debug)
722: return;
723:
724: if (new_locale.rl_encoding[0])
725: fprintf(stderr, "ENCODING %s\n", new_locale.rl_encoding);
726: if (new_locale.rl_variable)
727: fprintf(stderr, "VARIABLE %s\n",
728: (char *)new_locale.rl_variable);
729:
730: fprintf(stderr, "\nMAPLOWER:\n\n");
731:
732: for (x = 0; x < _CACHED_RUNES; ++x) {
733: if (isprint(maplower.map[x]))
734: fprintf(stderr, " '%c'", (int)maplower.map[x]);
735: else if (maplower.map[x])
736: fprintf(stderr, "%04x", maplower.map[x]);
737: else
738: fprintf(stderr, "%4x", 0);
739: if ((x & 0xf) == 0xf)
740: fprintf(stderr, "\n");
741: else
742: fprintf(stderr, " ");
743: }
744: fprintf(stderr, "\n");
745:
746: for (list = maplower.root; list; list = list->next)
747: fprintf(stderr, "\t%04x - %04x : %04x\n", list->min, list->max, list->map);
748:
749: fprintf(stderr, "\nMAPUPPER:\n\n");
750:
751: for (x = 0; x < _CACHED_RUNES; ++x) {
752: if (isprint(mapupper.map[x]))
753: fprintf(stderr, " '%c'", (int)mapupper.map[x]);
754: else if (mapupper.map[x])
755: fprintf(stderr, "%04x", mapupper.map[x]);
756: else
757: fprintf(stderr, "%4x", 0);
758: if ((x & 0xf) == 0xf)
759: fprintf(stderr, "\n");
760: else
761: fprintf(stderr, " ");
762: }
763: fprintf(stderr, "\n");
764:
765: for (list = mapupper.root; list; list = list->next)
766: fprintf(stderr, "\t%04x - %04x : %04x\n", list->min, list->max, list->map);
767:
768:
769: fprintf(stderr, "\nTYPES:\n\n");
770:
771: for (x = 0; x < _CACHED_RUNES; ++x) {
772: u_int32_t r = types.map[x];
773:
774: if (r) {
775: if (isprint(x))
776: fprintf(stderr, " '%c':%2d", x, (int)(r & 0xff));
777: else
778: fprintf(stderr, "%04x:%2d", x, (int)(r & 0xff));
779:
780: fprintf(stderr, " %4s", (r & _RUNETYPE_A) ? "alph" : "");
781: fprintf(stderr, " %4s", (r & _RUNETYPE_C) ? "ctrl" : "");
782: fprintf(stderr, " %4s", (r & _RUNETYPE_D) ? "dig" : "");
783: fprintf(stderr, " %4s", (r & _RUNETYPE_G) ? "graf" : "");
784: fprintf(stderr, " %4s", (r & _RUNETYPE_L) ? "low" : "");
785: fprintf(stderr, " %4s", (r & _RUNETYPE_P) ? "punc" : "");
786: fprintf(stderr, " %4s", (r & _RUNETYPE_S) ? "spac" : "");
787: fprintf(stderr, " %4s", (r & _RUNETYPE_U) ? "upp" : "");
788: fprintf(stderr, " %4s", (r & _RUNETYPE_X) ? "xdig" : "");
789: fprintf(stderr, " %4s", (r & _RUNETYPE_B) ? "blnk" : "");
790: fprintf(stderr, " %4s", (r & _RUNETYPE_R) ? "prnt" : "");
791: fprintf(stderr, " %4s", (r & _RUNETYPE_I) ? "ideo" : "");
792: fprintf(stderr, " %4s", (r & _RUNETYPE_T) ? "spec" : "");
793: fprintf(stderr, " %4s", (r & _RUNETYPE_Q) ? "phon" : "");
794: fprintf(stderr, "\n");
795: }
796: }
797:
798: for (list = types.root; list; list = list->next) {
799: if (list->map && list->min + 3 < list->max) {
800: u_int32_t r = list->map;
801:
802: fprintf(stderr, "%04x:%2d", list->min, r & 0xff);
803:
804: fprintf(stderr, " %4s", (r & _RUNETYPE_A) ? "alph" : "");
805: fprintf(stderr, " %4s", (r & _RUNETYPE_C) ? "ctrl" : "");
806: fprintf(stderr, " %4s", (r & _RUNETYPE_D) ? "dig" : "");
807: fprintf(stderr, " %4s", (r & _RUNETYPE_G) ? "graf" : "");
808: fprintf(stderr, " %4s", (r & _RUNETYPE_L) ? "low" : "");
809: fprintf(stderr, " %4s", (r & _RUNETYPE_P) ? "punc" : "");
810: fprintf(stderr, " %4s", (r & _RUNETYPE_S) ? "spac" : "");
811: fprintf(stderr, " %4s", (r & _RUNETYPE_U) ? "upp" : "");
812: fprintf(stderr, " %4s", (r & _RUNETYPE_X) ? "xdig" : "");
813: fprintf(stderr, " %4s", (r & _RUNETYPE_B) ? "blnk" : "");
814: fprintf(stderr, " %4s", (r & _RUNETYPE_R) ? "prnt" : "");
815: fprintf(stderr, " %4s", (r & _RUNETYPE_I) ? "ideo" : "");
816: fprintf(stderr, " %4s", (r & _RUNETYPE_T) ? "spec" : "");
817: fprintf(stderr, " %4s", (r & _RUNETYPE_Q) ? "phon" : "");
818: fprintf(stderr, "\n...\n");
819:
820: fprintf(stderr, "%04x:%2d", list->max, r & 0xff);
821:
822: fprintf(stderr, " %4s", (r & _RUNETYPE_A) ? "alph" : "");
823: fprintf(stderr, " %4s", (r & _RUNETYPE_C) ? "ctrl" : "");
824: fprintf(stderr, " %4s", (r & _RUNETYPE_D) ? "dig" : "");
825: fprintf(stderr, " %4s", (r & _RUNETYPE_G) ? "graf" : "");
826: fprintf(stderr, " %4s", (r & _RUNETYPE_L) ? "low" : "");
827: fprintf(stderr, " %4s", (r & _RUNETYPE_P) ? "punc" : "");
828: fprintf(stderr, " %4s", (r & _RUNETYPE_S) ? "spac" : "");
829: fprintf(stderr, " %4s", (r & _RUNETYPE_U) ? "upp" : "");
830: fprintf(stderr, " %4s", (r & _RUNETYPE_X) ? "xdig" : "");
831: fprintf(stderr, " %4s", (r & _RUNETYPE_B) ? "blnk" : "");
832: fprintf(stderr, " %4s", (r & _RUNETYPE_R) ? "prnt" : "");
833: fprintf(stderr, " %4s", (r & _RUNETYPE_I) ? "ideo" : "");
834: fprintf(stderr, " %4s", (r & _RUNETYPE_T) ? "spec" : "");
835: fprintf(stderr, " %4s", (r & _RUNETYPE_Q) ? "phon" : "");
836: fprintf(stderr, " %1u", (unsigned)((r & _RUNETYPE_SWM)>>_RUNETYPE_SWS));
837: fprintf(stderr, "\n");
838: } else
839: for (x = list->min; x <= list->max; ++x) {
840: u_int32_t r = ntohl(list->types[x - list->min]);
841:
842: if (r) {
843: fprintf(stderr, "%04x:%2d", x, (int)(r & 0xff));
844:
845: fprintf(stderr, " %4s", (r & _RUNETYPE_A) ? "alph" : "");
846: fprintf(stderr, " %4s", (r & _RUNETYPE_C) ? "ctrl" : "");
847: fprintf(stderr, " %4s", (r & _RUNETYPE_D) ? "dig" : "");
848: fprintf(stderr, " %4s", (r & _RUNETYPE_G) ? "graf" : "");
849: fprintf(stderr, " %4s", (r & _RUNETYPE_L) ? "low" : "");
850: fprintf(stderr, " %4s", (r & _RUNETYPE_P) ? "punc" : "");
851: fprintf(stderr, " %4s", (r & _RUNETYPE_S) ? "spac" : "");
852: fprintf(stderr, " %4s", (r & _RUNETYPE_U) ? "upp" : "");
853: fprintf(stderr, " %4s", (r & _RUNETYPE_X) ? "xdig" : "");
854: fprintf(stderr, " %4s", (r & _RUNETYPE_B) ? "blnk" : "");
855: fprintf(stderr, " %4s", (r & _RUNETYPE_R) ? "prnt" : "");
856: fprintf(stderr, " %4s", (r & _RUNETYPE_I) ? "ideo" : "");
857: fprintf(stderr, " %4s", (r & _RUNETYPE_T) ? "spec" : "");
858: fprintf(stderr, " %4s", (r & _RUNETYPE_Q) ? "phon" : "");
859: fprintf(stderr, " %1u", (unsigned)((r & _RUNETYPE_SWM)>>_RUNETYPE_SWS));
860: fprintf(stderr, "\n");
861: }
862: }
863: }
864: }