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