yacc.y revision 2509
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 *, unsigned long)); 59void set_digitmap __P((rune_map *, rune_list *)); 60void add_map __P((rune_map *, rune_list *, unsigned 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 254unsigned long * 255xlalloc(sz) 256 unsigned int sz; 257{ 258 unsigned long *r = (unsigned long *)malloc(sz * sizeof(unsigned long)); 259 if (!r) { 260 perror("xlalloc"); 261 abort(); 262 } 263 return(r); 264} 265 266unsigned long * 267xrelalloc(old, sz) 268 unsigned long *old; 269 unsigned int sz; 270{ 271 unsigned long *r = (unsigned long *)realloc((char *)old, 272 sz * sizeof(unsigned long)); 273 if (!r) { 274 perror("xrelalloc"); 275 abort(); 276 } 277 return(r); 278} 279 280void 281set_map(map, list, flag) 282 rune_map *map; 283 rune_list *list; 284 unsigned long flag; 285{ 286 while (list) { 287 rune_list *nlist = list->next; 288 add_map(map, list, flag); 289 list = nlist; 290 } 291} 292 293void 294set_digitmap(map, list) 295 rune_map *map; 296 rune_list *list; 297{ 298 rune_t i; 299 300 while (list) { 301 rune_list *nlist = list->next; 302 for (i = list->min; i <= list->max; ++i) { 303 if (list->map + (i - list->min)) { 304 rune_list *tmp = (rune_list *)xmalloc(sizeof(rune_list)); 305 tmp->min = i; 306 tmp->max = i; 307 add_map(map, tmp, list->map + (i - list->min)); 308 } 309 } 310 free(list); 311 list = nlist; 312 } 313} 314 315void 316add_map(map, list, flag) 317 rune_map *map; 318 rune_list *list; 319 unsigned long flag; 320{ 321 rune_t i; 322 rune_list *lr = 0; 323 rune_list *r; 324 rune_t run; 325 326 while (list->min < _CACHED_RUNES && list->min <= list->max) { 327 if (flag) 328 map->map[list->min++] |= flag; 329 else 330 map->map[list->min++] = list->map++; 331 } 332 333 if (list->min > list->max) { 334 free(list); 335 return; 336 } 337 338 run = list->max - list->min + 1; 339 340 if (!(r = map->root) || (list->max < r->min - 1) 341 || (!flag && list->max == r->min - 1)) { 342 if (flag) { 343 list->types = xlalloc(run); 344 for (i = 0; i < run; ++i) 345 list->types[i] = flag; 346 } 347 list->next = map->root; 348 map->root = list; 349 return; 350 } 351 352 for (r = map->root; r && r->max + 1 < list->min; r = r->next) 353 lr = r; 354 355 if (!r) { 356 /* 357 * We are off the end. 358 */ 359 if (flag) { 360 list->types = xlalloc(run); 361 for (i = 0; i < run; ++i) 362 list->types[i] = flag; 363 } 364 list->next = 0; 365 lr->next = list; 366 return; 367 } 368 369 if (list->max < r->min - 1) { 370 /* 371 * We come before this range and we do not intersect it. 372 * We are not before the root node, it was checked before the loop 373 */ 374 if (flag) { 375 list->types = xlalloc(run); 376 for (i = 0; i < run; ++i) 377 list->types[i] = flag; 378 } 379 list->next = lr->next; 380 lr->next = list; 381 return; 382 } 383 384 /* 385 * At this point we have found that we at least intersect with 386 * the range pointed to by `r', we might intersect with one or 387 * more ranges beyond `r' as well. 388 */ 389 390 if (!flag && list->map - list->min != r->map - r->min) { 391 /* 392 * There are only two cases when we are doing case maps and 393 * our maps needn't have the same offset. When we are adjoining 394 * but not intersecting. 395 */ 396 if (list->max + 1 == r->min) { 397 lr->next = list; 398 list->next = r; 399 return; 400 } 401 if (list->min - 1 == r->max) { 402 list->next = r->next; 403 r->next = list; 404 return; 405 } 406 fprintf(stderr, "Error: conflicting map entries\n"); 407 exit(1); 408 } 409 410 if (list->min >= r->min && list->max <= r->max) { 411 /* 412 * Subset case. 413 */ 414 415 if (flag) { 416 for (i = list->min; i <= list->max; ++i) 417 r->types[i - r->min] |= flag; 418 } 419 free(list); 420 return; 421 } 422 if (list->min <= r->min && list->max >= r->max) { 423 /* 424 * Superset case. Make him big enough to hold us. 425 * We might need to merge with the guy after him. 426 */ 427 if (flag) { 428 list->types = xlalloc(list->max - list->min + 1); 429 430 for (i = list->min; i <= list->max; ++i) 431 list->types[i - list->min] = flag; 432 433 for (i = r->min; i <= r->max; ++i) 434 list->types[i - list->min] |= r->types[i - r->min]; 435 436 free(r->types); 437 r->types = list->types; 438 } else { 439 r->map = list->map; 440 } 441 r->min = list->min; 442 r->max = list->max; 443 free(list); 444 } else if (list->min < r->min) { 445 /* 446 * Our tail intersects his head. 447 */ 448 if (flag) { 449 list->types = xlalloc(r->max - list->min + 1); 450 451 for (i = r->min; i <= r->max; ++i) 452 list->types[i - list->min] = r->types[i - r->min]; 453 454 for (i = list->min; i < r->min; ++i) 455 list->types[i - list->min] = flag; 456 457 for (i = r->min; i <= list->max; ++i) 458 list->types[i - list->min] |= flag; 459 460 free(r->types); 461 r->types = list->types; 462 } else { 463 r->map = list->map; 464 } 465 r->min = list->min; 466 free(list); 467 return; 468 } else { 469 /* 470 * Our head intersects his tail. 471 * We might need to merge with the guy after him. 472 */ 473 if (flag) { 474 r->types = xrelalloc(r->types, list->max - r->min + 1); 475 476 for (i = list->min; i <= r->max; ++i) 477 r->types[i - r->min] |= flag; 478 479 for (i = r->max+1; i <= list->max; ++i) 480 r->types[i - r->min] = flag; 481 } 482 r->max = r->max; 483 free(list); 484 } 485 486 /* 487 * Okay, check to see if we grew into the next guy(s) 488 */ 489 while ((lr = r->next) && r->max >= lr->min) { 490 if (flag) { 491 if (r->max >= lr->max) { 492 /* 493 * Good, we consumed all of him. 494 */ 495 for (i = lr->min; i <= lr->max; ++i) 496 r->types[i - r->min] |= lr->types[i - lr->min]; 497 } else { 498 /* 499 * "append" him on to the end of us. 500 */ 501 r->types = xrelalloc(r->types, lr->max - r->min + 1); 502 503 for (i = lr->min; i <= r->max; ++i) 504 r->types[i - r->min] |= lr->types[i - lr->min]; 505 506 for (i = r->max+1; i <= lr->max; ++i) 507 r->types[i - r->min] = lr->types[i - lr->min]; 508 509 r->max = lr->max; 510 } 511 } else { 512 if (lr->max > r->max) 513 r->max = lr->max; 514 } 515 516 r->next = lr->next; 517 518 if (flag) 519 free(lr->types); 520 free(lr); 521 } 522} 523 524void 525dump_tables() 526{ 527 int x; 528 rune_list *list; 529 530 /* 531 * See if we can compress some of the istype arrays 532 */ 533 for(list = types.root; list; list = list->next) { 534 list->map = list->types[0]; 535 for (x = 1; x < list->max - list->min + 1; ++x) { 536 if (list->types[x] != list->map) { 537 list->map = 0; 538 break; 539 } 540 } 541 } 542 543 new_locale.invalid_rune = htonl(new_locale.invalid_rune); 544 545 /* 546 * Fill in our tables. Do this in network order so that 547 * diverse machines have a chance of sharing data. 548 * (Machines like Crays cannot share with little machines due to 549 * word size. Sigh. We tried.) 550 */ 551 for (x = 0; x < _CACHED_RUNES; ++x) { 552 new_locale.runetype[x] = htonl(types.map[x]); 553 new_locale.maplower[x] = htonl(maplower.map[x]); 554 new_locale.mapupper[x] = htonl(mapupper.map[x]); 555 } 556 557 /* 558 * Count up how many ranges we will need for each of the extents. 559 */ 560 list = types.root; 561 562 while (list) { 563 new_locale.runetype_ext.nranges++; 564 list = list->next; 565 } 566 new_locale.runetype_ext.nranges = htonl(new_locale.runetype_ext.nranges); 567 568 list = maplower.root; 569 570 while (list) { 571 new_locale.maplower_ext.nranges++; 572 list = list->next; 573 } 574 new_locale.maplower_ext.nranges = htonl(new_locale.maplower_ext.nranges); 575 576 list = mapupper.root; 577 578 while (list) { 579 new_locale.mapupper_ext.nranges++; 580 list = list->next; 581 } 582 new_locale.mapupper_ext.nranges = htonl(new_locale.mapupper_ext.nranges); 583 584 new_locale.variable_len = htonl(new_locale.variable_len); 585 586 /* 587 * Okay, we are now ready to write the new locale file. 588 */ 589 590 /* 591 * PART 1: The _RuneLocale structure 592 */ 593 if (fwrite((char *)&new_locale, sizeof(new_locale), 1, fp) != 1) { 594 perror(locale_file); 595 exit(1); 596 } 597 /* 598 * PART 2: The runetype_ext structures (not the actual tables) 599 */ 600 list = types.root; 601 602 while (list) { 603 _RuneEntry re; 604 605 re.min = htonl(list->min); 606 re.max = htonl(list->max); 607 re.map = htonl(list->map); 608 609 if (fwrite((char *)&re, sizeof(re), 1, fp) != 1) { 610 perror(locale_file); 611 exit(1); 612 } 613 614 list = list->next; 615 } 616 /* 617 * PART 3: The maplower_ext structures 618 */ 619 list = maplower.root; 620 621 while (list) { 622 _RuneEntry re; 623 624 re.min = htonl(list->min); 625 re.max = htonl(list->max); 626 re.map = htonl(list->map); 627 628 if (fwrite((char *)&re, sizeof(re), 1, fp) != 1) { 629 perror(locale_file); 630 exit(1); 631 } 632 633 list = list->next; 634 } 635 /* 636 * PART 4: The mapupper_ext structures 637 */ 638 list = mapupper.root; 639 640 while (list) { 641 _RuneEntry re; 642 643 re.min = htonl(list->min); 644 re.max = htonl(list->max); 645 re.map = htonl(list->map); 646 647 if (fwrite((char *)&re, sizeof(re), 1, fp) != 1) { 648 perror(locale_file); 649 exit(1); 650 } 651 652 list = list->next; 653 } 654 /* 655 * PART 5: The runetype_ext tables 656 */ 657 list = types.root; 658 659 while (list) { 660 for (x = 0; x < list->max - list->min + 1; ++x) 661 list->types[x] = htonl(list->types[x]); 662 663 if (!list->map) { 664 if (fwrite((char *)&list->types, 665 (list->max - list->min + 1) * sizeof(unsigned long), 666 1, fp) != 1) { 667 perror(locale_file); 668 exit(1); 669 } 670 } 671 list = list->next; 672 } 673 /* 674 * PART 5: And finally the variable data 675 */ 676 if (fwrite((char *)new_locale.variable, 677 ntohl(new_locale.variable_len), 1, fp) != 1) { 678 perror(locale_file); 679 exit(1); 680 } 681 fclose(fp); 682 683 if (!debug) 684 return; 685 686 if (new_locale.encoding[0]) 687 fprintf(stderr, "ENCODING %s\n", new_locale.encoding); 688 if (new_locale.variable) 689 fprintf(stderr, "VARIABLE %s\n", new_locale.variable); 690 691 fprintf(stderr, "\nMAPLOWER:\n\n"); 692 693 for (x = 0; x < _CACHED_RUNES; ++x) { 694 if (isprint(maplower.map[x])) 695 fprintf(stderr, " '%c'", maplower.map[x]); 696 else if (maplower.map[x]) 697 fprintf(stderr, "%04x", maplower.map[x]); 698 else 699 fprintf(stderr, "%4x", 0); 700 if ((x & 0xf) == 0xf) 701 fprintf(stderr, "\n"); 702 else 703 fprintf(stderr, " "); 704 } 705 fprintf(stderr, "\n"); 706 707 for (list = maplower.root; list; list = list->next) 708 fprintf(stderr, "\t%04x - %04x : %04x\n", list->min, list->max, list->map); 709 710 fprintf(stderr, "\nMAPUPPER:\n\n"); 711 712 for (x = 0; x < _CACHED_RUNES; ++x) { 713 if (isprint(mapupper.map[x])) 714 fprintf(stderr, " '%c'", mapupper.map[x]); 715 else if (mapupper.map[x]) 716 fprintf(stderr, "%04x", mapupper.map[x]); 717 else 718 fprintf(stderr, "%4x", 0); 719 if ((x & 0xf) == 0xf) 720 fprintf(stderr, "\n"); 721 else 722 fprintf(stderr, " "); 723 } 724 fprintf(stderr, "\n"); 725 726 for (list = mapupper.root; list; list = list->next) 727 fprintf(stderr, "\t%04x - %04x : %04x\n", list->min, list->max, list->map); 728 729 730 fprintf(stderr, "\nTYPES:\n\n"); 731 732 for (x = 0; x < _CACHED_RUNES; ++x) { 733 unsigned long r = types.map[x]; 734 735 if (r) { 736 if (isprint(x)) 737 fprintf(stderr, " '%c': %2d", x, r & 0xff); 738 else 739 fprintf(stderr, "%04x: %2d", x, r & 0xff); 740 741 fprintf(stderr, " %4s", (r & _A) ? "alph" : ""); 742 fprintf(stderr, " %4s", (r & _C) ? "ctrl" : ""); 743 fprintf(stderr, " %4s", (r & _D) ? "dig" : ""); 744 fprintf(stderr, " %4s", (r & _G) ? "graf" : ""); 745 fprintf(stderr, " %4s", (r & _L) ? "low" : ""); 746 fprintf(stderr, " %4s", (r & _P) ? "punc" : ""); 747 fprintf(stderr, " %4s", (r & _S) ? "spac" : ""); 748 fprintf(stderr, " %4s", (r & _U) ? "upp" : ""); 749 fprintf(stderr, " %4s", (r & _X) ? "xdig" : ""); 750 fprintf(stderr, " %4s", (r & _B) ? "blnk" : ""); 751 fprintf(stderr, " %4s", (r & _R) ? "prnt" : ""); 752 fprintf(stderr, " %4s", (r & _I) ? "ideo" : ""); 753 fprintf(stderr, " %4s", (r & _T) ? "spec" : ""); 754 fprintf(stderr, " %4s", (r & _Q) ? "phon" : ""); 755 fprintf(stderr, "\n"); 756 } 757 } 758 759 for (list = types.root; list; list = list->next) { 760 if (list->map && list->min + 3 < list->max) { 761 unsigned long r = list->map; 762 763 fprintf(stderr, "%04x: %2d", list->min, r & 0xff); 764 765 fprintf(stderr, " %4s", (r & _A) ? "alph" : ""); 766 fprintf(stderr, " %4s", (r & _C) ? "ctrl" : ""); 767 fprintf(stderr, " %4s", (r & _D) ? "dig" : ""); 768 fprintf(stderr, " %4s", (r & _G) ? "graf" : ""); 769 fprintf(stderr, " %4s", (r & _L) ? "low" : ""); 770 fprintf(stderr, " %4s", (r & _P) ? "punc" : ""); 771 fprintf(stderr, " %4s", (r & _S) ? "spac" : ""); 772 fprintf(stderr, " %4s", (r & _U) ? "upp" : ""); 773 fprintf(stderr, " %4s", (r & _X) ? "xdig" : ""); 774 fprintf(stderr, " %4s", (r & _B) ? "blnk" : ""); 775 fprintf(stderr, " %4s", (r & _R) ? "prnt" : ""); 776 fprintf(stderr, " %4s", (r & _I) ? "ideo" : ""); 777 fprintf(stderr, " %4s", (r & _T) ? "spec" : ""); 778 fprintf(stderr, " %4s", (r & _Q) ? "phon" : ""); 779 fprintf(stderr, "\n...\n"); 780 781 fprintf(stderr, "%04x: %2d", list->max, r & 0xff); 782 783 fprintf(stderr, " %4s", (r & _A) ? "alph" : ""); 784 fprintf(stderr, " %4s", (r & _C) ? "ctrl" : ""); 785 fprintf(stderr, " %4s", (r & _D) ? "dig" : ""); 786 fprintf(stderr, " %4s", (r & _G) ? "graf" : ""); 787 fprintf(stderr, " %4s", (r & _L) ? "low" : ""); 788 fprintf(stderr, " %4s", (r & _P) ? "punc" : ""); 789 fprintf(stderr, " %4s", (r & _S) ? "spac" : ""); 790 fprintf(stderr, " %4s", (r & _U) ? "upp" : ""); 791 fprintf(stderr, " %4s", (r & _X) ? "xdig" : ""); 792 fprintf(stderr, " %4s", (r & _B) ? "blnk" : ""); 793 fprintf(stderr, " %4s", (r & _R) ? "prnt" : ""); 794 fprintf(stderr, " %4s", (r & _I) ? "ideo" : ""); 795 fprintf(stderr, " %4s", (r & _T) ? "spec" : ""); 796 fprintf(stderr, " %4s", (r & _Q) ? "phon" : ""); 797 fprintf(stderr, "\n"); 798 } else 799 for (x = list->min; x <= list->max; ++x) { 800 unsigned long r = ntohl(list->types[x - list->min]); 801 802 if (r) { 803 fprintf(stderr, "%04x: %2d", x, r & 0xff); 804 805 fprintf(stderr, " %4s", (r & _A) ? "alph" : ""); 806 fprintf(stderr, " %4s", (r & _C) ? "ctrl" : ""); 807 fprintf(stderr, " %4s", (r & _D) ? "dig" : ""); 808 fprintf(stderr, " %4s", (r & _G) ? "graf" : ""); 809 fprintf(stderr, " %4s", (r & _L) ? "low" : ""); 810 fprintf(stderr, " %4s", (r & _P) ? "punc" : ""); 811 fprintf(stderr, " %4s", (r & _S) ? "spac" : ""); 812 fprintf(stderr, " %4s", (r & _U) ? "upp" : ""); 813 fprintf(stderr, " %4s", (r & _X) ? "xdig" : ""); 814 fprintf(stderr, " %4s", (r & _B) ? "blnk" : ""); 815 fprintf(stderr, " %4s", (r & _R) ? "prnt" : ""); 816 fprintf(stderr, " %4s", (r & _I) ? "ideo" : ""); 817 fprintf(stderr, " %4s", (r & _T) ? "spec" : ""); 818 fprintf(stderr, " %4s", (r & _Q) ? "phon" : ""); 819 fprintf(stderr, "\n"); 820 } 821 } 822 } 823} 824