yacc.y revision 21393
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> 471590Srgrimes 481590Srgrimes#include "ldef.h" 491590Srgrimes 501590Srgrimeschar *locale_file = "<stdout>"; 511590Srgrimes 521590Srgrimesrune_map maplower = { 0, }; 531590Srgrimesrune_map mapupper = { 0, }; 541590Srgrimesrune_map types = { 0, }; 551590Srgrimes 561590Srgrimes_RuneLocale new_locale = { 0, }; 571590Srgrimes 582509Sbdevoid set_map __P((rune_map *, rune_list *, unsigned long)); 591590Srgrimesvoid set_digitmap __P((rune_map *, rune_list *)); 602509Sbdevoid add_map __P((rune_map *, rune_list *, unsigned long)); 611590Srgrimes%} 621590Srgrimes 631590Srgrimes%union { 641590Srgrimes rune_t rune; 651590Srgrimes int i; 661590Srgrimes char *str; 671590Srgrimes 681590Srgrimes rune_list *list; 691590Srgrimes} 701590Srgrimes 711590Srgrimes%token <rune> RUNE 721590Srgrimes%token LBRK 731590Srgrimes%token RBRK 741590Srgrimes%token THRU 751590Srgrimes%token MAPLOWER 761590Srgrimes%token MAPUPPER 771590Srgrimes%token DIGITMAP 781590Srgrimes%token <i> LIST 791590Srgrimes%token <str> VARIABLE 801590Srgrimes%token ENCODING 811590Srgrimes%token INVALID 821590Srgrimes%token <str> STRING 831590Srgrimes 841590Srgrimes%type <list> list 851590Srgrimes%type <list> map 861590Srgrimes 871590Srgrimes 881590Srgrimes%% 891590Srgrimes 901590Srgrimeslocale : /* empty */ 911590Srgrimes | table 921590Srgrimes { dump_tables(); } 931590Srgrimes ; 941590Srgrimes 951590Srgrimestable : entry 961590Srgrimes | table entry 971590Srgrimes ; 981590Srgrimes 991590Srgrimesentry : ENCODING STRING 1001590Srgrimes { strncpy(new_locale.encoding, $2, sizeof(new_locale.encoding)); } 1011590Srgrimes | VARIABLE 1021590Srgrimes { new_locale.variable_len = strlen($1) + 1; 1031590Srgrimes new_locale.variable = malloc(new_locale.variable_len); 1041590Srgrimes strcpy((char *)new_locale.variable, $1); 1051590Srgrimes } 1061590Srgrimes | INVALID RUNE 1071590Srgrimes { new_locale.invalid_rune = $2; } 1081590Srgrimes | LIST list 1091590Srgrimes { set_map(&types, $2, $1); } 1101590Srgrimes | MAPLOWER map 1111590Srgrimes { set_map(&maplower, $2, 0); } 1121590Srgrimes | MAPUPPER map 1131590Srgrimes { set_map(&mapupper, $2, 0); } 1141590Srgrimes | DIGITMAP map 1151590Srgrimes { set_digitmap(&types, $2); } 1161590Srgrimes ; 1171590Srgrimes 1181590Srgrimeslist : RUNE 1191590Srgrimes { 1201590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1211590Srgrimes $$->min = $1; 1221590Srgrimes $$->max = $1; 1231590Srgrimes $$->next = 0; 1241590Srgrimes } 1251590Srgrimes | RUNE THRU RUNE 1261590Srgrimes { 1271590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1281590Srgrimes $$->min = $1; 1291590Srgrimes $$->max = $3; 1301590Srgrimes $$->next = 0; 1311590Srgrimes } 1321590Srgrimes | list RUNE 1331590Srgrimes { 1341590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1351590Srgrimes $$->min = $2; 1361590Srgrimes $$->max = $2; 1371590Srgrimes $$->next = $1; 1381590Srgrimes } 1391590Srgrimes | list RUNE THRU RUNE 1401590Srgrimes { 1411590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1421590Srgrimes $$->min = $2; 1431590Srgrimes $$->max = $4; 1441590Srgrimes $$->next = $1; 1451590Srgrimes } 1461590Srgrimes ; 1471590Srgrimes 1481590Srgrimesmap : LBRK RUNE RUNE RBRK 1491590Srgrimes { 1501590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1511590Srgrimes $$->min = $2; 1521590Srgrimes $$->max = $2; 1531590Srgrimes $$->map = $3; 1541590Srgrimes $$->next = 0; 1551590Srgrimes } 1561590Srgrimes | map LBRK RUNE RUNE RBRK 1571590Srgrimes { 1581590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1591590Srgrimes $$->min = $3; 1601590Srgrimes $$->max = $3; 1611590Srgrimes $$->map = $4; 1621590Srgrimes $$->next = $1; 1631590Srgrimes } 1641590Srgrimes | LBRK RUNE THRU RUNE ':' RUNE RBRK 1651590Srgrimes { 1661590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1671590Srgrimes $$->min = $2; 1681590Srgrimes $$->max = $4; 1691590Srgrimes $$->map = $6; 1701590Srgrimes $$->next = 0; 1711590Srgrimes } 1721590Srgrimes | map LBRK RUNE THRU RUNE ':' RUNE RBRK 1731590Srgrimes { 1741590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1751590Srgrimes $$->min = $3; 1761590Srgrimes $$->max = $5; 1771590Srgrimes $$->map = $7; 1781590Srgrimes $$->next = $1; 1791590Srgrimes } 1801590Srgrimes ; 1811590Srgrimes%% 1821590Srgrimes 1831590Srgrimesint debug = 0; 1841590SrgrimesFILE *fp = stdout; 1851590Srgrimes 1861590Srgrimesmain(ac, av) 1871590Srgrimes int ac; 1881590Srgrimes char *av[]; 1891590Srgrimes{ 1901590Srgrimes int x; 1911590Srgrimes 1921590Srgrimes extern char *optarg; 1931590Srgrimes extern int optind; 1941590Srgrimes 1951590Srgrimes while ((x = getopt(ac, av, "do:")) != EOF) { 1961590Srgrimes switch(x) { 1971590Srgrimes case 'd': 1981590Srgrimes debug = 1; 1991590Srgrimes break; 2001590Srgrimes case 'o': 2011590Srgrimes locale_file = optarg; 2021590Srgrimes if ((fp = fopen(locale_file, "w")) == 0) { 2031590Srgrimes perror(locale_file); 2041590Srgrimes exit(1); 2051590Srgrimes } 2061590Srgrimes break; 2071590Srgrimes default: 2081590Srgrimes usage: 2091590Srgrimes fprintf(stderr, "Usage: mklocale [-d] [-o output] [source]\n"); 2101590Srgrimes exit(1); 2111590Srgrimes } 2121590Srgrimes } 2131590Srgrimes 2141590Srgrimes switch (ac - optind) { 2151590Srgrimes case 0: 2161590Srgrimes break; 2171590Srgrimes case 1: 2181590Srgrimes if (freopen(av[optind], "r", stdin) == 0) { 2191590Srgrimes perror(av[optind]); 2201590Srgrimes exit(1); 2211590Srgrimes } 2221590Srgrimes break; 2231590Srgrimes default: 2241590Srgrimes goto usage; 2251590Srgrimes } 2261590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 2271590Srgrimes mapupper.map[x] = x; 2281590Srgrimes maplower.map[x] = x; 2291590Srgrimes } 2301590Srgrimes new_locale.invalid_rune = _INVALID_RUNE; 2311590Srgrimes memcpy(new_locale.magic, _RUNE_MAGIC_1, sizeof(new_locale.magic)); 2321590Srgrimes 2331590Srgrimes yyparse(); 2341590Srgrimes} 2351590Srgrimes 2361590Srgrimesyyerror(s) 2371590Srgrimes char *s; 2381590Srgrimes{ 2391590Srgrimes fprintf(stderr, "%s\n", s); 2401590Srgrimes} 2411590Srgrimes 2421590Srgrimesvoid * 2431590Srgrimesxmalloc(sz) 2441590Srgrimes unsigned int sz; 2451590Srgrimes{ 2461590Srgrimes void *r = malloc(sz); 2471590Srgrimes if (!r) { 2481590Srgrimes perror("xmalloc"); 2491590Srgrimes abort(); 2501590Srgrimes } 2511590Srgrimes return(r); 2521590Srgrimes} 2531590Srgrimes 2542509Sbdeunsigned long * 2551590Srgrimesxlalloc(sz) 2561590Srgrimes unsigned int sz; 2571590Srgrimes{ 2582509Sbde unsigned long *r = (unsigned long *)malloc(sz * sizeof(unsigned long)); 2591590Srgrimes if (!r) { 2601590Srgrimes perror("xlalloc"); 2611590Srgrimes abort(); 2621590Srgrimes } 2631590Srgrimes return(r); 2641590Srgrimes} 2651590Srgrimes 2662509Sbdeunsigned long * 2671590Srgrimesxrelalloc(old, sz) 2682509Sbde unsigned long *old; 2691590Srgrimes unsigned int sz; 2701590Srgrimes{ 2712509Sbde unsigned long *r = (unsigned long *)realloc((char *)old, 2722509Sbde sz * sizeof(unsigned long)); 2731590Srgrimes if (!r) { 2741590Srgrimes perror("xrelalloc"); 2751590Srgrimes abort(); 2761590Srgrimes } 2771590Srgrimes return(r); 2781590Srgrimes} 2791590Srgrimes 2801590Srgrimesvoid 2811590Srgrimesset_map(map, list, flag) 2821590Srgrimes rune_map *map; 2831590Srgrimes rune_list *list; 2842509Sbde unsigned long flag; 2851590Srgrimes{ 2861590Srgrimes while (list) { 2871590Srgrimes rune_list *nlist = list->next; 2881590Srgrimes add_map(map, list, flag); 2891590Srgrimes list = nlist; 2901590Srgrimes } 2911590Srgrimes} 2921590Srgrimes 2931590Srgrimesvoid 2941590Srgrimesset_digitmap(map, list) 2951590Srgrimes rune_map *map; 2961590Srgrimes rune_list *list; 2971590Srgrimes{ 2981590Srgrimes rune_t i; 2991590Srgrimes 3001590Srgrimes while (list) { 3011590Srgrimes rune_list *nlist = list->next; 3021590Srgrimes for (i = list->min; i <= list->max; ++i) { 3031590Srgrimes if (list->map + (i - list->min)) { 3041590Srgrimes rune_list *tmp = (rune_list *)xmalloc(sizeof(rune_list)); 3051590Srgrimes tmp->min = i; 3061590Srgrimes tmp->max = i; 3071590Srgrimes add_map(map, tmp, list->map + (i - list->min)); 3081590Srgrimes } 3091590Srgrimes } 3101590Srgrimes free(list); 3111590Srgrimes list = nlist; 3121590Srgrimes } 3131590Srgrimes} 3141590Srgrimes 3151590Srgrimesvoid 3161590Srgrimesadd_map(map, list, flag) 3171590Srgrimes rune_map *map; 3181590Srgrimes rune_list *list; 3192509Sbde unsigned long flag; 3201590Srgrimes{ 3211590Srgrimes rune_t i; 3221590Srgrimes rune_list *lr = 0; 3231590Srgrimes rune_list *r; 3241590Srgrimes rune_t run; 3251590Srgrimes 3261590Srgrimes while (list->min < _CACHED_RUNES && list->min <= list->max) { 3271590Srgrimes if (flag) 3281590Srgrimes map->map[list->min++] |= flag; 3291590Srgrimes else 3301590Srgrimes map->map[list->min++] = list->map++; 3311590Srgrimes } 3321590Srgrimes 3331590Srgrimes if (list->min > list->max) { 3341590Srgrimes free(list); 3351590Srgrimes return; 3361590Srgrimes } 3371590Srgrimes 3381590Srgrimes run = list->max - list->min + 1; 3391590Srgrimes 3401590Srgrimes if (!(r = map->root) || (list->max < r->min - 1) 3411590Srgrimes || (!flag && list->max == r->min - 1)) { 3421590Srgrimes if (flag) { 3431590Srgrimes list->types = xlalloc(run); 3441590Srgrimes for (i = 0; i < run; ++i) 3451590Srgrimes list->types[i] = flag; 3461590Srgrimes } 3471590Srgrimes list->next = map->root; 3481590Srgrimes map->root = list; 3491590Srgrimes return; 3501590Srgrimes } 3511590Srgrimes 3521590Srgrimes for (r = map->root; r && r->max + 1 < list->min; r = r->next) 3531590Srgrimes lr = r; 3541590Srgrimes 3551590Srgrimes if (!r) { 3561590Srgrimes /* 3571590Srgrimes * We are off the end. 3581590Srgrimes */ 3591590Srgrimes if (flag) { 3601590Srgrimes list->types = xlalloc(run); 3611590Srgrimes for (i = 0; i < run; ++i) 3621590Srgrimes list->types[i] = flag; 3631590Srgrimes } 3641590Srgrimes list->next = 0; 3651590Srgrimes lr->next = list; 3661590Srgrimes return; 3671590Srgrimes } 3681590Srgrimes 3691590Srgrimes if (list->max < r->min - 1) { 3701590Srgrimes /* 3711590Srgrimes * We come before this range and we do not intersect it. 3721590Srgrimes * We are not before the root node, it was checked before the loop 3731590Srgrimes */ 3741590Srgrimes if (flag) { 3751590Srgrimes list->types = xlalloc(run); 3761590Srgrimes for (i = 0; i < run; ++i) 3771590Srgrimes list->types[i] = flag; 3781590Srgrimes } 3791590Srgrimes list->next = lr->next; 3801590Srgrimes lr->next = list; 3811590Srgrimes return; 3821590Srgrimes } 3831590Srgrimes 3841590Srgrimes /* 3851590Srgrimes * At this point we have found that we at least intersect with 3861590Srgrimes * the range pointed to by `r', we might intersect with one or 3871590Srgrimes * more ranges beyond `r' as well. 3881590Srgrimes */ 3891590Srgrimes 3901590Srgrimes if (!flag && list->map - list->min != r->map - r->min) { 3911590Srgrimes /* 3921590Srgrimes * There are only two cases when we are doing case maps and 3931590Srgrimes * our maps needn't have the same offset. When we are adjoining 3941590Srgrimes * but not intersecting. 3951590Srgrimes */ 3961590Srgrimes if (list->max + 1 == r->min) { 3971590Srgrimes lr->next = list; 3981590Srgrimes list->next = r; 3991590Srgrimes return; 4001590Srgrimes } 4011590Srgrimes if (list->min - 1 == r->max) { 4021590Srgrimes list->next = r->next; 4031590Srgrimes r->next = list; 4041590Srgrimes return; 4051590Srgrimes } 4061590Srgrimes fprintf(stderr, "Error: conflicting map entries\n"); 4071590Srgrimes exit(1); 4081590Srgrimes } 4091590Srgrimes 4101590Srgrimes if (list->min >= r->min && list->max <= r->max) { 4111590Srgrimes /* 4121590Srgrimes * Subset case. 4131590Srgrimes */ 4141590Srgrimes 4151590Srgrimes if (flag) { 4161590Srgrimes for (i = list->min; i <= list->max; ++i) 4171590Srgrimes r->types[i - r->min] |= flag; 4181590Srgrimes } 4191590Srgrimes free(list); 4201590Srgrimes return; 4211590Srgrimes } 4221590Srgrimes if (list->min <= r->min && list->max >= r->max) { 4231590Srgrimes /* 4241590Srgrimes * Superset case. Make him big enough to hold us. 4251590Srgrimes * We might need to merge with the guy after him. 4261590Srgrimes */ 4271590Srgrimes if (flag) { 4281590Srgrimes list->types = xlalloc(list->max - list->min + 1); 4291590Srgrimes 4301590Srgrimes for (i = list->min; i <= list->max; ++i) 4311590Srgrimes list->types[i - list->min] = flag; 4321590Srgrimes 4331590Srgrimes for (i = r->min; i <= r->max; ++i) 4341590Srgrimes list->types[i - list->min] |= r->types[i - r->min]; 4351590Srgrimes 4361590Srgrimes free(r->types); 4371590Srgrimes r->types = list->types; 4381590Srgrimes } else { 4391590Srgrimes r->map = list->map; 4401590Srgrimes } 4411590Srgrimes r->min = list->min; 4421590Srgrimes r->max = list->max; 4431590Srgrimes free(list); 4441590Srgrimes } else if (list->min < r->min) { 4451590Srgrimes /* 4461590Srgrimes * Our tail intersects his head. 4471590Srgrimes */ 4481590Srgrimes if (flag) { 4491590Srgrimes list->types = xlalloc(r->max - list->min + 1); 4501590Srgrimes 4511590Srgrimes for (i = r->min; i <= r->max; ++i) 4521590Srgrimes list->types[i - list->min] = r->types[i - r->min]; 4531590Srgrimes 4541590Srgrimes for (i = list->min; i < r->min; ++i) 4551590Srgrimes list->types[i - list->min] = flag; 4561590Srgrimes 4571590Srgrimes for (i = r->min; i <= list->max; ++i) 4581590Srgrimes list->types[i - list->min] |= flag; 4591590Srgrimes 4601590Srgrimes free(r->types); 4611590Srgrimes r->types = list->types; 4621590Srgrimes } else { 4631590Srgrimes r->map = list->map; 4641590Srgrimes } 4651590Srgrimes r->min = list->min; 4661590Srgrimes free(list); 4671590Srgrimes return; 4681590Srgrimes } else { 4691590Srgrimes /* 4701590Srgrimes * Our head intersects his tail. 4711590Srgrimes * We might need to merge with the guy after him. 4721590Srgrimes */ 4731590Srgrimes if (flag) { 4741590Srgrimes r->types = xrelalloc(r->types, list->max - r->min + 1); 4751590Srgrimes 4761590Srgrimes for (i = list->min; i <= r->max; ++i) 4771590Srgrimes r->types[i - r->min] |= flag; 4781590Srgrimes 4791590Srgrimes for (i = r->max+1; i <= list->max; ++i) 4801590Srgrimes r->types[i - r->min] = flag; 4811590Srgrimes } 48221393Sache r->max = list->max; 4831590Srgrimes free(list); 4841590Srgrimes } 4851590Srgrimes 4861590Srgrimes /* 4871590Srgrimes * Okay, check to see if we grew into the next guy(s) 4881590Srgrimes */ 4891590Srgrimes while ((lr = r->next) && r->max >= lr->min) { 4901590Srgrimes if (flag) { 4911590Srgrimes if (r->max >= lr->max) { 4921590Srgrimes /* 4931590Srgrimes * Good, we consumed all of him. 4941590Srgrimes */ 4951590Srgrimes for (i = lr->min; i <= lr->max; ++i) 4961590Srgrimes r->types[i - r->min] |= lr->types[i - lr->min]; 4971590Srgrimes } else { 4981590Srgrimes /* 4991590Srgrimes * "append" him on to the end of us. 5001590Srgrimes */ 5011590Srgrimes r->types = xrelalloc(r->types, lr->max - r->min + 1); 5021590Srgrimes 5031590Srgrimes for (i = lr->min; i <= r->max; ++i) 5041590Srgrimes r->types[i - r->min] |= lr->types[i - lr->min]; 5051590Srgrimes 5061590Srgrimes for (i = r->max+1; i <= lr->max; ++i) 5071590Srgrimes r->types[i - r->min] = lr->types[i - lr->min]; 5081590Srgrimes 5091590Srgrimes r->max = lr->max; 5101590Srgrimes } 5111590Srgrimes } else { 5121590Srgrimes if (lr->max > r->max) 5131590Srgrimes r->max = lr->max; 5141590Srgrimes } 5151590Srgrimes 5161590Srgrimes r->next = lr->next; 5171590Srgrimes 5181590Srgrimes if (flag) 5191590Srgrimes free(lr->types); 5201590Srgrimes free(lr); 5211590Srgrimes } 5221590Srgrimes} 5231590Srgrimes 5241590Srgrimesvoid 5251590Srgrimesdump_tables() 5261590Srgrimes{ 5271590Srgrimes int x; 5281590Srgrimes rune_list *list; 5291590Srgrimes 5301590Srgrimes /* 5311590Srgrimes * See if we can compress some of the istype arrays 5321590Srgrimes */ 5331590Srgrimes for(list = types.root; list; list = list->next) { 5341590Srgrimes list->map = list->types[0]; 5351590Srgrimes for (x = 1; x < list->max - list->min + 1; ++x) { 5361590Srgrimes if (list->types[x] != list->map) { 5371590Srgrimes list->map = 0; 5381590Srgrimes break; 5391590Srgrimes } 5401590Srgrimes } 5411590Srgrimes } 5421590Srgrimes 5431590Srgrimes new_locale.invalid_rune = htonl(new_locale.invalid_rune); 5441590Srgrimes 5451590Srgrimes /* 5461590Srgrimes * Fill in our tables. Do this in network order so that 5471590Srgrimes * diverse machines have a chance of sharing data. 5481590Srgrimes * (Machines like Crays cannot share with little machines due to 5491590Srgrimes * word size. Sigh. We tried.) 5501590Srgrimes */ 5511590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 5521590Srgrimes new_locale.runetype[x] = htonl(types.map[x]); 5531590Srgrimes new_locale.maplower[x] = htonl(maplower.map[x]); 5541590Srgrimes new_locale.mapupper[x] = htonl(mapupper.map[x]); 5551590Srgrimes } 5561590Srgrimes 5571590Srgrimes /* 5581590Srgrimes * Count up how many ranges we will need for each of the extents. 5591590Srgrimes */ 5601590Srgrimes list = types.root; 5611590Srgrimes 5621590Srgrimes while (list) { 5631590Srgrimes new_locale.runetype_ext.nranges++; 5641590Srgrimes list = list->next; 5651590Srgrimes } 5661590Srgrimes new_locale.runetype_ext.nranges = htonl(new_locale.runetype_ext.nranges); 5671590Srgrimes 5681590Srgrimes list = maplower.root; 5691590Srgrimes 5701590Srgrimes while (list) { 5711590Srgrimes new_locale.maplower_ext.nranges++; 5721590Srgrimes list = list->next; 5731590Srgrimes } 5741590Srgrimes new_locale.maplower_ext.nranges = htonl(new_locale.maplower_ext.nranges); 5751590Srgrimes 5761590Srgrimes list = mapupper.root; 5771590Srgrimes 5781590Srgrimes while (list) { 5791590Srgrimes new_locale.mapupper_ext.nranges++; 5801590Srgrimes list = list->next; 5811590Srgrimes } 5821590Srgrimes new_locale.mapupper_ext.nranges = htonl(new_locale.mapupper_ext.nranges); 5831590Srgrimes 5841590Srgrimes new_locale.variable_len = htonl(new_locale.variable_len); 5851590Srgrimes 5861590Srgrimes /* 5871590Srgrimes * Okay, we are now ready to write the new locale file. 5881590Srgrimes */ 5891590Srgrimes 5901590Srgrimes /* 5911590Srgrimes * PART 1: The _RuneLocale structure 5921590Srgrimes */ 5931590Srgrimes if (fwrite((char *)&new_locale, sizeof(new_locale), 1, fp) != 1) { 5941590Srgrimes perror(locale_file); 5951590Srgrimes exit(1); 5961590Srgrimes } 5971590Srgrimes /* 5981590Srgrimes * PART 2: The runetype_ext structures (not the actual tables) 5991590Srgrimes */ 6001590Srgrimes list = types.root; 6011590Srgrimes 6021590Srgrimes while (list) { 6031590Srgrimes _RuneEntry re; 6041590Srgrimes 6051590Srgrimes re.min = htonl(list->min); 6061590Srgrimes re.max = htonl(list->max); 6071590Srgrimes re.map = htonl(list->map); 6081590Srgrimes 6091590Srgrimes if (fwrite((char *)&re, sizeof(re), 1, fp) != 1) { 6101590Srgrimes perror(locale_file); 6111590Srgrimes exit(1); 6121590Srgrimes } 6131590Srgrimes 6141590Srgrimes list = list->next; 6151590Srgrimes } 6161590Srgrimes /* 6171590Srgrimes * PART 3: The maplower_ext structures 6181590Srgrimes */ 6191590Srgrimes list = maplower.root; 6201590Srgrimes 6211590Srgrimes while (list) { 6221590Srgrimes _RuneEntry re; 6231590Srgrimes 6241590Srgrimes re.min = htonl(list->min); 6251590Srgrimes re.max = htonl(list->max); 6261590Srgrimes re.map = htonl(list->map); 6271590Srgrimes 6281590Srgrimes if (fwrite((char *)&re, sizeof(re), 1, fp) != 1) { 6291590Srgrimes perror(locale_file); 6301590Srgrimes exit(1); 6311590Srgrimes } 6321590Srgrimes 6331590Srgrimes list = list->next; 6341590Srgrimes } 6351590Srgrimes /* 6361590Srgrimes * PART 4: The mapupper_ext structures 6371590Srgrimes */ 6381590Srgrimes list = mapupper.root; 6391590Srgrimes 6401590Srgrimes while (list) { 6411590Srgrimes _RuneEntry re; 6421590Srgrimes 6431590Srgrimes re.min = htonl(list->min); 6441590Srgrimes re.max = htonl(list->max); 6451590Srgrimes re.map = htonl(list->map); 6461590Srgrimes 6471590Srgrimes if (fwrite((char *)&re, sizeof(re), 1, fp) != 1) { 6481590Srgrimes perror(locale_file); 6491590Srgrimes exit(1); 6501590Srgrimes } 6511590Srgrimes 6521590Srgrimes list = list->next; 6531590Srgrimes } 6541590Srgrimes /* 6551590Srgrimes * PART 5: The runetype_ext tables 6561590Srgrimes */ 6571590Srgrimes list = types.root; 6581590Srgrimes 6591590Srgrimes while (list) { 6601590Srgrimes for (x = 0; x < list->max - list->min + 1; ++x) 6611590Srgrimes list->types[x] = htonl(list->types[x]); 6621590Srgrimes 6631590Srgrimes if (!list->map) { 66421393Sache if (fwrite((char *)list->types, 6652509Sbde (list->max - list->min + 1) * sizeof(unsigned long), 6662509Sbde 1, fp) != 1) { 6671590Srgrimes perror(locale_file); 6681590Srgrimes exit(1); 6691590Srgrimes } 6701590Srgrimes } 6711590Srgrimes list = list->next; 6721590Srgrimes } 6731590Srgrimes /* 6741590Srgrimes * PART 5: And finally the variable data 6751590Srgrimes */ 6761590Srgrimes if (fwrite((char *)new_locale.variable, 6771590Srgrimes ntohl(new_locale.variable_len), 1, fp) != 1) { 6781590Srgrimes perror(locale_file); 6791590Srgrimes exit(1); 6801590Srgrimes } 6811590Srgrimes fclose(fp); 6821590Srgrimes 6831590Srgrimes if (!debug) 6841590Srgrimes return; 6851590Srgrimes 6861590Srgrimes if (new_locale.encoding[0]) 6871590Srgrimes fprintf(stderr, "ENCODING %s\n", new_locale.encoding); 6881590Srgrimes if (new_locale.variable) 6891590Srgrimes fprintf(stderr, "VARIABLE %s\n", new_locale.variable); 6901590Srgrimes 6911590Srgrimes fprintf(stderr, "\nMAPLOWER:\n\n"); 6921590Srgrimes 6931590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 6941590Srgrimes if (isprint(maplower.map[x])) 6951590Srgrimes fprintf(stderr, " '%c'", maplower.map[x]); 6961590Srgrimes else if (maplower.map[x]) 6971590Srgrimes fprintf(stderr, "%04x", maplower.map[x]); 6981590Srgrimes else 6991590Srgrimes fprintf(stderr, "%4x", 0); 7001590Srgrimes if ((x & 0xf) == 0xf) 7011590Srgrimes fprintf(stderr, "\n"); 7021590Srgrimes else 7031590Srgrimes fprintf(stderr, " "); 7041590Srgrimes } 7051590Srgrimes fprintf(stderr, "\n"); 7061590Srgrimes 7071590Srgrimes for (list = maplower.root; list; list = list->next) 7081590Srgrimes fprintf(stderr, "\t%04x - %04x : %04x\n", list->min, list->max, list->map); 7091590Srgrimes 7101590Srgrimes fprintf(stderr, "\nMAPUPPER:\n\n"); 7111590Srgrimes 7121590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 7131590Srgrimes if (isprint(mapupper.map[x])) 7141590Srgrimes fprintf(stderr, " '%c'", mapupper.map[x]); 7151590Srgrimes else if (mapupper.map[x]) 7161590Srgrimes fprintf(stderr, "%04x", mapupper.map[x]); 7171590Srgrimes else 7181590Srgrimes fprintf(stderr, "%4x", 0); 7191590Srgrimes if ((x & 0xf) == 0xf) 7201590Srgrimes fprintf(stderr, "\n"); 7211590Srgrimes else 7221590Srgrimes fprintf(stderr, " "); 7231590Srgrimes } 7241590Srgrimes fprintf(stderr, "\n"); 7251590Srgrimes 7261590Srgrimes for (list = mapupper.root; list; list = list->next) 7271590Srgrimes fprintf(stderr, "\t%04x - %04x : %04x\n", list->min, list->max, list->map); 7281590Srgrimes 7291590Srgrimes 7301590Srgrimes fprintf(stderr, "\nTYPES:\n\n"); 7311590Srgrimes 7321590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 7332509Sbde unsigned long r = types.map[x]; 7341590Srgrimes 7351590Srgrimes if (r) { 7361590Srgrimes if (isprint(x)) 7371590Srgrimes fprintf(stderr, " '%c': %2d", x, r & 0xff); 7381590Srgrimes else 7391590Srgrimes fprintf(stderr, "%04x: %2d", x, r & 0xff); 7401590Srgrimes 7411590Srgrimes fprintf(stderr, " %4s", (r & _A) ? "alph" : ""); 7421590Srgrimes fprintf(stderr, " %4s", (r & _C) ? "ctrl" : ""); 7431590Srgrimes fprintf(stderr, " %4s", (r & _D) ? "dig" : ""); 7441590Srgrimes fprintf(stderr, " %4s", (r & _G) ? "graf" : ""); 7451590Srgrimes fprintf(stderr, " %4s", (r & _L) ? "low" : ""); 7461590Srgrimes fprintf(stderr, " %4s", (r & _P) ? "punc" : ""); 7471590Srgrimes fprintf(stderr, " %4s", (r & _S) ? "spac" : ""); 7481590Srgrimes fprintf(stderr, " %4s", (r & _U) ? "upp" : ""); 7491590Srgrimes fprintf(stderr, " %4s", (r & _X) ? "xdig" : ""); 7501590Srgrimes fprintf(stderr, " %4s", (r & _B) ? "blnk" : ""); 7511590Srgrimes fprintf(stderr, " %4s", (r & _R) ? "prnt" : ""); 7521590Srgrimes fprintf(stderr, " %4s", (r & _I) ? "ideo" : ""); 7531590Srgrimes fprintf(stderr, " %4s", (r & _T) ? "spec" : ""); 7541590Srgrimes fprintf(stderr, " %4s", (r & _Q) ? "phon" : ""); 7551590Srgrimes fprintf(stderr, "\n"); 7561590Srgrimes } 7571590Srgrimes } 7581590Srgrimes 7591590Srgrimes for (list = types.root; list; list = list->next) { 7601590Srgrimes if (list->map && list->min + 3 < list->max) { 7612509Sbde unsigned long r = list->map; 7621590Srgrimes 7631590Srgrimes fprintf(stderr, "%04x: %2d", list->min, r & 0xff); 7641590Srgrimes 7651590Srgrimes fprintf(stderr, " %4s", (r & _A) ? "alph" : ""); 7661590Srgrimes fprintf(stderr, " %4s", (r & _C) ? "ctrl" : ""); 7671590Srgrimes fprintf(stderr, " %4s", (r & _D) ? "dig" : ""); 7681590Srgrimes fprintf(stderr, " %4s", (r & _G) ? "graf" : ""); 7691590Srgrimes fprintf(stderr, " %4s", (r & _L) ? "low" : ""); 7701590Srgrimes fprintf(stderr, " %4s", (r & _P) ? "punc" : ""); 7711590Srgrimes fprintf(stderr, " %4s", (r & _S) ? "spac" : ""); 7721590Srgrimes fprintf(stderr, " %4s", (r & _U) ? "upp" : ""); 7731590Srgrimes fprintf(stderr, " %4s", (r & _X) ? "xdig" : ""); 7741590Srgrimes fprintf(stderr, " %4s", (r & _B) ? "blnk" : ""); 7751590Srgrimes fprintf(stderr, " %4s", (r & _R) ? "prnt" : ""); 7761590Srgrimes fprintf(stderr, " %4s", (r & _I) ? "ideo" : ""); 7771590Srgrimes fprintf(stderr, " %4s", (r & _T) ? "spec" : ""); 7781590Srgrimes fprintf(stderr, " %4s", (r & _Q) ? "phon" : ""); 7791590Srgrimes fprintf(stderr, "\n...\n"); 7801590Srgrimes 7811590Srgrimes fprintf(stderr, "%04x: %2d", list->max, r & 0xff); 7821590Srgrimes 7831590Srgrimes fprintf(stderr, " %4s", (r & _A) ? "alph" : ""); 7841590Srgrimes fprintf(stderr, " %4s", (r & _C) ? "ctrl" : ""); 7851590Srgrimes fprintf(stderr, " %4s", (r & _D) ? "dig" : ""); 7861590Srgrimes fprintf(stderr, " %4s", (r & _G) ? "graf" : ""); 7871590Srgrimes fprintf(stderr, " %4s", (r & _L) ? "low" : ""); 7881590Srgrimes fprintf(stderr, " %4s", (r & _P) ? "punc" : ""); 7891590Srgrimes fprintf(stderr, " %4s", (r & _S) ? "spac" : ""); 7901590Srgrimes fprintf(stderr, " %4s", (r & _U) ? "upp" : ""); 7911590Srgrimes fprintf(stderr, " %4s", (r & _X) ? "xdig" : ""); 7921590Srgrimes fprintf(stderr, " %4s", (r & _B) ? "blnk" : ""); 7931590Srgrimes fprintf(stderr, " %4s", (r & _R) ? "prnt" : ""); 7941590Srgrimes fprintf(stderr, " %4s", (r & _I) ? "ideo" : ""); 7951590Srgrimes fprintf(stderr, " %4s", (r & _T) ? "spec" : ""); 7961590Srgrimes fprintf(stderr, " %4s", (r & _Q) ? "phon" : ""); 7971590Srgrimes fprintf(stderr, "\n"); 7981590Srgrimes } else 7991590Srgrimes for (x = list->min; x <= list->max; ++x) { 8002509Sbde unsigned long r = ntohl(list->types[x - list->min]); 8011590Srgrimes 8021590Srgrimes if (r) { 8031590Srgrimes fprintf(stderr, "%04x: %2d", x, r & 0xff); 8041590Srgrimes 8051590Srgrimes fprintf(stderr, " %4s", (r & _A) ? "alph" : ""); 8061590Srgrimes fprintf(stderr, " %4s", (r & _C) ? "ctrl" : ""); 8071590Srgrimes fprintf(stderr, " %4s", (r & _D) ? "dig" : ""); 8081590Srgrimes fprintf(stderr, " %4s", (r & _G) ? "graf" : ""); 8091590Srgrimes fprintf(stderr, " %4s", (r & _L) ? "low" : ""); 8101590Srgrimes fprintf(stderr, " %4s", (r & _P) ? "punc" : ""); 8111590Srgrimes fprintf(stderr, " %4s", (r & _S) ? "spac" : ""); 8121590Srgrimes fprintf(stderr, " %4s", (r & _U) ? "upp" : ""); 8131590Srgrimes fprintf(stderr, " %4s", (r & _X) ? "xdig" : ""); 8141590Srgrimes fprintf(stderr, " %4s", (r & _B) ? "blnk" : ""); 8151590Srgrimes fprintf(stderr, " %4s", (r & _R) ? "prnt" : ""); 8161590Srgrimes fprintf(stderr, " %4s", (r & _I) ? "ideo" : ""); 8171590Srgrimes fprintf(stderr, " %4s", (r & _T) ? "spec" : ""); 8181590Srgrimes fprintf(stderr, " %4s", (r & _Q) ? "phon" : ""); 8191590Srgrimes fprintf(stderr, "\n"); 8201590Srgrimes } 8211590Srgrimes } 8221590Srgrimes } 8231590Srgrimes} 824