📄 gen_collate.c
字号:
printf("%s not found\n", *argv); return EXIT_FAILURE; } } i = p->base_locale; ++der_count[i]; if (!strcmp(base_name[i], *argv)) { /* same name as base, so skip after count incremented */ continue; } /* add it to the list. the main body will catch duplicates */ lli = (ll_item_t *) xmalloc(sizeof(ll_item_t)); lli->prev = lli->next = NULL; lli->data = (void *) *argv; insque(lli, locale_list[i]); } total = 0; for (i=0 ; i < BASE_MAX ; i++) {/* printf("der_count[%2d] = %3d\n", i, der_count[i]); */ total += der_count[i]; }/* printf("total = %d\n", total); */ new_args[new_arg_count++] = "dummyprogramname"; for (i=0 ; i < BASE_MAX ; i++) { if (!der_count[i]) { continue; } new_args[new_arg_count++] = (i == BASE_comm) ? "-c" : "-b"; lli = locale_list[i]; do { new_args[new_arg_count++] = (const char *) (lli->data); lli = lli->next; } while (lli != locale_list[i]); new_args[new_arg_count++] = "-f"; }/* for (i=0 ; i < new_arg_count ; i++) { *//* printf("%3d: %s\n", i, new_args[i]); *//* } */ return old_main(new_arg_count, (char **) new_args);}/* usage... prog -b basefile derived {derived} -s single {single} */static int old_main(int argc, char **argv){ int next_is_base = 0; int next_is_subset = 0; superset = 0; while (--argc) { ++argv; if (**argv == '-') { if ((*argv)[1] == 'd') { dump_weights((*argv) + 2); } else if ((*argv)[1] == 'f') { /* dump all weight rules */ finalize_base(); } else if ((*argv)[1] == 'R') { /* dump all weight rules */ twalk(root_weight, print_weight_node); } else if (((*argv)[1] == 'c') && !(*argv)[2]) { /* new common subset */ cur_base = cur_derived = NULL; next_is_subset = 1; next_is_base = 1; superset = 0; } else if (((*argv)[1] == 'b') && !(*argv)[2]) { /* new base locale */ cur_base = cur_derived = NULL; next_is_subset = 0; next_is_base = 1; superset = 0; } else if (((*argv)[1] == 's') && !(*argv)[2]) { /* single locales follow */ cur_base = cur_derived = NULL; next_is_subset = 0; next_is_base = 2; superset = 0; } else { error_msg("unrecognized option %s", *argv); } continue; } /* new file */ new_col_locale(*argv); /* automaticly sets cur_col */ if (next_is_base) { cur_base = cur_col; } else { cur_derived = cur_col; } pushfile(*argv);/* fprintf(stderr, "processing file %s\n", *argv); */ processfile(); /* this does a popfile *//* twalk(cur_col->root_colitem, print_colnode); */ if (next_is_base == 1) { next_is_base = 0; } if (next_is_subset) { next_is_subset = 0; superset = 1; } } fprintf(stderr, "success!\n"); fprintf(stderr,/* "num_sym=%zu mem_sym=%zu unique_weights=%zu\n", */ "num_sym=%u mem_sym=%u unique_weights=%u\n", num_sym, mem_sym, unique_weights);/* twalk(root_weight, print_weight_node); */ fprintf(stderr, "num base locales = %d num derived locales = %d\n", base_locale_len, der_locale_len); fprintf(stderr, "override_len = %d multistart_len = %d weightstr_len = %d\n" "wcs2colidt_len = %d index2weight_len = %d index2ruleidx_len = %d\n" "ruletable_len = %d\n" "total size is %d bytes or %d kB\n", override_len, multistart_len, weightstr_len, wcs2colidt_len, index2weight_len, index2ruleidx_len, ruletable_len,#warning mult by 2 for rule indecies (override_len + multistart_len + weightstr_len + wcs2colidt_len + index2weight_len + index2ruleidx_len + ruletable_len) * 2, (override_len + multistart_len + weightstr_len + wcs2colidt_len + index2weight_len + index2ruleidx_len + ruletable_len + 511) / 512);#if 0 { int i; for (i=0 ; i < base_locale_len ; i++) { dump_base_locale(i); } for (i=0 ; i < der_locale_len ; i++) { dump_der_locale(i); } }#endif { FILE *fp = fopen("locale_collate.h", "w"); if (!fp) { error_msg("couldn't open output file!"); } dump_collate(fp); if (ferror(fp) || fclose(fp)) { error_msg("write error or close error for output file!\n"); } } return EXIT_SUCCESS;}static void error_msg(const char *fmt, ...) { va_list arg; fprintf(stderr, "Error: "); if (fno >= 0) { fprintf(stderr, "file %s (%d): ", fname[fno], lineno[fno]); } va_start(arg, fmt); vfprintf(stderr, fmt, arg); va_end(arg); fprintf(stderr, "\n"); exit(EXIT_FAILURE);}static void pushfile(char *filename){ static char fbuf[PATH_MAX]; snprintf(fbuf, PATH_MAX, "collation/%s", filename); if (fno >= MAX_FNO) { error_msg("file stack size exceeded"); } if (!(fstack[++fno] = fopen(fbuf, "r"))) { --fno; /* oops */ error_msg("cannot open file %s", fbuf); } fname[fno] = xsymdup(filename); lineno[fno] = 0;}static void popfile(void){ if (fno < 0) { error_msg("pop on empty file stack"); }/* free(fname[fno]); */ fclose(fstack[fno]); --fno;}static void eatwhitespace(void){ while (isspace(*pos)) { ++pos; }}static int iscommentchar(int c){ return ((c == '#') || (c == '%'));}static int next_line(void){ size_t n; char *s = linebuf; assert(fno >= 0); pos_e = NULL; do { if (fgets(s, sizeof(linebuf), fstack[fno]) != NULL) { ++lineno[fno]; n = strlen(linebuf); if ((n == sizeof(linebuf) - 1) && (linebuf[n-1] != '\n')) { /* Either line is too long or last line is very long with * no trailing newline. But we'll always treat it as an * errro. */ error_msg("line too long?"); } --n; /* Be careful... last line doesn't need a newline. */ if (linebuf[n] == '\n') { linebuf[n--] = 0; /* trim trailing newline */ } pos = linebuf; eatwhitespace(); if (*pos && !iscommentchar(*pos)) { /* not empty or comment line */ return 1; /* got a line */ } } else { /* eof */ popfile(); } } while (fno >= 0); return 0;}static char *next_token(void){ char *p;#if 0 if (pos_e == NULL) { return NULL pos = pos_e; *pos = end_of_token; end_of_token = 0; }#else if (pos_e != NULL) { pos = pos_e; *pos = end_of_token; end_of_token = 0; }#endif eatwhitespace(); p = pos; if (!*p || iscommentchar(*p)) { /* end of line or start of comment */ pos = pos_e = NULL; *p = 0; /* treat comment as end of line *//* fprintf(stdout, "returning NUL token |%s|\n", pos); */ return NULL;#if 1 } else if (*p == '<') { /* collating symbol, element, or value */ while (*++p) { if ((*p == '/') && p[1]) { ++p; continue; } if (*p == '>') { pos_e = ++p; end_of_token = *p; *p = 0;/* fprintf(stdout, "returning col token |%s|\n", pos); */ return pos; } } } else if (*p == '"') { /* collating element value? */ while (*++p) { if (*p == '"') { /* found the end of the quoted string */ pos_e = ++p; end_of_token = *p; *p = 0;/* fprintf(stdout, "returning quote token |%s|\n", pos); */ return pos; } }#endif } else { /* some kind of keyword */ while (*++p) { if (isspace(*p) || (*p == ';')) { break; } } pos_e = p; end_of_token = *p; *p = 0;/* fprintf(stdout, "returning key token |%s|\n", pos); */ return pos; } error_msg("illegal token |%s|", pos);}static void *xmalloc(size_t n){ void *p; if (!(p = malloc(n))) { error_msg("OUT OF MEMORY"); } return p;}static void do_copy(void){ char *s; char *e; if ((s = next_token()) != NULL) { e = strchr(s + 1, '"'); if ((*s == '"') && e && (*e == '"') && !e[1]) { if (next_token() != NULL) { error_msg("illegal trailing text: %s", pos); } *e = 0; ++s; if (cur_base && !strcmp(cur_base->name,s)) {/* fprintf(stderr, "skipping copy of base file %s\n", s); */#warning need to update last in order and position or check return; }/* fprintf(stderr, "full copy of %s\n", s); */ pushfile(s); return; } } error_msg("illegal or missing arg for copy: %s", s);}static void do_colsym(void){ char *s; char *e; if ((s = next_token()) != NULL) { e = strrchr(s,'>'); if ((*s == '<') && e && (*e == '>') && !e[1]) { if (next_token() != NULL) { error_msg("illegal trailing text: %s", pos); } e[1] = 0; /* cleanup in case next_token stored something */ add_colitem(s,NULL); return; } } error_msg("illegal or missing arg for collating-symbol: %s", s);}static void do_colele(void){ char *s; char *e; char *s1; char *e1; int n; if ((s = next_token()) != NULL) { e = strrchr(s,'>'); if ((*s == '<') && e && (*e == '>') && !e[1]) { if (((s1 = next_token()) == NULL) || (strcmp(s1,"from") != 0) || ((s1 = next_token()) == NULL) || (*s1 != '\"') ) { error_msg("illegal format for collating-element spec"); } e1 = strchr(s1 + 1, '"'); if ((*s1 != '"') || !e1 || (*e1 != '"') || (e1[1] != 0)) { error_msg("illegal definition for collating-element: %s", s1); } if (next_token() != NULL) { error_msg("illegal trailing text: %s", pos); } e[1] = 0; /* cleanup in case next_token stored something */ e1[1] = 0; add_colitem(s,s1); ++s1; if (!(n = is_ucode(s1))) { error_msg("starting char must be a <U####> code: %s", s1); } assert(s1[n] == '<'); s1[n] = 0; s = xsymdup(s1); if (!(tsearch(s, &cur_base->root_starter_char, sym_cmp))) { error_msg("OUT OF MEMORY"); } return; } } error_msg("illegal or missing arg for collating-element: %s", s);}static ll_item_t *find_section_list_item(const char *name, col_locale_t *loc){ ll_item_t *p; if (!loc) { return NULL; } p = loc->section_list; while (p) {#warning devel code/* if (!((p->data_type == DT_SECTION) || (p->data_type == DT_REORDER))) { *//* fprintf(stderr, "fsli = %d\n", p->data_type); *//* } */ assert((p->data_type == DT_SECTION) || (p->data_type == DT_REORDER)); if (!strcmp(name, ((section_t *)(p->data))->name)) { break; } p = p->next; } return p;}static ll_item_t *find_ll_last(ll_item_t *p){ assert(p); while (p->next) { p = p->next; } return p;}static void do_script(void){ char *s; char *e; if ((s = next_token()) != NULL) { e = strrchr(s,'>'); if ((*s == '<') && e && (*e == '>') && !e[1]) { if (next_token() != NULL) { error_msg("illegal trailing text: %s", pos); } e[1] = 0; /* cleanup in case next_token stored something */ add_script(s); return; } } error_msg("illegal or missing arg for script: %s", s);}static col_locale_t *new_col_locale(char *name){ ll_item_t *lli; ll_item_t *lli2; cur_col = (col_locale_t *) xmalloc(sizeof(col_locale_t)); cur_col->name = name; cur_col->root_colitem = NULL; cur_col->root_element = NULL; cur_col->root_scripts = NULL; cur_col->base_locale = NULL; if (!superset) { /* start with an anonymous section */ cur_section = new_section(NULL); cur_col->section_list = new_ll_item(DT_SECTION, cur_section); } else { /* start with a reorder section */ cur_section = new_section("R"); cur_num_weights = cur_section->num_rules = ((section_t *)(cur_base->section_list->data))->num_rules; memcpy(cur_rule, ((section_t *)(cur_base->section_list->data))->rules, MAX_COLLATION_WEIGHTS); memcpy(cur_section->rules, ((section_t *)(cur_base->section_list->data))->rules, MAX_COLLATION_WEIGHTS); cur_col->section_list = new_ll_item(DT_REORDER, cur_section); assert(cur_base->section_list->next == NULL); /* currently only one section allowed */ lli = ((section_t *)(cur_base->section_list->data))->itm_list; assert(lli); lli2 = new_ll_item(DT_REORDER, cur_section); lli2->prev = lli2->next = lli2; insque(lli2, lli->prev); ((section_t *)(cur_base->section_list->data))->itm_list = lli2; }/* cur_col->section_list = NULL; *//* add_script(((section_t *)(cur_col->section_list->data))->name); */ cur_col->root_wi_index = NULL; cur_col->root_wi_index_reordered = NULL; cur_col->root_derived_wi = NULL; cur_col->derived_list = NULL; cur_col->root_starter_char = NULL; cur_col->root_starter_all = NULL; cur_col->undefined_idx = NULL; return cur_col;}static int colitem_cmp(const void *n1, const void *n2){ return strcmp(((colitem_t *)n1)->string, ((colitem_t *)n2)->string);}static int colelement_cmp(const void *n1, const void *n2){ int r; r = strcmp(((colitem_t *)n1)->string, ((colitem_t *)n2)->string); if (!r) { if (((colitem_t *)n1)->element && ((colitem_t *)n2)->element) { r = strcmp(((colitem_t *)n1)->element, ((colitem_t *)n2)->element); } else if (((colitem_t *)n1)->element == ((colitem_t *)n2)->element) { r = 0; /* both null */ } else { r = (((colitem_t *)n1)->element == NULL) ? -1 : 1; } } return r;}static void del_colitem(colitem_t *p){/* free((void *) p->element); *//* free((void *) p->string); */ free(p);}static colitem_t *new_colitem(char *item, char *def)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -