1*4887Schin /*********************************************************************** 2*4887Schin * * 3*4887Schin * This software is part of the ast package * 4*4887Schin * Copyright (c) 1985-2007 AT&T Knowledge Ventures * 5*4887Schin * and is licensed under the * 6*4887Schin * Common Public License, Version 1.0 * 7*4887Schin * by AT&T Knowledge Ventures * 8*4887Schin * * 9*4887Schin * A copy of the License is available at * 10*4887Schin * http://www.opensource.org/licenses/cpl1.0.txt * 11*4887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12*4887Schin * * 13*4887Schin * Information and Software Systems Research * 14*4887Schin * AT&T Research * 15*4887Schin * Florham Park NJ * 16*4887Schin * * 17*4887Schin * Glenn Fowler <gsf@research.att.com> * 18*4887Schin * David Korn <dgk@research.att.com> * 19*4887Schin * Phong Vo <kpv@research.att.com> * 20*4887Schin * * 21*4887Schin ***********************************************************************/ 22*4887Schin /* 23*4887Schin * generate <lc.h> implementation tables from lc.tab 24*4887Schin * this must make it through vanilla cc with no -last 25*4887Schin * 26*4887Schin * # comment 27*4887Schin * :charset: 28*4887Schin * code name ms-codepage 29*4887Schin * :language: 30*4887Schin * code name alt1|alt2... charset|... attr1|attr2|... 31*4887Schin * ... 32*4887Schin * :territory: 33*4887Schin * code name lang1|lang2... 34*4887Schin * :abbreviation: 35*4887Schin */ 36*4887Schin 37*4887Schin #include <stdio.h> 38*4887Schin #include <ctype.h> 39*4887Schin #ifdef __STDC__ 40*4887Schin #include <stdlib.h> 41*4887Schin #include <string.h> 42*4887Schin #endif 43*4887Schin 44*4887Schin typedef struct Link_s 45*4887Schin { 46*4887Schin struct Link_s* next; 47*4887Schin char* code; 48*4887Schin int index; 49*4887Schin } Link_t; 50*4887Schin 51*4887Schin typedef struct Table_s 52*4887Schin { 53*4887Schin Link_t* root; 54*4887Schin int count; 55*4887Schin } Table_t; 56*4887Schin 57*4887Schin typedef struct Abbreviation_s 58*4887Schin { 59*4887Schin Link_t link; 60*4887Schin char* value; 61*4887Schin } Abbreviation_t; 62*4887Schin 63*4887Schin typedef struct Attribute_s 64*4887Schin { 65*4887Schin Link_t link; 66*4887Schin } Attribute_t; 67*4887Schin 68*4887Schin typedef struct Attribute_list_s 69*4887Schin { 70*4887Schin struct Attribute_list_s*next; 71*4887Schin Attribute_t* attribute; 72*4887Schin } Attribute_list_t; 73*4887Schin 74*4887Schin typedef struct Charset_s 75*4887Schin { 76*4887Schin Link_t link; 77*4887Schin char* alternates; 78*4887Schin char* ms; 79*4887Schin } Charset_t; 80*4887Schin 81*4887Schin typedef struct Language_s 82*4887Schin { 83*4887Schin Link_t link; 84*4887Schin char* name; 85*4887Schin char* alternates; 86*4887Schin Charset_t* charset; 87*4887Schin Attribute_list_t* attributes; 88*4887Schin } Language_t; 89*4887Schin 90*4887Schin typedef struct Language_list_s 91*4887Schin { 92*4887Schin struct Language_list_s* next; 93*4887Schin Language_t* language; 94*4887Schin } Language_list_t; 95*4887Schin 96*4887Schin typedef struct Territory_s 97*4887Schin { 98*4887Schin Link_t link; 99*4887Schin char* name; 100*4887Schin Language_list_t* languages; 101*4887Schin int primary; 102*4887Schin int index; 103*4887Schin } Territory_t; 104*4887Schin 105*4887Schin typedef struct Map_s 106*4887Schin { 107*4887Schin Link_t link; 108*4887Schin Language_t* language; 109*4887Schin Territory_t* territory; 110*4887Schin Charset_t* charset; 111*4887Schin Attribute_t* attribute; 112*4887Schin } Map_t; 113*4887Schin 114*4887Schin static struct State_s 115*4887Schin { 116*4887Schin Table_t attribute; 117*4887Schin Table_t charset; 118*4887Schin Table_t language; 119*4887Schin Table_t territory; 120*4887Schin Table_t map; 121*4887Schin } state; 122*4887Schin 123*4887Schin #define INIT 0 124*4887Schin #define CHARSET 1 125*4887Schin #define LANGUAGE 2 126*4887Schin #define TERRITORY 3 127*4887Schin #define MAP 4 128*4887Schin 129*4887Schin #define elementsof(x) (sizeof(x)/sizeof(x[0])) 130*4887Schin #define newof(p,t,n,x) ((t*)malloc(sizeof(t)*(n)+(x))) 131*4887Schin 132*4887Schin static Link_t* 133*4887Schin #if defined(__STDC__) || defined(__cplusplus) 134*4887Schin enter(register Table_t* tab, register Link_t* v) 135*4887Schin #else 136*4887Schin enter(tab, v) 137*4887Schin register Table_t* tab; 138*4887Schin register Link_t* v; 139*4887Schin #endif 140*4887Schin { 141*4887Schin register Link_t* x; 142*4887Schin register Link_t* p; 143*4887Schin 144*4887Schin for (p = 0, x = tab->root; x; p = x, x = x->next) 145*4887Schin if (!strcmp(x->code, v->code)) 146*4887Schin return x; 147*4887Schin if (p) 148*4887Schin p->next = v; 149*4887Schin else 150*4887Schin tab->root = v; 151*4887Schin v->next = 0; 152*4887Schin v->index = tab->count++; 153*4887Schin return v; 154*4887Schin } 155*4887Schin 156*4887Schin static Link_t* 157*4887Schin #if defined(__STDC__) || defined(__cplusplus) 158*4887Schin lookup(register Table_t* tab, register char* s) 159*4887Schin #else 160*4887Schin lookup(tab, s) 161*4887Schin register Table_t* tab; 162*4887Schin register char* s; 163*4887Schin #endif 164*4887Schin { 165*4887Schin register Link_t* x; 166*4887Schin 167*4887Schin for (x = tab->root; x; x = x->next) 168*4887Schin if (!strcmp(x->code, s)) 169*4887Schin return x; 170*4887Schin return 0; 171*4887Schin } 172*4887Schin 173*4887Schin static char* 174*4887Schin #if defined(__STDC__) || defined(__cplusplus) 175*4887Schin copy(char** p, register char* f) 176*4887Schin #else 177*4887Schin copy(p, f) 178*4887Schin char** p; 179*4887Schin register char* f; 180*4887Schin #endif 181*4887Schin { 182*4887Schin register char* t; 183*4887Schin char* b; 184*4887Schin 185*4887Schin if (!f) 186*4887Schin return 0; 187*4887Schin b = t = *p; 188*4887Schin while (*t++ = *f++); 189*4887Schin *p = t; 190*4887Schin return b; 191*4887Schin } 192*4887Schin 193*4887Schin static void 194*4887Schin #if defined(__STDC__) || defined(__cplusplus) 195*4887Schin macro(FILE* f, char* p1, char* p2, char* p3) 196*4887Schin #else 197*4887Schin macro(f, p1, p2, p3) 198*4887Schin FILE* f; 199*4887Schin char* p1; 200*4887Schin char* p2; 201*4887Schin char* p3; 202*4887Schin #endif 203*4887Schin { 204*4887Schin register int c; 205*4887Schin register char* s; 206*4887Schin register char* b; 207*4887Schin register char* e; 208*4887Schin int i; 209*4887Schin int m; 210*4887Schin int n; 211*4887Schin char* part[4]; 212*4887Schin char buf[128]; 213*4887Schin 214*4887Schin part[0] = p1; 215*4887Schin part[1] = p2; 216*4887Schin part[2] = p3; 217*4887Schin part[3] = 0; 218*4887Schin n = 0; 219*4887Schin fprintf(f, "\n"); 220*4887Schin do 221*4887Schin { 222*4887Schin i = m = 0; 223*4887Schin b = buf; 224*4887Schin e = &buf[sizeof(buf)-1]; 225*4887Schin while (b < e) 226*4887Schin { 227*4887Schin if (!(s = part[i++])) 228*4887Schin break; 229*4887Schin if (i > 1) 230*4887Schin *b++ = '_'; 231*4887Schin while ((c = *s++) && b < e) 232*4887Schin { 233*4887Schin if (c == '|') 234*4887Schin { 235*4887Schin part[i-1] = s; 236*4887Schin m = 1; 237*4887Schin break; 238*4887Schin } 239*4887Schin else if (islower(c)) 240*4887Schin c = toupper(c); 241*4887Schin else if (!isalnum(c)) 242*4887Schin c = '_'; 243*4887Schin *b++ = c; 244*4887Schin } 245*4887Schin } 246*4887Schin *b = 0; 247*4887Schin fprintf(f, "#ifdef %s\n%s,\n#else\n", buf, buf); 248*4887Schin n++; 249*4887Schin } while (m); 250*4887Schin fprintf(f, "0,\n"); 251*4887Schin while (n-- > 0) 252*4887Schin fprintf(f, "#endif\n"); 253*4887Schin } 254*4887Schin 255*4887Schin #if defined(__STDC__) || defined(__cplusplus) 256*4887Schin int 257*4887Schin main(int argc, char** argv) 258*4887Schin #else 259*4887Schin int 260*4887Schin main(argc, argv) 261*4887Schin int argc; 262*4887Schin char** argv; 263*4887Schin #endif 264*4887Schin { 265*4887Schin register char* s; 266*4887Schin register char** vp; 267*4887Schin register char** ve; 268*4887Schin Attribute_t* ap; 269*4887Schin Attribute_list_t* al; 270*4887Schin Attribute_list_t* az; 271*4887Schin Charset_t* cp; 272*4887Schin Territory_t* tp; 273*4887Schin Language_t* lp; 274*4887Schin Language_list_t* ll; 275*4887Schin Language_list_t* lz; 276*4887Schin Map_t* mp; 277*4887Schin char* b; 278*4887Schin char* f; 279*4887Schin char* command; 280*4887Schin char* hdr; 281*4887Schin char* lib; 282*4887Schin FILE* hf; 283*4887Schin FILE* lf; 284*4887Schin int c; 285*4887Schin int i; 286*4887Schin int line; 287*4887Schin int type; 288*4887Schin int language_attribute_max; 289*4887Schin int territory_language_max; 290*4887Schin char* arg[5]; 291*4887Schin char buf[1024]; 292*4887Schin 293*4887Schin command = *argv++; 294*4887Schin line = 0; 295*4887Schin if (!(hdr = *argv++) || !(lib = *argv++) || *argv) 296*4887Schin { 297*4887Schin fprintf(stderr, "%s: hdr and lib arguments expected\n", command); 298*4887Schin return 1; 299*4887Schin } 300*4887Schin if (!(hf = fopen(hdr, "w"))) 301*4887Schin { 302*4887Schin fprintf(stderr, "%s: %s: cannot write\n", command, hdr); 303*4887Schin return 1; 304*4887Schin } 305*4887Schin if (!(lf = fopen(lib, "w"))) 306*4887Schin { 307*4887Schin fprintf(stderr, "%s: %s: cannot write\n", command, lib); 308*4887Schin return 1; 309*4887Schin } 310*4887Schin type = 0; 311*4887Schin language_attribute_max = 0; 312*4887Schin territory_language_max = 0; 313*4887Schin state.language.count = 2; 314*4887Schin state.territory.count = 2; 315*4887Schin ve = &arg[elementsof(arg)]; 316*4887Schin fprintf(hf, "/* : : generated by %s : : */\n", command); 317*4887Schin fprintf(hf, "#pragma prototyped\n"); 318*4887Schin fprintf(hf, "\n"); 319*4887Schin fprintf(hf, "#ifndef _LC_H\n"); 320*4887Schin fprintf(hf, "#define _LC_H\t\t\t1\n"); 321*4887Schin fprintf(hf, "\n"); 322*4887Schin fprintf(hf, "#include <ast.h>\n"); 323*4887Schin fprintf(hf, "\n"); 324*4887Schin fprintf(hf, "#define LC_abbreviated\t\t0x00001\n"); 325*4887Schin fprintf(hf, "#define LC_checked\t\t0x00002\n"); 326*4887Schin fprintf(hf, "#define LC_default\t\t0x00004\n"); 327*4887Schin fprintf(hf, "#define LC_defined\t\t0x00008\n"); 328*4887Schin fprintf(hf, "#define LC_debug\t\t0x00010\n"); 329*4887Schin fprintf(hf, "#define LC_local\t\t0x00020\n"); 330*4887Schin fprintf(hf, "#define LC_primary\t\t0x00040\n"); 331*4887Schin fprintf(hf, "#define LC_qualified\t\t0x00080\n"); 332*4887Schin fprintf(hf, "#define LC_undefined\t\t0x00100\n"); 333*4887Schin fprintf(hf, "#define LC_verbose\t\t0x00200\n"); 334*4887Schin fprintf(hf, "#define LC_user\t\t\t0x10000\n"); 335*4887Schin fprintf(lf, "/* : : generated by %s : : */\n", command); 336*4887Schin while (s = fgets(buf, sizeof(buf), stdin)) 337*4887Schin { 338*4887Schin line++; 339*4887Schin while (isspace(*s)) 340*4887Schin s++; 341*4887Schin if (!*s || *s == '#') 342*4887Schin continue; 343*4887Schin b = s; 344*4887Schin vp = arg; 345*4887Schin for (;;) 346*4887Schin { 347*4887Schin for (*vp++ = s; *s && !isspace(*s); s++); 348*4887Schin if (!*s) 349*4887Schin break; 350*4887Schin for (*s++ = 0; isspace(*s); s++); 351*4887Schin if (!strcmp(*(vp - 1), "-")) 352*4887Schin *(vp - 1) = 0; 353*4887Schin if (!*s || vp >= ve) 354*4887Schin break; 355*4887Schin } 356*4887Schin while (vp < ve) 357*4887Schin *vp++ = 0; 358*4887Schin if (*arg[0] == ':') 359*4887Schin { 360*4887Schin if (!strcmp(arg[0], ":map:")) 361*4887Schin { 362*4887Schin if (type != TERRITORY) 363*4887Schin { 364*4887Schin fprintf(stderr, "%s: %d: %s: must be specified after :territory:\n", command, line, arg[0]); 365*4887Schin return 1; 366*4887Schin } 367*4887Schin type = MAP; 368*4887Schin continue; 369*4887Schin } 370*4887Schin else if (!strcmp(arg[0], ":charset:")) 371*4887Schin { 372*4887Schin if (type != INIT) 373*4887Schin { 374*4887Schin fprintf(stderr, "%s: %d: %s must be specified first\n", command, line, arg[0]); 375*4887Schin return 1; 376*4887Schin } 377*4887Schin type = CHARSET; 378*4887Schin continue; 379*4887Schin } 380*4887Schin else if (!strcmp(arg[0], ":territory:")) 381*4887Schin { 382*4887Schin if (type != LANGUAGE) 383*4887Schin { 384*4887Schin fprintf(stderr, "%s: %d: %s: must be specified after :language:\n", command, line, arg[0]); 385*4887Schin return 1; 386*4887Schin } 387*4887Schin type = TERRITORY; 388*4887Schin continue; 389*4887Schin } 390*4887Schin else if (!strcmp(arg[0], ":language:")) 391*4887Schin { 392*4887Schin if (type != CHARSET) 393*4887Schin { 394*4887Schin fprintf(stderr, "%s: %d: %s must be specified after :charset:\n", command, line, arg[0]); 395*4887Schin return 1; 396*4887Schin } 397*4887Schin type = LANGUAGE; 398*4887Schin continue; 399*4887Schin } 400*4887Schin else 401*4887Schin { 402*4887Schin fprintf(stderr, "%s: %d: %s invalid\n", command, line, arg[0]); 403*4887Schin return 1; 404*4887Schin } 405*4887Schin } 406*4887Schin if (!arg[1]) 407*4887Schin { 408*4887Schin fprintf(stderr, "%s: %d: at least two arguments expected\n", command, line); 409*4887Schin return 1; 410*4887Schin } 411*4887Schin switch (type) 412*4887Schin { 413*4887Schin case CHARSET: 414*4887Schin if (!(cp = newof(0, Charset_t, 1, s - b + 1))) 415*4887Schin { 416*4887Schin fprintf(stderr, "%s: %d: out of space\n", command, line); 417*4887Schin return 1; 418*4887Schin } 419*4887Schin b = (char*)(cp + 1); 420*4887Schin cp->link.code = copy(&b, arg[0]); 421*4887Schin cp->alternates = copy(&b, arg[1]); 422*4887Schin cp->ms = copy(&b, arg[2]); 423*4887Schin if (cp != (Charset_t*)enter(&state.charset, (Link_t*)cp)) 424*4887Schin { 425*4887Schin fprintf(stderr, "%s: %d: %s: duplicate charset\n", command, line, cp->link.code); 426*4887Schin return 1; 427*4887Schin } 428*4887Schin break; 429*4887Schin case TERRITORY: 430*4887Schin if (!(tp = newof(0, Territory_t, 1, s - b + 1))) 431*4887Schin { 432*4887Schin fprintf(stderr, "%s: %d: out of space\n", command, line); 433*4887Schin return 1; 434*4887Schin } 435*4887Schin b = (char*)(tp + 1); 436*4887Schin tp->link.code = copy(&b, arg[0]); 437*4887Schin tp->name = copy(&b, arg[1]); 438*4887Schin tp->languages = 0; 439*4887Schin if (s = copy(&b, arg[2])) 440*4887Schin { 441*4887Schin i = 0; 442*4887Schin while (*(b = s)) 443*4887Schin { 444*4887Schin for (; *s && *s != ':' && *s != '|'; s++); 445*4887Schin if (c = *s) 446*4887Schin *s++ = 0; 447*4887Schin if (!(lp = (Language_t*)lookup(&state.language, b))) 448*4887Schin { 449*4887Schin fprintf(stderr, "%s: %d: %s: unknown language\n", command, line, b); 450*4887Schin return 1; 451*4887Schin } 452*4887Schin if (!(ll = newof(0, Language_list_t, 1, 0))) 453*4887Schin { 454*4887Schin fprintf(stderr, "%s: %d: out of space\n", command, line); 455*4887Schin return 1; 456*4887Schin } 457*4887Schin if (!tp->languages) 458*4887Schin tp->languages = ll; 459*4887Schin else 460*4887Schin lz->next = ll; 461*4887Schin lz = ll; 462*4887Schin ll->language = lp; 463*4887Schin ll->next = 0; 464*4887Schin i++; 465*4887Schin if (c == ':') 466*4887Schin { 467*4887Schin for (b = s; *s && *s != '|'; s++); 468*4887Schin if (*s) 469*4887Schin *s++ = 0; 470*4887Schin if (!strcmp(b, "primary")) 471*4887Schin tp->primary = 1; 472*4887Schin } 473*4887Schin } 474*4887Schin if (territory_language_max < i) 475*4887Schin territory_language_max = i; 476*4887Schin } 477*4887Schin if (tp != (Territory_t*)enter(&state.territory, (Link_t*)tp)) 478*4887Schin { 479*4887Schin fprintf(stderr, "%s: %d: %s: duplicate territory\n", command, line, tp->link.code); 480*4887Schin return 1; 481*4887Schin } 482*4887Schin break; 483*4887Schin case LANGUAGE: 484*4887Schin if (!(lp = newof(0, Language_t, 1, s - b + 1))) 485*4887Schin { 486*4887Schin fprintf(stderr, "%s: %d: out of space\n", command, line); 487*4887Schin return 1; 488*4887Schin } 489*4887Schin b = (char*)(lp + 1); 490*4887Schin lp->link.code = copy(&b, arg[0]); 491*4887Schin lp->name = copy(&b, arg[1]); 492*4887Schin lp->alternates = copy(&b, arg[2]); 493*4887Schin if (!arg[3]) 494*4887Schin lp->charset = 0; 495*4887Schin else if (!(lp->charset = (Charset_t*)lookup(&state.charset, arg[3]))) 496*4887Schin { 497*4887Schin fprintf(stderr, "%s: %d: %s: unknown charset\n", command, line, arg[3]); 498*4887Schin return 1; 499*4887Schin } 500*4887Schin lp->attributes = 0; 501*4887Schin if (s = copy(&b, arg[4])) 502*4887Schin { 503*4887Schin i = 0; 504*4887Schin fprintf(lf, "\nstatic Lc_attribute_t attribute_%s[] =\n{\n", lp->link.code); 505*4887Schin while (*(b = s)) 506*4887Schin { 507*4887Schin for (f = 0; *s && *s != '|'; s++) 508*4887Schin if (*s == ':') 509*4887Schin { 510*4887Schin *s++ = 0; 511*4887Schin f = s; 512*4887Schin } 513*4887Schin if (*s) 514*4887Schin *s++ = 0; 515*4887Schin fprintf(lf, "{\"%s\",", b); 516*4887Schin if (f) 517*4887Schin fprintf(lf, "LC_%s,", f); 518*4887Schin else 519*4887Schin fprintf(lf, "0,"); 520*4887Schin if (!(ap = newof(0, Attribute_t, 1, 0))) 521*4887Schin { 522*4887Schin fprintf(stderr, "%s: %d: out of space\n", command, line); 523*4887Schin return 1; 524*4887Schin } 525*4887Schin ap->link.code = b; 526*4887Schin ap->link.index = i++; 527*4887Schin if (!(al = newof(0, Attribute_list_t, 1, 0))) 528*4887Schin { 529*4887Schin fprintf(stderr, "%s: %d: out of space\n", command, line); 530*4887Schin return 1; 531*4887Schin } 532*4887Schin if (!lp->attributes) 533*4887Schin lp->attributes = al; 534*4887Schin else 535*4887Schin az->next = al; 536*4887Schin az = al; 537*4887Schin al->attribute = ap; 538*4887Schin al->next = 0; 539*4887Schin macro(lf, "SUBLANG", lp->name, b); 540*4887Schin fprintf(lf, "\n},\n"); 541*4887Schin } 542*4887Schin if (language_attribute_max < i) 543*4887Schin language_attribute_max = i; 544*4887Schin fprintf(lf, "};\n"); 545*4887Schin } 546*4887Schin if (lp != (Language_t*)enter(&state.language, (Link_t*)lp)) 547*4887Schin { 548*4887Schin fprintf(stderr, "%s: %d: %s: duplicate language\n", command, line, lp->link.code); 549*4887Schin return 1; 550*4887Schin } 551*4887Schin break; 552*4887Schin case MAP: 553*4887Schin if (!(mp = newof(0, Map_t, 1, s - b + 1))) 554*4887Schin { 555*4887Schin fprintf(stderr, "%s: %d: out of space\n", command, line); 556*4887Schin return 1; 557*4887Schin } 558*4887Schin b = (char*)(mp + 1); 559*4887Schin mp->link.code = copy(&b, arg[0]); 560*4887Schin if (!arg[2]) 561*4887Schin { 562*4887Schin fprintf(stderr, "%s: %d: territory code expected\n", command, line); 563*4887Schin return 1; 564*4887Schin } 565*4887Schin if (!(mp->language = (Language_t*)lookup(&state.language, arg[1]))) 566*4887Schin { 567*4887Schin fprintf(stderr, "%s: %d: %s: unknown language\n", command, line, arg[1]); 568*4887Schin return 1; 569*4887Schin } 570*4887Schin if (!(mp->territory = (Territory_t*)lookup(&state.territory, arg[2]))) 571*4887Schin { 572*4887Schin fprintf(stderr, "%s: %d: %s: unknown territory\n", command, line, arg[2]); 573*4887Schin return 1; 574*4887Schin } 575*4887Schin if (!arg[3]) 576*4887Schin mp->charset = 0; 577*4887Schin else if (!(mp->charset = (Charset_t*)lookup(&state.charset, arg[3]))) 578*4887Schin { 579*4887Schin fprintf(stderr, "%s: %d: %s: unknown charset\n", command, line, arg[3]); 580*4887Schin return 1; 581*4887Schin } 582*4887Schin mp->attribute = 0; 583*4887Schin if (arg[4]) 584*4887Schin { 585*4887Schin for (al = mp->language->attributes; al; al = al->next) 586*4887Schin if (!strcmp(al->attribute->link.code, arg[4])) 587*4887Schin { 588*4887Schin mp->attribute = al->attribute; 589*4887Schin break; 590*4887Schin } 591*4887Schin if (!mp->attribute) 592*4887Schin { 593*4887Schin fprintf(stderr, "%s: %d: %s: unknown attribute\n", command, line, arg[4]); 594*4887Schin return 1; 595*4887Schin } 596*4887Schin } 597*4887Schin if (mp != (Map_t*)enter(&state.map, (Link_t*)mp)) 598*4887Schin { 599*4887Schin fprintf(stderr, "%s: %d: %s: duplicate map\n", command, line, mp->link.code); 600*4887Schin return 1; 601*4887Schin } 602*4887Schin break; 603*4887Schin } 604*4887Schin } 605*4887Schin fprintf(hf, "#define LC_language_attribute_max\t\t%d\n", language_attribute_max); 606*4887Schin fprintf(hf, "#define LC_territory_language_max\t\t%d\n", territory_language_max); 607*4887Schin fprintf(hf, "\nstruct Lc_s;\n"); 608*4887Schin fprintf(hf, "\ntypedef struct Lc_info_s\n{\n"); 609*4887Schin fprintf(hf, "\tconst struct Lc_s*\tlc;\n"); 610*4887Schin fprintf(hf, "\tunsigned long\t\tnumber;\n"); 611*4887Schin fprintf(hf, "\tvoid*\t\t\tdata;\n"); 612*4887Schin fprintf(hf, "} Lc_info_t;\n"); 613*4887Schin fprintf(hf, "\ntypedef struct Lc_attribute_s\n{\n"); 614*4887Schin fprintf(hf, "\tconst char*\t\tname;\n"); 615*4887Schin fprintf(hf, "\tunsigned long\t\tflags;\n"); 616*4887Schin fprintf(hf, "\tunsigned long\t\tindex;\n"); 617*4887Schin fprintf(hf, "} Lc_attribute_t;\n"); 618*4887Schin fprintf(hf, "\ntypedef struct Lc_charset_s\n{\n"); 619*4887Schin fprintf(hf, "\tconst char*\t\tcode;\n"); 620*4887Schin fprintf(hf, "\tconst char*\t\talternates;\n"); 621*4887Schin fprintf(hf, "\tconst char*\t\tms;\n"); 622*4887Schin fprintf(hf, "\tunsigned long\t\tindex;\n"); 623*4887Schin fprintf(hf, "} Lc_charset_t;\n"); 624*4887Schin fprintf(hf, "\ntypedef struct Lc_language_s\n{\n"); 625*4887Schin fprintf(hf, "\tconst char*\t\tcode;\n"); 626*4887Schin fprintf(hf, "\tconst char*\t\tname;\n"); 627*4887Schin fprintf(hf, "\tconst char*\t\talternates;\n"); 628*4887Schin fprintf(hf, "\tconst Lc_charset_t*\tcharset;\n"); 629*4887Schin fprintf(hf, "\tunsigned long\t\tflags;\n"); 630*4887Schin fprintf(hf, "\tunsigned long\t\tindex;\n"); 631*4887Schin fprintf(hf, "\tconst Lc_attribute_t*\tattributes[LC_language_attribute_max];\n"); 632*4887Schin fprintf(hf, "} Lc_language_t;\n"); 633*4887Schin fprintf(hf, "\ntypedef struct Lc_territory_s\n{\n"); 634*4887Schin fprintf(hf, "\tconst char*\t\tcode;\n"); 635*4887Schin fprintf(hf, "\tconst char*\t\tname;\n"); 636*4887Schin fprintf(hf, "\tunsigned long\t\tflags;\n"); 637*4887Schin fprintf(hf, "\tunsigned long\t\tindex;\n"); 638*4887Schin fprintf(hf, "\tconst Lc_language_t*\tlanguages[LC_territory_language_max];\n"); 639*4887Schin fprintf(hf, "#ifdef _LC_TERRITORY_PRIVATE_\n"); 640*4887Schin fprintf(hf, "\t_LC_TERRITORY_PRIVATE_\n"); 641*4887Schin fprintf(hf, "#endif\n"); 642*4887Schin fprintf(hf, "} Lc_territory_t;\n"); 643*4887Schin fprintf(hf, "\ntypedef struct Lc_map_s\n{\n"); 644*4887Schin fprintf(hf, "\tconst char*\t\tcode;\n"); 645*4887Schin fprintf(hf, "\tconst Lc_language_t*\tlanguage;\n"); 646*4887Schin fprintf(hf, "\tconst Lc_territory_t*\tterritory;\n"); 647*4887Schin fprintf(hf, "\tconst Lc_charset_t*\tcharset;\n"); 648*4887Schin fprintf(hf, "\tconst Lc_attribute_t*\tattribute;\n"); 649*4887Schin fprintf(hf, "} Lc_map_t;\n"); 650*4887Schin fprintf(hf, "\ntypedef struct Lc_attribute_list_s\n{\n"); 651*4887Schin fprintf(hf, "\tstruct Lc_attribute_list_s*\tnext;\n"); 652*4887Schin fprintf(hf, "\tconst Lc_attribute_t*\t\tattribute;\n"); 653*4887Schin fprintf(hf, "} Lc_attribute_list_t;\n"); 654*4887Schin fprintf(hf, "\ntypedef struct Lc_s\n{\n"); 655*4887Schin fprintf(hf, "\tconst char*\t\tname;\n"); 656*4887Schin fprintf(hf, "\tconst char*\t\tcode;\n"); 657*4887Schin fprintf(hf, "\tconst Lc_language_t*\tlanguage;\n"); 658*4887Schin fprintf(hf, "\tconst Lc_territory_t*\tterritory;\n"); 659*4887Schin fprintf(hf, "\tconst Lc_charset_t*\tcharset;\n"); 660*4887Schin fprintf(hf, "\tconst Lc_attribute_list_t*\tattributes;\n"); 661*4887Schin fprintf(hf, "\tunsigned long\t\tflags;\n"); 662*4887Schin fprintf(hf, "\tunsigned long\t\tindex;\n"); 663*4887Schin fprintf(hf, "#ifdef _LC_PRIVATE_\n"); 664*4887Schin fprintf(hf, "\t_LC_PRIVATE_\n"); 665*4887Schin fprintf(hf, "#endif\n"); 666*4887Schin fprintf(hf, "} Lc_t;\n"); 667*4887Schin fprintf(hf, "\nstruct Lc_category_s;\n"); 668*4887Schin fprintf(hf, "\ntypedef int (*Lc_category_set_f)(struct Lc_category_s*);\n"); 669*4887Schin fprintf(hf, "\ntypedef struct Lc_category_s\n{\n"); 670*4887Schin fprintf(hf, "\tconst char*\t\tname;\n"); 671*4887Schin fprintf(hf, "\tint\t\t\texternal;\n"); 672*4887Schin fprintf(hf, "\tint\t\t\tinternal;\n"); 673*4887Schin fprintf(hf, "\tLc_category_set_f\tsetf;\n"); 674*4887Schin fprintf(hf, "\tLc_t*\t\t\tprev;\n"); 675*4887Schin fprintf(hf, "} Lc_category_t;\n"); 676*4887Schin fprintf(hf, "\n"); 677*4887Schin fprintf(hf, "#if _BLD_ast && defined(__EXPORT__)\n"); 678*4887Schin fprintf(hf, "#define extern\t\t__EXPORT__\n"); 679*4887Schin fprintf(hf, "#endif\n"); 680*4887Schin fprintf(hf, "\n"); 681*4887Schin fprintf(hf, "extern size_t\t\tlccanon(Lc_t*, unsigned long flags, char*, size_t);\n"); 682*4887Schin fprintf(hf, "extern Lc_category_t*\tlccategories(void);\n"); 683*4887Schin fprintf(hf, "extern int\t\tlcindex(int, int);\n"); 684*4887Schin fprintf(hf, "extern Lc_info_t*\tlcinfo(int);\n"); 685*4887Schin fprintf(hf, "extern Lc_t*\t\tlcmake(const char*);\n"); 686*4887Schin fprintf(hf, "extern Lc_t*\t\tlcscan(Lc_t*);\n"); 687*4887Schin fprintf(hf, "\n"); 688*4887Schin fprintf(hf, "#undef\textern\n"); 689*4887Schin fprintf(lf, "\nstatic const Lc_charset_t charset[] =\n{\n"); 690*4887Schin for (cp = (Charset_t*)state.charset.root; cp; cp = (Charset_t*)cp->link.next) 691*4887Schin { 692*4887Schin fprintf(lf, "{\"%s\",", cp->link.code); 693*4887Schin if (cp->alternates) 694*4887Schin fprintf(lf, "\"%s\",", cp->alternates); 695*4887Schin else 696*4887Schin fprintf(lf, "0,"); 697*4887Schin if (cp->ms) 698*4887Schin fprintf(lf, "\"%s\",", cp->ms); 699*4887Schin else 700*4887Schin fprintf(lf, "0"); 701*4887Schin fprintf(lf, "},\n"); 702*4887Schin } 703*4887Schin fprintf(lf, "\t0\n};\n"); 704*4887Schin fprintf(lf, "\nstatic const Lc_language_t language[] =\n{\n"); 705*4887Schin fprintf(lf, "{\"C\",\"C\",\"POSIX\",&charset[0],LC_default,0,"); 706*4887Schin for (i = 0; i < language_attribute_max; i++) 707*4887Schin fprintf(lf, "0,"); 708*4887Schin fprintf(lf, "},\n"); 709*4887Schin fprintf(lf, "{\"debug\",\"debug\",0,&charset[0],LC_debug,0,"); 710*4887Schin for (i = 0; i < language_attribute_max; i++) 711*4887Schin fprintf(lf, "0,"); 712*4887Schin fprintf(lf, "},\n"); 713*4887Schin for (lp = (Language_t*)state.language.root; lp; lp = (Language_t*)lp->link.next) 714*4887Schin { 715*4887Schin fprintf(lf, "{\"%s\",\"%s\",", lp->link.code, lp->name); 716*4887Schin if (lp->alternates) 717*4887Schin fprintf(lf, "\"%s\",", lp->alternates); 718*4887Schin else 719*4887Schin fprintf(lf, "0,"); 720*4887Schin fprintf(lf, "&charset[%d],0,", lp->charset ? lp->charset->link.index : 0); 721*4887Schin macro(lf, "LANG", lp->name, (char*)0); 722*4887Schin for (i = 0, al = lp->attributes; al; al = al->next, i++) 723*4887Schin fprintf(lf, "&attribute_%s[%d],", lp->link.code, al->attribute->link.index); 724*4887Schin for (; i < language_attribute_max; i++) 725*4887Schin fprintf(lf, "0,"); 726*4887Schin fprintf(lf, "\n},\n"); 727*4887Schin } 728*4887Schin fprintf(lf, "\t0\n};\n"); 729*4887Schin fprintf(lf, "\nstatic const Lc_territory_t territory[] =\n{\n"); 730*4887Schin fprintf(lf, "{\"C\",\"C\",LC_default,0,&language[0],"); 731*4887Schin for (i = 1; i < 2 * territory_language_max; i++) 732*4887Schin fprintf(lf, "0,"); 733*4887Schin fprintf(lf, "},\n"); 734*4887Schin fprintf(lf, "{\"debug\",\"debug\",LC_debug,0,&language[1],"); 735*4887Schin for (i = 1; i < 2 * territory_language_max; i++) 736*4887Schin fprintf(lf, "0,"); 737*4887Schin fprintf(lf, "},\n"); 738*4887Schin for (tp = (Territory_t*)state.territory.root; tp; tp = (Territory_t*)tp->link.next) 739*4887Schin { 740*4887Schin fprintf(lf, "{\"%s\",\"%s\",", tp->link.code, tp->name); 741*4887Schin if (tp->primary) 742*4887Schin fprintf(lf, "LC_primary,"); 743*4887Schin else 744*4887Schin fprintf(lf, "0,"); 745*4887Schin macro(lf, "CTRY", tp->name, (char*)0); 746*4887Schin for (i = 0, ll = tp->languages; ll; ll = ll->next, i++) 747*4887Schin fprintf(lf, "&language[%d],", ll->language->link.index); 748*4887Schin for (; i < territory_language_max; i++) 749*4887Schin fprintf(lf, "0,"); 750*4887Schin for (i = 0, ll = tp->languages; ll; ll = ll->next, i++) 751*4887Schin macro(lf, "SUBLANG", ll->language->name, tp->name); 752*4887Schin for (; i < territory_language_max; i++) 753*4887Schin fprintf(lf, "0,"); 754*4887Schin fprintf(lf, "\n},\n"); 755*4887Schin } 756*4887Schin fprintf(lf, "\t0\n};\n"); 757*4887Schin fprintf(lf, "\nstatic const Lc_map_t map[] =\n{\n"); 758*4887Schin for (mp = (Map_t*)state.map.root; mp; mp = (Map_t*)mp->link.next) 759*4887Schin { 760*4887Schin fprintf(lf, "{\"%s\",", mp->link.code); 761*4887Schin fprintf(lf, "&language[%d],", mp->language->link.index); 762*4887Schin fprintf(lf, "&territory[%d],", mp->territory->link.index); 763*4887Schin fprintf(lf, "&charset[%d],", mp->charset ? mp->charset->link.index : 0); 764*4887Schin if (mp->attribute) 765*4887Schin fprintf(lf, "&attribute_%s[%d]", mp->language->link.code, mp->attribute->link.index); 766*4887Schin else 767*4887Schin fprintf(lf, "0"); 768*4887Schin fprintf(lf, "},\n"); 769*4887Schin } 770*4887Schin fprintf(lf, "\t0\n};\n"); 771*4887Schin fclose(lf); 772*4887Schin fprintf(hf, "\n#endif\n"); 773*4887Schin fclose(hf); 774*4887Schin return 0; 775*4887Schin } 776