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