1999-12-21  Shinya Hanataka  <hanataka@abyss.rim.or.jp>

	* 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  <yosshy@debian.or.jp>

	* 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  <drepper@cygnus.com>

	* sysdeps/arm/dl-machine.c (CLEAR_CACHE): Fix a2 value.
	Patch by Scott Bambrough <scottb@netwinder.org>.
This commit is contained in:
Ulrich Drepper 1999-12-21 17:50:57 +00:00
parent bef248950a
commit 958d68077b
9 changed files with 256 additions and 159 deletions

View File

@ -1,3 +1,28 @@
1999-12-21 Shinya Hanataka <hanataka@abyss.rim.or.jp>
* 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 <yosshy@debian.or.jp>
* 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 <drepper@cygnus.com>
* sysdeps/arm/dl-machine.c (CLEAR_CACHE): Fix a2 value.
Patch by Scott Bambrough <scottb@netwinder.org>.
1999-12-21 Andreas Schwab <schwab@suse.de>
* sysdeps/unix/sysv/linux/pread.c: Fix typo.

View File

@ -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 struct era_entry *eras;
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;
@ -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,28 +74,16 @@ 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)
if (eras == NULL)
{
num_eras = 0;
eras = NULL;
eras_nf = NULL;
}
else
{
@ -104,27 +92,41 @@ init_era_entry (void)
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)
struct era_entry *
_nl_select_era_entry (int cnt)
{
const void *result;
if (era_initialized == 0)
_nl_init_era_entries ();
__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);
init_era_entry ();
result = eras[cnt]->start_date[0];
__libc_lock_unlock (__libc_setlocale_lock);
return result;
return &eras[cnt];
}

View File

@ -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);

View File

@ -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 != '/')

View File

@ -1,3 +1,8 @@
1999-12-21 Ulrich Drepper <drepper@cygnus.com>
* locales/ja_JP: Fix cntrl mapping and era definition.
Patch by Shinya Hanataka <hanataka@abyss.rim.or.jp>.
1999-12-20 Ulrich Drepper <drepper@cygnus.com>
* locales/af_ZA: New file.

View File

@ -3,8 +3,8 @@ comment_char %
repertoiremap mnemonic.ja
% Name: localedef for ja_JP
% Version: 0.6
% Date: 1999-11-28
% Version: 0.7
% Date: 1999-12-05
% Write: HANATAKA, Shinya <hanataka@abyss.rim.or.jp>
LC_CTYPE
@ -76,7 +76,7 @@ cntrl <alert>;<backspace>;<tab>;<newline>;<vertical-tab>;/
<NUL>;<SOH>;<STX>;<ETX>;<EOT>;<ENQ>;<ACK>;<SO>;<SI>;/
<DLE>;<DC1>;<DC2>;<DC3>;<DC4>;<NAK>;<SYN>;<ETB>;<CAN>;/
<EM>;<SUB>;<ESC>;<IS4>;<IS3>;<IS2>;<IS1>;<DEL>;/
<PBH>;<HOP>;<BPH>;<NBH>;<IND>;<NEL>;<SSA>;<ESA>;<HTS>;<HTJ>;/
<PAD>;<HOP>;<BPH>;<NBH>;<IND>;<NEL>;<SSA>;<ESA>;<HTS>;<HTJ>;/
<VTS>;<PLD>;<PLU>;<RI>;<DCS>;<PU1>;<PU2>;<STS>;<CCH>;<MW>;/
<SPA>;<EPA>;<SOS>;<SGCI>;<SCI>;<CSI>;<ST>;<OSC>;<PM>;<APC>
@ -1652,7 +1652,7 @@ era "+:2:1990//01//01:+*:<j4231><j3214>:%EC%Ey<j3915>";/
"+:2:1912//07//30:1912//12//31:<j3471><j3221>:%EC<j2421><j3915>";/
"+:6:1873//01//01:1912//07//29:<j4432><j2803>:%EC%Ey<j3915>";/
"+:1:0001//01//01:1872//12//31:<j3230><j4681>:%EC%Ey<j3915>";/
"-:1:0000//12//31:-*:<j2110><j2421><j3316>:%EC%Ey<j3915>"
"+:1:-0001//12//31:-*:<j2110><j2421><j3316>:%EC%Ey<j3915>"
era_d_fmt "%EY%m<j2378>%d<j3892>"

View File

