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