diff options
Diffstat (limited to 'locale')
-rw-r--r-- | locale/C-time.c | 12 | ||||
-rw-r--r-- | locale/categories.def | 9 | ||||
-rw-r--r-- | locale/langinfo.h | 2 | ||||
-rw-r--r-- | locale/lc-time.c | 156 | ||||
-rw-r--r-- | locale/loadlocale.c | 8 | ||||
-rw-r--r-- | locale/localeinfo.h | 19 | ||||
-rw-r--r-- | locale/nl_langinfo.c | 4 | ||||
-rw-r--r-- | locale/programs/ld-time.c | 416 | ||||
-rw-r--r-- | locale/programs/locale.c | 9 | ||||
-rw-r--r-- | locale/programs/localedef.c | 14 | ||||
-rw-r--r-- | locale/programs/locfile.c | 4 | ||||
-rw-r--r-- | locale/setlocale.c | 12 |
12 files changed, 624 insertions, 41 deletions
diff --git a/locale/C-time.c b/locale/C-time.c index b03ff498ab..dbb51f383b 100644 --- a/locale/C-time.c +++ b/locale/C-time.c @@ -26,7 +26,7 @@ const struct locale_data _nl_C_LC_TIME = { _nl_C_name, NULL, 0, /* no file mapped */ - 45, + 53, { { string: "Sun" }, { string: "Mon" }, @@ -72,6 +72,14 @@ const struct locale_data _nl_C_LC_TIME = { string: "%m/%d/%y" }, { string: "%H:%M:%S" }, { string: "%I:%M:%S %p" }, - { string: NULL } + { string: NULL }, + { string: NULL }, + { string: NULL }, + { string: NULL }, + { string: NULL }, + { string: NULL }, + { word: 0 }, + { string: NULL }, + { string: NULL }, } }; diff --git a/locale/categories.def b/locale/categories.def index 5e72319774..664fc901c4 100644 --- a/locale/categories.def +++ b/locale/categories.def @@ -137,16 +137,17 @@ DEFINE_CATEGORY DEFINE_ELEMENT (D_FMT, "d_fmt", std, string) DEFINE_ELEMENT (T_FMT, "t_fmt", std, string) DEFINE_ELEMENT (T_FMT_AMPM, "t_fmt_ampm", std, string) - DEFINE_ELEMENT (ERA, "era", opt, stringarray, 0, 100)/*XXX*/ + DEFINE_ELEMENT (ERA, "era", opt, stringarray) DEFINE_ELEMENT (ERA_YEAR, "era_year", opt, string) DEFINE_ELEMENT (ERA_D_FMT, "era_d_fmt", opt, string) DEFINE_ELEMENT (ALT_DIGITS, "alt_digits", opt, stringarray, 0, 100) DEFINE_ELEMENT (ERA_D_T_FMT, "era_d_t_fmt", opt, string) DEFINE_ELEMENT (ERA_T_FMT, "era_t_fmt", opt, string) + DEFINE_ELEMENT (_NL_TIME_NUM_ALT_DIGITS, "time-num-alt-digits", opt, word) DEFINE_ELEMENT (_NL_TIME_ERA_NUM_ENTRIES, "time-era-num-entries", opt, word) - DEFINE_ELEMENT (_NL_TIME_ERA_ENTRIES_EB, "time-era-entries-eb", opt, string) - DEFINE_ELEMENT (_NL_TIME_ERA_ENTRIES_EL, "time-era-entries-el", opt, string) - ), NO_POSTLOAD, NULL, NULL, NULL) + DEFINE_ELEMENT (_NL_TIME_ERA_ENTRIES_EB, "time-era-entries-eb", opt, string) + DEFINE_ELEMENT (_NL_TIME_ERA_ENTRIES_EL, "time-era-entries-el", opt, string) + ), _nl_postload_time, NULL, NULL, NULL) DEFINE_CATEGORY diff --git a/locale/langinfo.h b/locale/langinfo.h index 82bd51024a..4df8df7a45 100644 --- a/locale/langinfo.h +++ b/locale/langinfo.h @@ -101,6 +101,8 @@ typedef enum ERA_D_T_FMT, /* Date and time in alternate era format. */ ERA_T_FMT, /* Time in alternate era format. */ + _NL_TIME_NUM_ALT_DIGITS, /* Number entries in the alt_digits arrays. */ + _NL_TIME_ERA_NUM_ENTRIES, /* Number entries in the era arrays. */ _NL_TIME_ERA_ENTRIES_EB, /* Structure with era entries in usable form.*/ _NL_TIME_ERA_ENTRIES_EL, diff --git a/locale/lc-time.c b/locale/lc-time.c index 7b84f99dc2..f4fe561cb9 100644 --- a/locale/lc-time.c +++ b/locale/lc-time.c @@ -1,5 +1,5 @@ /* Define current locale data for LC_TIME category. -Copyright (C) 1995 Free Software Foundation, Inc. +Copyright (C) 1995, 1996 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -17,6 +17,160 @@ License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include <libc-lock.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> #include "localeinfo.h" _NL_CURRENT_DEFINE (LC_TIME); + +/* Some of the functions here must not be used while setlocale is called. */ +__libc_lock_define (extern, __libc_setlocale_lock) + + +static int era_initialized; +static struct era_entry **eras; +static size_t num_eras; + + +static int alt_digits_initialized; +static const char **alt_digits; +static size_t num_alt_digits; + + +void +_nl_postload_time (void) +{ + /* Prepare lazy initialization of `era' and `alt_digits' array. */ + era_initialized = 0; + alt_digits_initialized = 0; +} + + +struct era_entry * +_nl_get_era_entry (const struct tm *tp) +{ + struct era_entry *result; + size_t cnt; + + __libc_lock_lock (__libc_setlocale_lock); + + if (era_initialized == 0) + { + size_t new_num_eras = _NL_CURRENT_WORD (LC_TIME, + _NL_TIME_ERA_NUM_ENTRIES); + + if (eras != NULL && new_num_eras == 0) + { + free (eras); + eras = NULL; + } + else if (new_num_eras != 0) + { + if (num_eras != new_num_eras) + eras = realloc (eras, new_num_eras * sizeof (struct era_entry *)); + + if (eras == NULL) + num_eras = 0; + else + { +#if __BYTE_ORDER == __LITTLE_ENDIAN + const char *ptr = _NL_CURRENT (LC_TIME, _NL_TIME_ERA_ENTRIES_EL); +#else + const char *ptr = _NL_CURRENT (LC_TIME, _NL_TIME_ERA_ENTRIES_EB); +#endif + num_eras = new_num_eras; + + for (cnt = 0; cnt < num_eras; ++cnt) + { + eras[cnt] = (struct era_entry *) ptr; + + /* Skip numeric values. */ + ptr += sizeof (struct era_entry); + /* Skip era name. */ + ptr = strchr (ptr, '\0') + 1; + /* Skip era format. */ + ptr = strchr (ptr, '\0') + 1; + + ptr += 3 - (((ptr - (const char *) eras[cnt]) + 3) & 3); + } + } + } + + era_initialized = 1; + } + + /* Now compare date with the available eras. */ + for (cnt = 0; cnt < num_eras; ++cnt) + if ((eras[cnt]->start_date[0] < tp->tm_year + || (eras[cnt]->start_date[0] == tp->tm_year + && (eras[cnt]->start_date[1] < tp->tm_mon + || (eras[cnt]->start_date[1] == tp->tm_mon + && eras[cnt]->start_date[2] <= tp->tm_mday)))) + && (eras[cnt]->stop_date[0] > tp->tm_year + || (eras[cnt]->stop_date[0] == tp->tm_year + && (eras[cnt]->stop_date[1] > tp->tm_mon + || (eras[cnt]->stop_date[1] == tp->tm_mon + && eras[cnt]->stop_date[2] >= tp->tm_mday))))) + break; + + result = cnt < num_eras ? eras[cnt] : NULL; + + __libc_lock_unlock (__libc_setlocale_lock); + + return result; +} + + +const char * +_nl_get_alt_digit (unsigned int number) +{ + const char *result; + + __libc_lock_lock (__libc_setlocale_lock); + + if (alt_digits_initialized == 0) + { + size_t new_num_alt_digits = _NL_CURRENT_WORD (LC_TIME, + _NL_TIME_NUM_ALT_DIGITS); + + if (alt_digits != NULL && new_num_alt_digits == 0) + { + free (alt_digits); + alt_digits = NULL; + } + else if (new_num_alt_digits != 0) + { + if (num_alt_digits != new_num_alt_digits) + alt_digits = realloc (alt_digits, (new_num_alt_digits + * sizeof (const char *))); + + if (alt_digits == NULL) + num_alt_digits = 0; + else + { + const char *ptr = _NL_CURRENT (LC_TIME, ALT_DIGITS); + size_t cnt; + + num_alt_digits = new_num_alt_digits; + + for (cnt = 0; cnt < num_alt_digits; ++cnt) + { + alt_digits[cnt] = ptr; + + /* Skip digit format. */ + ptr = strchr (ptr, '\0') + 1; + } + } + } + + alt_digits_initialized = 1; + } + + result = number < num_alt_digits ? alt_digits[number] : NULL; + + __libc_lock_unlock (__libc_setlocale_lock); + + return result; +} diff --git a/locale/loadlocale.c b/locale/loadlocale.c index 5894b074de..474a73cf6e 100644 --- a/locale/loadlocale.c +++ b/locale/loadlocale.c @@ -144,7 +144,7 @@ _nl_load_locale (struct loaded_l10nfile *file, int category) { free (filedata); if (nread == 0) - errno = EINVAL; /* Bizarreness going on. */ + __set_errno (EINVAL); /* Bizarreness going on. */ goto puntfd; } p += nread; @@ -153,7 +153,7 @@ _nl_load_locale (struct loaded_l10nfile *file, int category) } else goto puntfd; - errno = save_err; + __set_errno (save_err); } else goto puntfd; @@ -184,7 +184,7 @@ _nl_load_locale (struct loaded_l10nfile *file, int category) >= (size_t) st.st_size)) { /* Insufficient data. */ - errno = EINVAL; + __set_errno (EINVAL); goto puntmap; } @@ -204,7 +204,7 @@ _nl_load_locale (struct loaded_l10nfile *file, int category) if (idx >= newdata->filesize) { free (newdata); - errno = EINVAL; + __set_errno (EINVAL); goto puntmap; } if (_nl_value_types[category][cnt] == word) diff --git a/locale/localeinfo.h b/locale/localeinfo.h index 0646f0e8db..335e866f91 100644 --- a/locale/localeinfo.h +++ b/locale/localeinfo.h @@ -22,6 +22,7 @@ Cambridge, MA 02139, USA. */ #include <stddef.h> #include <langinfo.h> +#include <time.h> #include <sys/types.h> #include "../intl/loadinfo.h" /* For loaded_l10nfile definition. */ @@ -76,6 +77,17 @@ enum value_type }; +/* Structure to access `era' information from LC_TIME. */ +struct era_entry +{ + u_int32_t direction; /* Contains '+' or '-'. */ + int32_t offset; + int32_t start_date[3]; + int32_t stop_date[3]; + const char name_fmt[0]; +}; + + /* For each category declare the variable for the current locale data. */ #define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \ extern const struct locale_data *_nl_current_##category; @@ -114,6 +126,13 @@ extern const struct locale_data *_nl_find_locale (const char *locale_path, extern void _nl_load_locale (struct loaded_l10nfile *file, int category); +/* Return `era' entry which corresponds to TP. Used in strftime. */ +struct era_entry *_nl_get_era_entry (const struct tm *tp); + +/* Return `alt_digit' which corresponds to NUMBER. Used in strftime. */ +const char *_nl_get_alt_digit (unsigned int number); + + /* Global variables for LC_COLLATE category data. */ extern const u_int32_t *__collate_table; extern const u_int32_t *__collate_extra; diff --git a/locale/nl_langinfo.c b/locale/nl_langinfo.c index a9fa4238c2..1c42e14a4a 100644 --- a/locale/nl_langinfo.c +++ b/locale/nl_langinfo.c @@ -48,7 +48,7 @@ nl_langinfo (item) if (category < 0 || category >= LC_ALL) { /* Bogus category: bogus item. */ - errno = EINVAL; + __set_errno (EINVAL); return NULL; } @@ -57,7 +57,7 @@ nl_langinfo (item) if (index >= data->nstrings) { /* Bogus index for this category: bogus item. */ - errno = EINVAL; + __set_errno (EINVAL); return NULL; } diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c index 75f6021109..1b118ae14c 100644 --- a/locale/programs/ld-time.c +++ b/locale/programs/ld-time.c @@ -27,16 +27,32 @@ Boston, MA 02111-1307, USA. */ /* Undefine following line in production version. */ /* #define NDEBUG 1 */ #include <assert.h> +#include <stdlib.h> #include "locales.h" #include "localeinfo.h" #include "stringtrans.h" +#define SWAPU32(w) \ + (((w) << 24) | (((w) & 0xff00) << 8) | (((w) >> 8) & 0xff00) | ((w) >> 24)) + void *xmalloc (size_t __n); void *xrealloc (void *__p, size_t __n); +/* Entry describing an entry of the era specification. */ +struct era_data +{ + int32_t direction; + int32_t offset; + int32_t start_date[3]; + int32_t stop_date[3]; + const char *name; + const char *format; +}; + + /* The real definition of the struct for the LC_TIME locale. */ struct locale_time_t { @@ -55,13 +71,16 @@ struct locale_time_t const char *t_fmt; const char *t_fmt_ampm; const char **era; - size_t era_num; + u_int32_t cur_num_era; const char *era_year; const char *era_d_t_fmt; const char *era_t_fmt; const char *era_d_fmt; const char *alt_digits[100]; - size_t cur_num_alt_digits; + u_int32_t cur_num_alt_digits; + + struct era_data *era_entries; + struct era_data *era_entries_ob; }; @@ -109,6 +128,263 @@ time_finish (struct localedef_t *locale) TEST_ELEM (d_fmt); TEST_ELEM (t_fmt); TEST_ELEM (t_fmt_ampm); + + /* Now process the era entries. */ + if (time->cur_num_era != 0) + { + const int days_per_month[12] = { 31, 29, 31, 30, 31, 30, + 31, 31, 30, 31 ,30, 31 }; + size_t idx; + + time->era_entries = + (struct era_data *) xmalloc (time->cur_num_era + * sizeof (struct era_data)); + + for (idx = 0; idx < time->cur_num_era; ++idx) + { + size_t era_len = strlen (time->era[idx]); + char *str = xmalloc ((era_len + 1 + 3) & ~3); + char *endp; + + memcpy (str, time->era[idx], era_len + 1); + + /* First character must be + or - for the direction. */ + if (*str != '+' && *str != '-') + { + error (0, 0, _("direction flag in string %d in `era' field" + " in category `%s' is not '+' nor '-'"), + idx + 1, "LC_TIME"); + /* Default arbitrarily to '+'. */ + time->era_entries[idx].direction = '+'; + } + else + time->era_entries[idx].direction = *str; + if (*++str != ':') + { + error (0, 0, _("direction flag in string %d in `era' field" + " in category `%s' is not a single character"), + idx + 1, "LC_TIME"); + (void) strsep (&str, ":"); + } + else + ++str; + + /* Now the offset year. */ + time->era_entries[idx].offset = strtol (str, &endp, 10); + if (endp == str) + { + error (0, 0, _("illegal number for offset in string %d in" + " `era' field in category `%s'"), + idx + 1, "LC_TIME"); + (void) strsep (&str, ":"); + } + else if (*endp != ':') + { + error (0, 0, _("garbage at end of offset value in string %d in" + " `era' field in category `%s'"), + idx + 1, "LC_TIME"); + (void) strsep (&str, ":"); + } + else + str = endp + 1; + + /* Next is the starting date in ISO format. */ + if (strncmp (str, "-*", 2) == 0) + { + time->era_entries[idx].start_date[0] = + time->era_entries[idx].start_date[1] = + time->era_entries[idx].start_date[2] = 0x80000000; + if (str[2] != ':') + goto garbage_start_date; + str += 3; + } + else if (strncmp (str, "+*", 2) == 0) + { + time->era_entries[idx].start_date[0] = + time->era_entries[idx].start_date[1] = + time->era_entries[idx].start_date[2] = 0x7fffffff; + if (str[2] != ':') + goto garbage_start_date; + str += 3; + } + else + { + time->era_entries[idx].start_date[0] = strtol (str, &endp, 10); + if (endp == str || *endp != '/') + goto invalid_start_date; + else + str = endp + 1; + time->era_entries[idx].start_date[0] -= 1900; + + time->era_entries[idx].start_date[1] = strtol (str, &endp, 10); + if (endp == str || *endp != '/') + goto invalid_start_date; + else + str = endp + 1; + time->era_entries[idx].start_date[1] -= 1; + + time->era_entries[idx].start_date[2] = strtol (str, &endp, 10); + if (endp == str) + { + invalid_start_date: + error (0, 0, _("illegal starting date in string %d in" + " `era' field in category `%s'"), + idx + 1, "LC_TIME"); + (void) strsep (&str, ":"); + } + else if (*endp != ':') + { + garbage_start_date: + error (0, 0, _("garbage at end of starting date in string %d" + " in `era' field in category `%s'"), + idx + 1, "LC_TIME"); + (void) strsep (&str, ":"); + } + else + { + str = endp + 1; + + /* Check for valid value. */ + if (time->era_entries[idx].start_date[1] < 0 + || time->era_entries[idx].start_date[1] >= 12 + || time->era_entries[idx].start_date[2] < 0 + || (time->era_entries[idx].start_date[2] + > days_per_month[time->era_entries[idx].start_date[1]]) + || (time->era_entries[idx].start_date[1] == 2 + && time->era_entries[idx].start_date[2] == 29 + && !__isleap (time->era_entries[idx].start_date[0]))) + error (0, 0, _("starting date is illegal in" + " string %d in `era' field in" + " category `%s'"), + idx + 1, "LC_TIME"); + } + } + + /* Next is the stoping date in ISO format. */ + if (strncmp (str, "-*", 2) == 0) + { + time->era_entries[idx].stop_date[0] = + time->era_entries[idx].stop_date[1] = + time->era_entries[idx].stop_date[2] = 0x80000000; + if (str[2] != ':') + goto garbage_stop_date; + str += 3; + } + else if (strncmp (str, "+*", 2) == 0) + { + time->era_entries[idx].stop_date[0] = + time->era_entries[idx].stop_date[1] = + time->era_entries[idx].stop_date[2] = 0x7fffffff; + if (str[2] != ':') + goto garbage_stop_date; + str += 3; + } + else + { + time->era_entries[idx].stop_date[0] = strtol (str, &endp, 10); + if (endp == str || *endp != '/') + goto invalid_stop_date; + else + str = endp + 1; + time->era_entries[idx].stop_date[0] -= 1900; + + time->era_entries[idx].stop_date[1] = strtol (str, &endp, 10); + if (endp == str || *endp != '/') + goto invalid_stop_date; + else + str = endp + 1; + time->era_entries[idx].stop_date[1] -= 1; + + time->era_entries[idx].stop_date[2] = strtol (str, &endp, 10); + if (endp == str) + { + invalid_stop_date: + error (0, 0, _("illegal stopping date in string %d in" + " `era' field in category `%s'"), + idx + 1, "LC_TIME"); + (void) strsep (&str, ":"); + } + else if (*endp != ':') + { + garbage_stop_date: + error (0, 0, _("garbage at end of stopping date in string %d" + " in `era' field in category `%s'"), + idx + 1, "LC_TIME"); + (void) strsep (&str, ":"); + } + else + { + str = endp + 1; + + /* Check for valid value. */ + if (time->era_entries[idx].stop_date[1] < 0 + || time->era_entries[idx].stop_date[1] >= 12 + || time->era_entries[idx].stop_date[2] < 0 + || (time->era_entries[idx].stop_date[2] + > days_per_month[time->era_entries[idx].stop_date[1]]) + || (time->era_entries[idx].stop_date[1] == 2 + && time->era_entries[idx].stop_date[2] == 29 + && !__isleap (time->era_entries[idx].stop_date[0]))) + error (0, 0, _("stopping date is illegal in" + " string %d in `era' field in" + " category `%s'"), + idx + 1, "LC_TIME"); + } + } + + if (str == NULL || *str == '\0') + { + error (0, 0, _("missing era name in string %d in `era' field" + "in category `%s'"), idx + 1, "LC_TIME"); + time->era_entries[idx].name = + time->era_entries[idx].format = ""; + } + else + { + time->era_entries[idx].name = strsep (&str, ":"); + + if (str == NULL || *str == '\0') + { + error (0, 0, _("missing era format in string %d in `era'" + " field in category `%s'"), + idx + 1, "LC_TIME"); + time->era_entries[idx].name = + time->era_entries[idx].format = ""; + } + else + time->era_entries[idx].format = str; + } + } + + /* Construct the array for the other byte order. */ + time->era_entries_ob = + (struct era_data *) xmalloc (time->cur_num_era + * sizeof (struct era_data)); + + for (idx = 0; idx < time->cur_num_era; ++idx) + { + time->era_entries_ob[idx].direction = + SWAPU32 (time->era_entries[idx].direction); + time->era_entries_ob[idx].offset = + SWAPU32 (time->era_entries[idx].offset); + time->era_entries_ob[idx].start_date[0] = + SWAPU32 (time->era_entries[idx].start_date[0]); + time->era_entries_ob[idx].start_date[1] = + SWAPU32 (time->era_entries[idx].start_date[1]); + time->era_entries_ob[idx].start_date[2] = + SWAPU32 (time->era_entries[idx].stop_date[2]); + time->era_entries_ob[idx].stop_date[0] = + SWAPU32 (time->era_entries[idx].stop_date[0]); + time->era_entries_ob[idx].stop_date[1] = + SWAPU32 (time->era_entries[idx].stop_date[1]); + time->era_entries_ob[idx].stop_date[2] = + SWAPU32 (time->era_entries[idx].stop_date[2]); + time->era_entries_ob[idx].name = + time->era_entries[idx].name; + time->era_entries_ob[idx].format = + time->era_entries[idx].format; + } + } } @@ -117,8 +393,9 @@ time_output (struct localedef_t *locale, const char *output_path) { struct locale_time_t *time = locale->categories[LC_TIME].time; struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_TIME) - + (time->era_num > 0 ? time->era_num - 1 : 0) - + time->cur_num_alt_digits]; + + time->cur_num_era - 1 + + time->cur_num_alt_digits - 1 + + 1 + (time->cur_num_era * 9 - 1) * 2]; struct locale_file data; u_int32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_TIME)]; size_t cnt, last_idx, num; @@ -209,10 +486,11 @@ time_output (struct localedef_t *locale, const char *output_path) last_idx = ++cnt; idx[1 + last_idx] = idx[last_idx]; - for (num = 0; num < time->era_num; ++num, ++cnt) + for (num = 0; num < time->cur_num_era; ++num, ++cnt) { iov[2 + cnt].iov_base = (void *) time->era[num]; iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; + idx[1 + last_idx] += iov[2 + cnt].iov_len; } ++last_idx; @@ -241,13 +519,128 @@ time_output (struct localedef_t *locale, const char *output_path) iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; ++cnt; + ++last_idx; - iov[2 + cnt].iov_base = (void *) (time->era_d_fmt ?: ""); + iov[2 + cnt].iov_base = (void *) (time->era_t_fmt ?: ""); iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1; + idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; ++cnt; + ++last_idx; + + + /* We must align the following data. */ + iov[2 + cnt].iov_base = (void *) "\0\0"; + iov[2 + cnt].iov_len = ((idx[last_idx] + 3) & ~3) - idx[last_idx]; + idx[last_idx] = (idx[last_idx] + 3) & ~3; + ++cnt; + + iov[2 + cnt].iov_base = (void *) &time->cur_num_alt_digits; + iov[2 + cnt].iov_len = sizeof (u_int32_t); + idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; + ++cnt; + ++last_idx; + + /* The `era' data in usable form. */ + iov[2 + cnt].iov_base = (void *) &time->cur_num_era; + iov[2 + cnt].iov_len = sizeof (u_int32_t); + idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; + ++cnt; + ++last_idx; + +#if __BYTE_ORDER == __LITTLE_ENDIAN +# define ERA_B1 time->era_entries +# define ERA_B2 time->era_entries_ob +#else +# define ERA_B1 time->era_entries_ob +# define ERA_B2 time->era_entries +#endif + idx[1 + last_idx] = idx[last_idx]; + for (num = 0; num < time->cur_num_era; ++num) + { + size_t l; + + iov[2 + cnt].iov_base = (void *) &ERA_B1[num].direction; + iov[2 + cnt].iov_len = sizeof (int32_t); + ++cnt; + iov[2 + cnt].iov_base = (void *) &ERA_B1[num].offset; + iov[2 + cnt].iov_len = sizeof (int32_t); + ++cnt; + iov[2 + cnt].iov_base = (void *) &ERA_B1[num].start_date[0]; + iov[2 + cnt].iov_len = sizeof (int32_t); + ++cnt; + iov[2 + cnt].iov_base = (void *) &ERA_B1[num].start_date[1]; + iov[2 + cnt].iov_len = sizeof (int32_t); + ++cnt; + iov[2 + cnt].iov_base = (void *) &ERA_B1[num].start_date[2]; + iov[2 + cnt].iov_len = sizeof (int32_t); + ++cnt; + iov[2 + cnt].iov_base = (void *) &ERA_B1[num].stop_date[0]; + iov[2 + cnt].iov_len = sizeof (int32_t); + ++cnt; + iov[2 + cnt].iov_base = (void *) &ERA_B1[num].stop_date[1]; + iov[2 + cnt].iov_len = sizeof (int32_t); + ++cnt; + iov[2 + cnt].iov_base = (void *) &ERA_B1[num].stop_date[2]; + iov[2 + cnt].iov_len = sizeof (int32_t); + ++cnt; + + l = (strchr (ERA_B1[num].format, '\0') - ERA_B1[num].name) + 1; + l = (l + 3) & ~3; + iov[2 + cnt].iov_base = (void *) ERA_B1[num].name; + iov[2 + cnt].iov_len = l; + ++cnt; + + idx[1 + last_idx] += 8 * sizeof (int32_t) + l; + + assert (idx[1 + last_idx] % 4 == 0); + } + ++last_idx; + + /* idx[1 + last_idx] = idx[last_idx]; */ + for (num = 0; num < time->cur_num_era; ++num) + { + size_t l; + + iov[2 + cnt].iov_base = (void *) &ERA_B2[num].direction; + iov[2 + cnt].iov_len = sizeof (int32_t); + ++cnt; + iov[2 + cnt].iov_base = (void *) &ERA_B2[num].offset; + iov[2 + cnt].iov_len = sizeof (int32_t); + ++cnt; + iov[2 + cnt].iov_base = (void *) &ERA_B2[num].start_date[0]; + iov[2 + cnt].iov_len = sizeof (int32_t); + ++cnt; + iov[2 + cnt].iov_base = (void *) &ERA_B2[num].start_date[1]; + iov[2 + cnt].iov_len = sizeof (int32_t); + ++cnt; + iov[2 + cnt].iov_base = (void *) &ERA_B2[num].start_date[2]; + iov[2 + cnt].iov_len = sizeof (int32_t); + ++cnt; + iov[2 + cnt].iov_base = (void *) &ERA_B2[num].stop_date[0]; + iov[2 + cnt].iov_len = sizeof (int32_t); + ++cnt; + iov[2 + cnt].iov_base = (void *) &ERA_B2[num].stop_date[1]; + iov[2 + cnt].iov_len = sizeof (int32_t); + ++cnt; + iov[2 + cnt].iov_base = (void *) &ERA_B2[num].stop_date[2]; + iov[2 + cnt].iov_len = sizeof (int32_t); + ++cnt; + + l = (strchr (ERA_B2[num].format, '\0') - ERA_B2[num].name) + 1; + l = (l + 3) & ~3; + iov[2 + cnt].iov_base = (void *) ERA_B2[num].name; + iov[2 + cnt].iov_len = l; + ++cnt; + + /* idx[1 + last_idx] += 8 * sizeof (int32_t) + l; */ + } + - assert (cnt == (_NL_ITEM_INDEX (_NL_NUM_LC_TIME) - 1 - + time->cur_num_alt_digits)); + assert (cnt == (_NL_ITEM_INDEX (_NL_NUM_LC_TIME) + + time->cur_num_era - 1 + + time->cur_num_alt_digits - 1 + + 1 + (time->cur_num_era * 9 - 1) * 2) + && last_idx + 1 == _NL_ITEM_INDEX (_NL_NUM_LC_TIME)); write_locale_data (output_path, "LC_TIME", 2 + cnt, iov); } @@ -291,9 +684,10 @@ too many values for field `%s' in category `LC_TIME'"), \ "era", "LC_TIME"); else { - ++time->era_num; - time->era = xrealloc (time->era, time->era_num * sizeof (char *)); - time->era[time->era_num - 1] = code->val.str.start; + ++time->cur_num_era; + time->era = xrealloc (time->era, + time->cur_num_era * sizeof (char *)); + time->era[time->cur_num_era - 1] = code->val.str.start; } break; diff --git a/locale/programs/locale.c b/locale/programs/locale.c index ea15c87638..667afbd188 100644 --- a/locale/programs/locale.c +++ b/locale/programs/locale.c @@ -183,14 +183,14 @@ main (int argc, char *argv[]) /* Version information is requested. */ if (do_version) { - fprintf (stderr, "locale - GNU %s %s\n", PACKAGE, VERSION); + fprintf (stderr, "locale (GNU %s) %s\n", PACKAGE, VERSION); fprintf (stderr, _("\ Copyright (C) %s Free Software Foundation, Inc.\n\ This is free software; see the source for copying conditions. There is NO\n\ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ "), "1995, 1996"); - fprintf (stderr, _("Written by %s\n"), - "Ulrich Drepper <drepper@cygnus.com>"); + fprintf (stderr, _("Written by %s.\n"), + "Ulrich Drepper"); exit (EXIT_SUCCESS); } @@ -255,7 +255,8 @@ Mandatory arguments to long options are mandatory for short options too.\n\ -c, --category-name write names of selected categories\n\ -k, --keyword-name write names of selected keywords\n"), __progname); - printf (gettext ("Report bugs to <bug-glibc@prep.ai.mit.edu>.\n")); + fputs (gettext ("Report bugs to <bug-glibc@prep.ai.mit.edu>.\n"), + stdout); } exit (status); diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c index 1eae6e75d0..ff9248e317 100644 --- a/locale/programs/localedef.c +++ b/locale/programs/localedef.c @@ -173,14 +173,14 @@ main (int argc, char *argv[]) /* Version information is requested. */ if (do_version) { - fprintf (stderr, "localedef - GNU %s %s\n", PACKAGE, VERSION); + fprintf (stderr, "localedef (GNU %s) %s\n", PACKAGE, VERSION); fprintf (stderr, _("\ Copyright (C) %s Free Software Foundation, Inc.\n\ This is free software; see the source for copying conditions. There is NO\n\ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\ "), "1995, 1996"); - fprintf (stderr, _("Written by %s\n"), - "Ulrich Drepper <drepper@cygnus.com>"); + fprintf (stderr, _("Written by %s.\n"), + "Ulrich Drepper"); exit (0); } @@ -406,7 +406,8 @@ Mandatory arguments to long options are mandatory for short options too.\n\ System's directory for character maps: %s\n\ locale files : %s\n"), program_invocation_name, CHARMAP_PATH, LOCALE_PATH); - printf (gettext ("Report bugs to <bug-glibc@prep.ai.mit.edu>.\n")); + fputs (gettext ("Report bugs to <bug-glibc@prep.ai.mit.edu>.\n"), + stdout); } exit (status); @@ -429,7 +430,7 @@ error_print () static const char * construct_output_path (char *path) { - char *normal = NULL; + const char *normal = NULL; char *result; if (strchr (path, '/') == NULL) @@ -455,6 +456,9 @@ construct_output_path (char *path) if (endp > startp) normal = _nl_normalize_codeset (startp, endp - startp); } + else + /* This is to keep gcc quiet. */ + endp = NULL; /* We put an additional '\0' at the end of the string because at the end of the function we need another byte for the trailing diff --git a/locale/programs/locfile.c b/locale/programs/locfile.c index 63ebc4b856..97629e5132 100644 --- a/locale/programs/locfile.c +++ b/locale/programs/locfile.c @@ -829,6 +829,7 @@ syntax error in collating order definition")); case tok_mon: case tok_am_pm: case tok_alt_digits: + case tok_era: READ_STRING_LIST (time_add, bad_time); continue; @@ -836,7 +837,6 @@ syntax error in collating order definition")); case tok_d_fmt: case tok_t_fmt: case tok_t_fmt_ampm: - case tok_era: case tok_era_year: case tok_era_d_t_fmt: case tok_era_d_fmt: @@ -935,7 +935,7 @@ write_locale_data (const char *output_path, const char *category, int fd; char *fname; - fname = malloc (strlen (output_path) + strlen (category) + 6); + fname = malloc (strlen (output_path) + 2 * strlen (category) + 6); if (fname == NULL) error (5, errno, _("memory exhausted")); diff --git a/locale/setlocale.c b/locale/setlocale.c index d0d9223733..76320f8a32 100644 --- a/locale/setlocale.c +++ b/locale/setlocale.c @@ -116,13 +116,13 @@ static const char *_nl_current_names[] = /* Lock for protecting global data. */ -__libc_lock_define_initialized (static, lock) +__libc_lock_define_initialized (, __libc_setlocale_lock) /* Use this when we come along an error. */ #define ERROR_RETURN \ do { \ - errno = EINVAL; \ + __set_errno (EINVAL); \ return NULL; \ } while (0) @@ -314,7 +314,7 @@ setlocale (int category, const char *locale) } /* Protect global data. */ - __libc_lock_lock (lock); + __libc_lock_lock (__libc_setlocale_lock); /* Load the new data for each category. */ while (category-- > 0) @@ -354,7 +354,7 @@ setlocale (int category, const char *locale) } /* Critical section left. */ - __libc_lock_unlock (lock); + __libc_lock_unlock (__libc_setlocale_lock); return composite; } @@ -364,7 +364,7 @@ setlocale (int category, const char *locale) char *newname = (char *) locale; /* Protect global data. */ - __libc_lock_lock (lock); + __libc_lock_lock (__libc_setlocale_lock); if (_nl_current[category] != NULL) { @@ -393,7 +393,7 @@ setlocale (int category, const char *locale) } /* Critical section left. */ - __libc_lock_unlock (lock); + __libc_lock_unlock (__libc_setlocale_lock); return newname; } |