yacc.y revision 1591
1%{ 2/*- 3 * Copyright (c) 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Paul Borman at Krystal Technologies. 8 * 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. 36 */ 37 38#ifndef lint 39static char sccsid[] = "@(#)yacc.y 8.1 (Berkeley) 6/6/93"; 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} 822