yacc.y revision 166529
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 166529 2007-02-06 08:48:28Z kevlo $"); 4695643Smarkm 4790868Smike#include <arpa/inet.h> 4890868Smike 491590Srgrimes#include <ctype.h> 50108158Stjr#include <err.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" 59146261Sru#include "runefile.h" 601590Srgrimes 6195643Smarkmstatic void *xmalloc(unsigned int sz); 62142582Srustatic uint32_t *xlalloc(unsigned int sz); 63105548Sachevoid yyerror(const char *s); 64142582Srustatic uint32_t *xrelalloc(uint32_t *old, unsigned int sz); 6595643Smarkmstatic void dump_tables(void); 66105548Sachestatic void cleanout(void); 671590Srgrimes 6895643Smarkmconst char *locale_file = "<stdout>"; 691590Srgrimes 7095643Smarkmrune_map maplower = { { 0 }, NULL }; 7195643Smarkmrune_map mapupper = { { 0 }, NULL }; 7295643Smarkmrune_map types = { { 0 }, NULL }; 731590Srgrimes 74142582Sru_FileRuneLocale new_locale = { "", "", {}, {}, {}, 0, 0, 0, 0 }; 75142582Sruchar *variable = NULL; 7695643Smarkm 77142582Sruvoid set_map(rune_map *, rune_list *, uint32_t); 7899982Salfredvoid set_digitmap(rune_map *, rune_list *); 79142582Sruvoid add_map(rune_map *, rune_list *, uint32_t); 80116502Scharnierstatic void usage(void); 811590Srgrimes%} 821590Srgrimes 831590Srgrimes%union { 84142582Sru int32_t rune; 851590Srgrimes int i; 861590Srgrimes char *str; 871590Srgrimes 881590Srgrimes rune_list *list; 891590Srgrimes} 901590Srgrimes 911590Srgrimes%token <rune> RUNE 921590Srgrimes%token LBRK 931590Srgrimes%token RBRK 941590Srgrimes%token THRU 951590Srgrimes%token MAPLOWER 961590Srgrimes%token MAPUPPER 971590Srgrimes%token DIGITMAP 981590Srgrimes%token <i> LIST 991590Srgrimes%token <str> VARIABLE 1001590Srgrimes%token ENCODING 1011590Srgrimes%token INVALID 1021590Srgrimes%token <str> STRING 1031590Srgrimes 1041590Srgrimes%type <list> list 1051590Srgrimes%type <list> map 1061590Srgrimes 1071590Srgrimes 1081590Srgrimes%% 1091590Srgrimes 1101590Srgrimeslocale : /* empty */ 1111590Srgrimes | table 1121590Srgrimes { dump_tables(); } 1131590Srgrimes ; 1141590Srgrimes 1151590Srgrimestable : entry 1161590Srgrimes | table entry 1171590Srgrimes ; 1181590Srgrimes 1191590Srgrimesentry : ENCODING STRING 120115722Sache { if (strcmp($2, "NONE") && 121115722Sache strcmp($2, "UTF-8") && 122115722Sache strcmp($2, "EUC") && 123115722Sache strcmp($2, "GBK") && 124118147Sache strcmp($2, "GB18030") && 125122145Sdavidxu strcmp($2, "GB2312") && 126115722Sache strcmp($2, "BIG5") && 127115776Sache strcmp($2, "MSKanji")) 128115776Sache warnx("ENCODING %s is not supported by libc", $2); 129142582Sru strncpy(new_locale.encoding, $2, 130142582Sru sizeof(new_locale.encoding)); } 1311590Srgrimes | VARIABLE 132142582Sru { new_locale.variable_len = strlen($1) + 1; 133142582Sru variable = xmalloc(new_locale.variable_len); 134142582Sru strcpy(variable, $1); 1351590Srgrimes } 1361590Srgrimes | INVALID RUNE 137142582Sru { warnx("the INVALID keyword is deprecated"); } 1381590Srgrimes | LIST list 1391590Srgrimes { set_map(&types, $2, $1); } 1401590Srgrimes | MAPLOWER map 1411590Srgrimes { set_map(&maplower, $2, 0); } 1421590Srgrimes | MAPUPPER map 1431590Srgrimes { set_map(&mapupper, $2, 0); } 1441590Srgrimes | DIGITMAP map 1451590Srgrimes { set_digitmap(&types, $2); } 1461590Srgrimes ; 1471590Srgrimes 1481590Srgrimeslist : RUNE 1491590Srgrimes { 150116502Scharnier $$ = (rune_list *)xmalloc(sizeof(rune_list)); 1511590Srgrimes $$->min = $1; 1521590Srgrimes $$->max = $1; 1531590Srgrimes $$->next = 0; 1541590Srgrimes } 1551590Srgrimes | RUNE THRU RUNE 1561590Srgrimes { 157116502Scharnier $$ = (rune_list *)xmalloc(sizeof(rune_list)); 1581590Srgrimes $$->min = $1; 1591590Srgrimes $$->max = $3; 1601590Srgrimes $$->next = 0; 1611590Srgrimes } 1621590Srgrimes | list RUNE 1631590Srgrimes { 164116502Scharnier $$ = (rune_list *)xmalloc(sizeof(rune_list)); 1651590Srgrimes $$->min = $2; 1661590Srgrimes $$->max = $2; 1671590Srgrimes $$->next = $1; 1681590Srgrimes } 1691590Srgrimes | list RUNE THRU RUNE 1701590Srgrimes { 171116502Scharnier $$ = (rune_list *)xmalloc(sizeof(rune_list)); 1721590Srgrimes $$->min = $2; 1731590Srgrimes $$->max = $4; 1741590Srgrimes $$->next = $1; 1751590Srgrimes } 1761590Srgrimes ; 1771590Srgrimes 1781590Srgrimesmap : LBRK RUNE RUNE RBRK 1791590Srgrimes { 180116502Scharnier $$ = (rune_list *)xmalloc(sizeof(rune_list)); 1811590Srgrimes $$->min = $2; 1821590Srgrimes $$->max = $2; 1831590Srgrimes $$->map = $3; 1841590Srgrimes $$->next = 0; 1851590Srgrimes } 1861590Srgrimes | map LBRK RUNE RUNE RBRK 1871590Srgrimes { 188116502Scharnier $$ = (rune_list *)xmalloc(sizeof(rune_list)); 1891590Srgrimes $$->min = $3; 1901590Srgrimes $$->max = $3; 1911590Srgrimes $$->map = $4; 1921590Srgrimes $$->next = $1; 1931590Srgrimes } 1941590Srgrimes | LBRK RUNE THRU RUNE ':' RUNE RBRK 1951590Srgrimes { 196116502Scharnier $$ = (rune_list *)xmalloc(sizeof(rune_list)); 1971590Srgrimes $$->min = $2; 1981590Srgrimes $$->max = $4; 1991590Srgrimes $$->map = $6; 2001590Srgrimes $$->next = 0; 2011590Srgrimes } 2021590Srgrimes | map LBRK RUNE THRU RUNE ':' RUNE RBRK 2031590Srgrimes { 204116502Scharnier $$ = (rune_list *)xmalloc(sizeof(rune_list)); 2051590Srgrimes $$->min = $3; 2061590Srgrimes $$->max = $5; 2071590Srgrimes $$->map = $7; 2081590Srgrimes $$->next = $1; 2091590Srgrimes } 2101590Srgrimes ; 2111590Srgrimes%% 2121590Srgrimes 213105548Sacheint debug; 21481606SpeterFILE *fp; 2151590Srgrimes 216105548Sachestatic void 217105548Sachecleanout(void) 218105548Sache{ 219105548Sache if (fp != NULL) 220105548Sache unlink(locale_file); 221105548Sache} 222105548Sache 22395643Smarkmint 22499984Salfredmain(int ac, char *av[]) 2251590Srgrimes{ 2261590Srgrimes int x; 2271590Srgrimes 22881606Speter fp = stdout; 2291590Srgrimes 230166529Skevlo while ((x = getopt(ac, av, "do:")) != -1) { 2311590Srgrimes switch(x) { 2321590Srgrimes case 'd': 2331590Srgrimes debug = 1; 2341590Srgrimes break; 2351590Srgrimes case 'o': 2361590Srgrimes locale_file = optarg; 237116502Scharnier if ((fp = fopen(locale_file, "w")) == 0) 238116502Scharnier err(1, "%s", locale_file); 239105548Sache atexit(cleanout); 2401590Srgrimes break; 2411590Srgrimes default: 242116502Scharnier usage(); 2431590Srgrimes } 2441590Srgrimes } 2451590Srgrimes 2461590Srgrimes switch (ac - optind) { 2471590Srgrimes case 0: 2481590Srgrimes break; 2491590Srgrimes case 1: 250116502Scharnier if (freopen(av[optind], "r", stdin) == 0) 251116502Scharnier err(1, "%s", av[optind]); 2521590Srgrimes break; 2531590Srgrimes default: 254116502Scharnier usage(); 2551590Srgrimes } 2561590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 2571590Srgrimes mapupper.map[x] = x; 2581590Srgrimes maplower.map[x] = x; 2591590Srgrimes } 260142582Sru memcpy(new_locale.magic, _FILE_RUNE_MAGIC_1, sizeof(new_locale.magic)); 2611590Srgrimes 2621590Srgrimes yyparse(); 26395643Smarkm 26495643Smarkm return(0); 2651590Srgrimes} 2661590Srgrimes 267116502Scharnierstatic void 268116502Scharnierusage() 269116502Scharnier{ 270116502Scharnier fprintf(stderr, "usage: mklocale [-d] [-o output] [source]\n"); 271116502Scharnier exit(1); 272116502Scharnier} 273116502Scharnier 27495643Smarkmvoid 2751590Srgrimesyyerror(s) 27695643Smarkm const char *s; 2771590Srgrimes{ 2781590Srgrimes fprintf(stderr, "%s\n", s); 2791590Srgrimes} 2801590Srgrimes 281105548Sachestatic void * 2821590Srgrimesxmalloc(sz) 2831590Srgrimes unsigned int sz; 2841590Srgrimes{ 2851590Srgrimes void *r = malloc(sz); 286116502Scharnier if (!r) 287116502Scharnier errx(1, "xmalloc"); 2881590Srgrimes return(r); 2891590Srgrimes} 2901590Srgrimes 291142582Srustatic uint32_t * 2921590Srgrimesxlalloc(sz) 2931590Srgrimes unsigned int sz; 2941590Srgrimes{ 295142582Sru uint32_t *r = (uint32_t *)malloc(sz * sizeof(uint32_t)); 296116502Scharnier if (!r) 297116502Scharnier errx(1, "xlalloc"); 2981590Srgrimes return(r); 2991590Srgrimes} 3001590Srgrimes 301142582Srustatic uint32_t * 3021590Srgrimesxrelalloc(old, sz) 303142582Sru uint32_t *old; 3041590Srgrimes unsigned int sz; 3051590Srgrimes{ 306142582Sru uint32_t *r = (uint32_t *)realloc((char *)old, 307142582Sru sz * sizeof(uint32_t)); 308116502Scharnier if (!r) 309116502Scharnier errx(1, "xrelalloc"); 3101590Srgrimes return(r); 3111590Srgrimes} 3121590Srgrimes 3131590Srgrimesvoid 3141590Srgrimesset_map(map, list, flag) 3151590Srgrimes rune_map *map; 3161590Srgrimes rune_list *list; 317142582Sru uint32_t flag; 3181590Srgrimes{ 3191590Srgrimes while (list) { 3201590Srgrimes rune_list *nlist = list->next; 3211590Srgrimes add_map(map, list, flag); 3221590Srgrimes list = nlist; 3231590Srgrimes } 3241590Srgrimes} 3251590Srgrimes 3261590Srgrimesvoid 3271590Srgrimesset_digitmap(map, list) 3281590Srgrimes rune_map *map; 3291590Srgrimes rune_list *list; 3301590Srgrimes{ 331142582Sru int32_t i; 3321590Srgrimes 3331590Srgrimes while (list) { 3341590Srgrimes rune_list *nlist = list->next; 3351590Srgrimes for (i = list->min; i <= list->max; ++i) { 3361590Srgrimes if (list->map + (i - list->min)) { 3371590Srgrimes rune_list *tmp = (rune_list *)xmalloc(sizeof(rune_list)); 3381590Srgrimes tmp->min = i; 3391590Srgrimes tmp->max = i; 3401590Srgrimes add_map(map, tmp, list->map + (i - list->min)); 3411590Srgrimes } 3421590Srgrimes } 3431590Srgrimes free(list); 3441590Srgrimes list = nlist; 3451590Srgrimes } 3461590Srgrimes} 3471590Srgrimes 3481590Srgrimesvoid 3491590Srgrimesadd_map(map, list, flag) 3501590Srgrimes rune_map *map; 3511590Srgrimes rune_list *list; 352142582Sru uint32_t flag; 3531590Srgrimes{ 354142582Sru int32_t i; 3551590Srgrimes rune_list *lr = 0; 3561590Srgrimes rune_list *r; 357142582Sru int32_t run; 3581590Srgrimes 3591590Srgrimes while (list->min < _CACHED_RUNES && list->min <= list->max) { 3601590Srgrimes if (flag) 3611590Srgrimes map->map[list->min++] |= flag; 3621590Srgrimes else 3631590Srgrimes map->map[list->min++] = list->map++; 3641590Srgrimes } 3651590Srgrimes 3661590Srgrimes if (list->min > list->max) { 3671590Srgrimes free(list); 3681590Srgrimes return; 3691590Srgrimes } 3701590Srgrimes 3711590Srgrimes run = list->max - list->min + 1; 3721590Srgrimes 3731590Srgrimes if (!(r = map->root) || (list->max < r->min - 1) 3741590Srgrimes || (!flag && list->max == r->min - 1)) { 3751590Srgrimes if (flag) { 3761590Srgrimes list->types = xlalloc(run); 3771590Srgrimes for (i = 0; i < run; ++i) 3781590Srgrimes list->types[i] = flag; 3791590Srgrimes } 3801590Srgrimes list->next = map->root; 3811590Srgrimes map->root = list; 3821590Srgrimes return; 3831590Srgrimes } 3841590Srgrimes 3851590Srgrimes for (r = map->root; r && r->max + 1 < list->min; r = r->next) 3861590Srgrimes lr = r; 3871590Srgrimes 3881590Srgrimes if (!r) { 3891590Srgrimes /* 3901590Srgrimes * We are off the end. 3911590Srgrimes */ 3921590Srgrimes if (flag) { 3931590Srgrimes list->types = xlalloc(run); 3941590Srgrimes for (i = 0; i < run; ++i) 3951590Srgrimes list->types[i] = flag; 3961590Srgrimes } 3971590Srgrimes list->next = 0; 3981590Srgrimes lr->next = list; 3991590Srgrimes return; 4001590Srgrimes } 4011590Srgrimes 4021590Srgrimes if (list->max < r->min - 1) { 4031590Srgrimes /* 4041590Srgrimes * We come before this range and we do not intersect it. 4051590Srgrimes * We are not before the root node, it was checked before the loop 4061590Srgrimes */ 4071590Srgrimes if (flag) { 4081590Srgrimes list->types = xlalloc(run); 4091590Srgrimes for (i = 0; i < run; ++i) 4101590Srgrimes list->types[i] = flag; 4111590Srgrimes } 4121590Srgrimes list->next = lr->next; 4131590Srgrimes lr->next = list; 4141590Srgrimes return; 4151590Srgrimes } 4161590Srgrimes 4171590Srgrimes /* 4181590Srgrimes * At this point we have found that we at least intersect with 4191590Srgrimes * the range pointed to by `r', we might intersect with one or 4201590Srgrimes * more ranges beyond `r' as well. 4211590Srgrimes */ 4221590Srgrimes 4231590Srgrimes if (!flag && list->map - list->min != r->map - r->min) { 4241590Srgrimes /* 4251590Srgrimes * There are only two cases when we are doing case maps and 4261590Srgrimes * our maps needn't have the same offset. When we are adjoining 4271590Srgrimes * but not intersecting. 4281590Srgrimes */ 4291590Srgrimes if (list->max + 1 == r->min) { 4301590Srgrimes lr->next = list; 4311590Srgrimes list->next = r; 4321590Srgrimes return; 4331590Srgrimes } 4341590Srgrimes if (list->min - 1 == r->max) { 4351590Srgrimes list->next = r->next; 4361590Srgrimes r->next = list; 4371590Srgrimes return; 4381590Srgrimes } 439116502Scharnier errx(1, "error: conflicting map entries"); 4401590Srgrimes } 4411590Srgrimes 4421590Srgrimes if (list->min >= r->min && list->max <= r->max) { 4431590Srgrimes /* 4441590Srgrimes * Subset case. 4451590Srgrimes */ 4461590Srgrimes 4471590Srgrimes if (flag) { 4481590Srgrimes for (i = list->min; i <= list->max; ++i) 4491590Srgrimes r->types[i - r->min] |= flag; 4501590Srgrimes } 4511590Srgrimes free(list); 4521590Srgrimes return; 4531590Srgrimes } 4541590Srgrimes if (list->min <= r->min && list->max >= r->max) { 4551590Srgrimes /* 4561590Srgrimes * Superset case. Make him big enough to hold us. 4571590Srgrimes * We might need to merge with the guy after him. 4581590Srgrimes */ 4591590Srgrimes if (flag) { 4601590Srgrimes list->types = xlalloc(list->max - list->min + 1); 4611590Srgrimes 4621590Srgrimes for (i = list->min; i <= list->max; ++i) 4631590Srgrimes list->types[i - list->min] = flag; 4641590Srgrimes 4651590Srgrimes for (i = r->min; i <= r->max; ++i) 4661590Srgrimes list->types[i - list->min] |= r->types[i - r->min]; 4671590Srgrimes 4681590Srgrimes free(r->types); 4691590Srgrimes r->types = list->types; 4701590Srgrimes } else { 4711590Srgrimes r->map = list->map; 4721590Srgrimes } 4731590Srgrimes r->min = list->min; 4741590Srgrimes r->max = list->max; 4751590Srgrimes free(list); 4761590Srgrimes } else if (list->min < r->min) { 4771590Srgrimes /* 4781590Srgrimes * Our tail intersects his head. 4791590Srgrimes */ 4801590Srgrimes if (flag) { 4811590Srgrimes list->types = xlalloc(r->max - list->min + 1); 4821590Srgrimes 4831590Srgrimes for (i = r->min; i <= r->max; ++i) 4841590Srgrimes list->types[i - list->min] = r->types[i - r->min]; 4851590Srgrimes 4861590Srgrimes for (i = list->min; i < r->min; ++i) 4871590Srgrimes list->types[i - list->min] = flag; 4881590Srgrimes 4891590Srgrimes for (i = r->min; i <= list->max; ++i) 4901590Srgrimes list->types[i - list->min] |= flag; 4911590Srgrimes 4921590Srgrimes free(r->types); 4931590Srgrimes r->types = list->types; 4941590Srgrimes } else { 4951590Srgrimes r->map = list->map; 4961590Srgrimes } 4971590Srgrimes r->min = list->min; 4981590Srgrimes free(list); 4991590Srgrimes return; 5001590Srgrimes } else { 5011590Srgrimes /* 5021590Srgrimes * Our head intersects his tail. 5031590Srgrimes * We might need to merge with the guy after him. 5041590Srgrimes */ 5051590Srgrimes if (flag) { 5061590Srgrimes r->types = xrelalloc(r->types, list->max - r->min + 1); 5071590Srgrimes 5081590Srgrimes for (i = list->min; i <= r->max; ++i) 5091590Srgrimes r->types[i - r->min] |= flag; 5101590Srgrimes 5111590Srgrimes for (i = r->max+1; i <= list->max; ++i) 5121590Srgrimes r->types[i - r->min] = flag; 5131590Srgrimes } 51421393Sache r->max = list->max; 5151590Srgrimes free(list); 5161590Srgrimes } 5171590Srgrimes 5181590Srgrimes /* 5191590Srgrimes * Okay, check to see if we grew into the next guy(s) 5201590Srgrimes */ 5211590Srgrimes while ((lr = r->next) && r->max >= lr->min) { 5221590Srgrimes if (flag) { 5231590Srgrimes if (r->max >= lr->max) { 5241590Srgrimes /* 5251590Srgrimes * Good, we consumed all of him. 5261590Srgrimes */ 5271590Srgrimes for (i = lr->min; i <= lr->max; ++i) 5281590Srgrimes r->types[i - r->min] |= lr->types[i - lr->min]; 5291590Srgrimes } else { 5301590Srgrimes /* 5311590Srgrimes * "append" him on to the end of us. 5321590Srgrimes */ 5331590Srgrimes r->types = xrelalloc(r->types, lr->max - r->min + 1); 5341590Srgrimes 5351590Srgrimes for (i = lr->min; i <= r->max; ++i) 5361590Srgrimes r->types[i - r->min] |= lr->types[i - lr->min]; 5371590Srgrimes 5381590Srgrimes for (i = r->max+1; i <= lr->max; ++i) 5391590Srgrimes r->types[i - r->min] = lr->types[i - lr->min]; 5401590Srgrimes 5411590Srgrimes r->max = lr->max; 5421590Srgrimes } 5431590Srgrimes } else { 5441590Srgrimes if (lr->max > r->max) 5451590Srgrimes r->max = lr->max; 5461590Srgrimes } 5471590Srgrimes 5481590Srgrimes r->next = lr->next; 5491590Srgrimes 5501590Srgrimes if (flag) 5511590Srgrimes free(lr->types); 5521590Srgrimes free(lr); 5531590Srgrimes } 5541590Srgrimes} 5551590Srgrimes 556105548Sachestatic void 5571590Srgrimesdump_tables() 5581590Srgrimes{ 559105548Sache int x, first_d, curr_d; 5601590Srgrimes rune_list *list; 5611590Srgrimes 5621590Srgrimes /* 5631590Srgrimes * See if we can compress some of the istype arrays 5641590Srgrimes */ 5651590Srgrimes for(list = types.root; list; list = list->next) { 5661590Srgrimes list->map = list->types[0]; 5671590Srgrimes for (x = 1; x < list->max - list->min + 1; ++x) { 568142582Sru if ((int32_t)list->types[x] != list->map) { 5691590Srgrimes list->map = 0; 5701590Srgrimes break; 5711590Srgrimes } 5721590Srgrimes } 5731590Srgrimes } 5741590Srgrimes 575116502Scharnier first_d = curr_d = -1; 576105548Sache for (x = 0; x < _CACHED_RUNES; ++x) { 577142582Sru uint32_t r = types.map[x]; 578105548Sache 579105548Sache if (r & _CTYPE_D) { 580105548Sache if (first_d < 0) 581105548Sache first_d = curr_d = x; 582116502Scharnier else if (x != curr_d + 1) 583116502Scharnier errx(1, "error: DIGIT range is not contiguous"); 584116502Scharnier else if (x - first_d > 9) 585116502Scharnier errx(1, "error: DIGIT range is too big"); 586116502Scharnier else 587105548Sache curr_d++; 588116502Scharnier if (!(r & _CTYPE_X)) 589116502Scharnier errx(1, 590116502Scharnier "error: DIGIT range is not a subset of XDIGIT range"); 591105548Sache } 592105548Sache } 593116502Scharnier if (first_d < 0) 594116502Scharnier errx(1, "error: no DIGIT range defined in the single byte area"); 595116502Scharnier else if (curr_d - first_d < 9) 596116502Scharnier errx(1, "error: DIGIT range is too small in the single byte area"); 597105548Sache 5981590Srgrimes /* 5991590Srgrimes * Fill in our tables. Do this in network order so that 6001590Srgrimes * diverse machines have a chance of sharing data. 6011590Srgrimes * (Machines like Crays cannot share with little machines due to 6021590Srgrimes * word size. Sigh. We tried.) 6031590Srgrimes */ 6041590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 605142582Sru new_locale.runetype[x] = htonl(types.map[x]); 606142582Sru new_locale.maplower[x] = htonl(maplower.map[x]); 607142582Sru new_locale.mapupper[x] = htonl(mapupper.map[x]); 6081590Srgrimes } 6091590Srgrimes 6101590Srgrimes /* 6111590Srgrimes * Count up how many ranges we will need for each of the extents. 6121590Srgrimes */ 6131590Srgrimes list = types.root; 6141590Srgrimes 6151590Srgrimes while (list) { 616142582Sru new_locale.runetype_ext_nranges++; 6171590Srgrimes list = list->next; 6181590Srgrimes } 619142582Sru new_locale.runetype_ext_nranges = 620142582Sru htonl(new_locale.runetype_ext_nranges); 6211590Srgrimes 6221590Srgrimes list = maplower.root; 6231590Srgrimes 6241590Srgrimes while (list) { 625142582Sru new_locale.maplower_ext_nranges++; 6261590Srgrimes list = list->next; 6271590Srgrimes } 628142582Sru new_locale.maplower_ext_nranges = 629142582Sru htonl(new_locale.maplower_ext_nranges); 6301590Srgrimes 6311590Srgrimes list = mapupper.root; 6321590Srgrimes 6331590Srgrimes while (list) { 634142582Sru new_locale.mapupper_ext_nranges++; 6351590Srgrimes list = list->next; 6361590Srgrimes } 637142582Sru new_locale.mapupper_ext_nranges = 638142582Sru htonl(new_locale.mapupper_ext_nranges); 6391590Srgrimes 640142582Sru new_locale.variable_len = htonl(new_locale.variable_len); 6411590Srgrimes 6421590Srgrimes /* 6431590Srgrimes * Okay, we are now ready to write the new locale file. 6441590Srgrimes */ 6451590Srgrimes 6461590Srgrimes /* 647142582Sru * PART 1: The _FileRuneLocale structure 6481590Srgrimes */ 6491590Srgrimes if (fwrite((char *)&new_locale, sizeof(new_locale), 1, fp) != 1) { 6501590Srgrimes perror(locale_file); 6511590Srgrimes exit(1); 6521590Srgrimes } 6531590Srgrimes /* 6541590Srgrimes * PART 2: The runetype_ext structures (not the actual tables) 6551590Srgrimes */ 6561590Srgrimes list = types.root; 6571590Srgrimes 6581590Srgrimes while (list) { 659142582Sru _FileRuneEntry re; 6601590Srgrimes 661142582Sru re.min = htonl(list->min); 662142582Sru re.max = htonl(list->max); 663142582Sru re.map = htonl(list->map); 6641590Srgrimes 6651590Srgrimes if (fwrite((char *)&re, sizeof(re), 1, fp) != 1) { 6661590Srgrimes perror(locale_file); 6671590Srgrimes exit(1); 6681590Srgrimes } 6691590Srgrimes 6701590Srgrimes list = list->next; 6711590Srgrimes } 6721590Srgrimes /* 6731590Srgrimes * PART 3: The maplower_ext structures 6741590Srgrimes */ 6751590Srgrimes list = maplower.root; 6761590Srgrimes 6771590Srgrimes while (list) { 678142582Sru _FileRuneEntry re; 6791590Srgrimes 680142582Sru re.min = htonl(list->min); 681142582Sru re.max = htonl(list->max); 682142582Sru re.map = htonl(list->map); 6831590Srgrimes 6841590Srgrimes if (fwrite((char *)&re, sizeof(re), 1, fp) != 1) { 6851590Srgrimes perror(locale_file); 6861590Srgrimes exit(1); 6871590Srgrimes } 6881590Srgrimes 6891590Srgrimes list = list->next; 6901590Srgrimes } 6911590Srgrimes /* 6921590Srgrimes * PART 4: The mapupper_ext structures 6931590Srgrimes */ 6941590Srgrimes list = mapupper.root; 6951590Srgrimes 6961590Srgrimes while (list) { 697142582Sru _FileRuneEntry re; 6981590Srgrimes 699142582Sru re.min = htonl(list->min); 700142582Sru re.max = htonl(list->max); 701142582Sru re.map = htonl(list->map); 7021590Srgrimes 7031590Srgrimes if (fwrite((char *)&re, sizeof(re), 1, fp) != 1) { 7041590Srgrimes perror(locale_file); 7051590Srgrimes exit(1); 7061590Srgrimes } 7071590Srgrimes 7081590Srgrimes list = list->next; 7091590Srgrimes } 7101590Srgrimes /* 7111590Srgrimes * PART 5: The runetype_ext tables 7121590Srgrimes */ 7131590Srgrimes list = types.root; 7141590Srgrimes 7151590Srgrimes while (list) { 7161590Srgrimes for (x = 0; x < list->max - list->min + 1; ++x) 7171590Srgrimes list->types[x] = htonl(list->types[x]); 7181590Srgrimes 7191590Srgrimes if (!list->map) { 72021393Sache if (fwrite((char *)list->types, 721142582Sru (list->max - list->min + 1) * sizeof(uint32_t), 7222509Sbde 1, fp) != 1) { 7231590Srgrimes perror(locale_file); 7241590Srgrimes exit(1); 7251590Srgrimes } 7261590Srgrimes } 7271590Srgrimes list = list->next; 7281590Srgrimes } 7291590Srgrimes /* 730142582Sru * PART 6: And finally the variable data 7311590Srgrimes */ 732142582Sru if (fwrite(variable, 733142582Sru ntohl(new_locale.variable_len), 1, fp) != 1) { 7341590Srgrimes perror(locale_file); 7351590Srgrimes exit(1); 7361590Srgrimes } 737105548Sache if (fclose(fp) != 0) { 738105548Sache perror(locale_file); 739105548Sache exit(1); 740105548Sache } 741105548Sache fp = NULL; 7421590Srgrimes 7431590Srgrimes if (!debug) 7441590Srgrimes return; 7451590Srgrimes 746142582Sru if (new_locale.encoding[0]) 747142582Sru fprintf(stderr, "ENCODING %s\n", new_locale.encoding); 748142582Sru if (variable) 749142582Sru fprintf(stderr, "VARIABLE %s\n", variable); 7501590Srgrimes 7511590Srgrimes fprintf(stderr, "\nMAPLOWER:\n\n"); 7521590Srgrimes 7531590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 7541590Srgrimes if (isprint(maplower.map[x])) 75538022Sbde fprintf(stderr, " '%c'", (int)maplower.map[x]); 7561590Srgrimes else if (maplower.map[x]) 757142582Sru fprintf(stderr, "%04x", maplower.map[x]); 7581590Srgrimes else 7591590Srgrimes fprintf(stderr, "%4x", 0); 7601590Srgrimes if ((x & 0xf) == 0xf) 7611590Srgrimes fprintf(stderr, "\n"); 7621590Srgrimes else 7631590Srgrimes fprintf(stderr, " "); 7641590Srgrimes } 7651590Srgrimes fprintf(stderr, "\n"); 7661590Srgrimes 7671590Srgrimes for (list = maplower.root; list; list = list->next) 7681590Srgrimes fprintf(stderr, "\t%04x - %04x : %04x\n", list->min, list->max, list->map); 7691590Srgrimes 7701590Srgrimes fprintf(stderr, "\nMAPUPPER:\n\n"); 7711590Srgrimes 7721590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 7731590Srgrimes if (isprint(mapupper.map[x])) 77438022Sbde fprintf(stderr, " '%c'", (int)mapupper.map[x]); 7751590Srgrimes else if (mapupper.map[x]) 776142582Sru fprintf(stderr, "%04x", mapupper.map[x]); 7771590Srgrimes else 7781590Srgrimes fprintf(stderr, "%4x", 0); 7791590Srgrimes if ((x & 0xf) == 0xf) 7801590Srgrimes fprintf(stderr, "\n"); 7811590Srgrimes else 7821590Srgrimes fprintf(stderr, " "); 7831590Srgrimes } 7841590Srgrimes fprintf(stderr, "\n"); 7851590Srgrimes 7861590Srgrimes for (list = mapupper.root; list; list = list->next) 7871590Srgrimes fprintf(stderr, "\t%04x - %04x : %04x\n", list->min, list->max, list->map); 7881590Srgrimes 7891590Srgrimes 7901590Srgrimes fprintf(stderr, "\nTYPES:\n\n"); 7911590Srgrimes 7921590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 793142582Sru uint32_t r = types.map[x]; 7941590Srgrimes 7951590Srgrimes if (r) { 7961590Srgrimes if (isprint(x)) 79738022Sbde fprintf(stderr, " '%c': %2d", x, (int)(r & 0xff)); 7981590Srgrimes else 79938022Sbde fprintf(stderr, "%04x: %2d", x, (int)(r & 0xff)); 8001590Srgrimes 80157035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_A) ? "alph" : ""); 80257035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_C) ? "ctrl" : ""); 80357035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_D) ? "dig" : ""); 80457035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_G) ? "graf" : ""); 80557035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_L) ? "low" : ""); 80657035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_P) ? "punc" : ""); 80757035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_S) ? "spac" : ""); 80857035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_U) ? "upp" : ""); 80957035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_X) ? "xdig" : ""); 81057035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_B) ? "blnk" : ""); 81157035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_R) ? "prnt" : ""); 81257035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_I) ? "ideo" : ""); 81357035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_T) ? "spec" : ""); 81457035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_Q) ? "phon" : ""); 8151590Srgrimes fprintf(stderr, "\n"); 8161590Srgrimes } 8171590Srgrimes } 8181590Srgrimes 8191590Srgrimes for (list = types.root; list; list = list->next) { 8201590Srgrimes if (list->map && list->min + 3 < list->max) { 821142582Sru uint32_t r = list->map; 8221590Srgrimes 823142582Sru fprintf(stderr, "%04x: %2d", 824142582Sru (uint32_t)list->min, (int)(r & 0xff)); 8251590Srgrimes 82657035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_A) ? "alph" : ""); 82757035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_C) ? "ctrl" : ""); 82857035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_D) ? "dig" : ""); 82957035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_G) ? "graf" : ""); 83057035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_L) ? "low" : ""); 83157035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_P) ? "punc" : ""); 83257035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_S) ? "spac" : ""); 83357035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_U) ? "upp" : ""); 83457035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_X) ? "xdig" : ""); 83557035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_B) ? "blnk" : ""); 83657035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_R) ? "prnt" : ""); 83757035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_I) ? "ideo" : ""); 83857035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_T) ? "spec" : ""); 83957035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_Q) ? "phon" : ""); 8401590Srgrimes fprintf(stderr, "\n...\n"); 8411590Srgrimes 842142582Sru fprintf(stderr, "%04x: %2d", 843142582Sru (uint32_t)list->max, (int)(r & 0xff)); 8441590Srgrimes 84557035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_A) ? "alph" : ""); 84657035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_C) ? "ctrl" : ""); 84757035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_D) ? "dig" : ""); 84857035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_G) ? "graf" : ""); 84957035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_L) ? "low" : ""); 85057035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_P) ? "punc" : ""); 85157035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_S) ? "spac" : ""); 85257035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_U) ? "upp" : ""); 85357035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_X) ? "xdig" : ""); 85457035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_B) ? "blnk" : ""); 85557035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_R) ? "prnt" : ""); 85657035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_I) ? "ideo" : ""); 85757035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_T) ? "spec" : ""); 85857035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_Q) ? "phon" : ""); 8591590Srgrimes fprintf(stderr, "\n"); 8601590Srgrimes } else 8611590Srgrimes for (x = list->min; x <= list->max; ++x) { 862142582Sru uint32_t r = ntohl(list->types[x - list->min]); 8631590Srgrimes 8641590Srgrimes if (r) { 86538022Sbde fprintf(stderr, "%04x: %2d", x, (int)(r & 0xff)); 8661590Srgrimes 86757035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_A) ? "alph" : ""); 86857035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_C) ? "ctrl" : ""); 86957035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_D) ? "dig" : ""); 87057035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_G) ? "graf" : ""); 87157035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_L) ? "low" : ""); 87257035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_P) ? "punc" : ""); 87357035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_S) ? "spac" : ""); 87457035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_U) ? "upp" : ""); 87557035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_X) ? "xdig" : ""); 87657035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_B) ? "blnk" : ""); 87757035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_R) ? "prnt" : ""); 87857035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_I) ? "ideo" : ""); 87957035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_T) ? "spec" : ""); 88057035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_Q) ? "phon" : ""); 8811590Srgrimes fprintf(stderr, "\n"); 8821590Srgrimes } 8831590Srgrimes } 8841590Srgrimes } 8851590Srgrimes} 886