yacc.y revision 115722
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 115722 2003-06-02 19:54:29Z ache $"); 4695643Smarkm 4790868Smike#include <arpa/inet.h> 4890868Smike 491590Srgrimes#include <ctype.h> 50108158Stjr#include <err.h> 511590Srgrimes#include <rune.h> 521590Srgrimes#include <stddef.h> 531590Srgrimes#include <stdio.h> 541590Srgrimes#include <stdlib.h> 5533648Sjb#include <string.h> 5695643Smarkm#include <unistd.h> 571590Srgrimes 581590Srgrimes#include "ldef.h" 5995643Smarkm#include "extern.h" 601590Srgrimes 6195643Smarkmstatic void *xmalloc(unsigned int sz); 6295643Smarkmstatic unsigned long *xlalloc(unsigned int sz); 63105548Sachevoid yyerror(const char *s); 6495643Smarkmstatic unsigned long *xrelalloc(unsigned long *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 7495643Smarkm_RuneLocale new_locale = { "", "", NULL, NULL, 0, {}, {}, {}, 7595643Smarkm {0, NULL}, {0, NULL}, {0, NULL}, NULL, 0 }; 7695643Smarkm 7799982Salfredvoid set_map(rune_map *, rune_list *, unsigned long); 7899982Salfredvoid set_digitmap(rune_map *, rune_list *); 7999982Salfredvoid add_map(rune_map *, rune_list *, unsigned long); 801590Srgrimes%} 811590Srgrimes 821590Srgrimes%union { 831590Srgrimes rune_t rune; 841590Srgrimes int i; 851590Srgrimes char *str; 861590Srgrimes 871590Srgrimes rune_list *list; 881590Srgrimes} 891590Srgrimes 901590Srgrimes%token <rune> RUNE 911590Srgrimes%token LBRK 921590Srgrimes%token RBRK 931590Srgrimes%token THRU 941590Srgrimes%token MAPLOWER 951590Srgrimes%token MAPUPPER 961590Srgrimes%token DIGITMAP 971590Srgrimes%token <i> LIST 981590Srgrimes%token <str> VARIABLE 991590Srgrimes%token ENCODING 1001590Srgrimes%token INVALID 1011590Srgrimes%token <str> STRING 1021590Srgrimes 1031590Srgrimes%type <list> list 1041590Srgrimes%type <list> map 1051590Srgrimes 1061590Srgrimes 1071590Srgrimes%% 1081590Srgrimes 1091590Srgrimeslocale : /* empty */ 1101590Srgrimes | table 1111590Srgrimes { dump_tables(); } 1121590Srgrimes ; 1131590Srgrimes 1141590Srgrimestable : entry 1151590Srgrimes | table entry 1161590Srgrimes ; 1171590Srgrimes 1181590Srgrimesentry : ENCODING STRING 119115722Sache { if (strcmp($2, "NONE") && 120115722Sache strcmp($2, "UTF2") && 121115722Sache strcmp($2, "UTF-8") && 122115722Sache strcmp($2, "EUC") && 123115722Sache strcmp($2, "GBK") && 124115722Sache strcmp($2, "BIG5") && 125115722Sache strcmp($2, "MSKanji")) { 126115722Sache fprintf(stderr, "ENCODING %s is not supported by libc\n", $2); 127115722Sache exit(1); 128115722Sache } 129115722Sache strncpy(new_locale.encoding, $2, sizeof(new_locale.encoding)); } 1301590Srgrimes | VARIABLE 1311590Srgrimes { new_locale.variable_len = strlen($1) + 1; 1321590Srgrimes new_locale.variable = malloc(new_locale.variable_len); 1331590Srgrimes strcpy((char *)new_locale.variable, $1); 1341590Srgrimes } 1351590Srgrimes | INVALID RUNE 136108158Stjr { warnx("the INVALID keyword is deprecated"); 137108158Stjr new_locale.invalid_rune = $2; 138108158Stjr } 1391590Srgrimes | LIST list 1401590Srgrimes { set_map(&types, $2, $1); } 1411590Srgrimes | MAPLOWER map 1421590Srgrimes { set_map(&maplower, $2, 0); } 1431590Srgrimes | MAPUPPER map 1441590Srgrimes { set_map(&mapupper, $2, 0); } 1451590Srgrimes | DIGITMAP map 1461590Srgrimes { set_digitmap(&types, $2); } 1471590Srgrimes ; 1481590Srgrimes 1491590Srgrimeslist : RUNE 1501590Srgrimes { 1511590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1521590Srgrimes $$->min = $1; 1531590Srgrimes $$->max = $1; 1541590Srgrimes $$->next = 0; 1551590Srgrimes } 1561590Srgrimes | RUNE THRU RUNE 1571590Srgrimes { 1581590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1591590Srgrimes $$->min = $1; 1601590Srgrimes $$->max = $3; 1611590Srgrimes $$->next = 0; 1621590Srgrimes } 1631590Srgrimes | list RUNE 1641590Srgrimes { 1651590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1661590Srgrimes $$->min = $2; 1671590Srgrimes $$->max = $2; 1681590Srgrimes $$->next = $1; 1691590Srgrimes } 1701590Srgrimes | list RUNE THRU RUNE 1711590Srgrimes { 1721590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1731590Srgrimes $$->min = $2; 1741590Srgrimes $$->max = $4; 1751590Srgrimes $$->next = $1; 1761590Srgrimes } 1771590Srgrimes ; 1781590Srgrimes 1791590Srgrimesmap : LBRK RUNE RUNE RBRK 1801590Srgrimes { 1811590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1821590Srgrimes $$->min = $2; 1831590Srgrimes $$->max = $2; 1841590Srgrimes $$->map = $3; 1851590Srgrimes $$->next = 0; 1861590Srgrimes } 1871590Srgrimes | map LBRK RUNE RUNE RBRK 1881590Srgrimes { 1891590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1901590Srgrimes $$->min = $3; 1911590Srgrimes $$->max = $3; 1921590Srgrimes $$->map = $4; 1931590Srgrimes $$->next = $1; 1941590Srgrimes } 1951590Srgrimes | LBRK RUNE THRU RUNE ':' RUNE RBRK 1961590Srgrimes { 1971590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 1981590Srgrimes $$->min = $2; 1991590Srgrimes $$->max = $4; 2001590Srgrimes $$->map = $6; 2011590Srgrimes $$->next = 0; 2021590Srgrimes } 2031590Srgrimes | map LBRK RUNE THRU RUNE ':' RUNE RBRK 2041590Srgrimes { 2051590Srgrimes $$ = (rune_list *)malloc(sizeof(rune_list)); 2061590Srgrimes $$->min = $3; 2071590Srgrimes $$->max = $5; 2081590Srgrimes $$->map = $7; 2091590Srgrimes $$->next = $1; 2101590Srgrimes } 2111590Srgrimes ; 2121590Srgrimes%% 2131590Srgrimes 214105548Sacheint debug; 21581606SpeterFILE *fp; 2161590Srgrimes 217105548Sachestatic void 218105548Sachecleanout(void) 219105548Sache{ 220105548Sache if (fp != NULL) 221105548Sache unlink(locale_file); 222105548Sache} 223105548Sache 22495643Smarkmint 22599984Salfredmain(int ac, char *av[]) 2261590Srgrimes{ 2271590Srgrimes int x; 2281590Srgrimes 2291590Srgrimes extern char *optarg; 2301590Srgrimes extern int optind; 23181606Speter fp = stdout; 2321590Srgrimes 2331590Srgrimes while ((x = getopt(ac, av, "do:")) != EOF) { 2341590Srgrimes switch(x) { 2351590Srgrimes case 'd': 2361590Srgrimes debug = 1; 2371590Srgrimes break; 2381590Srgrimes case 'o': 2391590Srgrimes locale_file = optarg; 2401590Srgrimes if ((fp = fopen(locale_file, "w")) == 0) { 2411590Srgrimes perror(locale_file); 2421590Srgrimes exit(1); 2431590Srgrimes } 244105548Sache atexit(cleanout); 2451590Srgrimes break; 2461590Srgrimes default: 2471590Srgrimes usage: 24895258Sdes fprintf(stderr, "usage: mklocale [-d] [-o output] [source]\n"); 2491590Srgrimes exit(1); 2501590Srgrimes } 2511590Srgrimes } 2521590Srgrimes 2531590Srgrimes switch (ac - optind) { 2541590Srgrimes case 0: 2551590Srgrimes break; 2561590Srgrimes case 1: 2571590Srgrimes if (freopen(av[optind], "r", stdin) == 0) { 2581590Srgrimes perror(av[optind]); 2591590Srgrimes exit(1); 2601590Srgrimes } 2611590Srgrimes break; 2621590Srgrimes default: 2631590Srgrimes goto usage; 2641590Srgrimes } 2651590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 2661590Srgrimes mapupper.map[x] = x; 2671590Srgrimes maplower.map[x] = x; 2681590Srgrimes } 2691590Srgrimes new_locale.invalid_rune = _INVALID_RUNE; 2701590Srgrimes memcpy(new_locale.magic, _RUNE_MAGIC_1, sizeof(new_locale.magic)); 2711590Srgrimes 2721590Srgrimes yyparse(); 27395643Smarkm 27495643Smarkm return(0); 2751590Srgrimes} 2761590Srgrimes 27795643Smarkmvoid 2781590Srgrimesyyerror(s) 27995643Smarkm const char *s; 2801590Srgrimes{ 2811590Srgrimes fprintf(stderr, "%s\n", s); 2821590Srgrimes} 2831590Srgrimes 284105548Sachestatic void * 2851590Srgrimesxmalloc(sz) 2861590Srgrimes unsigned int sz; 2871590Srgrimes{ 2881590Srgrimes void *r = malloc(sz); 2891590Srgrimes if (!r) { 2901590Srgrimes perror("xmalloc"); 291105548Sache exit(1); 2921590Srgrimes } 2931590Srgrimes return(r); 2941590Srgrimes} 2951590Srgrimes 296105548Sachestatic unsigned long * 2971590Srgrimesxlalloc(sz) 2981590Srgrimes unsigned int sz; 2991590Srgrimes{ 3002509Sbde unsigned long *r = (unsigned long *)malloc(sz * sizeof(unsigned long)); 3011590Srgrimes if (!r) { 3021590Srgrimes perror("xlalloc"); 303105548Sache exit(1); 3041590Srgrimes } 3051590Srgrimes return(r); 3061590Srgrimes} 3071590Srgrimes 308105548Sachestatic unsigned long * 3091590Srgrimesxrelalloc(old, sz) 3102509Sbde unsigned long *old; 3111590Srgrimes unsigned int sz; 3121590Srgrimes{ 3132509Sbde unsigned long *r = (unsigned long *)realloc((char *)old, 3142509Sbde sz * sizeof(unsigned long)); 3151590Srgrimes if (!r) { 3161590Srgrimes perror("xrelalloc"); 317105548Sache exit(1); 3181590Srgrimes } 3191590Srgrimes return(r); 3201590Srgrimes} 3211590Srgrimes 3221590Srgrimesvoid 3231590Srgrimesset_map(map, list, flag) 3241590Srgrimes rune_map *map; 3251590Srgrimes rune_list *list; 3262509Sbde unsigned long flag; 3271590Srgrimes{ 3281590Srgrimes while (list) { 3291590Srgrimes rune_list *nlist = list->next; 3301590Srgrimes add_map(map, list, flag); 3311590Srgrimes list = nlist; 3321590Srgrimes } 3331590Srgrimes} 3341590Srgrimes 3351590Srgrimesvoid 3361590Srgrimesset_digitmap(map, list) 3371590Srgrimes rune_map *map; 3381590Srgrimes rune_list *list; 3391590Srgrimes{ 3401590Srgrimes rune_t i; 3411590Srgrimes 3421590Srgrimes while (list) { 3431590Srgrimes rune_list *nlist = list->next; 3441590Srgrimes for (i = list->min; i <= list->max; ++i) { 3451590Srgrimes if (list->map + (i - list->min)) { 3461590Srgrimes rune_list *tmp = (rune_list *)xmalloc(sizeof(rune_list)); 3471590Srgrimes tmp->min = i; 3481590Srgrimes tmp->max = i; 3491590Srgrimes add_map(map, tmp, list->map + (i - list->min)); 3501590Srgrimes } 3511590Srgrimes } 3521590Srgrimes free(list); 3531590Srgrimes list = nlist; 3541590Srgrimes } 3551590Srgrimes} 3561590Srgrimes 3571590Srgrimesvoid 3581590Srgrimesadd_map(map, list, flag) 3591590Srgrimes rune_map *map; 3601590Srgrimes rune_list *list; 3612509Sbde unsigned long flag; 3621590Srgrimes{ 3631590Srgrimes rune_t i; 3641590Srgrimes rune_list *lr = 0; 3651590Srgrimes rune_list *r; 3661590Srgrimes rune_t run; 3671590Srgrimes 3681590Srgrimes while (list->min < _CACHED_RUNES && list->min <= list->max) { 3691590Srgrimes if (flag) 3701590Srgrimes map->map[list->min++] |= flag; 3711590Srgrimes else 3721590Srgrimes map->map[list->min++] = list->map++; 3731590Srgrimes } 3741590Srgrimes 3751590Srgrimes if (list->min > list->max) { 3761590Srgrimes free(list); 3771590Srgrimes return; 3781590Srgrimes } 3791590Srgrimes 3801590Srgrimes run = list->max - list->min + 1; 3811590Srgrimes 3821590Srgrimes if (!(r = map->root) || (list->max < r->min - 1) 3831590Srgrimes || (!flag && list->max == r->min - 1)) { 3841590Srgrimes if (flag) { 3851590Srgrimes list->types = xlalloc(run); 3861590Srgrimes for (i = 0; i < run; ++i) 3871590Srgrimes list->types[i] = flag; 3881590Srgrimes } 3891590Srgrimes list->next = map->root; 3901590Srgrimes map->root = list; 3911590Srgrimes return; 3921590Srgrimes } 3931590Srgrimes 3941590Srgrimes for (r = map->root; r && r->max + 1 < list->min; r = r->next) 3951590Srgrimes lr = r; 3961590Srgrimes 3971590Srgrimes if (!r) { 3981590Srgrimes /* 3991590Srgrimes * We are off the end. 4001590Srgrimes */ 4011590Srgrimes if (flag) { 4021590Srgrimes list->types = xlalloc(run); 4031590Srgrimes for (i = 0; i < run; ++i) 4041590Srgrimes list->types[i] = flag; 4051590Srgrimes } 4061590Srgrimes list->next = 0; 4071590Srgrimes lr->next = list; 4081590Srgrimes return; 4091590Srgrimes } 4101590Srgrimes 4111590Srgrimes if (list->max < r->min - 1) { 4121590Srgrimes /* 4131590Srgrimes * We come before this range and we do not intersect it. 4141590Srgrimes * We are not before the root node, it was checked before the loop 4151590Srgrimes */ 4161590Srgrimes if (flag) { 4171590Srgrimes list->types = xlalloc(run); 4181590Srgrimes for (i = 0; i < run; ++i) 4191590Srgrimes list->types[i] = flag; 4201590Srgrimes } 4211590Srgrimes list->next = lr->next; 4221590Srgrimes lr->next = list; 4231590Srgrimes return; 4241590Srgrimes } 4251590Srgrimes 4261590Srgrimes /* 4271590Srgrimes * At this point we have found that we at least intersect with 4281590Srgrimes * the range pointed to by `r', we might intersect with one or 4291590Srgrimes * more ranges beyond `r' as well. 4301590Srgrimes */ 4311590Srgrimes 4321590Srgrimes if (!flag && list->map - list->min != r->map - r->min) { 4331590Srgrimes /* 4341590Srgrimes * There are only two cases when we are doing case maps and 4351590Srgrimes * our maps needn't have the same offset. When we are adjoining 4361590Srgrimes * but not intersecting. 4371590Srgrimes */ 4381590Srgrimes if (list->max + 1 == r->min) { 4391590Srgrimes lr->next = list; 4401590Srgrimes list->next = r; 4411590Srgrimes return; 4421590Srgrimes } 4431590Srgrimes if (list->min - 1 == r->max) { 4441590Srgrimes list->next = r->next; 4451590Srgrimes r->next = list; 4461590Srgrimes return; 4471590Srgrimes } 4481590Srgrimes fprintf(stderr, "Error: conflicting map entries\n"); 4491590Srgrimes exit(1); 4501590Srgrimes } 4511590Srgrimes 4521590Srgrimes if (list->min >= r->min && list->max <= r->max) { 4531590Srgrimes /* 4541590Srgrimes * Subset case. 4551590Srgrimes */ 4561590Srgrimes 4571590Srgrimes if (flag) { 4581590Srgrimes for (i = list->min; i <= list->max; ++i) 4591590Srgrimes r->types[i - r->min] |= flag; 4601590Srgrimes } 4611590Srgrimes free(list); 4621590Srgrimes return; 4631590Srgrimes } 4641590Srgrimes if (list->min <= r->min && list->max >= r->max) { 4651590Srgrimes /* 4661590Srgrimes * Superset case. Make him big enough to hold us. 4671590Srgrimes * We might need to merge with the guy after him. 4681590Srgrimes */ 4691590Srgrimes if (flag) { 4701590Srgrimes list->types = xlalloc(list->max - list->min + 1); 4711590Srgrimes 4721590Srgrimes for (i = list->min; i <= list->max; ++i) 4731590Srgrimes list->types[i - list->min] = flag; 4741590Srgrimes 4751590Srgrimes for (i = r->min; i <= r->max; ++i) 4761590Srgrimes list->types[i - list->min] |= r->types[i - r->min]; 4771590Srgrimes 4781590Srgrimes free(r->types); 4791590Srgrimes r->types = list->types; 4801590Srgrimes } else { 4811590Srgrimes r->map = list->map; 4821590Srgrimes } 4831590Srgrimes r->min = list->min; 4841590Srgrimes r->max = list->max; 4851590Srgrimes free(list); 4861590Srgrimes } else if (list->min < r->min) { 4871590Srgrimes /* 4881590Srgrimes * Our tail intersects his head. 4891590Srgrimes */ 4901590Srgrimes if (flag) { 4911590Srgrimes list->types = xlalloc(r->max - list->min + 1); 4921590Srgrimes 4931590Srgrimes for (i = r->min; i <= r->max; ++i) 4941590Srgrimes list->types[i - list->min] = r->types[i - r->min]; 4951590Srgrimes 4961590Srgrimes for (i = list->min; i < r->min; ++i) 4971590Srgrimes list->types[i - list->min] = flag; 4981590Srgrimes 4991590Srgrimes for (i = r->min; i <= list->max; ++i) 5001590Srgrimes list->types[i - list->min] |= flag; 5011590Srgrimes 5021590Srgrimes free(r->types); 5031590Srgrimes r->types = list->types; 5041590Srgrimes } else { 5051590Srgrimes r->map = list->map; 5061590Srgrimes } 5071590Srgrimes r->min = list->min; 5081590Srgrimes free(list); 5091590Srgrimes return; 5101590Srgrimes } else { 5111590Srgrimes /* 5121590Srgrimes * Our head intersects his tail. 5131590Srgrimes * We might need to merge with the guy after him. 5141590Srgrimes */ 5151590Srgrimes if (flag) { 5161590Srgrimes r->types = xrelalloc(r->types, list->max - r->min + 1); 5171590Srgrimes 5181590Srgrimes for (i = list->min; i <= r->max; ++i) 5191590Srgrimes r->types[i - r->min] |= flag; 5201590Srgrimes 5211590Srgrimes for (i = r->max+1; i <= list->max; ++i) 5221590Srgrimes r->types[i - r->min] = flag; 5231590Srgrimes } 52421393Sache r->max = list->max; 5251590Srgrimes free(list); 5261590Srgrimes } 5271590Srgrimes 5281590Srgrimes /* 5291590Srgrimes * Okay, check to see if we grew into the next guy(s) 5301590Srgrimes */ 5311590Srgrimes while ((lr = r->next) && r->max >= lr->min) { 5321590Srgrimes if (flag) { 5331590Srgrimes if (r->max >= lr->max) { 5341590Srgrimes /* 5351590Srgrimes * Good, we consumed all of him. 5361590Srgrimes */ 5371590Srgrimes for (i = lr->min; i <= lr->max; ++i) 5381590Srgrimes r->types[i - r->min] |= lr->types[i - lr->min]; 5391590Srgrimes } else { 5401590Srgrimes /* 5411590Srgrimes * "append" him on to the end of us. 5421590Srgrimes */ 5431590Srgrimes r->types = xrelalloc(r->types, lr->max - r->min + 1); 5441590Srgrimes 5451590Srgrimes for (i = lr->min; i <= r->max; ++i) 5461590Srgrimes r->types[i - r->min] |= lr->types[i - lr->min]; 5471590Srgrimes 5481590Srgrimes for (i = r->max+1; i <= lr->max; ++i) 5491590Srgrimes r->types[i - r->min] = lr->types[i - lr->min]; 5501590Srgrimes 5511590Srgrimes r->max = lr->max; 5521590Srgrimes } 5531590Srgrimes } else { 5541590Srgrimes if (lr->max > r->max) 5551590Srgrimes r->max = lr->max; 5561590Srgrimes } 5571590Srgrimes 5581590Srgrimes r->next = lr->next; 5591590Srgrimes 5601590Srgrimes if (flag) 5611590Srgrimes free(lr->types); 5621590Srgrimes free(lr); 5631590Srgrimes } 5641590Srgrimes} 5651590Srgrimes 566105548Sachestatic void 5671590Srgrimesdump_tables() 5681590Srgrimes{ 569105548Sache int x, first_d, curr_d; 5701590Srgrimes rune_list *list; 5711590Srgrimes 5721590Srgrimes /* 5731590Srgrimes * See if we can compress some of the istype arrays 5741590Srgrimes */ 5751590Srgrimes for(list = types.root; list; list = list->next) { 5761590Srgrimes list->map = list->types[0]; 5771590Srgrimes for (x = 1; x < list->max - list->min + 1; ++x) { 57895643Smarkm if ((rune_t)list->types[x] != list->map) { 5791590Srgrimes list->map = 0; 5801590Srgrimes break; 5811590Srgrimes } 5821590Srgrimes } 5831590Srgrimes } 5841590Srgrimes 585105548Sache first_d = -1; 586105548Sache for (x = 0; x < _CACHED_RUNES; ++x) { 587105548Sache unsigned long r = types.map[x]; 588105548Sache 589105548Sache if (r & _CTYPE_D) { 590105548Sache if (first_d < 0) 591105548Sache first_d = curr_d = x; 592105548Sache else if (x != curr_d + 1) { 593105589Sache fprintf(stderr, "Error: DIGIT range is not contiguous\n"); 594105548Sache exit(1); 595105548Sache } else if (x - first_d > 9) { 596105589Sache fprintf(stderr, "Error: DIGIT range is too big\n"); 597105548Sache exit(1); 598105548Sache } else 599105548Sache curr_d++; 600105548Sache if (!(r & _CTYPE_X)) { 601105589Sache fprintf(stderr, "Error: DIGIT range is not a subset of XDIGIT range\n"); 602105548Sache exit(1); 603105548Sache } 604105548Sache } 605105548Sache } 606105548Sache if (first_d < 0) { 607105589Sache fprintf(stderr, "Error: no DIGIT range defined in the single byte area\n"); 608105548Sache exit(1); 609105548Sache } else if (curr_d - first_d < 9) { 610105589Sache fprintf(stderr, "Error: DIGIT range is too small in the single byte area\n"); 611105548Sache exit(1); 612105548Sache } 613105548Sache 6141590Srgrimes new_locale.invalid_rune = htonl(new_locale.invalid_rune); 6151590Srgrimes 6161590Srgrimes /* 6171590Srgrimes * Fill in our tables. Do this in network order so that 6181590Srgrimes * diverse machines have a chance of sharing data. 6191590Srgrimes * (Machines like Crays cannot share with little machines due to 6201590Srgrimes * word size. Sigh. We tried.) 6211590Srgrimes */ 6221590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 6231590Srgrimes new_locale.runetype[x] = htonl(types.map[x]); 6241590Srgrimes new_locale.maplower[x] = htonl(maplower.map[x]); 6251590Srgrimes new_locale.mapupper[x] = htonl(mapupper.map[x]); 6261590Srgrimes } 6271590Srgrimes 6281590Srgrimes /* 6291590Srgrimes * Count up how many ranges we will need for each of the extents. 6301590Srgrimes */ 6311590Srgrimes list = types.root; 6321590Srgrimes 6331590Srgrimes while (list) { 6341590Srgrimes new_locale.runetype_ext.nranges++; 6351590Srgrimes list = list->next; 6361590Srgrimes } 6371590Srgrimes new_locale.runetype_ext.nranges = htonl(new_locale.runetype_ext.nranges); 6381590Srgrimes 6391590Srgrimes list = maplower.root; 6401590Srgrimes 6411590Srgrimes while (list) { 6421590Srgrimes new_locale.maplower_ext.nranges++; 6431590Srgrimes list = list->next; 6441590Srgrimes } 6451590Srgrimes new_locale.maplower_ext.nranges = htonl(new_locale.maplower_ext.nranges); 6461590Srgrimes 6471590Srgrimes list = mapupper.root; 6481590Srgrimes 6491590Srgrimes while (list) { 6501590Srgrimes new_locale.mapupper_ext.nranges++; 6511590Srgrimes list = list->next; 6521590Srgrimes } 6531590Srgrimes new_locale.mapupper_ext.nranges = htonl(new_locale.mapupper_ext.nranges); 6541590Srgrimes 6551590Srgrimes new_locale.variable_len = htonl(new_locale.variable_len); 6561590Srgrimes 6571590Srgrimes /* 6581590Srgrimes * Okay, we are now ready to write the new locale file. 6591590Srgrimes */ 6601590Srgrimes 6611590Srgrimes /* 6621590Srgrimes * PART 1: The _RuneLocale structure 6631590Srgrimes */ 6641590Srgrimes if (fwrite((char *)&new_locale, sizeof(new_locale), 1, fp) != 1) { 6651590Srgrimes perror(locale_file); 6661590Srgrimes exit(1); 6671590Srgrimes } 6681590Srgrimes /* 6691590Srgrimes * PART 2: The runetype_ext structures (not the actual tables) 6701590Srgrimes */ 6711590Srgrimes list = types.root; 6721590Srgrimes 6731590Srgrimes while (list) { 6741590Srgrimes _RuneEntry re; 6751590Srgrimes 6761590Srgrimes re.min = htonl(list->min); 6771590Srgrimes re.max = htonl(list->max); 6781590Srgrimes re.map = htonl(list->map); 6791590Srgrimes 6801590Srgrimes if (fwrite((char *)&re, sizeof(re), 1, fp) != 1) { 6811590Srgrimes perror(locale_file); 6821590Srgrimes exit(1); 6831590Srgrimes } 6841590Srgrimes 6851590Srgrimes list = list->next; 6861590Srgrimes } 6871590Srgrimes /* 6881590Srgrimes * PART 3: The maplower_ext structures 6891590Srgrimes */ 6901590Srgrimes list = maplower.root; 6911590Srgrimes 6921590Srgrimes while (list) { 6931590Srgrimes _RuneEntry re; 6941590Srgrimes 6951590Srgrimes re.min = htonl(list->min); 6961590Srgrimes re.max = htonl(list->max); 6971590Srgrimes re.map = htonl(list->map); 6981590Srgrimes 6991590Srgrimes if (fwrite((char *)&re, sizeof(re), 1, fp) != 1) { 7001590Srgrimes perror(locale_file); 7011590Srgrimes exit(1); 7021590Srgrimes } 7031590Srgrimes 7041590Srgrimes list = list->next; 7051590Srgrimes } 7061590Srgrimes /* 7071590Srgrimes * PART 4: The mapupper_ext structures 7081590Srgrimes */ 7091590Srgrimes list = mapupper.root; 7101590Srgrimes 7111590Srgrimes while (list) { 7121590Srgrimes _RuneEntry re; 7131590Srgrimes 7141590Srgrimes re.min = htonl(list->min); 7151590Srgrimes re.max = htonl(list->max); 7161590Srgrimes re.map = htonl(list->map); 7171590Srgrimes 7181590Srgrimes if (fwrite((char *)&re, sizeof(re), 1, fp) != 1) { 7191590Srgrimes perror(locale_file); 7201590Srgrimes exit(1); 7211590Srgrimes } 7221590Srgrimes 7231590Srgrimes list = list->next; 7241590Srgrimes } 7251590Srgrimes /* 7261590Srgrimes * PART 5: The runetype_ext tables 7271590Srgrimes */ 7281590Srgrimes list = types.root; 7291590Srgrimes 7301590Srgrimes while (list) { 7311590Srgrimes for (x = 0; x < list->max - list->min + 1; ++x) 7321590Srgrimes list->types[x] = htonl(list->types[x]); 7331590Srgrimes 7341590Srgrimes if (!list->map) { 73521393Sache if (fwrite((char *)list->types, 7362509Sbde (list->max - list->min + 1) * sizeof(unsigned long), 7372509Sbde 1, fp) != 1) { 7381590Srgrimes perror(locale_file); 7391590Srgrimes exit(1); 7401590Srgrimes } 7411590Srgrimes } 7421590Srgrimes list = list->next; 7431590Srgrimes } 7441590Srgrimes /* 7451590Srgrimes * PART 5: And finally the variable data 7461590Srgrimes */ 7471590Srgrimes if (fwrite((char *)new_locale.variable, 7481590Srgrimes ntohl(new_locale.variable_len), 1, fp) != 1) { 7491590Srgrimes perror(locale_file); 7501590Srgrimes exit(1); 7511590Srgrimes } 752105548Sache if (fclose(fp) != 0) { 753105548Sache perror(locale_file); 754105548Sache exit(1); 755105548Sache } 756105548Sache fp = NULL; 7571590Srgrimes 7581590Srgrimes if (!debug) 7591590Srgrimes return; 7601590Srgrimes 7611590Srgrimes if (new_locale.encoding[0]) 7621590Srgrimes fprintf(stderr, "ENCODING %s\n", new_locale.encoding); 7631590Srgrimes if (new_locale.variable) 76438022Sbde fprintf(stderr, "VARIABLE %s\n", (char *)new_locale.variable); 7651590Srgrimes 7661590Srgrimes fprintf(stderr, "\nMAPLOWER:\n\n"); 7671590Srgrimes 7681590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 7691590Srgrimes if (isprint(maplower.map[x])) 77038022Sbde fprintf(stderr, " '%c'", (int)maplower.map[x]); 7711590Srgrimes else if (maplower.map[x]) 77238022Sbde fprintf(stderr, "%04lx", maplower.map[x]); 7731590Srgrimes else 7741590Srgrimes fprintf(stderr, "%4x", 0); 7751590Srgrimes if ((x & 0xf) == 0xf) 7761590Srgrimes fprintf(stderr, "\n"); 7771590Srgrimes else 7781590Srgrimes fprintf(stderr, " "); 7791590Srgrimes } 7801590Srgrimes fprintf(stderr, "\n"); 7811590Srgrimes 7821590Srgrimes for (list = maplower.root; list; list = list->next) 7831590Srgrimes fprintf(stderr, "\t%04x - %04x : %04x\n", list->min, list->max, list->map); 7841590Srgrimes 7851590Srgrimes fprintf(stderr, "\nMAPUPPER:\n\n"); 7861590Srgrimes 7871590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 7881590Srgrimes if (isprint(mapupper.map[x])) 78938022Sbde fprintf(stderr, " '%c'", (int)mapupper.map[x]); 7901590Srgrimes else if (mapupper.map[x]) 79138022Sbde fprintf(stderr, "%04lx", mapupper.map[x]); 7921590Srgrimes else 7931590Srgrimes fprintf(stderr, "%4x", 0); 7941590Srgrimes if ((x & 0xf) == 0xf) 7951590Srgrimes fprintf(stderr, "\n"); 7961590Srgrimes else 7971590Srgrimes fprintf(stderr, " "); 7981590Srgrimes } 7991590Srgrimes fprintf(stderr, "\n"); 8001590Srgrimes 8011590Srgrimes for (list = mapupper.root; list; list = list->next) 8021590Srgrimes fprintf(stderr, "\t%04x - %04x : %04x\n", list->min, list->max, list->map); 8031590Srgrimes 8041590Srgrimes 8051590Srgrimes fprintf(stderr, "\nTYPES:\n\n"); 8061590Srgrimes 8071590Srgrimes for (x = 0; x < _CACHED_RUNES; ++x) { 8082509Sbde unsigned long r = types.map[x]; 8091590Srgrimes 8101590Srgrimes if (r) { 8111590Srgrimes if (isprint(x)) 81238022Sbde fprintf(stderr, " '%c': %2d", x, (int)(r & 0xff)); 8131590Srgrimes else 81438022Sbde fprintf(stderr, "%04x: %2d", x, (int)(r & 0xff)); 8151590Srgrimes 81657035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_A) ? "alph" : ""); 81757035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_C) ? "ctrl" : ""); 81857035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_D) ? "dig" : ""); 81957035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_G) ? "graf" : ""); 82057035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_L) ? "low" : ""); 82157035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_P) ? "punc" : ""); 82257035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_S) ? "spac" : ""); 82357035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_U) ? "upp" : ""); 82457035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_X) ? "xdig" : ""); 82557035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_B) ? "blnk" : ""); 82657035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_R) ? "prnt" : ""); 82757035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_I) ? "ideo" : ""); 82857035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_T) ? "spec" : ""); 82957035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_Q) ? "phon" : ""); 8301590Srgrimes fprintf(stderr, "\n"); 8311590Srgrimes } 8321590Srgrimes } 8331590Srgrimes 8341590Srgrimes for (list = types.root; list; list = list->next) { 8351590Srgrimes if (list->map && list->min + 3 < list->max) { 8362509Sbde unsigned long r = list->map; 8371590Srgrimes 83838022Sbde fprintf(stderr, "%04lx: %2d", 83938022Sbde (unsigned long)list->min, (int)(r & 0xff)); 8401590Srgrimes 84157035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_A) ? "alph" : ""); 84257035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_C) ? "ctrl" : ""); 84357035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_D) ? "dig" : ""); 84457035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_G) ? "graf" : ""); 84557035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_L) ? "low" : ""); 84657035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_P) ? "punc" : ""); 84757035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_S) ? "spac" : ""); 84857035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_U) ? "upp" : ""); 84957035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_X) ? "xdig" : ""); 85057035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_B) ? "blnk" : ""); 85157035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_R) ? "prnt" : ""); 85257035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_I) ? "ideo" : ""); 85357035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_T) ? "spec" : ""); 85457035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_Q) ? "phon" : ""); 8551590Srgrimes fprintf(stderr, "\n...\n"); 8561590Srgrimes 85738022Sbde fprintf(stderr, "%04lx: %2d", 85838022Sbde (unsigned long)list->max, (int)(r & 0xff)); 8591590Srgrimes 86057035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_A) ? "alph" : ""); 86157035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_C) ? "ctrl" : ""); 86257035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_D) ? "dig" : ""); 86357035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_G) ? "graf" : ""); 86457035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_L) ? "low" : ""); 86557035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_P) ? "punc" : ""); 86657035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_S) ? "spac" : ""); 86757035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_U) ? "upp" : ""); 86857035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_X) ? "xdig" : ""); 86957035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_B) ? "blnk" : ""); 87057035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_R) ? "prnt" : ""); 87157035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_I) ? "ideo" : ""); 87257035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_T) ? "spec" : ""); 87357035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_Q) ? "phon" : ""); 8741590Srgrimes fprintf(stderr, "\n"); 8751590Srgrimes } else 8761590Srgrimes for (x = list->min; x <= list->max; ++x) { 8772509Sbde unsigned long r = ntohl(list->types[x - list->min]); 8781590Srgrimes 8791590Srgrimes if (r) { 88038022Sbde fprintf(stderr, "%04x: %2d", x, (int)(r & 0xff)); 8811590Srgrimes 88257035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_A) ? "alph" : ""); 88357035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_C) ? "ctrl" : ""); 88457035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_D) ? "dig" : ""); 88557035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_G) ? "graf" : ""); 88657035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_L) ? "low" : ""); 88757035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_P) ? "punc" : ""); 88857035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_S) ? "spac" : ""); 88957035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_U) ? "upp" : ""); 89057035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_X) ? "xdig" : ""); 89157035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_B) ? "blnk" : ""); 89257035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_R) ? "prnt" : ""); 89357035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_I) ? "ideo" : ""); 89457035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_T) ? "spec" : ""); 89557035Sobrien fprintf(stderr, " %4s", (r & _CTYPE_Q) ? "phon" : ""); 8961590Srgrimes fprintf(stderr, "\n"); 8971590Srgrimes } 8981590Srgrimes } 8991590Srgrimes } 9001590Srgrimes} 901