yacc.y revision 38022
11590Srgrimes%{ 21590Srgrimes/*- 31590Srgrimes * Copyright (c) 1993 41590Srgrimes * The Regents of the University of California. All rights reserved. 51590Srgrimes * 61590Srgrimes * This code is derived from software contributed to Berkeley by 71590Srgrimes * Paul Borman at Krystal Technologies. 81590Srgrimes * 91590Srgrimes * Redistribution and use in source and binary forms, with or without 101590Srgrimes * modification, are permitted provided that the following conditions 111590Srgrimes * are met: 121590Srgrimes * 1. Redistributions of source code must retain the above copyright 131590Srgrimes * notice, this list of conditions and the following disclaimer. 141590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 151590Srgrimes * notice, this list of conditions and the following disclaimer in the 161590Srgrimes * documentation and/or other materials provided with the distribution. 171590Srgrimes * 3. All advertising materials mentioning features or use of this software 181590Srgrimes * must display the following acknowledgement: 191590Srgrimes * This product includes software developed by the University of 201590Srgrimes * California, Berkeley and its contributors. 211590Srgrimes * 4. Neither the name of the University nor the names of its contributors 221590Srgrimes * may be used to endorse or promote products derived from this software 231590Srgrimes * without specific prior written permission. 241590Srgrimes * 251590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 261590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 271590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 281590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 291590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 301590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 311590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 321590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 331590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 341590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 351590Srgrimes * SUCH DAMAGE. 361590Srgrimes */ 371590Srgrimes 381590Srgrimes#ifndef lint 391590Srgrimesstatic char sccsid[] = "@(#)yacc.y 8.1 (Berkeley) 6/6/93"; 401590Srgrimes#endif /* not lint */ 411590Srgrimes 421590Srgrimes#include <ctype.h> 431590Srgrimes#include <rune.h> 441590Srgrimes#include <stddef.h> 451590Srgrimes#include <stdio.h> 461590Srgrimes#include <stdlib.h> 4733648Sjb#include <string.h> 481590Srgrimes 491590Srgrimes#include "ldef.h" 501590Srgrimes 511590Srgrimeschar *locale_file = "<stdout>"; 521590Srgrimes 531590Srgrimesrune_map maplower = { 0, }; 541590Srgrimesrune_map mapupper = { 0, }; 551590Srgrimesrune_map types = { 0, }; 561590Srgrimes 571590Srgrimes_RuneLocale new_locale = { 0, }; 581590Srgrimes 592509Sbdevoid set_map __P((rune_map *, rune_list *, unsigned long)); 601590Srgrimesvoid set_digitmap __P((rune_map *, rune_list *)); 612509Sbdevoid add_map __P((rune_map *, rune_list *, unsigned long)); 621590Srgrimes%} 631590Srgrimes 641590Srgrimes%union { 651590Srgrimes rune_t rune; 661590Srgrimes int i; 671590Srgrimes char *str; 681590Srgrimes 691590Srgrimes rune_list *list; 701590Srgrimes} 711590Srgrimes 721590Srgrimes%token <rune> RUNE 731590Srgrimes%token LBRK 741590Srgrimes%token RBRK 751590Srgrimes%token THRU 761590Srgrimes%token MAPLOWER 771590Srgrimes%token MAPUPPER 781590Srgrimes%token DIGITMAP 791590Srgrimes%token <i> LIST 801590Srgrimes%token <str> VARIABLE 811590Srgrimes%token ENCODING 821590Srgrimes%token INVALID 831590Srgrimes%token <str> STRING 841590Srgrimes 851590Srgrimes%type <list> list 861590Srgrimes%type <list> map 871590Srgrimes 881590Srgrimes 891590Srgrimes%% 901590Srgrimes 911590Srgrimeslocale : /* empty */ 921590Srgrimes | table 931590Srgrimes { dump_tables(); } 941590Srgrimes ; 951590Srgrimes 961590Srgrimestable : entry 971590Srgrimes | table entry 981590Srgrimes ; 991590Srgrimes 1001590Srgrimesentry : ENCODING STRING 1011590Srgrimes { strncpy(new_locale.encoding, $2, sizeof(new_locale.encoding)); } 1021590Srgrimes | VARIABLE 1031590Srgrimes { new_locale.variable_len = strlen($1) + 1; 1041590Srgrimes new_locale.variable = malloc(new_locale.variable_len); 1051590Srgrimes strcpy((char *)new_locale.variable, $1); 1061590Srgrimes } 1071590Srgrimes | INVALID RUNE 1081590Srgrimes { new_locale.invalid_rune = $2; } 1091590Srgrimes | LIST list 1101590Srgrimes { set_map(&types, $2, $1); } 1111590Srgrimes | MAPLOWER map 1121590Srgrimes { set_map(&maplower, $2, 0); } 1131590Srgrimes | MAPUPPER map 1141590Srgrimes { set_map(&mapupper, $2, 0); } 1151590Srgrimes | DIGITMAP map 1161590Srgrimes { set_digitmap(&types, $2); } 1171590Srgrimes ; 1181590Srgrimes 1191590Srgrimeslist : RUNE 1201590Srgrimes { 1211590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1221590Srgrimes $$->min = $1; 1231590Srgrimes $$->max = $1; 1241590Srgrimes $$->next = 0; 1251590Srgrimes } 1261590Srgrimes | RUNE THRU RUNE 1271590Srgrimes { 1281590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1291590Srgrimes $$->min = $1; 1301590Srgrimes $$->max = $3; 1311590Srgrimes $$->next = 0; 1321590Srgrimes } 1331590Srgrimes | list RUNE 1341590Srgrimes { 1351590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1361590Srgrimes $$->min = $2; 1371590Srgrimes $$->max = $2; 1381590Srgrimes $$->next = $1; 1391590Srgrimes } 1401590Srgrimes | list RUNE THRU RUNE 1411590Srgrimes { 1421590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1431590Srgrimes $$->min = $2; 1441590Srgrimes $$->max = $4; 1451590Srgrimes $$->next = $1; 1461590Srgrimes } 1471590Srgrimes ; 1481590Srgrimes 1491590Srgrimesmap : LBRK RUNE RUNE RBRK 1501590Srgrimes { 1511590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1521590Srgrimes $$->min = $2; 1531590Srgrimes $$->max = $2; 1541590Srgrimes $$->map = $3; 1551590Srgrimes $$->next = 0; 1561590Srgrimes } 1571590Srgrimes | map LBRK RUNE RUNE RBRK 1581590Srgrimes { 1591590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1601590Srgrimes $$->min = $3; 1611590Srgrimes $$->max = $3; 1621590Srgrimes $$->map = $4; 1631590Srgrimes $$->next = $1; 1641590Srgrimes } 1651590Srgrimes | LBRK RUNE THRU RUNE ':' RUNE RBRK 1661590Srgrimes { 1671590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1681590Srgrimes $$->min = $2; 1691590Srgrimes $$->max = $4; 1701590Srgrimes $$->map = $6; 1711590Srgrimes $$->next = 0; 1721590Srgrimes } 1731590Srgrimes | map LBRK RUNE THRU RUNE ':' RUNE RBRK 1741590Srgrimes { 1751590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1761590Srgrimes $$->min = $3; 1771590Srgrimes $$->max = $5; 1781590Srgrimes $$->map = $7; 1791590Srgrimes $$->next = $1; 1801590Srgrimes } 1811590Srgrimes ; 1821590Srgrimes%% 1831590Srgrimes 1841590Srgrimesint debug = 0; 1851590SrgrimesFILE *fp = stdout; 1861590Srgrimes 1871590Srgrimesmain(ac, av) 1881590Srgrimes int ac; 1891590Srgrimes char *av[]; 1901590Srgrimes{ 1911590Srgrimes int x; 1921590Srgrimes 1931590Srgrimes extern char *optarg; 1941590Srgrimes extern int optind; 1951590Srgrimes 1961590Srgrimes while ((x = getopt(ac, av, "do:")) != EOF) { 1971590Srgrimes switch(x) { 1981590Srgrimes case 'd': 1991590Srgrimes debug = 1; 2001590Srgrimes break; 2011590Srgrimes case 'o': 2021590Srgrimes locale_file = optarg; 2031590Srgrimes if ((fp = fopen(locale_file, "w")) == 0) { 2041590Srgrimes perror(locale_file); 2051590Srgrimes exit(1); 2061590Srgrimes } 2071590Srgrimes break; 2081590Srgrimes default: 2091590Srgrimes usage: 2101590Srgrimes fprintf(stderr, "Usage: mklocale [-d] [-o output] [source]\n"); 2111590Srgrimes exit(1); 2121590Srgrimes } 2131590Srgrimes } 2141590Srgrimes 2151590Srgrimes switch (ac - optind) { 2161590Srgrimes case 0: 2171590Srgrimes break; 2181590Srgrimes case 1: 2191590Srgrimes if (freopen(av[optind], "r", stdin) == 0) { 2201590Srgrimes perror(av[optind]); 2211590Srgrimes exit(1); 2221590Srgrimes } 2231590Srgrimes break; 2241590Srgrimes default: 2251590Srgrimes goto usage; 2261590Srgrimes } 2271590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 2281590Srgrimes mapupper.map[x] = x; 2291590Srgrimes maplower.map[x] = x; 2301590Srgrimes } 2311590Srgrimes new_locale.invalid_rune = _INVALID_RUNE; 2321590Srgrimes memcpy(new_locale.magic, _RUNE_MAGIC_1, sizeof(new_locale.magic)); 2331590Srgrimes 2341590Srgrimes yyparse(); 2351590Srgrimes} 2361590Srgrimes 2371590Srgrimesyyerror(s) 2381590Srgrimes char *s; 2391590Srgrimes{ 2401590Srgrimes fprintf(stderr, "%s\n", s); 2411590Srgrimes} 2421590Srgrimes 2431590Srgrimesvoid * 2441590Srgrimesxmalloc(sz) 2451590Srgrimes unsigned int sz; 2461590Srgrimes{ 2471590Srgrimes void *r = malloc(sz); 2481590Srgrimes if (!r) { 2491590Srgrimes perror("xmalloc"); 2501590Srgrimes abort(); 2511590Srgrimes } 2521590Srgrimes return(r); 2531590Srgrimes} 2541590Srgrimes 2552509Sbdeunsigned long * 2561590Srgrimesxlalloc(sz) 2571590Srgrimes unsigned int sz; 2581590Srgrimes{ 2592509Sbde unsigned long *r = (unsigned long *)malloc(sz * sizeof(unsigned long)); 2601590Srgrimes if (!r) { 2611590Srgrimes perror("xlalloc"); 2621590Srgrimes abort(); 2631590Srgrimes } 2641590Srgrimes return(r); 2651590Srgrimes} 2661590Srgrimes 2672509Sbdeunsigned long * 2681590Srgrimesxrelalloc(old, sz) 2692509Sbde unsigned long *old; 2701590Srgrimes unsigned int sz; 2711590Srgrimes{ 2722509Sbde unsigned long *r = (unsigned long *)realloc((char *)old, 2732509Sbde sz * sizeof(unsigned long)); 2741590Srgrimes if (!r) { 2751590Srgrimes perror("xrelalloc"); 2761590Srgrimes abort(); 2771590Srgrimes } 2781590Srgrimes return(r); 2791590Srgrimes} 2801590Srgrimes 2811590Srgrimesvoid 2821590Srgrimesset_map(map, list, flag) 2831590Srgrimes rune_map *map; 2841590Srgrimes rune_list *list; 2852509Sbde unsigned long flag; 2861590Srgrimes{ 2871590Srgrimes while (list) { 2881590Srgrimes rune_list *nlist = list->next; 2891590Srgrimes add_map(map, list, flag); 2901590Srgrimes list = nlist; 2911590Srgrimes } 2921590Srgrimes} 2931590Srgrimes 2941590Srgrimesvoid 2951590Srgrimesset_digitmap(map, list) 2961590Srgrimes rune_map *map; 2971590Srgrimes rune_list *list; 2981590Srgrimes{ 2991590Srgrimes rune_t i; 3001590Srgrimes 3011590Srgrimes while (list) { 3021590Srgrimes rune_list *nlist = list->next; 3031590Srgrimes for (i = list->min; i <= list->max; ++i) { 3041590Srgrimes if (list->map + (i - list->min)) { 3051590Srgrimes rune_list *tmp = (rune_list *)xmalloc(sizeof(rune_list)); 3061590Srgrimes tmp->min = i; 3071590Srgrimes tmp->max = i; 3081590Srgrimes add_map(map, tmp, list->map + (i - list->min)); 3091590Srgrimes } 3101590Srgrimes } 3111590Srgrimes free(list); 3121590Srgrimes list = nlist; 3131590Srgrimes } 3141590Srgrimes} 3151590Srgrimes 3161590Srgrimesvoid 3171590Srgrimesadd_map(map, list, flag) 3181590Srgrimes rune_map *map; 3191590Srgrimes rune_list *list; 3202509Sbde unsigned long flag; 3211590Srgrimes{ 3221590Srgrimes rune_t i; 3231590Srgrimes rune_list *lr = 0; 3241590Srgrimes rune_list *r; 3251590Srgrimes rune_t run; 3261590Srgrimes 3271590Srgrimes while (list->min < _CACHED_RUNES && list->min <= list->max) { 3281590Srgrimes if (flag) 3291590Srgrimes map->map[list->min++] |= flag; 3301590Srgrimes else 3311590Srgrimes map->map[list->min++] = list->map++; 3321590Srgrimes } 3331590Srgrimes 3341590Srgrimes if (list->min > list->max) { 3351590Srgrimes free(list); 3361590Srgrimes return; 3371590Srgrimes } 3381590Srgrimes 3391590Srgrimes run = list->max - list->min + 1; 3401590Srgrimes 3411590Srgrimes if (!(r = map->root) || (list->max < r->min - 1) 3421590Srgrimes || (!flag && list->max == r->min - 1)) { 3431590Srgrimes if (flag) { 3441590Srgrimes list->types = xlalloc(run); 3451590Srgrimes for (i = 0; i < run; ++i) 3461590Srgrimes list->types[i] = flag; 3471590Srgrimes } 3481590Srgrimes list->next = map->root; 3491590Srgrimes map->root = list; 3501590Srgrimes return; 3511590Srgrimes } 3521590Srgrimes 3531590Srgrimes for (r = map->root; r && r->max + 1 < list->min; r = r->next) 3541590Srgrimes lr = r; 3551590Srgrimes 3561590Srgrimes if (!r) { 3571590Srgrimes /* 3581590Srgrimes * We are off the end. 3591590Srgrimes */ 3601590Srgrimes if (flag) { 3611590Srgrimes list->types = xlalloc(run); 3621590Srgrimes for (i = 0; i < run; ++i) 3631590Srgrimes list->types[i] = flag; 3641590Srgrimes } 3651590Srgrimes list->next = 0; 3661590Srgrimes lr->next = list; 3671590Srgrimes return; 3681590Srgrimes } 3691590Srgrimes 3701590Srgrimes if (list->max < r->min - 1) { 3711590Srgrimes /* 3721590Srgrimes * We come before this range and we do not intersect it. 3731590Srgrimes * We are not before the root node, it was checked before the loop 3741590Srgrimes */ 3751590Srgrimes if (flag) { 3761590Srgrimes list->types = xlalloc(run); 3771590Srgrimes for (i = 0; i < run; ++i) 3781590Srgrimes list->types[i] = flag; 3791590Srgrimes } 3801590Srgrimes list->next = lr->next; 3811590Srgrimes lr->next = list; 3821590Srgrimes return; 3831590Srgrimes } 3841590Srgrimes 3851590Srgrimes /* 3861590Srgrimes * At this point we have found that we at least intersect with 3871590Srgrimes * the range pointed to by `r', we might intersect with one or 3881590Srgrimes * more ranges beyond `r' as well. 3891590Srgrimes */ 3901590Srgrimes 3911590Srgrimes if (!flag && list->map - list->min != r->map - r->min) { 3921590Srgrimes /* 3931590Srgrimes * There are only two cases when we are doing case maps and 3941590Srgrimes * our maps needn't have the same offset. When we are adjoining 3951590Srgrimes * but not intersecting. 3961590Srgrimes */ 3971590Srgrimes if (list->max + 1 == r->min) { 3981590Srgrimes lr->next = list; 3991590Srgrimes list->next = r; 4001590Srgrimes return; 4011590Srgrimes } 4021590Srgrimes if (list->min - 1 == r->max) { 4031590Srgrimes list->next = r->next; 4041590Srgrimes r->next = list; 4051590Srgrimes return; 4061590Srgrimes } 4071590Srgrimes fprintf(stderr, "Error: conflicting map entries\n"); 4081590Srgrimes exit(1); 4091590Srgrimes } 4101590Srgrimes 4111590Srgrimes if (list->min >= r->min && list->max <= r->max) { 4121590Srgrimes /* 4131590Srgrimes * Subset case. 4141590Srgrimes */ 4151590Srgrimes 4161590Srgrimes if (flag) { 4171590Srgrimes for (i = list->min; i <= list->max; ++i) 4181590Srgrimes r->types[i - r->min] |= flag; 4191590Srgrimes } 4201590Srgrimes free(list); 4211590Srgrimes return; 4221590Srgrimes } 4231590Srgrimes if (list->min <= r->min && list->max >= r->max) { 4241590Srgrimes /* 4251590Srgrimes * Superset case. Make him big enough to hold us. 4261590Srgrimes * We might need to merge with the guy after him. 4271590Srgrimes */ 4281590Srgrimes if (flag) { 4291590Srgrimes list->types = xlalloc(list->max - list->min + 1); 4301590Srgrimes 4311590Srgrimes for (i = list->min; i <= list->max; ++i) 4321590Srgrimes list->types[i - list->min] = flag; 4331590Srgrimes 4341590Srgrimes for (i = r->min; i <= r->max; ++i) 4351590Srgrimes list->types[i - list->min] |= r->types[i - r->min]; 4361590Srgrimes 4371590Srgrimes free(r->types); 4381590Srgrimes r->types = list->types; 4391590Srgrimes } else { 4401590Srgrimes r->map = list->map; 4411590Srgrimes } 4421590Srgrimes r->min = list->min; 4431590Srgrimes r->max = list->max; 4441590Srgrimes free(list); 4451590Srgrimes } else if (list->min < r->min) { 4461590Srgrimes /* 4471590Srgrimes * Our tail intersects his head. 4481590Srgrimes */ 4491590Srgrimes if (flag) { 4501590Srgrimes list->types = xlalloc(r->max - list->min + 1); 4511590Srgrimes 4521590Srgrimes for (i = r->min; i <= r->max; ++i) 4531590Srgrimes list->types[i - list->min] = r->types[i - r->min]; 4541590Srgrimes 4551590Srgrimes for (i = list->min; i < r->min; ++i) 4561590Srgrimes list->types[i - list->min] = flag; 4571590Srgrimes 4581590Srgrimes for (i = r->min; i <= list->max; ++i) 4591590Srgrimes list->types[i - list->min] |= flag; 4601590Srgrimes 4611590Srgrimes free(r->types); 4621590Srgrimes r->types = list->types; 4631590Srgrimes } else { 4641590Srgrimes r->map = list->map; 4651590Srgrimes } 4661590Srgrimes r->min = list->min; 4671590Srgrimes free(list); 4681590Srgrimes return; 4691590Srgrimes } else { 4701590Srgrimes /* 4711590Srgrimes * Our head intersects his tail. 4721590Srgrimes * We might need to merge with the guy after him. 4731590Srgrimes */ 4741590Srgrimes if (flag) { 4751590Srgrimes r->types = xrelalloc(r->types, list->max - r->min + 1); 4761590Srgrimes 4771590Srgrimes for (i = list->min; i <= r->max; ++i) 4781590Srgrimes r->types[i - r->min] |= flag; 4791590Srgrimes 4801590Srgrimes for (i = r->max+1; i <= list->max; ++i) 4811590Srgrimes r->types[i - r->min] = flag; 4821590Srgrimes } 48321393Sache r->max = list->max; 4841590Srgrimes free(list); 4851590Srgrimes } 4861590Srgrimes 4871590Srgrimes /* 4881590Srgrimes * Okay, check to see if we grew into the next guy(s) 4891590Srgrimes */ 4901590Srgrimes while ((lr = r->next) && r->max >= lr->min) { 4911590Srgrimes if (flag) { 4921590Srgrimes if (r->max >= lr->max) { 4931590Srgrimes /* 4941590Srgrimes * Good, we consumed all of him. 4951590Srgrimes */ 4961590Srgrimes for (i = lr->min; i <= lr->max; ++i) 4971590Srgrimes r->types[i - r->min] |= lr->types[i - lr->min]; 4981590Srgrimes } else { 4991590Srgrimes /* 5001590Srgrimes * "append" him on to the end of us. 5011590Srgrimes */ 5021590Srgrimes r->types = xrelalloc(r->types, lr->max - r->min + 1); 5031590Srgrimes 5041590Srgrimes for (i = lr->min; i <= r->max; ++i) 5051590Srgrimes r->types[i - r->min] |= lr->types[i - lr->min]; 5061590Srgrimes 5071590Srgrimes for (i = r->max+1; i <= lr->max; ++i) 5081590Srgrimes r->types[i - r->min] = lr->types[i - lr->min]; 5091590Srgrimes 5101590Srgrimes r->max = lr->max; 5111590Srgrimes } 5121590Srgrimes } else { 5131590Srgrimes if (lr->max > r->max) 5141590Srgrimes r->max = lr->max; 5151590Srgrimes } 5161590Srgrimes 5171590Srgrimes r->next = lr->next; 5181590Srgrimes 5191590Srgrimes if (flag) 5201590Srgrimes free(lr->types); 5211590Srgrimes free(lr); 5221590Srgrimes } 5231590Srgrimes} 5241590Srgrimes 5251590Srgrimesvoid 5261590Srgrimesdump_tables() 5271590Srgrimes{ 5281590Srgrimes int x; 5291590Srgrimes rune_list *list; 5301590Srgrimes 5311590Srgrimes /* 5321590Srgrimes * See if we can compress some of the istype arrays 5331590Srgrimes */ 5341590Srgrimes for(list = types.root; list; list = list->next) { 5351590Srgrimes list->map = list->types[0]; 5361590Srgrimes for (x = 1; x < list->max - list->min + 1; ++x) { 5371590Srgrimes if (list->types[x] != list->map) { 5381590Srgrimes list->map = 0; 5391590Srgrimes break; 5401590Srgrimes } 5411590Srgrimes } 5421590Srgrimes } 5431590Srgrimes 5441590Srgrimes new_locale.invalid_rune = htonl(new_locale.invalid_rune); 5451590Srgrimes 5461590Srgrimes /* 5471590Srgrimes * Fill in our tables. Do this in network order so that 5481590Srgrimes * diverse machines have a chance of sharing data. 5491590Srgrimes * (Machines like Crays cannot share with little machines due to 5501590Srgrimes * word size. Sigh. We tried.) 5511590Srgrimes */ 5521590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 5531590Srgrimes new_locale.runetype[x] = htonl(types.map[x]); 5541590Srgrimes new_locale.maplower[x] = htonl(maplower.map[x]); 5551590Srgrimes new_locale.mapupper[x] = htonl(mapupper.map[x]); 5561590Srgrimes } 5571590Srgrimes 5581590Srgrimes /* 5591590Srgrimes * Count up how many ranges we will need for each of the extents. 5601590Srgrimes */ 5611590Srgrimes list = types.root; 5621590Srgrimes 5631590Srgrimes while (list) { 5641590Srgrimes new_locale.runetype_ext.nranges++; 5651590Srgrimes list = list->next; 5661590Srgrimes } 5671590Srgrimes new_locale.runetype_ext.nranges = htonl(new_locale.runetype_ext.nranges); 5681590Srgrimes 5691590Srgrimes list = maplower.root; 5701590Srgrimes 5711590Srgrimes while (list) { 5721590Srgrimes new_locale.maplower_ext.nranges++; 5731590Srgrimes list = list->next; 5741590Srgrimes } 5751590Srgrimes new_locale.maplower_ext.nranges = htonl(new_locale.maplower_ext.nranges); 5761590Srgrimes 5771590Srgrimes list = mapupper.root; 5781590Srgrimes 5791590Srgrimes while (list) { 5801590Srgrimes new_locale.mapupper_ext.nranges++; 5811590Srgrimes list = list->next; 5821590Srgrimes } 5831590Srgrimes new_locale.mapupper_ext.nranges = htonl(new_locale.mapupper_ext.nranges); 5841590Srgrimes 5851590Srgrimes new_locale.variable_len = htonl(new_locale.variable_len); 5861590Srgrimes 5871590Srgrimes /* 5881590Srgrimes * Okay, we are now ready to write the new locale file. 5891590Srgrimes */ 5901590Srgrimes 5911590Srgrimes /* 5921590Srgrimes * PART 1: The _RuneLocale structure 5931590Srgrimes */ 5941590Srgrimes if (fwrite((char *)&new_locale, sizeof(new_locale), 1, fp) != 1) { 5951590Srgrimes perror(locale_file); 5961590Srgrimes exit(1); 5971590Srgrimes } 5981590Srgrimes /* 5991590Srgrimes * PART 2: The runetype_ext structures (not the actual tables) 6001590Srgrimes */ 6011590Srgrimes list = types.root; 6021590Srgrimes 6031590Srgrimes while (list) { 6041590Srgrimes _RuneEntry re; 6051590Srgrimes 6061590Srgrimes re.min = htonl(list->min); 6071590Srgrimes re.max = htonl(list->max); 6081590Srgrimes re.map = htonl(list->map); 6091590Srgrimes 6101590Srgrimes if (fwrite((char *)&re, sizeof(re), 1, fp) != 1) { 6111590Srgrimes perror(locale_file); 6121590Srgrimes exit(1); 6131590Srgrimes } 6141590Srgrimes 6151590Srgrimes list = list->next; 6161590Srgrimes } 6171590Srgrimes /* 6181590Srgrimes * PART 3: The maplower_ext structures 6191590Srgrimes */ 6201590Srgrimes list = maplower.root; 6211590Srgrimes 6221590Srgrimes while (list) { 6231590Srgrimes _RuneEntry re; 6241590Srgrimes 6251590Srgrimes re.min = htonl(list->min); 6261590Srgrimes re.max = htonl(list->max); 6271590Srgrimes re.map = htonl(list->map); 6281590Srgrimes 6291590Srgrimes if (fwrite((char *)&re, sizeof(re), 1, fp) != 1) { 6301590Srgrimes perror(locale_file); 6311590Srgrimes exit(1); 6321590Srgrimes } 6331590Srgrimes 6341590Srgrimes list = list->next; 6351590Srgrimes } 6361590Srgrimes /* 6371590Srgrimes * PART 4: The mapupper_ext structures 6381590Srgrimes */ 6391590Srgrimes list = mapupper.root; 6401590Srgrimes 6411590Srgrimes while (list) { 6421590Srgrimes _RuneEntry re; 6431590Srgrimes 6441590Srgrimes re.min = htonl(list->min); 6451590Srgrimes re.max = htonl(list->max); 6461590Srgrimes re.map = htonl(list->map); 6471590Srgrimes 6481590Srgrimes if (fwrite((char *)&re, sizeof(re), 1, fp) != 1) { 6491590Srgrimes perror(locale_file); 6501590Srgrimes exit(1); 6511590Srgrimes } 6521590Srgrimes 6531590Srgrimes list = list->next; 6541590Srgrimes } 6551590Srgrimes /* 6561590Srgrimes * PART 5: The runetype_ext tables 6571590Srgrimes */ 6581590Srgrimes list = types.root; 6591590Srgrimes 6601590Srgrimes while (list) { 6611590Srgrimes for (x = 0; x < list->max - list->min + 1; ++x) 6621590Srgrimes list->types[x] = htonl(list->types[x]); 6631590Srgrimes 6641590Srgrimes if (!list->map) { 66521393Sache if (fwrite((char *)list->types, 6662509Sbde (list->max - list->min + 1) * sizeof(unsigned long), 6672509Sbde 1, fp) != 1) { 6681590Srgrimes perror(locale_file); 6691590Srgrimes exit(1); 6701590Srgrimes } 6711590Srgrimes } 6721590Srgrimes list = list->next; 6731590Srgrimes } 6741590Srgrimes /* 6751590Srgrimes * PART 5: And finally the variable data 6761590Srgrimes */ 6771590Srgrimes if (fwrite((char *)new_locale.variable, 6781590Srgrimes ntohl(new_locale.variable_len), 1, fp) != 1) { 6791590Srgrimes perror(locale_file); 6801590Srgrimes exit(1); 6811590Srgrimes } 6821590Srgrimes fclose(fp); 6831590Srgrimes 6841590Srgrimes if (!debug) 6851590Srgrimes return; 6861590Srgrimes 6871590Srgrimes if (new_locale.encoding[0]) 6881590Srgrimes fprintf(stderr, "ENCODING %s\n", new_locale.encoding); 6891590Srgrimes if (new_locale.variable) 69038022Sbde fprintf(stderr, "VARIABLE %s\n", (char *)new_locale.variable); 6911590Srgrimes 6921590Srgrimes fprintf(stderr, "\nMAPLOWER:\n\n"); 6931590Srgrimes 6941590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 6951590Srgrimes if (isprint(maplower.map[x])) 69638022Sbde fprintf(stderr, " '%c'", (int)maplower.map[x]); 6971590Srgrimes else if (maplower.map[x]) 69838022Sbde fprintf(stderr, "%04lx", maplower.map[x]); 6991590Srgrimes else 7001590Srgrimes fprintf(stderr, "%4x", 0); 7011590Srgrimes if ((x & 0xf) == 0xf) 7021590Srgrimes fprintf(stderr, "\n"); 7031590Srgrimes else 7041590Srgrimes fprintf(stderr, " "); 7051590Srgrimes } 7061590Srgrimes fprintf(stderr, "\n"); 7071590Srgrimes 7081590Srgrimes for (list = maplower.root; list; list = list->next) 7091590Srgrimes fprintf(stderr, "\t%04x - %04x : %04x\n", list->min, list->max, list->map); 7101590Srgrimes 7111590Srgrimes fprintf(stderr, "\nMAPUPPER:\n\n"); 7121590Srgrimes 7131590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 7141590Srgrimes if (isprint(mapupper.map[x])) 71538022Sbde fprintf(stderr, " '%c'", (int)mapupper.map[x]); 7161590Srgrimes else if (mapupper.map[x]) 71738022Sbde fprintf(stderr, "%04lx", mapupper.map[x]); 7181590Srgrimes else 7191590Srgrimes fprintf(stderr, "%4x", 0); 7201590Srgrimes if ((x & 0xf) == 0xf) 7211590Srgrimes fprintf(stderr, "\n"); 7221590Srgrimes else 7231590Srgrimes fprintf(stderr, " "); 7241590Srgrimes } 7251590Srgrimes fprintf(stderr, "\n"); 7261590Srgrimes 7271590Srgrimes for (list = mapupper.root; list; list = list->next) 7281590Srgrimes fprintf(stderr, "\t%04x - %04x : %04x\n", list->min, list->max, list->map); 7291590Srgrimes 7301590Srgrimes 7311590Srgrimes fprintf(stderr, "\nTYPES:\n\n"); 7321590Srgrimes 7331590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 7342509Sbde unsigned long r = types.map[x]; 7351590Srgrimes 7361590Srgrimes if (r) { 7371590Srgrimes if (isprint(x)) 73838022Sbde fprintf(stderr, " '%c': %2d", x, (int)(r & 0xff)); 7391590Srgrimes else 74038022Sbde fprintf(stderr, "%04x: %2d", x, (int)(r & 0xff)); 7411590Srgrimes 7421590Srgrimes fprintf(stderr, " %4s", (r & _A) ? "alph" : ""); 7431590Srgrimes fprintf(stderr, " %4s", (r & _C) ? "ctrl" : ""); 7441590Srgrimes fprintf(stderr, " %4s", (r & _D) ? "dig" : ""); 7451590Srgrimes fprintf(stderr, " %4s", (r & _G) ? "graf" : ""); 7461590Srgrimes fprintf(stderr, " %4s", (r & _L) ? "low" : ""); 7471590Srgrimes fprintf(stderr, " %4s", (r & _P) ? "punc" : ""); 7481590Srgrimes fprintf(stderr, " %4s", (r & _S) ? "spac" : ""); 7491590Srgrimes fprintf(stderr, " %4s", (r & _U) ? "upp" : ""); 7501590Srgrimes fprintf(stderr, " %4s", (r & _X) ? "xdig" : ""); 7511590Srgrimes fprintf(stderr, " %4s", (r & _B) ? "blnk" : ""); 7521590Srgrimes fprintf(stderr, " %4s", (r & _R) ? "prnt" : ""); 7531590Srgrimes fprintf(stderr, " %4s", (r & _I) ? "ideo" : ""); 7541590Srgrimes fprintf(stderr, " %4s", (r & _T) ? "spec" : ""); 7551590Srgrimes fprintf(stderr, " %4s", (r & _Q) ? "phon" : ""); 7561590Srgrimes fprintf(stderr, "\n"); 7571590Srgrimes } 7581590Srgrimes } 7591590Srgrimes 7601590Srgrimes for (list = types.root; list; list = list->next) { 7611590Srgrimes if (list->map && list->min + 3 < list->max) { 7622509Sbde unsigned long r = list->map; 7631590Srgrimes 76438022Sbde fprintf(stderr, "%04lx: %2d", 76538022Sbde (unsigned long)list->min, (int)(r & 0xff)); 7661590Srgrimes 7671590Srgrimes fprintf(stderr, " %4s", (r & _A) ? "alph" : ""); 7681590Srgrimes fprintf(stderr, " %4s", (r & _C) ? "ctrl" : ""); 7691590Srgrimes fprintf(stderr, " %4s", (r & _D) ? "dig" : ""); 7701590Srgrimes fprintf(stderr, " %4s", (r & _G) ? "graf" : ""); 7711590Srgrimes fprintf(stderr, " %4s", (r & _L) ? "low" : ""); 7721590Srgrimes fprintf(stderr, " %4s", (r & _P) ? "punc" : ""); 7731590Srgrimes fprintf(stderr, " %4s", (r & _S) ? "spac" : ""); 7741590Srgrimes fprintf(stderr, " %4s", (r & _U) ? "upp" : ""); 7751590Srgrimes fprintf(stderr, " %4s", (r & _X) ? "xdig" : ""); 7761590Srgrimes fprintf(stderr, " %4s", (r & _B) ? "blnk" : ""); 7771590Srgrimes fprintf(stderr, " %4s", (r & _R) ? "prnt" : ""); 7781590Srgrimes fprintf(stderr, " %4s", (r & _I) ? "ideo" : ""); 7791590Srgrimes fprintf(stderr, " %4s", (r & _T) ? "spec" : ""); 7801590Srgrimes fprintf(stderr, " %4s", (r & _Q) ? "phon" : ""); 7811590Srgrimes fprintf(stderr, "\n...\n"); 7821590Srgrimes 78338022Sbde fprintf(stderr, "%04lx: %2d", 78438022Sbde (unsigned long)list->max, (int)(r & 0xff)); 7851590Srgrimes 7861590Srgrimes fprintf(stderr, " %4s", (r & _A) ? "alph" : ""); 7871590Srgrimes fprintf(stderr, " %4s", (r & _C) ? "ctrl" : ""); 7881590Srgrimes fprintf(stderr, " %4s", (r & _D) ? "dig" : ""); 7891590Srgrimes fprintf(stderr, " %4s", (r & _G) ? "graf" : ""); 7901590Srgrimes fprintf(stderr, " %4s", (r & _L) ? "low" : ""); 7911590Srgrimes fprintf(stderr, " %4s", (r & _P) ? "punc" : ""); 7921590Srgrimes fprintf(stderr, " %4s", (r & _S) ? "spac" : ""); 7931590Srgrimes fprintf(stderr, " %4s", (r & _U) ? "upp" : ""); 7941590Srgrimes fprintf(stderr, " %4s", (r & _X) ? "xdig" : ""); 7951590Srgrimes fprintf(stderr, " %4s", (r & _B) ? "blnk" : ""); 7961590Srgrimes fprintf(stderr, " %4s", (r & _R) ? "prnt" : ""); 7971590Srgrimes fprintf(stderr, " %4s", (r & _I) ? "ideo" : ""); 7981590Srgrimes fprintf(stderr, " %4s", (r & _T) ? "spec" : ""); 7991590Srgrimes fprintf(stderr, " %4s", (r & _Q) ? "phon" : ""); 8001590Srgrimes fprintf(stderr, "\n"); 8011590Srgrimes } else 8021590Srgrimes for (x = list->min; x <= list->max; ++x) { 8032509Sbde unsigned long r = ntohl(list->types[x - list->min]); 8041590Srgrimes 8051590Srgrimes if (r) { 80638022Sbde fprintf(stderr, "%04x: %2d", x, (int)(r & 0xff)); 8071590Srgrimes 8081590Srgrimes fprintf(stderr, " %4s", (r & _A) ? "alph" : ""); 8091590Srgrimes fprintf(stderr, " %4s", (r & _C) ? "ctrl" : ""); 8101590Srgrimes fprintf(stderr, " %4s", (r & _D) ? "dig" : ""); 8111590Srgrimes fprintf(stderr, " %4s", (r & _G) ? "graf" : ""); 8121590Srgrimes fprintf(stderr, " %4s", (r & _L) ? "low" : ""); 8131590Srgrimes fprintf(stderr, " %4s", (r & _P) ? "punc" : ""); 8141590Srgrimes fprintf(stderr, " %4s", (r & _S) ? "spac" : ""); 8151590Srgrimes fprintf(stderr, " %4s", (r & _U) ? "upp" : ""); 8161590Srgrimes fprintf(stderr, " %4s", (r & _X) ? "xdig" : ""); 8171590Srgrimes fprintf(stderr, " %4s", (r & _B) ? "blnk" : ""); 8181590Srgrimes fprintf(stderr, " %4s", (r & _R) ? "prnt" : ""); 8191590Srgrimes fprintf(stderr, " %4s", (r & _I) ? "ideo" : ""); 8201590Srgrimes fprintf(stderr, " %4s", (r & _T) ? "spec" : ""); 8211590Srgrimes fprintf(stderr, " %4s", (r & _Q) ? "phon" : ""); 8221590Srgrimes fprintf(stderr, "\n"); 8231590Srgrimes } 8241590Srgrimes } 8251590Srgrimes } 8261590Srgrimes} 827