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