diff options
Diffstat (limited to 'extra/locale/gen_locale.c')
-rw-r--r-- | extra/locale/gen_locale.c | 1230 |
1 files changed, 605 insertions, 625 deletions
diff --git a/extra/locale/gen_locale.c b/extra/locale/gen_locale.c index 268c3d61b..1d50480ee 100644 --- a/extra/locale/gen_locale.c +++ b/extra/locale/gen_locale.c @@ -47,6 +47,7 @@ typedef struct { unsigned char lc_numeric_row; unsigned char lc_monetary_row; unsigned char lc_messages_row; + unsigned char lc_ctype_row; #if CATEGORIES != 6 #error unsupported CATEGORIES value #endif @@ -68,6 +69,7 @@ static void do_lc_numeric(void); static void do_lc_monetary(void); static void do_lc_messages(void); +static void do_lc_ctype(void); static FILE *fp; @@ -119,11 +121,23 @@ static void do_locale_names(void) fprintf(ofp, "\t%#4x, ", (int)((unsigned char) locales[i].dot_cs)); fprintf(ofp, "\t%#4x, ", (int)((unsigned char) locales[i].cs)); /* lc_ctype would store translit flags and turkish up/low flag. */ - fprintf(ofp, "%#4x, ", 0); /* place holder for lc_ctype */ + fprintf(ofp, "%#4x, ", (int)((unsigned char) locales[i].lc_ctype_row)); fprintf(ofp, "%#4x, ", (int)((unsigned char) locales[i].lc_numeric_row)); fprintf(ofp, "%#4x, ", (int)((unsigned char) locales[i].lc_monetary_row)); fprintf(ofp, "%#4x, ", (int)((unsigned char) locales[i].lc_time_row)); +#if 1 + /* lc_collate */ + if (strlen(locales[i].glibc_name) >= 5) { + fprintf(ofp, "COL_IDX_%.2s_%.2s, ", locales[i].glibc_name, locales[i].glibc_name+3); + } else if (!strcmp(locales[i].glibc_name, "C")) { + fprintf(ofp, "COL_IDX_C , "); + } else { + printf("don't know how to handle COL_IDX_ for %s\n", locales[i].glibc_name); + exit(EXIT_FAILURE); + } +#else fprintf(ofp, "%#4x, ", 0); /* place holder for lc_collate */ +#endif fprintf(ofp, "%#4x, ", (int)((unsigned char) locales[i].lc_messages_row)); fprintf(ofp, "\t/* %s */\n", locales[i].glibc_name); } @@ -213,6 +227,332 @@ static void do_locale_names(void) } +static void read_at_mappings(void) +{ + char *p; + char *m; + int mc = 0; + + do { + if (!(p = strtok(line_buf, " \t\n")) || (*p == '#')) { + if (!fgets(line_buf, sizeof(line_buf), fp)) { + if (ferror(fp)) { + printf("error reading file\n"); + exit(EXIT_FAILURE); + } + return; /* EOF */ + } + if ((*line_buf == '#') && (line_buf[1] == '-')) { + break; + } + continue; + } + if (*p == '@') { + if (p[1] == 0) { + printf("error: missing @modifier name\n"); + exit(EXIT_FAILURE); + } + m = p; /* save the modifier name */ + if (!(p = strtok(NULL, " \t\n")) || p[1] || (((unsigned char) *p) > 0x7f)) { + printf("error: missing or illegal @modifier mapping char\n"); + exit(EXIT_FAILURE); + } + if (at_mappings[(int)((unsigned char) *p)]) { + printf("error: reused @modifier mapping char\n"); + exit(EXIT_FAILURE); + } + at_mappings[(int)((unsigned char) *p)] = 1; + at_mapto[mc] = *p; + ++mc; + *at_strings_end = (char)( (unsigned char) (strlen(m)) ); + strcpy(++at_strings_end, m+1); + at_strings_end += (unsigned char) at_strings_end[-1]; + + printf("@mapping: \"%s\" to '%c'\n", m, *p); + + if (((p = strtok(NULL, " \t\n")) != NULL) && (*p != '#')) { + printf("ignoring trailing text: %s...\n", p); + } + *line_buf = 0; + continue; + } + break; + } while (1); + +#if 0 + { + p = at_strings; + + if (!*p) { + printf("no @ strings\n"); + return; + } + + do { + printf("%s\n", p+1); + p += 1 + (unsigned char) *p; + } while (*p); + } +#endif +} + +static void read_enable_disable(void) +{ + char *p; + + do { + if (!(p = strtok(line_buf, " =\t\n")) || (*p == '#')) { + if (!fgets(line_buf, sizeof(line_buf), fp)) { + if (ferror(fp)) { + printf("error reading file\n"); + exit(EXIT_FAILURE); + } + return; /* EOF */ + } + if ((*line_buf == '#') && (line_buf[1] == '-')) { + break; + } + continue; + } + if (!strcmp(p, "UTF-8")) { + if (!(p = strtok(NULL, " =\t\n")) + || ((toupper(*p) != 'Y') && (toupper(*p) != 'N'))) { + printf("error: missing or illegal UTF-8 setting\n"); + exit(EXIT_FAILURE); + } + default_utf8 = (toupper(*p) == 'Y'); + printf("UTF-8 locales are %sabled\n", "dis\0en"+ (default_utf8 << 2)); + } else if (!strcmp(p, "8-BIT")) { + if (!(p = strtok(NULL, " =\t\n")) + || ((toupper(*p) != 'Y') && (toupper(*p) != 'N'))) { + printf("error: missing or illegal 8-BIT setting\n"); + exit(EXIT_FAILURE); + } + default_8bit = (toupper(*p) == 'Y'); + printf("8-BIT locales are %sabled\n", "dis\0en" + (default_8bit << 2)); + } else { + break; + } + + if (((p = strtok(NULL, " \t\n")) != NULL) && (*p != '#')) { + printf("ignoring trailing text: %s...\n", p); + } + *line_buf = 0; + continue; + + } while (1); +} + +#ifdef CODESET_LIST + +static int find_codeset_num(const char *cs) +{ + int r = 2; + char *s = CODESET_LIST; + + /* 7-bit is 1, UTF-8 is 2, 8-bits are > 2 */ + + if (strcmp(cs, "UTF-8") != 0) { + ++r; + while (*s && strcmp(CODESET_LIST+ ((unsigned char) *s), cs)) { +/* printf("tried %s\n", CODESET_LIST + ((unsigned char) *s)); */ + ++r; + ++s; + } + if (!*s) { + printf("error: unsupported codeset %s\n", cs); + exit(EXIT_FAILURE); + } + } + return r; +} + +#else + +static int find_codeset_num(const char *cs) +{ + int r = 2; + + /* 7-bit is 1, UTF-8 is 2, 8-bits are > 2 */ + + if (strcmp(cs, "UTF-8") != 0) { + printf("error: unsupported codeset %s\n", cs); + exit(EXIT_FAILURE); + } + return r; +} + +#endif + +static int find_at_string_num(const char *as) +{ + int i = 0; + char *p = at_strings; + + while (*p) { + if (!strcmp(p+1, as)) { + return i; + } + ++i; + p += 1 + (unsigned char) *p; + } + + printf("error: unmapped @string %s\n", as); + exit(EXIT_FAILURE); +} + +static void read_locale_list(void) +{ + char *p; + char *s; + char *ln; /* locale name */ + char *ls; /* locale name ll_CC */ + char *as; /* at string */ + char *ds; /* dot string */ + char *cs; /* codeset */ + int i; + + typedef struct { + char *glibc_name; + char name[5]; + char dot_cs; /* 0 if no codeset specified */ + char cs; + } locale_entry; + + /* First the C locale. */ + locales[0].glibc_name = locales[0].name; + strncpy(locales[0].name,"C",5); + locales[0].dot_cs = 0; + locales[0].cs = 1; /* 7-bit encoding */ + ++num_locales; + + do { + if (!(p = strtok(line_buf, " \t\n")) || (*p == '#')) { + if (!fgets(line_buf, sizeof(line_buf), fp)) { + if (ferror(fp)) { + printf("error reading file\n"); + exit(EXIT_FAILURE); + } + return; /* EOF */ + } + if ((*line_buf == '#') && (line_buf[1] == '-')) { + break; + } + continue; + } + + s = glibc_locale_names; + for (i=0 ; i < num_locales ; i++) { + if (!strcmp(s+1, p)) { + break; + } + s += 1 + ((unsigned char) *s); + } + if (i < num_locales) { + printf("ignoring dulplicate locale name: %s", p); + *line_buf = 0; + continue; + } + + /* New locale, but don't increment num until codeset verified! */ + *s = (char)((unsigned char) (strlen(p) + 1)); + strcpy(s+1, p); + locales[num_locales].glibc_name = s+1; + ln = p; /* save locale name */ + + if (!(p = strtok(NULL, " \t\n"))) { + printf("error: missing codeset for locale %s\n", ln); + exit(EXIT_FAILURE); + } + cs = p; + i = find_codeset_num(p); + if ((i == 2) && !default_utf8) { + printf("ignoring UTF-8 locale %s\n", ln); + *line_buf = 0; + continue; + } else if ((i > 2) && !default_8bit) { + printf("ignoring 8-bit codeset locale %s\n", ln); + *line_buf = 0; + continue; + } + locales[num_locales].cs = (char)((unsigned char) i); + + if (((p = strtok(NULL, " \t\n")) != NULL) && (*p != '#')) { + printf("ignoring trailing text: %s...\n", p); + } + + /* Now go back to locale string for .codeset and @modifier */ + as = strtok(ln, "@"); + if (as) { + as = strtok(NULL, "@"); + } + ds = strtok(ln, "."); + if (ds) { + ds = strtok(NULL, "."); + } + ls = ln; + + if ((strlen(ls) != 5) || (ls[2] != '_')) { + printf("error: illegal locale name %s\n", ls); + exit(EXIT_FAILURE); + } + + i = 0; /* value for unspecified codeset */ + if (ds) { + i = find_codeset_num(ds); + if ((i == 2) && !default_utf8) { + printf("ignoring UTF-8 locale %s\n", ln); + *line_buf = 0; + continue; + } else if ((i > 2) && !default_8bit) { + printf("ignoring 8-bit codeset locale %s\n", ln); + *line_buf = 0; + continue; + } + } + locales[num_locales].dot_cs = (char)((unsigned char) i); + + if (as) { + i = find_at_string_num(as); + ls[2] = at_mapto[i]; + } + memcpy(locales[num_locales].name, ls, 5); +/* printf("locale: %5.5s %2d %2d %s\n", */ +/* locales[num_locales].name, */ +/* locales[num_locales].cs, */ +/* locales[num_locales].dot_cs, */ +/* locales[num_locales].glibc_name */ +/* ); */ + ++num_locales; + *line_buf = 0; + } while (1); +} + +static int le_cmp(const void *a, const void *b) +{ + const locale_entry *p; + const locale_entry *q; + int r; + + p = (const locale_entry *) a; + q = (const locale_entry *) b; + + if (!(r = p->name[0] - q->name[0]) + && !(r = p->name[1] - q->name[1]) + && !(r = p->name[3] - q->name[3]) + && !(r = p->name[4] - q->name[4]) + && !(r = p->name[2] - q->name[2]) + && !(r = -(p->cs - q->cs)) + ) { + r = -(p->dot_cs - q->dot_cs); + /* Reverse the ordering of the codesets so UTF-8 comes last. + * Work-around (hopefully) for glibc bug affecting at least + * the euro currency symbol. */ + } + + return r; +} + int main(int argc, char **argv) { if ((argc != 2) || (!(fp = fopen(*++argv, "r")))) { @@ -251,6 +591,7 @@ int main(int argc, char **argv) do_lc_numeric(); do_lc_monetary(); do_lc_messages(); + do_lc_ctype(); do_locale_names(); @@ -267,6 +608,36 @@ static char buf[100000]; static char *last; static int uniq; +static int addblock(const char *s, size_t n) /* l includes nul terminator */ +{ + int j; + + if (!s) { + ++null_count; + return 0; + } + + for (j=0 ; (j < uniq) && (idx[j] + n < last) ; j++) { + if (!memcmp(s, idx[j], n)) { + return idx[j] - buf; + } + } + if (uniq >= sizeof(idx)) { + printf("too many uniq strings!\n"); + exit(EXIT_FAILURE); + } + if (last + n >= buf + sizeof(buf)) { + printf("need to increase size of buf!\n"); + exit(EXIT_FAILURE); + } + + idx[uniq] = last; + ++uniq; + memcpy(last, s, n); + last += n; + return idx[uniq - 1] - buf; +} + static int addstring(const char *s) { int j; @@ -299,20 +670,178 @@ static int addstring(const char *s) return idx[uniq - 1] - buf; } -static int buf16[50*256]; +#define DO_LC_COMMON(CATEGORY) \ + printf("buf-size=%d uniq=%d rows=%d\n", \ + (int)(last - buf), uniq, lc_##CATEGORY##_uniq); \ + printf("total = %d + %d * %d + %d = %d\n", \ + num_locales, lc_##CATEGORY##_uniq, NUM_NL_##CATEGORY, (int)(last - buf), \ + i = num_locales + lc_##CATEGORY##_uniq*NUM_NL_##CATEGORY + (int)(last - buf)); \ + total_size += i; \ + dump_table8c("__lc_" #CATEGORY "_data", buf, (int)(last - buf)); \ + for (i=0 ; i < lc_##CATEGORY##_uniq ; i++) { \ + m = locales[i].lc_##CATEGORY##_row; \ + for (k=0 ; k < NUM_NL_##CATEGORY ; k++) { \ + buf[NUM_NL_##CATEGORY*i + k] = (char)((unsigned char) lc_##CATEGORY##_uniq_X[i][k]); \ + } \ + } \ + dump_table8("__lc_" #CATEGORY "_rows", buf, lc_##CATEGORY##_uniq * NUM_NL_##CATEGORY); \ + buf16[0] =0; \ + for (i=0 ; i < NUM_NL_##CATEGORY - 1 ; i++) { \ + buf16[i+1] = buf16[i] + lc_##CATEGORY##_count[i]; \ + } \ + dump_table16("__lc_" #CATEGORY "_item_offsets", buf16, NUM_NL_##CATEGORY); \ + m = 0; \ + for (k=0 ; k < NUM_NL_##CATEGORY ; k++) { \ + for (i=0 ; i < lc_##CATEGORY##_count[k] ; i++) { \ + buf16[m] = lc_##CATEGORY##_item[k][i]; \ + ++m; \ + } \ + } \ + dump_table16("__lc_" #CATEGORY "_item_idx", buf16, m); + + +#define DL_LC_LOOPTAIL(CATEGORY) \ + if (k > NUM_NL_##CATEGORY) { \ + printf("error -- lc_" #CATEGORY " nl_item count > %d!\n", NUM_NL_##CATEGORY); \ + exit(EXIT_FAILURE); \ + } \ + { \ + int r; \ + for (r=0 ; r < lc_##CATEGORY##_uniq ; r++) { \ + if (!memcmp(lc_##CATEGORY##_uniq_X[lc_##CATEGORY##_uniq], \ + lc_##CATEGORY##_uniq_X[r], NUM_NL_##CATEGORY)) { \ + break; \ + } \ + } \ + if (r == lc_##CATEGORY##_uniq) { /* new locale row */ \ + ++lc_##CATEGORY##_uniq; \ + if (lc_##CATEGORY##_uniq > 255) { \ + printf("too many unique lc_" #CATEGORY " rows!\n"); \ + exit(EXIT_FAILURE); \ + } \ + } \ + locales[i].lc_##CATEGORY##_row = r; \ + } + + + +static int buf16[100*256]; + +static void dump_table8(const char *name, const char *tbl, int len) +{ + int i; + + fprintf(ofp, "#define %s_LEN\t\t%d\n", name, len); + fprintf(ofp, "static const unsigned char %s[%d] = {", name, len); + for (i=0 ; i < len ; i++) { + if ((i % 12) == 0) { + fprintf(ofp, "\n\t"); + } + fprintf(ofp, "%#4x, ", (int)((unsigned char) tbl[i])); + } + fprintf(ofp, "\n};\n\n"); +} + +#define __C_isdigit(c) \ + ((sizeof(c) == sizeof(char)) \ + ? (((unsigned char)((c) - '0')) < 10) \ + : (((unsigned int)((c) - '0')) < 10)) +#define __C_isalpha(c) \ + ((sizeof(c) == sizeof(char)) \ + ? (((unsigned char)(((c) | 0x20) - 'a')) < 26) \ + : (((unsigned int)(((c) | 0x20) - 'a')) < 26)) +#define __C_isalnum(c) (__C_isalpha(c) || __C_isdigit(c)) + +static void dump_table8c(const char *name, const char *tbl, int len) +{ + int i; + + fprintf(ofp, "#define %s_LEN\t\t%d\n", name, len); + fprintf(ofp, "static const unsigned char %s[%d] = {", name, len); + for (i=0 ; i < len ; i++) { + if ((i % 12) == 0) { + fprintf(ofp, "\n\t"); + } + if (__C_isalnum(tbl[i]) || (tbl[i] == ' ')) { + fprintf(ofp, " '%c', ", (int)((unsigned char) tbl[i])); + } else { + fprintf(ofp, "%#4x, ", (int)((unsigned char) tbl[i])); + } + } + fprintf(ofp, "\n};\n\n"); +} + +static void dump_table16(const char *name, const int *tbl, int len) +{ + int i; + + fprintf(ofp, "#define %s_LEN\t\t%d\n", name, len); + fprintf(ofp, "static const uint16_t %s[%d] = {", name, len); + for (i=0 ; i < len ; i++) { + if ((i % 8) == 0) { + fprintf(ofp, "\n\t"); + } + if (tbl[i] != (uint16_t) tbl[i]) { + printf("error - falls outside uint16 range!\n"); + exit(EXIT_FAILURE); + } + fprintf(ofp, "%#6x, ", tbl[i]); + } + fprintf(ofp, "\n};\n\n"); +} + +#define NUM_NL_time 50 -static int lc_time_item[50][256]; -static int lc_time_count[50]; -static unsigned char lc_time_uniq_50[700][50]; +static int lc_time_item[NUM_NL_time][256]; +static int lc_time_count[NUM_NL_time]; +static unsigned char lc_time_uniq_X[700][NUM_NL_time]; static int lc_time_uniq; #define DO_NL_S(X) lc_time_S(X, k++) static void lc_time_S(int X, int k) { + size_t len; int j, m; - j = addstring(nl_langinfo(X)); + const char *s = nl_langinfo(X); + const char *p; + static const char nulbuf[] = ""; + + if (X == ALT_DIGITS) { + len = 1; + if (!s) { + s = nulbuf; + } + if (*s) { + p = s; + for (j = 0 ; j < 100 ; j++) { + while (*p) { + ++p; + } + ++p; + } + len = p - s; + } + j = addblock(s, len); +/* if (len > 1) fprintf(stderr, "alt_digit: called addblock with len %zd\n", len); */ + } else if (X == ERA) { + if (!s) { + s = nulbuf; + } + p = s; + while (*p) { + while (*p) { + ++p; + } + ++p; + } + ++p; + j = addblock(s, p - s); +/* if (p-s > 1) fprintf(stderr, "era: called addblock with len %d\n", p-s); */ + } else { + j = addstring(s); + } for (m=0 ; m < lc_time_count[k] ; m++) { if (lc_time_item[k][m] == j) { break; @@ -326,8 +855,7 @@ static void lc_time_S(int X, int k) lc_time_item[k][m] = j; ++lc_time_count[k]; } -/* printf("\\x%02x", m); */ - lc_time_uniq_50[lc_time_uniq][k] = m; + lc_time_uniq_X[lc_time_uniq][k] = m; } static void do_lc_time(void) @@ -339,11 +867,9 @@ static void do_lc_time(void) *buf = 0; *idx = buf; -/* printf("processing lc_time..."); */ for (i=0 ; i < num_locales ; i++) { k = 0; -/* printf(" %d", i); fflush(stdout); */ if (!setlocale(LC_ALL, locales[i].glibc_name)) { printf("setlocale(LC_ALL,%s) failed!\n", locales[i].glibc_name); @@ -406,143 +932,19 @@ static void do_lc_time(void) DO_NL_S(ERA_D_T_FMT); DO_NL_S(ERA_T_FMT); - if (k > 50) { - printf("error -- lc_time nl_item count > 50!\n"); - exit(EXIT_FAILURE); - } - - { - int r; - for (r=0 ; r < lc_time_uniq ; r++) { - if (!memcmp(lc_time_uniq_50[lc_time_uniq], - lc_time_uniq_50[r], 50)) { - break; - } - } - if (r == lc_time_uniq) { /* new locale row */ - ++lc_time_uniq; - if (lc_time_uniq > 255) { - printf("too many unique lc_time rows!\n"); - exit(EXIT_FAILURE); - } - } - locales[i].lc_time_row = r; - } -/* printf("\n"); */ - } -/* printf(" done\n"); */ - - m = k = 0; - for (i=0 ; i < 50 ; i++) { - k += lc_time_count[i]; - if (m < lc_time_count[i]) { - m = lc_time_count[i]; - } - } - printf("buf-size=%d uniq=%d item_offsets=%d max=%d rows=%d\n", - (int)(last - buf), uniq, k, m, lc_time_uniq); -/* printf("total = %d * 50 + 2 * (50 + %d) + %d = %d\n", */ -/* num_locales, k, (int)(last - buf), */ -/* num_locales*50 + 2*(50 + k) + (int)(last - buf)); */ - printf("total = %d + %d * 50 + 2 * (50 + %d) + %d = %d\n", - num_locales, lc_time_uniq, k, (int)(last - buf), - i = num_locales + lc_time_uniq*50 + 2*(50 + k) + (int)(last - buf)); - total_size += i; - - dump_table8c("__lc_time_data", buf, (int)(last - buf)); - - for (i=0 ; i < lc_time_uniq ; i++) { - m = locales[i].lc_time_row; - for (k=0 ; k < 50 ; k++) { - buf[50*i + k] = (char)((unsigned char) lc_time_uniq_50[i][k]); - } - } - dump_table8("__lc_time_rows", buf, lc_time_uniq * 50); - - buf16[0] =0; - for (i=0 ; i < 50 - 1 ; i++) { - buf16[i+1] = buf16[i] + lc_time_count[i]; - } - dump_table16("__lc_time_item_offsets", buf16, 50); - - m = 0; - for (k=0 ; k < 50 ; k++) { - for (i=0 ; i < lc_time_count[k] ; i++) { - buf16[m] = lc_time_item[k][i]; - ++m; - } - } - dump_table16("__lc_time_item_idx", buf16, m); -} - -static void dump_table8(const char *name, const char *tbl, int len) -{ - int i; - - fprintf(ofp, "#define %s_LEN\t\t%d\n", name, len); - fprintf(ofp, "static const unsigned char %s[%d] = {", name, len); - for (i=0 ; i < len ; i++) { - if ((i % 12) == 0) { - fprintf(ofp, "\n\t"); - } - fprintf(ofp, "%#4x, ", (int)((unsigned char) tbl[i])); + DL_LC_LOOPTAIL(time) } - fprintf(ofp, "\n};\n\n"); -} - -#define __C_isdigit(c) \ - ((sizeof(c) == sizeof(char)) \ - ? (((unsigned char)((c) - '0')) < 10) \ - : (((unsigned int)((c) - '0')) < 10)) -#define __C_isalpha(c) \ - ((sizeof(c) == sizeof(char)) \ - ? (((unsigned char)(((c) | 0x20) - 'a')) < 26) \ - : (((unsigned int)(((c) | 0x20) - 'a')) < 26)) -#define __C_isalnum(c) (__C_isalpha(c) || __C_isdigit(c)) - -static void dump_table8c(const char *name, const char *tbl, int len) -{ - int i; - fprintf(ofp, "#define %s_LEN\t\t%d\n", name, len); - fprintf(ofp, "static const unsigned char %s[%d] = {", name, len); - for (i=0 ; i < len ; i++) { - if ((i % 12) == 0) { - fprintf(ofp, "\n\t"); - } - if (__C_isalnum(tbl[i]) || (tbl[i] == ' ')) { - fprintf(ofp, " '%c', ", (int)((unsigned char) tbl[i])); - } else { - fprintf(ofp, "%#4x, ", (int)((unsigned char) tbl[i])); - } - } - fprintf(ofp, "\n};\n\n"); -} - -static void dump_table16(const char *name, const int *tbl, int len) -{ - int i; - - fprintf(ofp, "#define %s_LEN\t\t%d\n", name, len); - fprintf(ofp, "static const uint16_t %s[%d] = {", name, len); - for (i=0 ; i < len ; i++) { - if ((i % 8) == 0) { - fprintf(ofp, "\n\t"); - } - if (tbl[i] != (uint16_t) tbl[i]) { - printf("error - falls outside uint16 range!\n"); - exit(EXIT_FAILURE); - } - fprintf(ofp, "%#6x, ", tbl[i]); - } - fprintf(ofp, "\n};\n\n"); + DO_LC_COMMON(time) } #undef DO_NL_S -static int lc_numeric_item[3][256]; -static int lc_numeric_count[3]; -static unsigned char lc_numeric_uniq_3[700][3]; +#define NUM_NL_numeric 3 + +static int lc_numeric_item[NUM_NL_numeric][256]; +static int lc_numeric_count[NUM_NL_numeric]; +static unsigned char lc_numeric_uniq_X[700][NUM_NL_numeric]; static int lc_numeric_uniq; #define DO_NL_S(X) lc_numeric_S(X, k++) @@ -606,7 +1008,7 @@ static void lc_numeric_S(int X, int k) ++lc_numeric_count[k]; } /* printf("\\x%02x", m); */ - lc_numeric_uniq_3[lc_numeric_uniq][k] = m; + lc_numeric_uniq_X[lc_numeric_uniq][k] = m; } static void do_lc_numeric(void) @@ -630,74 +1032,19 @@ static void do_lc_numeric(void) DO_NL_S(THOUSEP); /* THOUSANDS_SEP */ DO_NL_S(GROUPING); - if (k > 3) { - printf("error -- lc_numeric nl_item count > 3!\n"); - exit(EXIT_FAILURE); - } - - { - int r; - for (r=0 ; r < lc_numeric_uniq ; r++) { - if (!memcmp(lc_numeric_uniq_3[lc_numeric_uniq], - lc_numeric_uniq_3[r], 3)) { - break; - } - } - if (r == lc_numeric_uniq) { /* new locale row */ - ++lc_numeric_uniq; - if (lc_numeric_uniq > 255) { - printf("too many unique lc_numeric rows!\n"); - exit(EXIT_FAILURE); - } - } - locales[i].lc_numeric_row = r; - } - } - - printf("buf-size=%d uniq=%d rows=%d\n", - (int)(last - buf), uniq, lc_numeric_uniq); - printf("total = %d + %d * 3 + %d = %d\n", - num_locales, lc_numeric_uniq, (int)(last - buf), - i = num_locales + lc_numeric_uniq*3 + (int)(last - buf)); - total_size += i; - -/* printf("buf-size=%d uniq=%d\n", (int)(last - buf), uniq); */ - - dump_table8c("__lc_numeric_data", buf, (int)(last - buf)); - - - for (i=0 ; i < lc_numeric_uniq ; i++) { - m = locales[i].lc_numeric_row; - for (k=0 ; k < 3 ; k++) { - buf[3*i + k] = (char)((unsigned char) lc_numeric_uniq_3[i][k]); - } - } - dump_table8("__lc_numeric_rows", buf, lc_numeric_uniq * 3); - - buf16[0] =0; - for (i=0 ; i < 3 - 1 ; i++) { - buf16[i+1] = buf16[i] + lc_numeric_count[i]; + DL_LC_LOOPTAIL(numeric) } - dump_table16("__lc_numeric_item_offsets", buf16, 3); - m = 0; - for (k=0 ; k < 3 ; k++) { - for (i=0 ; i < lc_numeric_count[k] ; i++) { - buf16[m] = lc_numeric_item[k][i]; - ++m; - } - } - dump_table16("__lc_numeric_item_idx", buf16, m); + DO_LC_COMMON(numeric) } #undef DO_NL_S -/* #define NUM_NL_MONETARY 7 */ -#define NUM_NL_MONETARY (7+14+1) +#define NUM_NL_monetary (7+14+1) -static int lc_monetary_item[NUM_NL_MONETARY][256]; -static int lc_monetary_count[NUM_NL_MONETARY]; -static unsigned char lc_monetary_uniq_X[700][NUM_NL_MONETARY]; +static int lc_monetary_item[NUM_NL_monetary][256]; +static int lc_monetary_count[NUM_NL_monetary]; +static unsigned char lc_monetary_uniq_X[700][NUM_NL_monetary]; static int lc_monetary_uniq; #define DO_NL_S(X) lc_monetary_S(X, k++) @@ -838,71 +1185,20 @@ static void do_lc_monetary(void) DO_NL_S(CRNCYSTR); /* CURRENCY_SYMBOL */ -/* printf("\n"); */ - - if (k > NUM_NL_MONETARY) { - printf("error -- lc_monetary nl_item count > %d!\n", NUM_NL_MONETARY); - exit(EXIT_FAILURE); - } - - { - int r; - for (r=0 ; r < lc_monetary_uniq ; r++) { - if (!memcmp(lc_monetary_uniq_X[lc_monetary_uniq], - lc_monetary_uniq_X[r], NUM_NL_MONETARY)) { - break; - } - } - if (r == lc_monetary_uniq) { /* new locale row */ - ++lc_monetary_uniq; - if (lc_monetary_uniq > 255) { - printf("too many unique lc_monetary rows!\n"); - exit(EXIT_FAILURE); - } - } - locales[i].lc_monetary_row = r; - } - } - - printf("buf-size=%d uniq=%d rows=%d\n", - (int)(last - buf), uniq, lc_monetary_uniq); - printf("total = %d + %d * %d + %d = %d\n", - num_locales, lc_monetary_uniq, NUM_NL_MONETARY, (int)(last - buf), - i = num_locales + lc_monetary_uniq*NUM_NL_MONETARY + (int)(last - buf)); - total_size += i; - - dump_table8c("__lc_monetary_data", buf, (int)(last - buf)); - - for (i=0 ; i < lc_monetary_uniq ; i++) { - m = locales[i].lc_monetary_row; - for (k=0 ; k < NUM_NL_MONETARY ; k++) { - buf[NUM_NL_MONETARY*i + k] = (char)((unsigned char) lc_monetary_uniq_X[i][k]); - } - } - dump_table8("__lc_monetary_rows", buf, lc_monetary_uniq * NUM_NL_MONETARY); - - buf16[0] =0; - for (i=0 ; i < NUM_NL_MONETARY - 1 ; i++) { - buf16[i+1] = buf16[i] + lc_monetary_count[i]; + DL_LC_LOOPTAIL(monetary) } - dump_table16("__lc_monetary_item_offsets", buf16, NUM_NL_MONETARY); - m = 0; - for (k=0 ; k < NUM_NL_MONETARY ; k++) { - for (i=0 ; i < lc_monetary_count[k] ; i++) { - buf16[m] = lc_monetary_item[k][i]; - ++m; - } - } - dump_table16("__lc_monetary_item_idx", buf16, m); + DO_LC_COMMON(monetary) } #undef DO_NL_S -static int lc_messages_item[2][256]; -static int lc_messages_count[2]; -static unsigned char lc_messages_uniq_2[700][2]; +#define NUM_NL_messages 4 + +static int lc_messages_item[NUM_NL_messages][256]; +static int lc_messages_count[NUM_NL_messages]; +static unsigned char lc_messages_uniq_X[700][NUM_NL_messages]; static int lc_messages_uniq; #define DO_NL_S(X) lc_messages_S(X, k++) @@ -925,7 +1221,7 @@ static void lc_messages_S(int X, int k) ++lc_messages_count[k]; } /* printf("\\x%02x", m); */ - lc_messages_uniq_2[lc_messages_uniq][k] = m; + lc_messages_uniq_X[lc_messages_uniq][k] = m; } static void do_lc_messages(void) @@ -947,393 +1243,77 @@ static void do_lc_messages(void) DO_NL_S(YESEXPR); DO_NL_S(NOEXPR); + DO_NL_S(YESSTR); + DO_NL_S(NOSTR); - if (k > 2) { - printf("error -- lc_messages nl_item count > 2!\n"); - exit(EXIT_FAILURE); - } - - { - int r; - for (r=0 ; r < lc_messages_uniq ; r++) { - if (!memcmp(lc_messages_uniq_2[lc_messages_uniq], - lc_messages_uniq_2[r], 2)) { - break; - } - } - if (r == lc_messages_uniq) { /* new locale row */ - ++lc_messages_uniq; - if (lc_messages_uniq > 255) { - printf("too many unique lc_messages rows!\n"); - exit(EXIT_FAILURE); - } - } - locales[i].lc_messages_row = r; - } - } - - printf("buf-size=%d uniq=%d rows=%d\n", - (int)(last - buf), uniq, lc_messages_uniq); - printf("total = %d + %d * 2 + %d = %d\n", - num_locales, lc_messages_uniq, (int)(last - buf), - i = num_locales + lc_messages_uniq*2 + (int)(last - buf)); - total_size += i; - -/* printf("buf-size=%d uniq=%d\n", (int)(last - buf), uniq); */ - - dump_table8c("__lc_messages_data", buf, (int)(last - buf)); - - for (i=0 ; i < lc_messages_uniq ; i++) { - m = locales[i].lc_messages_row; - for (k=0 ; k < 2 ; k++) { - buf[2*i + k] = (char)((unsigned char) lc_messages_uniq_2[i][k]); - } - } - dump_table8("__lc_messages_rows", buf, lc_messages_uniq * 2); - - buf16[0] =0; - for (i=0 ; i < 2 - 1 ; i++) { - buf16[i+1] = buf16[i] + lc_messages_count[i]; + DL_LC_LOOPTAIL(messages) } - dump_table16("__lc_messages_item_offsets", buf16, 2); - m = 0; - for (k=0 ; k < 2 ; k++) { - for (i=0 ; i < lc_messages_count[k] ; i++) { - buf16[m] = lc_messages_item[k][i]; - ++m; - } - } - dump_table16("__lc_messages_item_idx", buf16, m); + DO_LC_COMMON(messages) } +#undef DO_NL_S +#define NUM_NL_ctype 10 +static int lc_ctype_item[NUM_NL_ctype][256]; +static int lc_ctype_count[NUM_NL_ctype]; +static unsigned char lc_ctype_uniq_X[700][NUM_NL_ctype]; +static int lc_ctype_uniq; +#define DO_NL_S(X) lc_ctype_S(X, k++) -static void read_at_mappings(void) -{ - char *p; - char *m; - int mc = 0; - - do { - if (!(p = strtok(line_buf, " \t\n")) || (*p == '#')) { - if (!fgets(line_buf, sizeof(line_buf), fp)) { - if (ferror(fp)) { - printf("error reading file\n"); - exit(EXIT_FAILURE); - } - return; /* EOF */ - } - if ((*line_buf == '#') && (line_buf[1] == '-')) { - break; - } - continue; - } - if (*p == '@') { - if (p[1] == 0) { - printf("error: missing @modifier name\n"); - exit(EXIT_FAILURE); - } - m = p; /* save the modifier name */ - if (!(p = strtok(NULL, " \t\n")) || p[1] || (((unsigned char) *p) > 0x7f)) { - printf("error: missing or illegal @modifier mapping char\n"); - exit(EXIT_FAILURE); - } - if (at_mappings[(int)((unsigned char) *p)]) { - printf("error: reused @modifier mapping char\n"); - exit(EXIT_FAILURE); - } - at_mappings[(int)((unsigned char) *p)] = 1; - at_mapto[mc] = *p; - ++mc; - *at_strings_end = (char)( (unsigned char) (strlen(m)) ); - strcpy(++at_strings_end, m+1); - at_strings_end += (unsigned char) at_strings_end[-1]; - - printf("@mapping: \"%s\" to '%c'\n", m, *p); - - if (((p = strtok(NULL, " \t\n")) != NULL) && (*p != '#')) { - printf("ignoring trailing text: %s...\n", p); - } - *line_buf = 0; - continue; - } - break; - } while (1); - -#if 0 - { - p = at_strings; - - if (!*p) { - printf("no @ strings\n"); - return; - } - - do { - printf("%s\n", p+1); - p += 1 + (unsigned char) *p; - } while (*p); - } -#endif -} - -static void read_enable_disable(void) +static void lc_ctype_S(int X, int k) { - char *p; - - do { - if (!(p = strtok(line_buf, " =\t\n")) || (*p == '#')) { - if (!fgets(line_buf, sizeof(line_buf), fp)) { - if (ferror(fp)) { - printf("error reading file\n"); - exit(EXIT_FAILURE); - } - return; /* EOF */ - } - if ((*line_buf == '#') && (line_buf[1] == '-')) { - break; - } - continue; - } - if (!strcmp(p, "UTF-8")) { - if (!(p = strtok(NULL, " =\t\n")) - || ((toupper(*p) != 'Y') && (toupper(*p) != 'N'))) { - printf("error: missing or illegal UTF-8 setting\n"); - exit(EXIT_FAILURE); - } - default_utf8 = (toupper(*p) == 'Y'); - printf("UTF-8 locales are %sabled\n", "dis\0en"+ (default_utf8 << 2)); - } else if (!strcmp(p, "8-BIT")) { - if (!(p = strtok(NULL, " =\t\n")) - || ((toupper(*p) != 'Y') && (toupper(*p) != 'N'))) { - printf("error: missing or illegal 8-BIT setting\n"); - exit(EXIT_FAILURE); - } - default_8bit = (toupper(*p) == 'Y'); - printf("8-BIT locales are %sabled\n", "dis\0en" + (default_8bit << 2)); - } else { + int j, m; + j = addstring(nl_langinfo(X)); + for (m=0 ; m < lc_ctype_count[k] ; m++) { + if (lc_ctype_item[k][m] == j) { break; } - - if (((p = strtok(NULL, " \t\n")) != NULL) && (*p != '#')) { - printf("ignoring trailing text: %s...\n", p); - } - *line_buf = 0; - continue; - - } while (1); -} - -#ifdef CODESET_LIST - -static int find_codeset_num(const char *cs) -{ - int r = 2; - char *s = CODESET_LIST; - - /* 7-bit is 1, UTF-8 is 2, 8-bits are > 2 */ - - if (strcmp(cs, "UTF-8") != 0) { - ++r; - while (*s && strcmp(CODESET_LIST+ ((unsigned char) *s), cs)) { -/* printf("tried %s\n", CODESET_LIST + ((unsigned char) *s)); */ - ++r; - ++s; - } - if (!*s) { - printf("error: unsupported codeset %s\n", cs); - exit(EXIT_FAILURE); - } - } - return r; -} - -#else - -static int find_codeset_num(const char *cs) -{ - int r = 2; - - /* 7-bit is 1, UTF-8 is 2, 8-bits are > 2 */ - - if (strcmp(cs, "UTF-8") != 0) { - printf("error: unsupported codeset %s\n", cs); - exit(EXIT_FAILURE); } - return r; -} - -#endif - -static int find_at_string_num(const char *as) -{ - int i = 0; - char *p = at_strings; - - while (*p) { - if (!strcmp(p+1, as)) { - return i; + if (m == lc_ctype_count[k]) { /* new for this nl_item */ + if (m > 255) { + printf("too many nl_item %d entries in lc_ctype\n", k); + exit(EXIT_FAILURE); } - ++i; - p += 1 + (unsigned char) *p; + lc_ctype_item[k][m] = j; + ++lc_ctype_count[k]; } - - printf("error: unmapped @string %s\n", as); - exit(EXIT_FAILURE); +/* printf("\\x%02x", m); */ + lc_ctype_uniq_X[lc_ctype_uniq][k] = m; } -static void read_locale_list(void) +static void do_lc_ctype(void) { - char *p; - char *s; - char *ln; /* locale name */ - char *ls; /* locale name ll_CC */ - char *as; /* at string */ - char *ds; /* dot string */ - char *cs; /* codeset */ - int i; - - typedef struct { - char *glibc_name; - char name[5]; - char dot_cs; /* 0 if no codeset specified */ - char cs; - } locale_entry; - - /* First the C locale. */ - locales[0].glibc_name = locales[0].name; - strncpy(locales[0].name,"C",5); - locales[0].dot_cs = 0; - locales[0].cs = 1; /* 7-bit encoding */ - ++num_locales; - - do { - if (!(p = strtok(line_buf, " \t\n")) || (*p == '#')) { - if (!fgets(line_buf, sizeof(line_buf), fp)) { - if (ferror(fp)) { - printf("error reading file\n"); - exit(EXIT_FAILURE); - } - return; /* EOF */ - } - if ((*line_buf == '#') && (line_buf[1] == '-')) { - break; - } - continue; - } - - s = glibc_locale_names; - for (i=0 ; i < num_locales ; i++) { - if (!strcmp(s+1, p)) { - break; - } - s += 1 + ((unsigned char) *s); - } - if (i < num_locales) { - printf("ignoring dulplicate locale name: %s", p); - *line_buf = 0; - continue; - } - - /* New locale, but don't increment num until codeset verified! */ - *s = (char)((unsigned char) (strlen(p) + 1)); - strcpy(s+1, p); - locales[num_locales].glibc_name = s+1; - ln = p; /* save locale name */ - - if (!(p = strtok(NULL, " \t\n"))) { - printf("error: missing codeset for locale %s\n", ln); - exit(EXIT_FAILURE); - } - cs = p; - i = find_codeset_num(p); - if ((i == 2) && !default_utf8) { - printf("ignoring UTF-8 locale %s\n", ln); - *line_buf = 0; - continue; - } else if ((i > 2) && !default_8bit) { - printf("ignoring 8-bit codeset locale %s\n", ln); - *line_buf = 0; - continue; - } - locales[num_locales].cs = (char)((unsigned char) i); - - if (((p = strtok(NULL, " \t\n")) != NULL) && (*p != '#')) { - printf("ignoring trailing text: %s...\n", p); - } - - /* Now go back to locale string for .codeset and @modifier */ - as = strtok(ln, "@"); - if (as) { - as = strtok(NULL, "@"); - } - ds = strtok(ln, "."); - if (ds) { - ds = strtok(NULL, "."); - } - ls = ln; + int i, k, m; - if ((strlen(ls) != 5) || (ls[2] != '_')) { - printf("error: illegal locale name %s\n", ls); - exit(EXIT_FAILURE); - } + last = buf+1; + uniq = 1; + *buf = 0; + *idx = buf; - i = 0; /* value for unspecified codeset */ - if (ds) { - i = find_codeset_num(ds); - if ((i == 2) && !default_utf8) { - printf("ignoring UTF-8 locale %s\n", ln); - *line_buf = 0; - continue; - } else if ((i > 2) && !default_8bit) { - printf("ignoring 8-bit codeset locale %s\n", ln); - *line_buf = 0; - continue; - } - } - locales[num_locales].dot_cs = (char)((unsigned char) i); + for (i=0 ; i < num_locales ; i++) { + k = 0; - if (as) { - i = find_at_string_num(as); - ls[2] = at_mapto[i]; + if (!setlocale(LC_ALL, locales[i].glibc_name)) { + printf("setlocale(LC_ALL,%s) failed!\n", + locales[i].glibc_name); } - memcpy(locales[num_locales].name, ls, 5); -/* printf("locale: %5.5s %2d %2d %s\n", */ -/* locales[num_locales].name, */ -/* locales[num_locales].cs, */ -/* locales[num_locales].dot_cs, */ -/* locales[num_locales].glibc_name */ -/* ); */ - ++num_locales; - *line_buf = 0; - } while (1); -} -static int le_cmp(const void *a, const void *b) -{ - const locale_entry *p; - const locale_entry *q; - int r; - - p = (const locale_entry *) a; - q = (const locale_entry *) b; + DO_NL_S(_NL_CTYPE_OUTDIGIT0_MB); + DO_NL_S(_NL_CTYPE_OUTDIGIT1_MB); + DO_NL_S(_NL_CTYPE_OUTDIGIT2_MB); + DO_NL_S(_NL_CTYPE_OUTDIGIT3_MB); + DO_NL_S(_NL_CTYPE_OUTDIGIT4_MB); + DO_NL_S(_NL_CTYPE_OUTDIGIT5_MB); + DO_NL_S(_NL_CTYPE_OUTDIGIT6_MB); + DO_NL_S(_NL_CTYPE_OUTDIGIT7_MB); + DO_NL_S(_NL_CTYPE_OUTDIGIT8_MB); + DO_NL_S(_NL_CTYPE_OUTDIGIT9_MB); - if (!(r = p->name[0] - q->name[0]) - && !(r = p->name[1] - q->name[1]) - && !(r = p->name[3] - q->name[3]) - && !(r = p->name[4] - q->name[4]) - && !(r = p->name[2] - q->name[2]) - && !(r = -(p->cs - q->cs)) - ) { - r = -(p->dot_cs - q->dot_cs); - /* Reverse the ordering of the codesets so UTF-8 comes last. - * Work-around (hopefully) for glibc bug affecting at least - * the euro currency symbol. */ + DL_LC_LOOPTAIL(ctype) } - return r; + DO_LC_COMMON(ctype) } - |