diff options
Diffstat (limited to 'locale/programs')
-rw-r--r-- | locale/programs/charmap.c | 2 | ||||
-rw-r--r-- | locale/programs/ld-ctype.c | 47 | ||||
-rw-r--r-- | locale/programs/locfile.c | 23 |
3 files changed, 37 insertions, 35 deletions
diff --git a/locale/programs/charmap.c b/locale/programs/charmap.c index 35a6987fbc..7c013b24c3 100644 --- a/locale/programs/charmap.c +++ b/locale/programs/charmap.c @@ -1042,7 +1042,7 @@ hexadecimal range format should use only capital characters")); char *endp; errno = 0; - newp->ucs4 = strtoul (name_end, &endp, 16); + newp->ucs4 = strtoul (name_end + 1, &endp, 16); if (endp - name_end != len1 || (newp->ucs4 == ULONG_MAX && errno == ERANGE) || newp->ucs4 >= 0x80000000) diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c index 24a53919f2..e3f55644d3 100644 --- a/locale/programs/ld-ctype.c +++ b/locale/programs/ld-ctype.c @@ -116,6 +116,14 @@ struct translit_include_t }; +/* Sparse table of uint32_t. */ +#define TABLE idx_table +#define ELEMENT uint32_t +#define DEFAULT ~((uint32_t) 0) +#define NO_FINALIZE +#include "3level.h" + + /* The real definition of the struct for the LC_CTYPE locale. */ struct locale_ctype_t { @@ -123,8 +131,7 @@ struct locale_ctype_t size_t charnames_max; size_t charnames_act; /* An index lookup table, to speedup find_idx. */ -#define MAX_CHARNAMES_IDX 0x10000 - uint32_t *charnames_idx; + struct idx_table charnames_idx; struct repertoire_t *repertoire; @@ -261,10 +268,7 @@ ctype_startup (struct linereader *lr, struct localedef_t *locale, for (cnt = 0; cnt < 256; ++cnt) ctype->charnames[cnt] = cnt; ctype->charnames_act = 256; - ctype->charnames_idx = - (uint32_t *) xmalloc (MAX_CHARNAMES_IDX * sizeof (uint32_t)); - for (cnt = 0; cnt < MAX_CHARNAMES_IDX; ++cnt) - ctype->charnames_idx[cnt] = ~((uint32_t) 0); + idx_table_init (&ctype->charnames_idx); /* Fill character class information. */ ctype->last_class_char = ILLEGAL_CHAR_VALUE; @@ -1280,23 +1284,17 @@ find_idx (struct locale_ctype_t *ctype, uint32_t **table, size_t *max, if (idx < 256) return table == NULL ? NULL : &(*table)[idx]; - /* If idx is in the usual range, use the charnames_idx lookup table - instead of the slow search loop. */ - if (idx < MAX_CHARNAMES_IDX) - { - if (ctype->charnames_idx[idx] != ~((uint32_t) 0)) - /* Found. */ - cnt = ctype->charnames_idx[idx]; - else - /* Not found. */ - cnt = ctype->charnames_act; - } - else - { - for (cnt = 256; cnt < ctype->charnames_act; ++cnt) - if (ctype->charnames[cnt] == idx) - break; - } + /* Use the charnames_idx lookup table instead of the slow search loop. */ +#if 1 + cnt = idx_table_get (&ctype->charnames_idx, idx); + if (cnt == ~((uint32_t) 0)) + /* Not found. */ + cnt = ctype->charnames_act; +#else + for (cnt = 256; cnt < ctype->charnames_act; ++cnt) + if (ctype->charnames[cnt] == idx) + break; +#endif /* We have to distinguish two cases: the name is found or not. */ if (cnt == ctype->charnames_act) @@ -1310,8 +1308,7 @@ find_idx (struct locale_ctype_t *ctype, uint32_t **table, size_t *max, sizeof (uint32_t) * ctype->charnames_max); } ctype->charnames[ctype->charnames_act++] = idx; - if (idx < MAX_CHARNAMES_IDX) - ctype->charnames_idx[idx] = cnt; + idx_table_add (&ctype->charnames_idx, idx, cnt); } if (table == NULL) diff --git a/locale/programs/locfile.c b/locale/programs/locfile.c index 7c724e292f..185ccbc77f 100644 --- a/locale/programs/locfile.c +++ b/locale/programs/locfile.c @@ -338,30 +338,33 @@ write_locale_data (const char *output_path, const char *category, data. This means we need to have a directory LC_MESSAGES in which we place the file under the name SYS_LC_MESSAGES. */ sprintf (fname, "%s%s", output_path, category); + fd = -2; if (strcmp (category, "LC_MESSAGES") == 0) { struct stat st; if (stat (fname, &st) < 0) { - if (mkdir (fname, 0777) < 0) - fd = creat (fname, 0666); - else + if (mkdir (fname, 0777) >= 0) { fd = -1; errno = EISDIR; } } - else if (S_ISREG (st.st_mode)) - fd = creat (fname, 0666); - else + else if (!S_ISREG (st.st_mode)) { fd = -1; errno = EISDIR; } } - else - fd = creat (fname, 0666); + + /* Create the locale file with nlinks == 1; this avoids crashing processes + which currently use the locale. */ + if (fd == -2) + { + unlink (fname); + fd = creat (fname, 0666); + } if (fd == -1) { @@ -369,7 +372,8 @@ write_locale_data (const char *output_path, const char *category, if (errno == EISDIR) { - sprintf (fname, "%1$s/%2$s/SYS_%2$s", output_path, category); + sprintf (fname, "%1$s%2$s/SYS_%2$s", output_path, category); + unlink (fname); fd = creat (fname, 0666); if (fd == -1) save_err = errno; @@ -381,6 +385,7 @@ write_locale_data (const char *output_path, const char *category, error (0, save_err, _("\ cannot open output file `%s' for category `%s'"), fname, category); + free (fname); return; } } |