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