@ -35,7 +35,7 @@
#define CLEAR_CACHE(BEG,END) \
{ \
register unsigned long _beg __asm ("a1") = (unsigned long)(BEG); \
register unsigned long _end __asm ("a2") = (unsigned long)((END) - (BEG));\
register unsigned long _end __asm ("a2") = (unsigned long)(END); \
register unsigned long _flg __asm ("a3") = 0; \
__asm __volatile ("swi 0x9f0002"); \
}

View File

@ -834,19 +834,11 @@ my_strftime (s, maxsize, format, tp ut_argument)
if (era)
{
# ifdef COMPILE_WIDE
/* The wide name is after the multi byte name and
format. */
wchar_t *ws;
size_t len;
char *tcp = strchr (era->name_fmt, '\0') + 1;
tcp = strchr (tcp, '\0') + 1;
tcp += 3 - (((tcp - era->name_fmt) + 3) & 3);
ws = (wchar_t *) tcp;
len = wcslen (ws);
cpy (len, ws);
size_t len = strlen (era->era_name);
cpy (len, era->era_name);
# else
size_t len = strlen (era->name_fmt);
cpy (len, era->name_fmt);
size_t len = strlen (era->era_name);
cpy (len, era->era_name);
# endif
break;
}
@ -1199,15 +1191,9 @@ my_strftime (s, maxsize, format, tp ut_argument)
if (era)
{
# ifdef COMPILE_WIDE
/* The wide name is after the multi byte name and
format. */
char *tcp = strchr (era->name_fmt, '\0') + 1;
tcp = strchr (tcp, '\0') + 1;
tcp += 3 - (((tcp - era->name_fmt) + 3) & 3);
subfmt = (wchar_t *) tcp;
subfmt = wcschr (subfmt, L'\0') + 1;
subfmt = era->era_wformat;
# else
subfmt = strchr (era->name_fmt, '\0') + 1;
subfmt = era->era_format;
# endif
goto subformat;
}
@ -1231,7 +1217,7 @@ my_strftime (s, maxsize, format, tp ut_argument)
{
int delta = tp->tm_year - era->start_date[0];
DO_NUMBER (1, (era->offset
+ (era->direction == '-' ? -delta : delta)));
+ delta * era->absolute_direction));
}
#else
# if HAVE_STRFTIME

View File

