yacc.y revision 95643
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 3995643Smarkm#if 0 401590Srgrimesstatic char sccsid[] = "@(#)yacc.y 8.1 (Berkeley) 6/6/93"; 4195643Smarkm#endif /* 0 */ 421590Srgrimes#endif /* not lint */ 431590Srgrimes 4495643Smarkm#include <sys/cdefs.h> 4595643Smarkm__FBSDID("$FreeBSD: head/usr.bin/mklocale/yacc.y 95643 2002-04-28 12:34:54Z markm $"); 4695643Smarkm 4790868Smike#include <arpa/inet.h> 4890868Smike 491590Srgrimes#include <ctype.h> 501590Srgrimes#include <rune.h> 511590Srgrimes#include <stddef.h> 521590Srgrimes#include <stdio.h> 531590Srgrimes#include <stdlib.h> 5433648Sjb#include <string.h> 5595643Smarkm#include <unistd.h> 561590Srgrimes 571590Srgrimes#include "ldef.h" 5895643Smarkm#include "extern.h" 591590Srgrimes 6095643Smarkmstatic void *xmalloc(unsigned int sz); 6195643Smarkmstatic unsigned long *xlalloc(unsigned int sz); 6295643Smarkmstatic void yyerror(const char *s); 6395643Smarkmstatic unsigned long *xrelalloc(unsigned long *old, unsigned int sz); 6495643Smarkmstatic void dump_tables(void); 651590Srgrimes 6695643Smarkmconst char *locale_file = "<stdout>"; 671590Srgrimes 6895643Smarkmrune_map maplower = { { 0 }, NULL }; 6995643Smarkmrune_map mapupper = { { 0 }, NULL }; 7095643Smarkmrune_map types = { { 0 }, NULL }; 711590Srgrimes 7295643Smarkm_RuneLocale new_locale = { "", "", NULL, NULL, 0, {}, {}, {}, 7395643Smarkm {0, NULL}, {0, NULL}, {0, NULL}, NULL, 0 }; 7495643Smarkm 752509Sbdevoid set_map __P((rune_map *, rune_list *, unsigned long)); 761590Srgrimesvoid set_digitmap __P((rune_map *, rune_list *)); 772509Sbdevoid add_map __P((rune_map *, rune_list *, unsigned long)); 781590Srgrimes%} 791590Srgrimes 801590Srgrimes%union { 811590Srgrimes rune_t rune; 821590Srgrimes int i; 831590Srgrimes char *str; 841590Srgrimes 851590Srgrimes rune_list *list; 861590Srgrimes} 871590Srgrimes 881590Srgrimes%token <rune> RUNE 891590Srgrimes%token LBRK 901590Srgrimes%token RBRK 911590Srgrimes%token THRU 921590Srgrimes%token MAPLOWER 931590Srgrimes%token MAPUPPER 941590Srgrimes%token DIGITMAP 951590Srgrimes%token <i> LIST 961590Srgrimes%token <str> VARIABLE 971590Srgrimes%token ENCODING 981590Srgrimes%token INVALID 991590Srgrimes%token <str> STRING 1001590Srgrimes 1011590Srgrimes%type <list> list 1021590Srgrimes%type <list> map 1031590Srgrimes 1041590Srgrimes 1051590Srgrimes%% 1061590Srgrimes 1071590Srgrimeslocale : /* empty */ 1081590Srgrimes | table 1091590Srgrimes { dump_tables(); } 1101590Srgrimes ; 1111590Srgrimes 1121590Srgrimestable : entry 1131590Srgrimes | table entry 1141590Srgrimes ; 1151590Srgrimes 1161590Srgrimesentry : ENCODING STRING 1171590Srgrimes { strncpy(new_locale.encoding, $2, sizeof(new_locale.encoding)); } 1181590Srgrimes | VARIABLE 1191590Srgrimes { new_locale.variable_len = strlen($1) + 1; 1201590Srgrimes new_locale.variable = malloc(new_locale.variable_len); 1211590Srgrimes strcpy((char *)new_locale.variable, $1); 1221590Srgrimes } 1231590Srgrimes | INVALID RUNE 1241590Srgrimes { new_locale.invalid_rune = $2; } 1251590Srgrimes | LIST list 1261590Srgrimes { set_map(&types, $2, $1); } 1271590Srgrimes | MAPLOWER map 1281590Srgrimes { set_map(&maplower, $2, 0); } 1291590Srgrimes | MAPUPPER map 1301590Srgrimes { set_map(&mapupper, $2, 0); } 1311590Srgrimes | DIGITMAP map 1321590Srgrimes { set_digitmap(&types, $2); } 1331590Srgrimes ; 1341590Srgrimes 1351590Srgrimeslist : RUNE 1361590Srgrimes { 1371590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1381590Srgrimes $$->min = $1; 1391590Srgrimes $$->max = $1; 1401590Srgrimes $$->next = 0; 1411590Srgrimes } 1421590Srgrimes | RUNE THRU RUNE 1431590Srgrimes { 1441590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1451590Srgrimes $$->min = $1; 1461590Srgrimes $$->max = $3; 1471590Srgrimes $$->next = 0; 1481590Srgrimes } 1491590Srgrimes | list RUNE 1501590Srgrimes { 1511590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1521590Srgrimes $$->min = $2; 1531590Srgrimes $$->max = $2; 1541590Srgrimes $$->next = $1; 1551590Srgrimes } 1561590Srgrimes | list RUNE THRU RUNE 1571590Srgrimes { 1581590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1591590Srgrimes $$->min = $2; 1601590Srgrimes $$->max = $4; 1611590Srgrimes $$->next = $1; 1621590Srgrimes } 1631590Srgrimes ; 1641590Srgrimes 1651590Srgrimesmap : LBRK RUNE RUNE RBRK 1661590Srgrimes { 1671590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1681590Srgrimes $$->min = $2; 1691590Srgrimes $$->max = $2; 1701590Srgrimes $$->map = $3; 1711590Srgrimes $$->next = 0; 1721590Srgrimes } 1731590Srgrimes | map LBRK RUNE RUNE RBRK 1741590Srgrimes { 1751590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1761590Srgrimes $$->min = $3; 1771590Srgrimes $$->max = $3; 1781590Srgrimes $$->map = $4; 1791590Srgrimes $$->next = $1; 1801590Srgrimes } 1811590Srgrimes | LBRK RUNE THRU RUNE ':' RUNE RBRK 1821590Srgrimes { 1831590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1841590Srgrimes $$->min = $2; 1851590Srgrimes $$->max = $4; 1861590Srgrimes $$->map = $6; 1871590Srgrimes $$->next = 0; 1881590Srgrimes } 1891590Srgrimes | map LBRK RUNE THRU RUNE ':' RUNE RBRK 1901590Srgrimes { 1911590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1921590Srgrimes $$->min = $3; 1931590Srgrimes $$->max = $5; 1941590Srgrimes $$->map = $7; 1951590Srgrimes $$->next = $1; 1961590Srgrimes } 1971590Srgrimes ; 1981590Srgrimes%% 1991590Srgrimes 2001590Srgrimesint debug = 0; 20181606SpeterFILE *fp; 2021590Srgrimes 20395643Smarkmint 2041590Srgrimesmain(ac, av) 2051590Srgrimes int ac; 2061590Srgrimes char *av[]; 2071590Srgrimes{ 2081590Srgrimes int x; 2091590Srgrimes 2101590Srgrimes extern char *optarg; 2111590Srgrimes extern int optind; 21281606Speter fp = stdout; 2131590Srgrimes 2141590Srgrimes while ((x = getopt(ac, av, "do:")) != EOF) { 2151590Srgrimes switch(x) { 2161590Srgrimes case 'd': 2171590Srgrimes debug = 1; 2181590Srgrimes break; 2191590Srgrimes case 'o': 2201590Srgrimes locale_file = optarg; 2211590Srgrimes if ((fp = fopen(locale_file, "w")) == 0) { 2221590Srgrimes perror(locale_file); 2231590Srgrimes exit(1); 2241590Srgrimes } 2251590Srgrimes break; 2261590Srgrimes default: 2271590Srgrimes usage: 22895258Sdes fprintf(stderr, "usage: mklocale [-d] [-o output] [source]\n"); 2291590Srgrimes exit(1); 2301590Srgrimes } 2311590Srgrimes } 2321590Srgrimes 2331590Srgrimes switch (ac - optind) { 2341590Srgrimes case 0: 2351590Srgrimes break; 2361590Srgrimes case 1: 2371590Srgrimes if (freopen(av[optind], "r", stdin) == 0) { 2381590Srgrimes perror(av[optind]); 2391590Srgrimes exit(1); 2401590Srgrimes } 2411590Srgrimes break; 2421590Srgrimes default: 2431590Srgrimes goto usage; 2441590Srgrimes } 2451590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 2461590Srgrimes mapupper.map[x] = x; 2471590Srgrimes maplower.map[x] = x; 2481590Srgrimes } 2491590Srgrimes new_locale.invalid_rune = _INVALID_RUNE; 2501590Srgrimes memcpy(new_locale.magic, _RUNE_MAGIC_1, sizeof(new_locale.magic)); 2511590Srgrimes 2521590Srgrimes yyparse(); 25395643Smarkm 25495643Smarkm return(0); 2551590Srgrimes} 2561590Srgrimes 25795643Smarkmvoid 2581590Srgrimesyyerror(s) 25995643Smarkm const char *s; 2601590Srgrimes{ 2611590Srgrimes fprintf(stderr, "%s\n", s); 2621590Srgrimes} 2631590Srgrimes 2641590Srgrimesvoid * 2651590Srgrimesxmalloc(sz) 2661590Srgrimes unsigned int sz; 2671590Srgrimes{ 2681590Srgrimes void *r = malloc(sz); 2691590Srgrimes if (!r) { 2701590Srgrimes perror("xmalloc"); 2711590Srgrimes abort(); 2721590Srgrimes } 2731590Srgrimes return(r); 2741590Srgrimes} 2751590Srgrimes 2762509Sbdeunsigned long * 2771590Srgrimesxlalloc(sz) 2781590Srgrimes unsigned int sz; 2791590Srgrimes{ 2802509Sbde unsigned long *r = (unsigned long *)malloc(sz * sizeof(unsigned long)); 2811590Srgrimes if (!r) { 2821590Srgrimes perror("xlalloc"); 2831590Srgrimes abort(); 2841590Srgrimes } 2851590Srgrimes return(r); 2861590Srgrimes} 2871590Srgrimes 2882509Sbdeunsigned long * 2891590Srgrimesxrelalloc(old, sz) 2902509Sbde unsigned long *old; 2911590Srgrimes unsigned int sz; 2921590Srgrimes{ 2932509Sbde unsigned long *r = (unsigned long *)realloc((char *)old, 2942509Sbde sz * sizeof(unsigned long)); 2951590Srgrimes if (!r) { 2961590Srgrimes perror("xrelalloc"); 2971590Srgrimes abort(); 2981590Srgrimes } 2991590Srgrimes return(r); 3001590Srgrimes} 3011590Srgrimes 3021590Srgrimesvoid 3031590Srgrimesset_map(map, list, flag) 3041590Srgrimes rune_map *map; 3051590Srgrimes rune_list *list; 3062509Sbde unsigned long flag; 3071590Srgrimes{ 3081590Srgrimes while (list) { 3091590Srgrimes rune_list *nlist = list->next; 3101590Srgrimes add_map(map, list, flag); 3111590Srgrimes list = nlist; 3121590Srgrimes } 3131590Srgrimes} 3141590Srgrimes 3151590Srgrimesvoid 3161590Srgrimesset_digitmap(map, list) 3171590Srgrimes rune_map *map; 3181590Srgrimes rune_list *list; 3191590Srgrimes{ 3201590Srgrimes rune_t i; 3211590Srgrimes 3221590Srgrimes while (list) { 3231590Srgrimes rune_list *nlist = list->next; 3241590Srgrimes for (i = list->min; i <= list->max; ++i) { 3251590Srgrimes if (list->map + (i - list->min)) { 3261590Srgrimes rune_list *tmp = (rune_list *)xmalloc(sizeof(rune_list)); 3271590Srgrimes tmp->min = i; 3281590Srgrimes tmp->max = i; 3291590Srgrimes add_map(map, tmp, list->map + (i - list->min)); 3301590Srgrimes } 3311590Srgrimes } 3321590Srgrimes free(list); 3331590Srgrimes list = nlist; 3341590Srgrimes } 3351590Srgrimes} 3361590Srgrimes 3371590Srgrimesvoid 3381590Srgrimesadd_map(map, list, flag) 3391590Srgrimes rune_map *map; 3401590Srgrimes rune_list *list; 3412509Sbde unsigned long flag; 3421590Srgrimes{ 3431590Srgrimes rune_t i; 3441590Srgrimes rune_list *lr = 0; 3451590Srgrimes rune_list *r; 3461590Srgrimes rune_t run; 3471590Srgrimes 3481590Srgrimes while (list->min < _CACHED_RUNES && list->min <= list->max) { 3491590Srgrimes if (flag) 3501590Srgrimes map->map[list->min++] |= flag; 3511590Srgrimes else 3521590Srgrimes map->map[list->min++] = list->map++; 3531590Srgrimes } 3541590Srgrimes 3551590Srgrimes if (list->min > list->max) { 3561590Srgrimes free(list); 3571590Srgrimes return; 3581590Srgrimes } 3591590Srgrimes 3601590Srgrimes run = list->max - list->min + 1; 3611590Srgrimes 3621590Srgrimes if (!(r = map->root) || (list->max < r->min - 1) 3631590Srgrimes || (!flag && list->max == r->min - 1)) { 3641590Srgrimes if (flag) { 3651590Srgrimes list->types = xlalloc(run); 3661590Srgrimes for (i = 0; i < run; ++i) 3671590Srgrimes list->types[i] = flag; 3681590Srgrimes } 3691590Srgrimes list->next = map->root; 3701590Srgrimes map->root = list; 3711590Srgrimes return; 3721590Srgrimes } 3731590Srgrimes 3741590Srgrimes for (r = map->root; r && r->max + 1 < list->min; r = r->next) 3751590Srgrimes lr = r; 3761590Srgrimes 3771590Srgrimes if (!r) { 3781590Srgrimes /* 3791590Srgrimes * We are off the end. 3801590Srgrimes */ 3811590Srgrimes if (flag) { 3821590Srgrimes list->types = xlalloc(run); 3831590Srgrimes for (i = 0; i < run; ++i) 3841590Srgrimes list->types[i] = flag; 3851590Srgrimes } 3861590Srgrimes list->next = 0; 3871590Srgrimes lr->next = list; 3881590Srgrimes return; 3891590Srgrimes } 3901590Srgrimes 3911590Srgrimes if (list->max < r->min - 1) { 3921590Srgrimes /* 3931590Srgrimes * We come before this range and we do not intersect it. 3941590Srgrimes * We are not before the root node, it was checked before the loop 3951590Srgrimes */ 3961590Srgrimes if (flag) { 3971590Srgrimes list->types = xlalloc(run); 3981590Srgrimes for (i = 0; i < run; ++i) 3991590Srgrimes list->types[i] = flag; 4001590Srgrimes } 4011590Srgrimes list->next = lr->next; 4021590Srgrimes lr->next = list; 4031590Srgrimes return; 4041590Srgrimes } 4051590Srgrimes 4061590Srgrimes /* 4071590Srgrimes * At this point we have found that we at least intersect with 4081590Srgrimes * the range pointed to by `r', we might intersect with one or 4091590Srgrimes * more ranges beyond `r' as well. 4101590Srgrimes */ 4111590Srgrimes 4121590Srgrimes if (!flag && list->map - list->min != r->map - r->min) { 4131590Srgrimes /* 4141590Srgrimes * There are only two cases when we are doing case maps and 4151590Srgrimes * our maps needn't have the same offset. When we are adjoining 4161590Srgrimes * but not intersecting. 4171590Srgrimes */ 4181590Srgrimes if (list->max + 1 == r->min) { 4191590Srgrimes lr->next = list; 4201590Srgrimes list->next = r; 4211590Srgrimes return; 4221590Srgrimes } 4231590Srgrimes if (list->min - 1 == r->max) { 4241590Srgrimes list->next = r->next; 4251590Srgrimes r->next = list; 4261590Srgrimes return; 4271590Srgrimes } 4281590Srgrimes fprintf(stderr, "Error: conflicting map entries\n"); 4291590Srgrimes exit(1); 4301590Srgrimes } 4311590Srgrimes 4321590Srgrimes if (list->min >= r->min && list->max <= r->max) { 4331590Srgrimes /* 4341590Srgrimes * Subset case. 4351590Srgrimes */ 4361590Srgrimes 4371590Srgrimes if (flag) { 4381590Srgrimes for (i = list->min; i <= list->max; ++i) 4391590Srgrimes r->types[i - r->min] |= flag; 4401590Srgrimes } 4411590Srgrimes free(list); 4421590Srgrimes return; 4431590Srgrimes } 4441590Srgrimes if (list->min <= r->min && list->max >= r->max) { 4451590Srgrimes /* 4461590Srgrimes * Superset case. Make him big enough to hold us. 4471590Srgrimes * We might need to merge with the guy after him. 4481590Srgrimes */ 4491590Srgrimes if (flag) { 4501590Srgrimes list->types = xlalloc(list->max - list->min + 1); 4511590Srgrimes 4521590Srgrimes for (i = list->min; i <= list->max; ++i) 4531590Srgrimes list->types[i - list->min] = flag; 4541590Srgrimes 4551590Srgrimes for (i = r->min; i <= r->max; ++i) 4561590Srgrimes list->types[i - list->min] |= r->types[i - r->min]; 4571590Srgrimes 4581590Srgrimes free(r->types); 4591590Srgrimes r->types = list->types; 4601590Srgrimes } else { 4611590Srgrimes r->map = list->map; 4621590Srgrimes } 4631590Srgrimes r->min = list->min; 4641590Srgrimes r->max = list->max; 4651590Srgrimes free(list); 4661590Srgrimes } else if (list->min < r->min) { 4671590Srgrimes /* 4681590Srgrimes * Our tail intersects his head. 4691590Srgrimes */ 4701590Srgrimes if (flag) { 4711590Srgrimes list->types = xlalloc(r->max - list->min + 1); 4721590Srgrimes 4731590Srgrimes for (i = r->min; i <= r->max; ++i) 4741590Srgrimes list->types[i - list->min] = r->types[i - r->min]; 4751590Srgrimes 4761590Srgrimes for (i = list->min; i < r->min; ++i) 4771590Srgrimes list->types[i - list->min] = flag; 4781590Srgrimes 4791590Srgrimes for (i = r->min; i <= list->max; ++i) 4801590Srgrimes list->types[i - list->min] |= flag; 4811590Srgrimes 4821590Srgrimes free(r->types); 4831590Srgrimes r->types = list->types; 4841590Srgrimes } else { 4851590Srgrimes r->map = list->map; 4861590Srgrimes } 4871590Srgrimes r->min = list->min; 4881590Srgrimes free(list); 4891590Srgrimes return; 4901590Srgrimes } else { 4911590Srgrimes /* 4921590Srgrimes * Our head intersects his tail. 4931590Srgrimes * We might need to merge with the guy after him. 4941590Srgrimes */ 4951590Srgrimes if (flag) { 4961590Srgrimes r->types = xrelalloc(r->types, list->max - r->min + 1); 4971590Srgrimes 4981590Srgrimes for (i = list->min; i <= r->max; ++i) 4991590Srgrimes r->types[i - r->min] |= flag; 5001590Srgrimes 5011590Srgrimes for (i = r->max+1; i <= list->max; ++i) 5021590Srgrimes r->types[i - r->min] = flag; 5031590Srgrimes } 50421393Sache r->max = list->max; 5051590Srgrimes free(list); 5061590Srgrimes } 5071590Srgrimes 5081590Srgrimes /* 5091590Srgrimes * Okay, check to see if we grew into the next guy(s) 5101590Srgrimes */ 5111590Srgrimes while ((lr = r->next) && r->max >= lr->min) { 5121590Srgrimes if (flag) { 5131590Srgrimes if (r->max >= lr->max) { 5141590Srgrimes /* 5151590Srgrimes * Good, we consumed all of him. 5161590Srgrimes */ 5171590Srgrimes for (i = lr->min; i <= lr->max; ++i) 5181590Srgrimes r->types[i - r->min] |= lr->types[i - lr->min]; 5191590Srgrimes } else { 5201590Srgrimes /* 5211590Srgrimes * "append" him on to the end of us. 5221590Srgrimes */ 5231590Srgrimes r->types = xrelalloc(r->types, lr->max - r->min + 1); 5241590Srgrimes 5251590Srgrimes for (i = lr->min; i <= r->max; ++i) 5261590Srgrimes r->types[i - r->min] |= lr->types[i - lr->min]; 5271590Srgrimes 5281590Srgrimes for (i = r->max+1; i <= lr->max; ++i) 5291590Srgrimes r->types[i - r->min] = lr->types[i - lr->min]; 5301590Srgrimes 5311590Srgrimes r->max = lr->max; 5321590Srgrimes } 5331590Srgrimes } else { 5341590Srgrimes if (lr->max > r->max) 5351590Srgrimes r->max = lr->max; 5361590Srgrimes } 5371590Srgrimes 5381590Srgrimes r->next = lr->next; 5391590Srgrimes 5401590Srgrimes if (flag) 5411590Srgrimes free(lr->types); 5421590Srgrimes free(lr); 5431590Srgrimes } 5441590Srgrimes} 5451590Srgrimes 5461590Srgrimesvoid 5471590Srgrimesdump_tables() 5481590Srgrimes{ 5491590Srgrimes int x; 5501590Srgrimes rune_list *list; 5511590Srgrimes 5521590Srgrimes /* 5531590Srgrimes * See if we can compress some of the istype arrays 5541590Srgrimes */ 5551590Srgrimes for(list = types.root; list; list = list->next) { 5561590Srgrimes list->map = list->types[0]; 5571590Srgrimes for (x = 1; x < list->max - list->min + 1; ++x) { 55895643Smarkm if ((rune_t)list->types[x] != list->map) { 5591590Srgrimes list->map = 0; 5601590Srgrimes break; 5611590Srgrimes } 5621590Srgrimes } 5631590Srgrimes } 5641590Srgrimes 5651590Srgrimes new_locale.invalid_rune = htonl(new_locale.invalid_rune); 5661590Srgrimes 5671590Srgrimes /* 5681590Srgrimes * Fill in our tables. Do this in network order so that 5691590Srgrimes * diverse machines have a chance of sharing data. 5701590Srgrimes * (Machines like Crays cannot share with little machines due to 5711590Srgrimes * word size. Sigh. We tried.) 5721590Srgrimes */ 5731590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 5741590Srgrimes new_locale.runetype[x] = htonl(types.map[x]); 5751590Srgrimes new_locale.maplower[x] = htonl(maplower.map[x]); 5761590Srgrimes new_locale.mapupper[x] = htonl(mapupper.map[x]); 5771590Srgrimes } 5781590Srgrimes 5791590Srgrimes /* 5801590Srgrimes * Count up how many ranges we will need for each of the extents. 5811590Srgrimes */ 5821590Srgrimes list = types.root; 5831590Srgrimes 5841590Srgrimes while (list) { 5851590Srgrimes new_locale.runetype_ext.nranges++; 5861590Srgrimes list = list->next; 5871590Srgrimes } 5881590Srgrimes new_locale.runetype_ext.nranges = htonl(new_locale.runetype_ext.nranges); 5891590Srgrimes 5901590Srgrimes list = maplower.root; 5911590Srgrimes 5921590Srgrimes while (list) { 5931590Srgrimes new_locale.maplower_ext.nranges++; 5941590Srgrimes list = list->next; 5951590Srgrimes } 5961590Srgrimes new_locale.maplower_ext.nranges = htonl(new_locale.maplower_ext.nranges); 5971590Srgrimes 5981590Srgrimes list = mapupper.root; 5991590Srgrimes 6001590Srgrimes while (list) { 6011590Srgrimes new_locale.mapupper_ext.nranges++; 6021590Srgrimes list = list->next; 6031590Srgrimes } 6041590Srgrimes new_locale.mapupper_ext.nranges = htonl(new_locale.mapupper_ext.nranges); 6051590Srgrimes 6061590Srgrimes new_locale.variable_len = htonl(new_locale.variable_len); 6071590Srgrimes 6081590Srgrimes /* 6091590Srgrimes * Okay, we are now ready to write the new locale file. 6101590Srgrimes */ 6111590Srgrimes 6121590Srgrimes /* 6131590Srgrimes * PART 1: The _RuneLocale structure 6141590Srgrimes */ 6151590Srgrimes if (fwrite((char *)&new_locale, sizeof(new_locale), 1, fp) != 1) { 6161590Srgrimes perror(locale_file); 6171590Srgrimes exit(1); 6181590Srgrimes } 6191590Srgrimes /* 6201590Srgrimes * PART 2: The runetype_ext structures (not the actual tables) 6211590Srgrimes */ 6221590Srgrimes list = types.root; 6231590Srgrimes 6241590Srgrimes while (list) { 6251590Srgrimes _RuneEntry re; 6261590Srgrimes 6271590Srgrimes re.min = htonl(list->min); 6281590Srgrimes re.max = htonl(list->max); 6291590Srgrimes re.map = htonl(list->map); 6301590Srgrimes 6311590Srgrimes if (fwrite((char *)&re, sizeof(re), 1, fp) != 1) { 6321590Srgrimes perror(locale_file); 6331590Srgrimes exit(1); 6341590Srgrimes } 6351590Srgrimes 6361590Srgrimes list = list->next; 6371590Srgrimes } 6381590Srgrimes /* 6391590Srgrimes * PART 3: The maplower_ext structures 6401590Srgrimes */ 6411590Srgrimes list = maplower.root; 6421590Srgrimes 6431590Srgrimes while (list) { 6441590Srgrimes _RuneEntry re; 6451590Srgrimes 6461590Srgrimes re.min = htonl(list->min); 6471590Srgrimes re.max = htonl(list->max); 6481590Srgrimes re.map = htonl(list->map); 6491590Srgrimes 6501590Srgrimes if (fwrite((char *)&re, sizeof(re), 1, fp) != 1) { 6511590Srgrimes perror(locale_file); 6521590Srgrimes exit(1); 6531590Srgrimes } 6541590Srgrimes 6551590Srgrimes list = list->next; 6561590Srgrimes } 6571590Srgrimes /* 6581590Srgrimes * PART 4: The mapupper_ext structures 6591590Srgrimes */ 6601590Srgrimes list = mapupper.root; 6611590Srgrimes 6621590Srgrimes while (list) { 6631590Srgrimes _RuneEntry re; 6641590Srgrimes 6651590Srgrimes re.min = htonl(list->min); 6661590Srgrimes re.max = htonl(list->max); 6671590Srgrimes re.map = htonl(list->map); 6681590Srgrimes 6691590Srgrimes if (fwrite((char *)&re, sizeof(re), 1, fp) != 1) { 6701590Srgrimes perror(locale_file); 6711590Srgrimes exit(1); 6721590Srgrimes } 6731590Srgrimes 6741590Srgrimes list = list->next; 6751590Srgrimes } 6761590Srgrimes /* 6771590Srgrimes * PART 5: The runetype_ext tables 6781590Srgrimes */ 6791590Srgrimes list = types.root; 6801590Srgrimes 6811590Srgrimes while (list) { 6821590Srgrimes for (x = 0; x < list->max - list->min + 1; ++x) 6831590Srgrimes list->types[x] = htonl(list->types[x]); 6841590Srgrimes 6851590Srgrimes if (!list->map) { 68621393Sache if (fwrite((char *)list->types, 6872509Sbde (list->max - list->min + 1) * sizeof(unsigned long), 6882509Sbde 1, fp) != 1) { 6891590Srgrimes perror(locale_file); 6901590Srgrimes exit(1); 6911590Srgrimes } 6921590Srgrimes } 6931590Srgrimes list = list->next; 6941590Srgrimes } 6951590Srgrimes /* 6961590Srgrimes * PART 5: And finally the variable data 6971590Srgrimes */ 6981590Srgrimes if (fwrite((char *)new_locale.variable, 6991590Srgrimes ntohl(new_locale.variable_len), 1, fp) != 1) { 7001590Srgrimes perror(locale_file); 7011590Srgrimes exit(1); 7021590Srgrimes } 7031590Srgrimes fclose(fp); 7041590Srgrimes 7051590Srgrimes if (!debug) 7061590Srgrimes return; 7071590Srgrimes 7081590Srgrimes if (new_locale.encoding[0]) 7091590Srgrimes fprintf(stderr, "ENCODING %s\n", new_locale.encoding); 7101590Srgrimes if (new_locale.variable) 71138022Sbde fprintf(stderr, "VARIABLE %s\n", (char *)new_locale.variable); 7121590Srgrimes 7131590Srgrimes fprintf(stderr, "\nMAPLOWER:\n\n"); 7141590Srgrimes 7151590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 7161590Srgrimes if (isprint(maplower.map[x])) 71738022Sbde fprintf(stderr, " '%c'", (int)maplower.map[x]); 7181590Srgrimes else if (maplower.map[x]) 71938022Sbde fprintf(stderr, "%04lx", maplower.map[x]); 7201590Srgrimes else 7211590Srgrimes fprintf(stderr, "%4x", 0); 7221590Srgrimes if ((x & 0xf) == 0xf) 7231590Srgrimes fprintf(stderr, "\n"); 7241590Srgrimes else 7251590Srgrimes fprintf(stderr, " "); 7261590Srgrimes } 7271590Srgrimes fprintf(stderr, "\n"); 7281590Srgrimes 7291590Srgrimes for (list = maplower.root; list; list = list->next) 7301590Srgrimes fprintf(stderr, "\t%04x - %04x : %04x\n", list->min, list->max, list->map); 7311590Srgrimes 7321590Srgrimes fprintf(stderr, "\nMAPUPPER:\n\n"); 7331590Srgrimes 7341590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 7351590Srgrimes if (isprint(mapupper.map[x])) 73638022Sbde fprintf(stderr, " '%c'", (int)mapupper.map[x]); 7371590Srgrimes else if (mapupper.map[x]) 73838022Sbde fprintf(stderr, "%04lx", mapupper.map[x]); 7391590Srgrimes else 7401590Srgrimes fprintf(stderr, "%4x", 0); 7411590Srgrimes if ((x & 0xf) == 0xf) 7421590Srgrimes fprintf(stderr, "\n"); 7431590Srgrimes else 7441590Srgrimes fprintf(stderr, " "); 7451590Srgrimes } 7461590Srgrimes fprintf(stderr, "\n"); 7471590Srgrimes 7481590Srgrimes for (list = mapupper.root; list; list = list->next) 7491590Srgrimes fprintf(stderr, "\t%04x - %04x : %04x\n", list->min, list->max, list->map); 7501590Srgrimes 7511590Srgrimes 7521590Srgrimes fprintf(stderr, "\nTYPES:\n\n"); 7531590Srgrimes 7541590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 7552509Sbde unsigned long r = types.map[x]; 7561590Srgrimes 7571590Srgrimes if (r) { 7581590Srgrimes if (isprint(x)) 75938022Sbde fprintf(stderr, " '%c': %2d", x, (int)(r & 0xff)); 7601590Srgrimes else 76138022Sbde fprintf(stderr, "%04x: %2d", x, (int)(r & 0xff)); 7621590Srgrimes 76357035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_A) ? "alph" : ""); 76457035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_C) ? "ctrl" : ""); 76557035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_D) ? "dig" : ""); 76657035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_G) ? "graf" : ""); 76757035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_L) ? "low" : ""); 76857035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_P) ? "punc" : ""); 76957035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_S) ? "spac" : ""); 77057035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_U) ? "upp" : ""); 77157035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_X) ? "xdig" : ""); 77257035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_B) ? "blnk" : ""); 77357035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_R) ? "prnt" : ""); 77457035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_I) ? "ideo" : ""); 77557035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_T) ? "spec" : ""); 77657035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_Q) ? "phon" : ""); 7771590Srgrimes fprintf(stderr, "\n"); 7781590Srgrimes } 7791590Srgrimes } 7801590Srgrimes 7811590Srgrimes for (list = types.root; list; list = list->next) { 7821590Srgrimes if (list->map && list->min + 3 < list->max) { 7832509Sbde unsigned long r = list->map; 7841590Srgrimes 78538022Sbde fprintf(stderr, "%04lx: %2d", 78638022Sbde (unsigned long)list->min, (int)(r & 0xff)); 7871590Srgrimes 78857035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_A) ? "alph" : ""); 78957035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_C) ? "ctrl" : ""); 79057035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_D) ? "dig" : ""); 79157035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_G) ? "graf" : ""); 79257035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_L) ? "low" : ""); 79357035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_P) ? "punc" : ""); 79457035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_S) ? "spac" : ""); 79557035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_U) ? "upp" : ""); 79657035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_X) ? "xdig" : ""); 79757035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_B) ? "blnk" : ""); 79857035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_R) ? "prnt" : ""); 79957035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_I) ? "ideo" : ""); 80057035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_T) ? "spec" : ""); 80157035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_Q) ? "phon" : ""); 8021590Srgrimes fprintf(stderr, "\n...\n"); 8031590Srgrimes 80438022Sbde fprintf(stderr, "%04lx: %2d", 80538022Sbde (unsigned long)list->max, (int)(r & 0xff)); 8061590Srgrimes 80757035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_A) ? "alph" : ""); 80857035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_C) ? "ctrl" : ""); 80957035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_D) ? "dig" : ""); 81057035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_G) ? "graf" : ""); 81157035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_L) ? "low" : ""); 81257035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_P) ? "punc" : ""); 81357035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_S) ? "spac" : ""); 81457035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_U) ? "upp" : ""); 81557035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_X) ? "xdig" : ""); 81657035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_B) ? "blnk" : ""); 81757035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_R) ? "prnt" : ""); 81857035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_I) ? "ideo" : ""); 81957035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_T) ? "spec" : ""); 82057035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_Q) ? "phon" : ""); 8211590Srgrimes fprintf(stderr, "\n"); 8221590Srgrimes } else 8231590Srgrimes for (x = list->min; x <= list->max; ++x) { 8242509Sbde unsigned long r = ntohl(list->types[x - list->min]); 8251590Srgrimes 8261590Srgrimes if (r) { 82738022Sbde fprintf(stderr, "%04x: %2d", x, (int)(r & 0xff)); 8281590Srgrimes 82957035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_A) ? "alph" : ""); 83057035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_C) ? "ctrl" : ""); 83157035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_D) ? "dig" : ""); 83257035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_G) ? "graf" : ""); 83357035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_L) ? "low" : ""); 83457035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_P) ? "punc" : ""); 83557035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_S) ? "spac" : ""); 83657035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_U) ? "upp" : ""); 83757035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_X) ? "xdig" : ""); 83857035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_B) ? "blnk" : ""); 83957035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_R) ? "prnt" : ""); 84057035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_I) ? "ideo" : ""); 84157035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_T) ? "spec" : ""); 84257035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_Q) ? "phon" : ""); 8431590Srgrimes fprintf(stderr, "\n"); 8441590Srgrimes } 8451590Srgrimes } 8461590Srgrimes } 8471590Srgrimes} 848