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