From 958d68077b3fa1435c010711876a9229e5cd4192 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 21 Dec 1999 17:50:57 +0000 Subject: Update. 1999-12-21 Shinya Hanataka * locale/lc-time.c: Extend structure era_entry. * locale/localeinfo.h: Likewise. * locale/lc-time.c: Handle '-' direction used in locale's era part properly. * time/strptime.c: Likewise. * time/strftime.c: Likewise. * locale/programs/ld-time.c: Consider negative values in era part of locale as B.C.. * time/strptime.c (strptime_internal): Merged Yoshiyama's %E[CyY] implementation. 1999-12-21 Akira Yoshiyama * time/strptime.c (strptime_internal): Fix segV bugs of a couple of recursive() call. * time/strptime.c (strptime_internal): Implement `%EC',`%Ey',`%EY' parsing. 1999-12-21 Ulrich Drepper * sysdeps/arm/dl-machine.c (CLEAR_CACHE): Fix a2 value. Patch by Scott Bambrough . --- locale/lc-time.c | 153 ++++++++++++++++------------------------------ locale/localeinfo.h | 22 ++++--- locale/programs/ld-time.c | 6 ++ 3 files changed, 70 insertions(+), 111 deletions(-) (limited to 'locale') diff --git a/locale/lc-time.c b/locale/lc-time.c index 423adef..c6bf4b1 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]; } diff --git a/locale/localeinfo.h b/locale/localeinfo.h index ee402db..c72ea9d 100644 --- a/locale/localeinfo.h +++ b/locale/localeinfo.h @@ -107,7 +107,14 @@ struct era_entry int32_t offset; int32_t start_date[3]; int32_t stop_date[3]; - const char name_fmt[0]; + const char *era_name; + const char *era_format; + const wchar_t *era_wname; + const wchar_t *era_wformat; + int absolute_direction; + /* absolute direction: + +1 indicates that year number is higher in the future. (like A.D.) + -1 indicates that year number is higher in the past. (like B.C.) */ }; @@ -160,17 +167,14 @@ extern void _nl_unload_locale (struct locale_data *locale); extern void _nl_remove_locale (int locale, struct locale_data *data); +/* initialize `era' entries */ +extern void _nl_init_era_entries (void); + /* Return `era' entry which corresponds to TP. Used in strftime. */ extern struct era_entry *_nl_get_era_entry (const struct tm *tp); -/* Return `era' string of the cnt'th `category' entry. */ -extern const void *_nl_get_era_nf_entry (int cnt, int category); - -/* Return a offset of `era' year of the cnt'th entry. */ -extern int _nl_get_era_year_offset (int cnt, int category); - -/* Return a start of `era' year of the cnt'th entry. */ -extern int _nl_get_era_year_start (int cnt); +/* Return `era' cnt'th entry . Used in strptime. */ +extern struct era_entry *_nl_select_era_entry (int cnt); /* Return `alt_digit' which corresponds to NUMBER. Used in strftime. */ extern const char *_nl_get_alt_digit (unsigned int number); diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c index b2c06cc..5e12c9b 100644 --- a/locale/programs/ld-time.c +++ b/locale/programs/ld-time.c @@ -285,6 +285,9 @@ time_finish (struct localedef_t *locale, struct charmap_t *charmap) else str = endp + 1; time->era_entries[idx].start_date[0] -= 1900; + /* year -1 represent 1 B.C. (not -1 A.D.) */ + if (time->era_entries[idx].start_date[0] < -1900) + ++time->era_entries[idx].start_date[0]; time->era_entries[idx].start_date[1] = strtol (str, &endp, 10); if (endp == str || *endp != '/') @@ -359,6 +362,9 @@ time_finish (struct localedef_t *locale, struct charmap_t *charmap) else str = endp + 1; time->era_entries[idx].stop_date[0] -= 1900; + /* year -1 represent 1 B.C. (not -1 A.D.) */ + if (time->era_entries[idx].stop_date[0] < -1900) + ++time->era_entries[idx].stop_date[0]; time->era_entries[idx].stop_date[1] = strtol (str, &endp, 10); if (endp == str || *endp != '/') -- cgit v1.1