@ -151,7 +151,7 @@ localtime_r (t, tp)
#endif
#define recursive(new_fmt) \
(*(new_fmt) != '\0' \
&& (rp = strptime_internal (rp, (new_fmt), tm, decided)) != NULL)
&& (rp = strptime_internal (rp, (new_fmt), tm, decided, era_cnt)) != NULL)
#ifdef _LIBC
@ -250,34 +250,38 @@ static char *
#ifdef _LIBC
internal_function
#endif
strptime_internal __P ((const char *buf, const char *format, struct tm *tm,
enum locale_status *decided));
strptime_internal __P ((const char *rp, const char *fmt, struct tm *tm,
enum locale_status *decided, int era_cnt));
static char *
#ifdef _LIBC
internal_function
#endif
strptime_internal (buf, format, tm, decided)
const char *buf;
const char *format;
struct tm *tm;
enum locale_status *decided;
{
strptime_internal (rp, fmt, tm, decided, era_cnt)
const char *rp;
const char *fmt;
struct tm *tm;
enum locale_status *decided;
int era_cnt;
{
const char *rp_backup;
int cnt;
size_t val;
int have_I, is_pm;
int century, want_century;
int want_era;
int have_wday, want_xday;
int have_yday;
int have_mon, have_mday;
size_t num_eras;
struct era_entry *era;
rp = buf;
fmt = format;
have_I = is_pm = 0;
century = -1;
want_century = 0;
want_era = 0;
era = NULL;
have_wday = want_xday = have_yday = have_mon = have_mday = 0;
while (*fmt != '\0')
@ -305,6 +309,10 @@ strptime_internal (buf, format, tm, decided)
/* We need this for handling the `E' modifier. */
start_over:
#endif
/* Make back up of current processing pointer. */
rp_backup = rp;
switch (*fmt++)
{
case '%':
@ -400,6 +408,8 @@ strptime_internal (buf, format, tm, decided)
{
if (*decided == loc)
return NULL;
else
rp = rp_backup;
}
else
{
@ -418,6 +428,7 @@ strptime_internal (buf, format, tm, decided)
break;
case 'C':
/* Match century number. */
match_century:
get_number (0, 99, 2);
century = val;
want_xday = 1;
@ -443,6 +454,8 @@ strptime_internal (buf, format, tm, decided)
{
if (*decided == loc)
return NULL;
else
rp = rp_backup;
}
else
{
@ -534,6 +547,8 @@ strptime_internal (buf, format, tm, decided)
{
if (*decided == loc)
return NULL;
else
rp = rp_backup;
}
else
{
@ -588,6 +603,8 @@ strptime_internal (buf, format, tm, decided)
{
if (*decided == loc)
return NULL;
else
rp = rp_backup;
}
else
{
@ -635,6 +652,7 @@ strptime_internal (buf, format, tm, decided)
have_wday = 1;
break;
case 'y':
match_year_in_century:
/* Match year within century. */
get_number (0, 99, 2);
/* The "Year 2000: The Millennium Rollover" paper suggests that
@ -671,6 +689,8 @@ strptime_internal (buf, format, tm, decided)
{
if (*decided == loc)
return NULL;
else
rp = rp_backup;
}
else
{
@ -688,12 +708,90 @@ strptime_internal (buf, format, tm, decided)
want_xday = 1;
break;
case 'C':
if (*decided != raw)
{
if (era_cnt >= 0)
{
era = _nl_select_era_entry (era_cnt);
if (match_string (era->era_name, rp))
{
*decided = loc;
break;
}
else
return NULL;
}
else
{
num_eras = _NL_CURRENT_WORD (LC_TIME,
_NL_TIME_ERA_NUM_ENTRIES);
for (era_cnt = 0; era_cnt < num_eras;
++era_cnt, rp = rp_backup)
{
era = _nl_select_era_entry (era_cnt);
if (match_string (era->era_name, rp))
{
*decided = loc;
break;
}
}
if (era_cnt == num_eras)
{
era_cnt = -1;
if (*decided == loc)
return NULL;
}
else
break;
}
*decided = raw;
}
/* The C locale has no era information, so use the
normal representation. */
goto match_century;
case 'y':
if (*decided == raw)
goto match_year_in_century;
get_number(0, 9999, 4);
tm->tm_year = val;
want_era = 1;
want_xday = 1;
break;
case 'Y':
/* Match name of base year in locale's alternate
representation. */
/* XXX This is currently not implemented. It should
use the value _NL_CURRENT (LC_TIME, ERA). */
if (*decided != raw)
{
num_eras = _NL_CURRENT_WORD (LC_TIME,
_NL_TIME_ERA_NUM_ENTRIES);
for (era_cnt = 0; era_cnt < num_eras;
++era_cnt, rp = rp_backup)
{
era = _nl_select_era_entry (era_cnt);
if (recursive (era->era_format))
break;
}
if (era_cnt == num_eras)
{
era_cnt = -1;
if (*decided == loc)
return NULL;
else
rp = rp_backup;
}
else
{
*decided = loc;
era_cnt = -1;
break;
}
*decided = raw;
}
get_number (0, 9999, 4);
tm->tm_year = val - 1900;
want_century = 0;
want_xday = 1;
break;
case 'x':
if (*decided != raw)
@ -707,6 +805,8 @@ strptime_internal (buf, format, tm, decided)
{
if (*decided == loc)
return NULL;
else
rp = rp_backup;
}
else
{
@ -731,6 +831,8 @@ strptime_internal (buf, format, tm, decided)
{
if (*decided == loc)
return NULL;
else
rp = rp_backup;
}
else
{
@ -839,16 +941,35 @@ strptime_internal (buf, format, tm, decided)
tm->tm_year = (century - 19) * 100;
}
if (want_xday && !have_wday) {
if ( !(have_mon && have_mday) && have_yday) {
/* we don't have tm_mon and/or tm_mday, compute them */
if (era_cnt != -1)
{
era = _nl_select_era_entry(era_cnt);
if (want_era)
tm->tm_year = (era->start_date[0]
+ ((tm->tm_year - era->offset)
* era->absolute_direction));
else
/* Era start year assumed. */
tm->tm_year = era->start_date[0];
}
else
if (want_era)
return NULL;
if (want_xday && !have_wday)
{
if ( !(have_mon && have_mday) && have_yday)
{
/* We don't have tm_mon and/or tm_mday, compute them. */
int t_mon = 0;
while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday)
t_mon++;
if (!have_mon)
tm->tm_mon = t_mon - 1;
if (!have_mday)
tm->tm_mday = tm->tm_yday - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1;
tm->tm_mday =
(tm->tm_yday
- __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1);
}
day_of_the_week (tm);
}
@ -866,10 +987,11 @@ strptime (buf, format, tm)
struct tm *tm;
{
enum locale_status decided;
#ifdef _NL_CURRENT
decided = not;
#else
decided = raw;
#endif
return strptime_internal (buf, format, tm, &decided);
return strptime_internal (buf, format, tm, &decided, -1);
}