A little localtime clean-up
This commit is contained in:
parent
c23610994c
commit
f087e35676
@ -168,14 +168,20 @@ extern "C"
|
|||||||
#define EXTERN extern
|
#define EXTERN extern
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_LIBC_LOCALTIME
|
||||||
|
|
||||||
/* daylight - Daylight savings time flag */
|
/* daylight - Daylight savings time flag */
|
||||||
/* EXTERN int daylight; not supported */
|
/* EXTERN int daylight; not supported */
|
||||||
|
|
||||||
/* timezone - Difference from UTC and local standard time */
|
/* timezone - Difference from UTC and local standard time */
|
||||||
/* EXTERN long int timezone; not supported */
|
/* EXTERN long int timezone; not supported */
|
||||||
|
|
||||||
/* tzname[] - Timezone strings */
|
/* tzname[] - Timezone strings
|
||||||
/* EXTERN FAR char *tzname[]; not supported */
|
* Setup by tzset()
|
||||||
|
*/
|
||||||
|
|
||||||
|
EXTERN FAR char *tzname[2];
|
||||||
|
#endif
|
||||||
|
|
||||||
/********************************************************************************
|
/********************************************************************************
|
||||||
* Public Function Prototypes
|
* Public Function Prototypes
|
||||||
@ -206,6 +212,10 @@ int timer_getoverrun(timer_t timerid);
|
|||||||
|
|
||||||
int nanosleep(FAR const struct timespec *rqtp, FAR struct timespec *rmtp);
|
int nanosleep(FAR const struct timespec *rqtp, FAR struct timespec *rmtp);
|
||||||
|
|
||||||
|
#ifdef CONFIG_LIBC_LOCALTIME
|
||||||
|
void tzset(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
|
@ -265,14 +265,15 @@ config ARCH_LOWPUTC
|
|||||||
config LIBC_LOCALTIME
|
config LIBC_LOCALTIME
|
||||||
bool "localtime API call support"
|
bool "localtime API call support"
|
||||||
default "n"
|
default "n"
|
||||||
depends on !DISABLE_ENVIRON && EXPERIMENTAL
|
depends on !DISABLE_ENVIRON
|
||||||
---help---
|
---help---
|
||||||
localtime API call support
|
localtime API call support
|
||||||
|
|
||||||
Logic currently depends on file system support with, at a minimum, these
|
Logic currently depends on file system support with, at a minimum, these
|
||||||
files in the zoneinfo directory: GMT and posixrules. An additional
|
files in the zoneinfo directory: GMT and posixrules. An additional
|
||||||
timezone file is required for any another time zone and the environment
|
timezone file is required for any additional, local time zone(s) and the
|
||||||
variable TZ must be set to the name of that file.
|
environment variable TZ must be set to the name of that timezone file
|
||||||
|
when tzset() is called.
|
||||||
|
|
||||||
See https://www.iana.org/time-zones
|
See https://www.iana.org/time-zones
|
||||||
|
|
||||||
|
@ -298,27 +298,21 @@ struct rule_s
|
|||||||
|
|
||||||
/* The minimum and maximum finite time values. */
|
/* The minimum and maximum finite time values. */
|
||||||
|
|
||||||
static time_t const time_t_min =
|
static time_t const g_min_timet =
|
||||||
(TYPE_SIGNED(time_t)
|
(TYPE_SIGNED(time_t)
|
||||||
? (time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1)
|
? (time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1)
|
||||||
: 0);
|
: 0);
|
||||||
|
|
||||||
static time_t const time_t_max =
|
static time_t const g_max_timet =
|
||||||
(TYPE_SIGNED(time_t)
|
(TYPE_SIGNED(time_t)
|
||||||
? - (~ 0 < 0) - ((time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1))
|
? - (~ 0 < 0) - ((time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1))
|
||||||
: -1);
|
: -1);
|
||||||
|
|
||||||
static const char wildabbr[] = WILDABBR;
|
static const char g_wildabbr[] = WILDABBR;
|
||||||
|
|
||||||
static char lcl_TZname[MY_TZNAME_MAX + 1];
|
static char g_lcl_tzname[MY_TZNAME_MAX + 1];
|
||||||
static int lcl_is_set;
|
static int g_lcl_isset;
|
||||||
static int gmt_is_set;
|
static int g_gmt_isset;
|
||||||
|
|
||||||
char *tzname[2] =
|
|
||||||
{
|
|
||||||
(FAR char*)wildabbr,
|
|
||||||
(FAR char*)wildabbr
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Section 4.12.3 of X3.159-1989 requires that
|
/* Section 4.12.3 of X3.159-1989 requires that
|
||||||
* Except for the strftime function, these functions [asctime,
|
* Except for the strftime function, these functions [asctime,
|
||||||
@ -327,17 +321,31 @@ char *tzname[2] =
|
|||||||
* Thanks to Paul Eggert for noting this.
|
* Thanks to Paul Eggert for noting this.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static struct tm tm;
|
static struct tm g_tm;
|
||||||
|
|
||||||
static const int mon_lengths[2][MONSPERYEAR] = {
|
static const int g_mon_lengths[2][MONSPERYEAR] =
|
||||||
|
{
|
||||||
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
||||||
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
|
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int year_lengths[2] = {
|
static const int g_year_lengths[2] =
|
||||||
|
{
|
||||||
DAYSPERNYEAR, DAYSPERLYEAR
|
DAYSPERNYEAR, DAYSPERLYEAR
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Data
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/* Setup by tzset() */
|
||||||
|
|
||||||
|
FAR char *tzname[2] =
|
||||||
|
{
|
||||||
|
(FAR char *)g_wildabbr,
|
||||||
|
(FAR char *)g_wildabbr
|
||||||
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Function Prototypes
|
* Private Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -429,7 +437,7 @@ static void settzname(void)
|
|||||||
FAR struct state_s *const sp = lclptr;
|
FAR struct state_s *const sp = lclptr;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
tzname[0] = tzname[1] = (FAR char*)wildabbr;
|
tzname[0] = tzname[1] = (FAR char*)g_wildabbr;
|
||||||
if (sp == NULL)
|
if (sp == NULL)
|
||||||
{
|
{
|
||||||
tzname[0] = tzname[1] = (FAR char*)GMT;
|
tzname[0] = tzname[1] = (FAR char*)GMT;
|
||||||
@ -630,10 +638,10 @@ static int tzload(FAR const char *name,
|
|||||||
{
|
{
|
||||||
int_fast64_t at = stored == 4 ? detzcode(p) : detzcode64(p);
|
int_fast64_t at = stored == 4 ? detzcode(p) : detzcode64(p);
|
||||||
sp->types[i] = ((TYPE_SIGNED(time_t)
|
sp->types[i] = ((TYPE_SIGNED(time_t)
|
||||||
? time_t_min <= at : 0 <= at) && at <= time_t_max);
|
? g_min_timet <= at : 0 <= at) && at <= g_max_timet);
|
||||||
if (sp->types[i])
|
if (sp->types[i])
|
||||||
{
|
{
|
||||||
if (i && !timecnt && at != time_t_min)
|
if (i && !timecnt && at != g_min_timet)
|
||||||
{
|
{
|
||||||
/* Keep the earlier record, but tweak
|
/* Keep the earlier record, but tweak
|
||||||
* it so that it starts with the
|
* it so that it starts with the
|
||||||
@ -641,7 +649,7 @@ static int tzload(FAR const char *name,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
sp->types[i - 1] = 1;
|
sp->types[i - 1] = 1;
|
||||||
sp->ats[timecnt++] = time_t_min;
|
sp->ats[timecnt++] = g_min_timet;
|
||||||
}
|
}
|
||||||
|
|
||||||
sp->ats[timecnt++] = at;
|
sp->ats[timecnt++] = at;
|
||||||
@ -1219,7 +1227,7 @@ static int_fast32_t transtime(const int year,
|
|||||||
|
|
||||||
for (i = 1; i < rulep->r_week; ++i)
|
for (i = 1; i < rulep->r_week; ++i)
|
||||||
{
|
{
|
||||||
if (d + DAYSPERWEEK >= mon_lengths[leapyear][rulep->r_mon - 1])
|
if (d + DAYSPERWEEK >= g_mon_lengths[leapyear][rulep->r_mon - 1])
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1232,7 +1240,7 @@ static int_fast32_t transtime(const int year,
|
|||||||
value = d * SECSPERDAY;
|
value = d * SECSPERDAY;
|
||||||
for (i = 0; i < rulep->r_mon - 1; ++i)
|
for (i = 0; i < rulep->r_mon - 1; ++i)
|
||||||
{
|
{
|
||||||
value += mon_lengths[leapyear][i] * SECSPERDAY;
|
value += g_mon_lengths[leapyear][i] * SECSPERDAY;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1402,7 +1410,7 @@ static int tzparse(FAR const char *name, FAR struct state_s *const sp,
|
|||||||
int_fast32_t
|
int_fast32_t
|
||||||
starttime = transtime(year, &start, stdoffset),
|
starttime = transtime(year, &start, stdoffset),
|
||||||
endtime = transtime(year, &end, dstoffset);
|
endtime = transtime(year, &end, dstoffset);
|
||||||
int_fast32_t yearsecs = (year_lengths[isleap(year)] * SECSPERDAY);
|
int_fast32_t yearsecs = (g_year_lengths[isleap(year)] * SECSPERDAY);
|
||||||
int reversed = endtime < starttime;
|
int reversed = endtime < starttime;
|
||||||
if (reversed)
|
if (reversed)
|
||||||
{
|
{
|
||||||
@ -1603,12 +1611,12 @@ static void gmtload(FAR struct state_s *const sp)
|
|||||||
|
|
||||||
static void tzsetwall(void)
|
static void tzsetwall(void)
|
||||||
{
|
{
|
||||||
if (lcl_is_set < 0)
|
if (g_lcl_isset < 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lcl_is_set = -1;
|
g_lcl_isset = -1;
|
||||||
|
|
||||||
if (lclptr == NULL)
|
if (lclptr == NULL)
|
||||||
{
|
{
|
||||||
@ -1755,11 +1763,11 @@ static struct tm *localsub(FAR const time_t * const timep,
|
|||||||
static struct tm *gmtsub(FAR const time_t * const timep, const int_fast32_t offset,
|
static struct tm *gmtsub(FAR const time_t * const timep, const int_fast32_t offset,
|
||||||
struct tm *const tmp)
|
struct tm *const tmp)
|
||||||
{
|
{
|
||||||
if (!gmt_is_set)
|
if (!g_gmt_isset)
|
||||||
{
|
{
|
||||||
gmtptr = malloc(sizeof *gmtptr);
|
gmtptr = malloc(sizeof *gmtptr);
|
||||||
gmt_is_set = gmtptr != NULL;
|
g_gmt_isset = gmtptr != NULL;
|
||||||
if (gmt_is_set)
|
if (g_gmt_isset)
|
||||||
{
|
{
|
||||||
gmtload(gmtptr);
|
gmtload(gmtptr);
|
||||||
}
|
}
|
||||||
@ -1826,7 +1834,7 @@ static struct tm *timesub(FAR const time_t * const timep,
|
|||||||
y = EPOCH_YEAR;
|
y = EPOCH_YEAR;
|
||||||
tdays = *timep / SECSPERDAY;
|
tdays = *timep / SECSPERDAY;
|
||||||
rem = *timep - tdays * SECSPERDAY;
|
rem = *timep - tdays * SECSPERDAY;
|
||||||
while (tdays < 0 || tdays >= year_lengths[isleap(y)])
|
while (tdays < 0 || tdays >= g_year_lengths[isleap(y)])
|
||||||
{
|
{
|
||||||
int newy;
|
int newy;
|
||||||
time_t tdelta;
|
time_t tdelta;
|
||||||
@ -1885,12 +1893,12 @@ static struct tm *timesub(FAR const time_t * const timep,
|
|||||||
{
|
{
|
||||||
if (increment_overflow(&y, -1))
|
if (increment_overflow(&y, -1))
|
||||||
return NULL;
|
return NULL;
|
||||||
idays += year_lengths[isleap(y)];
|
idays += g_year_lengths[isleap(y)];
|
||||||
}
|
}
|
||||||
|
|
||||||
while (idays >= year_lengths[isleap(y)])
|
while (idays >= g_year_lengths[isleap(y)])
|
||||||
{
|
{
|
||||||
idays -= year_lengths[isleap(y)];
|
idays -= g_year_lengths[isleap(y)];
|
||||||
if (increment_overflow(&y, 1))
|
if (increment_overflow(&y, 1))
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1926,7 +1934,7 @@ static struct tm *timesub(FAR const time_t * const timep,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
tmp->tm_sec = (int)(rem % SECSPERMIN) + hit;
|
tmp->tm_sec = (int)(rem % SECSPERMIN) + hit;
|
||||||
ip = mon_lengths[isleap(y)];
|
ip = g_mon_lengths[isleap(y)];
|
||||||
for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
|
for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon))
|
||||||
{
|
{
|
||||||
idays -= ip[tmp->tm_mon];
|
idays -= ip[tmp->tm_mon];
|
||||||
@ -1983,13 +1991,13 @@ static int increment_overflow32(FAR int_fast32_t * const lp, int const m)
|
|||||||
static int increment_overflow_time(time_t * tp, int_fast32_t j)
|
static int increment_overflow_time(time_t * tp, int_fast32_t j)
|
||||||
{
|
{
|
||||||
/* This is like
|
/* This is like
|
||||||
* 'if (! (time_t_min <= *tp + j && *tp + j <= time_t_max)) ...',
|
* 'if (! (g_min_timet <= *tp + j && *tp + j <= g_max_timet)) ...',
|
||||||
* except that it does the right thing even if *tp + j would overflow.
|
* except that it does the right thing even if *tp + j would overflow.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!(j < 0
|
if (!(j < 0
|
||||||
? (TYPE_SIGNED(time_t) ? time_t_min - j <= *tp : -1 - j < *tp)
|
? (TYPE_SIGNED(time_t) ? g_min_timet - j <= *tp : -1 - j < *tp)
|
||||||
: *tp <= time_t_max - j))
|
: *tp <= g_max_timet - j))
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -2101,13 +2109,13 @@ static time_t time2sub(struct tm *const tmp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
li = y + (1 < yourtm.tm_mon);
|
li = y + (1 < yourtm.tm_mon);
|
||||||
yourtm.tm_mday += year_lengths[isleap(li)];
|
yourtm.tm_mday += g_year_lengths[isleap(li)];
|
||||||
}
|
}
|
||||||
|
|
||||||
while (yourtm.tm_mday > DAYSPERLYEAR)
|
while (yourtm.tm_mday > DAYSPERLYEAR)
|
||||||
{
|
{
|
||||||
li = y + (1 < yourtm.tm_mon);
|
li = y + (1 < yourtm.tm_mon);
|
||||||
yourtm.tm_mday -= year_lengths[isleap(li)];
|
yourtm.tm_mday -= g_year_lengths[isleap(li)];
|
||||||
if (increment_overflow32(&y, 1))
|
if (increment_overflow32(&y, 1))
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
@ -2116,7 +2124,7 @@ static time_t time2sub(struct tm *const tmp,
|
|||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
i = mon_lengths[isleap(y)][yourtm.tm_mon];
|
i = g_mon_lengths[isleap(y)][yourtm.tm_mon];
|
||||||
if (yourtm.tm_mday <= i)
|
if (yourtm.tm_mday <= i)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@ -2220,7 +2228,7 @@ static time_t time2sub(struct tm *const tmp,
|
|||||||
{
|
{
|
||||||
if (t == lo)
|
if (t == lo)
|
||||||
{
|
{
|
||||||
if (t == time_t_max)
|
if (t == g_max_timet)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -2230,7 +2238,7 @@ static time_t time2sub(struct tm *const tmp,
|
|||||||
}
|
}
|
||||||
else if (t == hi)
|
else if (t == hi)
|
||||||
{
|
{
|
||||||
if (t == time_t_min)
|
if (t == g_min_timet)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -2456,15 +2464,15 @@ void tzset(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lcl_is_set > 0 && strcmp(lcl_TZname, name) == 0)
|
if (g_lcl_isset > 0 && strcmp(g_lcl_tzname, name) == 0)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
lcl_is_set = strlen(name) < sizeof lcl_TZname;
|
g_lcl_isset = strlen(name) < sizeof g_lcl_tzname;
|
||||||
if (lcl_is_set)
|
if (g_lcl_isset)
|
||||||
{
|
{
|
||||||
(void)strcpy(lcl_TZname, name);
|
(void)strcpy(g_lcl_tzname, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lclptr == NULL)
|
if (lclptr == NULL)
|
||||||
@ -2503,7 +2511,7 @@ void tzset(void)
|
|||||||
FAR struct tm *localtime(FAR const time_t * const timep)
|
FAR struct tm *localtime(FAR const time_t * const timep)
|
||||||
{
|
{
|
||||||
tzset();
|
tzset();
|
||||||
return localsub(timep, 0L, &tm);
|
return localsub(timep, 0L, &g_tm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Re-entrant version of localtime */
|
/* Re-entrant version of localtime */
|
||||||
@ -2515,7 +2523,7 @@ FAR struct tm *localtime_r(FAR const time_t * const timep, struct tm *tmp)
|
|||||||
|
|
||||||
FAR struct tm *gmtime(FAR const time_t * const timep)
|
FAR struct tm *gmtime(FAR const time_t * const timep)
|
||||||
{
|
{
|
||||||
return gmtsub(timep, 0L, &tm);
|
return gmtsub(timep, 0L, &g_tm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Re-entrant version of gmtime */
|
/* Re-entrant version of gmtime */
|
||||||
|
Loading…
Reference in New Issue
Block a user