| 631 | } |
| 632 | |
| 633 | void parse_derived_norm_properties(const char *filename) |
| 634 | { |
| 635 | FILE *f; |
| 636 | char line[4096], *p, buf[256], *q; |
| 637 | uint32_t c0, c1, c; |
| 638 | |
| 639 | f = fopen(filename, "rb"); |
| 640 | if (!f) { |
| 641 | perror(filename); |
| 642 | exit(1); |
| 643 | } |
| 644 | |
| 645 | for(;;) { |
| 646 | if (!get_line(line, sizeof(line), f)) |
| 647 | break; |
| 648 | p = line; |
| 649 | while (isspace(*p)) |
| 650 | p++; |
| 651 | if (*p == '#' || *p == '@' || *p == '\0') |
| 652 | continue; |
| 653 | c0 = strtoul(p, (char **)&p, 16); |
| 654 | if (*p == '.' && p[1] == '.') { |
| 655 | p += 2; |
| 656 | c1 = strtoul(p, (char **)&p, 16); |
| 657 | } else { |
| 658 | c1 = c0; |
| 659 | } |
| 660 | assert(c1 <= CHARCODE_MAX); |
| 661 | p += strspn(p, " \t"); |
| 662 | if (*p == ';') { |
| 663 | p++; |
| 664 | p += strspn(p, " \t"); |
| 665 | q = buf; |
| 666 | while (*p != '\0' && *p != ' ' && *p != '#' && *p != '\t') { |
| 667 | if ((q - buf) < sizeof(buf) - 1) |
| 668 | *q++ = *p; |
| 669 | p++; |
| 670 | } |
| 671 | *q = '\0'; |
| 672 | if (!strcmp(buf, "Changes_When_NFKC_Casefolded")) { |
| 673 | for(c = c0; c <= c1; c++) { |
| 674 | set_prop(c, PROP_Changes_When_NFKC_Casefolded, 1); |
| 675 | } |
| 676 | } |
| 677 | } |
| 678 | } |
| 679 | fclose(f); |
| 680 | } |
| 681 | |
| 682 | void parse_prop_list(const char *filename) |
| 683 | { |