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