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