aboutsummaryrefslogtreecommitdiff
path: root/locale/lc-time.c
diff options
context:
space:
mode:
Diffstat (limited to 'locale/lc-time.c')
-rw-r--r--locale/lc-time.c130
1 files changed, 114 insertions, 16 deletions
diff --git a/locale/lc-time.c b/locale/lc-time.c
index 78789dce41..764aec8ef2 100644
--- a/locale/lc-time.c
+++ b/locale/lc-time.c
@@ -33,8 +33,11 @@ __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 int alt_digits_initialized;
static const char **alt_digits;
@@ -54,31 +57,46 @@ _nl_postload_time (void)
}
-struct era_entry *
-_nl_get_era_entry (const struct tm *tp)
+static void
+init_era_entry (void)
{
- 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)
+ if (new_num_eras == 0)
{
- free (eras);
- eras = NULL;
+ if (eras != NULL)
+ {
+ free (eras);
+ eras = NULL;
+ }
+ if (eras_nf != NULL)
+ {
+ free (eras_nf);
+ eras_nf = NULL;
+ }
}
- else if (new_num_eras != 0)
+ else
{
if (num_eras != new_num_eras)
- eras = realloc (eras, new_num_eras * sizeof (struct era_entry *));
+ {
+ 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)
- num_eras = 0;
+ if (eras == NULL || eras_nf == NULL)
+ {
+ num_eras = 0;
+ eras = NULL;
+ eras_nf = NULL;
+ }
else
{
const char *ptr = _NL_CURRENT (LC_TIME, _NL_TIME_ERA_ENTRIES);
@@ -90,16 +108,23 @@ _nl_get_era_entry (const struct tm *tp)
/* Skip numeric values. */
ptr += sizeof (struct era_entry);
- /* Skip era name. */
+
+ /* Set and skip era name. */
+ ERAS_NF (cnt, ERA_M_NAME) = (void *) ptr;
ptr = strchr (ptr, '\0') + 1;
- /* Skip era format. */
+
+ /* Set and skip era format. */
+ ERAS_NF (cnt, ERA_M_FORMAT) = (void *) ptr;
ptr = strchr (ptr, '\0') + 1;
ptr += 3 - (((ptr - (const char *) eras[cnt]) + 3) & 3);
- /* Skip wide era name. */
+ /* Set and skip wide era name. */
+ ERAS_NF (cnt, ERA_W_NAME) = (void *) ptr;
ptr = (char *) (wcschr ((wchar_t *) ptr, '\0') + 1);
- /* Skip wide era format. */
+
+ /* Set and skip wide era format. */
+ ERAS_NF (cnt, ERA_W_FORMAT) = (void *) ptr;
ptr = (char *) (wcschr ((wchar_t *) ptr, '\0') + 1);
}
}
@@ -107,6 +132,18 @@ _nl_get_era_entry (const struct tm *tp)
era_initialized = 1;
}
+}
+
+
+struct era_entry *
+_nl_get_era_entry (const struct tm *tp)
+{
+ struct era_entry *result;
+ size_t cnt;
+
+ __libc_lock_lock (__libc_setlocale_lock);
+
+ init_era_entry ();
/* Now compare date with the available eras. */
for (cnt = 0; cnt < num_eras; ++cnt)
@@ -130,6 +167,67 @@ _nl_get_era_entry (const struct tm *tp)
}
+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)
+{
+ int result;
+
+ __libc_lock_lock (__libc_setlocale_lock);
+
+ _nl_init_era_entry();
+
+ result = eras[cnt]->start_date[0];
+
+ __libc_lock_unlock (__libc_setlocale_lock);
+
+ return result;
+}
+
+
const char *
_nl_get_alt_digit (unsigned int number)
{