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