diff options
Diffstat (limited to 'locale/lc-time.c')
-rw-r--r-- | locale/lc-time.c | 153 |
1 files changed, 51 insertions, 102 deletions
diff --git a/locale/lc-time.c b/locale/lc-time.c index 423adefb2f..c6bf4b10e0 100644 --- a/locale/lc-time.c +++ b/locale/lc-time.c @@ -32,13 +32,9 @@ __libc_lock_define (extern, __libc_setlocale_lock) static int era_initialized; -static struct era_entry **eras; -static const void **eras_nf; -static size_t num_eras; - -#define ERAS_NF(cnt, category) \ - *(eras_nf + ERA_NAME_FORMAT_MEMBERS * (cnt) + (category)) +static struct era_entry *eras; +static size_t num_eras; static int alt_digits_initialized; static const char **alt_digits; @@ -56,17 +52,21 @@ _nl_postload_time (void) walt_digits_initialized = 0; } +#define ERA_DATE_CMP(a, b) \ + (a[0] < b[0] || (a[0] == b[0] && (a[1] < b[1] \ + || (a[1] == b[1] && a[2] <= b[2])))) static void -init_era_entry (void) +_nl_init_era_entries (void) { 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 (new_num_eras == 0) { if (eras != NULL) @@ -74,57 +74,59 @@ init_era_entry (void) free (eras); eras = NULL; } - if (eras_nf != NULL) - { - free (eras_nf); - eras_nf = NULL; - } } else { if (num_eras != new_num_eras) - { - eras = realloc (eras, - new_num_eras * sizeof (struct era_entry *)); - eras_nf = realloc (eras_nf, - new_num_eras * sizeof (void *) - * ERA_NAME_FORMAT_MEMBERS); - } - - if (eras == NULL || eras_nf == NULL) + eras = realloc (eras, + new_num_eras * sizeof (struct era_entry *)); + if (eras == NULL) { num_eras = 0; eras = NULL; - eras_nf = NULL; } - else + else { const char *ptr = _NL_CURRENT (LC_TIME, _NL_TIME_ERA_ENTRIES); num_eras = new_num_eras; for (cnt = 0; cnt < num_eras; ++cnt) { - eras[cnt] = (struct era_entry *) ptr; + const char *base_ptr = ptr; + memcpy((void*)(eras + cnt), (const void *) ptr, + sizeof (uint32_t) * 8); + + if (ERA_DATE_CMP(eras[cnt].start_date, + eras[cnt].stop_date)) + if (eras[cnt].direction == (uint32_t) '+') + eras[cnt].absolute_direction = 1; + else + eras[cnt].absolute_direction = -1; + else + if (eras[cnt].direction == (uint32_t) '+') + eras[cnt].absolute_direction = -1; + else + eras[cnt].absolute_direction = 1; /* Skip numeric values. */ - ptr += sizeof (struct era_entry); + ptr += sizeof (uint32_t) * 8; /* Set and skip era name. */ - ERAS_NF (cnt, ERA_M_NAME) = (void *) ptr; + eras[cnt].era_name = ptr; ptr = strchr (ptr, '\0') + 1; /* Set and skip era format. */ - ERAS_NF (cnt, ERA_M_FORMAT) = (void *) ptr; + eras[cnt].era_format = ptr; ptr = strchr (ptr, '\0') + 1; - ptr += 3 - (((ptr - (const char *) eras[cnt]) + 3) & 3); + ptr += 3 - (((ptr - (const char *) base_ptr) + 3) & 3); /* Set and skip wide era name. */ - ERAS_NF (cnt, ERA_W_NAME) = (void *) ptr; + eras[cnt].era_wname = (wchar_t *) ptr; ptr = (char *) (wcschr ((wchar_t *) ptr, '\0') + 1); /* Set and skip wide era format. */ - ERAS_NF (cnt, ERA_W_FORMAT) = (void *) ptr; + eras[cnt].era_wformat = (wchar_t *) ptr; ptr = (char *) (wcschr ((wchar_t *) ptr, '\0') + 1); } } @@ -132,6 +134,8 @@ init_era_entry (void) era_initialized = 1; } + + __libc_lock_unlock (__libc_setlocale_lock); } @@ -139,92 +143,37 @@ struct era_entry * _nl_get_era_entry (const struct tm *tp) { struct era_entry *result; + int32_t tdate[3]; size_t cnt; - __libc_lock_lock (__libc_setlocale_lock); + tdate[0] = tp->tm_year; + tdate[1] = tp->tm_mon; + tdate[2] = tp->tm_mday; - init_era_entry (); + if (era_initialized == 0) + _nl_init_era_entries (); /* 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))))) + if ((ERA_DATE_CMP(eras[cnt].start_date, tdate) + && ERA_DATE_CMP(tdate, eras[cnt].stop_date)) + || (ERA_DATE_CMP(eras[cnt].stop_date, tdate) + && ERA_DATE_CMP(tdate, eras[cnt].start_date))) break; - result = cnt < num_eras ? eras[cnt] : NULL; - - __libc_lock_unlock (__libc_setlocale_lock); + result = cnt < num_eras ? &eras[cnt] : NULL; return result; } -const void * -_nl_get_era_nf_entry (int cnt, int category) -{ - const void *result; - - __libc_lock_lock (__libc_setlocale_lock); - - init_era_entry (); - - if (eras_nf == NULL) - result = NULL; - else - result = ERAS_NF (cnt, category); - - __libc_lock_unlock (__libc_setlocale_lock); - - return result; -} - - -int -_nl_get_era_year_offset (int cnt, int val) -{ - __libc_lock_lock (__libc_setlocale_lock); - - init_era_entry (); - - if (eras == NULL) - val = -1; - else - { - val -= eras[cnt]->offset; - - if (val < 0 || - val > (eras[cnt]->stop_date[0] - eras[cnt]->start_date[0])) - val = -1; - } - - __libc_lock_unlock (__libc_setlocale_lock); - - return val; -} - - -int -_nl_get_era_year_start (int cnt) +struct era_entry * +_nl_select_era_entry (int cnt) { - int result; - - __libc_lock_lock (__libc_setlocale_lock); - - init_era_entry (); - - result = eras[cnt]->start_date[0]; - - __libc_lock_unlock (__libc_setlocale_lock); + if (era_initialized == 0) + _nl_init_era_entries (); - return result; + return &eras[cnt]; } |