mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-28 00:21:52 +03:00
Update timezone code from tzcode 2018g.
This patch updates files coming from tzcode to the versions in tzcode 2018g. No changes elsewhere in glibc were needed. Tested for x86_64. * timezone/private.h: Update from tzcode 2018g. * timezone/tzfile.h: Likewise. * timezone/tzselect.ksh: Likewise. * timezone/zdump.c: Likewise. * timezone/zic.c: Likewise.
This commit is contained in:
131
timezone/zdump.c
131
timezone/zdump.c
@ -1,3 +1,5 @@
|
||||
/* Dump time zone data in a textual format. */
|
||||
|
||||
/*
|
||||
** This file is in the public domain, so clarified as of
|
||||
** 2009-05-17 by Arthur David Olson.
|
||||
@ -5,21 +7,16 @@
|
||||
|
||||
#include "version.h"
|
||||
|
||||
/*
|
||||
** This code has been made independent of the rest of the time
|
||||
** conversion package to increase confidence in the verification it provides.
|
||||
** You can use this code to help in verifying other implementations.
|
||||
** To do this, compile with -DUSE_LTZ=0 and link without the tz library.
|
||||
*/
|
||||
|
||||
#ifndef NETBSD_INSPIRED
|
||||
# define NETBSD_INSPIRED 1
|
||||
#endif
|
||||
#ifndef USE_LTZ
|
||||
# define USE_LTZ 1
|
||||
#endif
|
||||
|
||||
#include "private.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef HAVE_SNPRINTF
|
||||
# define HAVE_SNPRINTF (199901 <= __STDC_VERSION__)
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_LOCALTIME_R
|
||||
# define HAVE_LOCALTIME_R 1
|
||||
@ -72,14 +69,11 @@ enum { SECSPER400YEARS_FITS = SECSPERLYEAR <= INTMAX_MAX / 400 };
|
||||
# define timezone_t char **
|
||||
#endif
|
||||
|
||||
extern char ** environ;
|
||||
|
||||
#if !HAVE_POSIX_DECLS
|
||||
extern int getopt(int argc, char * const argv[],
|
||||
const char * options);
|
||||
extern char * optarg;
|
||||
extern int optind;
|
||||
extern char * tzname[];
|
||||
#endif
|
||||
|
||||
/* The minimum and maximum finite time values. */
|
||||
@ -144,7 +138,7 @@ sumsize(size_t a, size_t b)
|
||||
|
||||
/* Return a pointer to a newly allocated buffer of size SIZE, exiting
|
||||
on failure. SIZE should be nonzero. */
|
||||
static void *
|
||||
static void * ATTRIBUTE_MALLOC
|
||||
xmalloc(size_t size)
|
||||
{
|
||||
void *p = malloc(size);
|
||||
@ -263,7 +257,7 @@ tzfree(timezone_t env)
|
||||
}
|
||||
#endif /* ! USE_LOCALTIME_RZ */
|
||||
|
||||
/* A UTC time zone, and its initializer. */
|
||||
/* A UT time zone, and its initializer. */
|
||||
static timezone_t gmtz;
|
||||
static void
|
||||
gmtzinit(void)
|
||||
@ -278,7 +272,7 @@ gmtzinit(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Convert *TP to UTC, storing the broken-down time into *TMP.
|
||||
/* Convert *TP to UT, storing the broken-down time into *TMP.
|
||||
Return TMP if successful, NULL otherwise. This is like gmtime_r(TP, TMP),
|
||||
except typically faster if USE_LOCALTIME_RZ. */
|
||||
static struct tm *
|
||||
@ -390,7 +384,7 @@ static void
|
||||
usage(FILE * const stream, const int status)
|
||||
{
|
||||
fprintf(stream,
|
||||
_("%s: usage: %s OPTIONS ZONENAME ...\n"
|
||||
_("%s: usage: %s OPTIONS TIMEZONE ...\n"
|
||||
"Options include:\n"
|
||||
" -c [L,]U Start at year L (default -500), end before year U (default 2500)\n"
|
||||
" -t [L,]U Start at time L, end before time U (in seconds since 1970)\n"
|
||||
@ -550,6 +544,7 @@ main(int argc, char *argv[])
|
||||
}
|
||||
if (t < cutlotime)
|
||||
t = cutlotime;
|
||||
INITIALIZE (ab);
|
||||
tm_ok = my_localtime_rz(tz, &t, &tm) != NULL;
|
||||
if (tm_ok) {
|
||||
ab = saveabbr(&abbrev, &abbrevsize, &tm);
|
||||
@ -565,11 +560,10 @@ main(int argc, char *argv[])
|
||||
: cuthitime);
|
||||
struct tm *newtmp = localtime_rz(tz, &newt, &newtm);
|
||||
bool newtm_ok = newtmp != NULL;
|
||||
if (! (tm_ok & newtm_ok
|
||||
? (delta(&newtm, &tm) == newt - t
|
||||
&& newtm.tm_isdst == tm.tm_isdst
|
||||
&& strcmp(abbr(&newtm), ab) == 0)
|
||||
: tm_ok == newtm_ok)) {
|
||||
if (tm_ok != newtm_ok
|
||||
|| (tm_ok && (delta(&newtm, &tm) != newt - t
|
||||
|| newtm.tm_isdst != tm.tm_isdst
|
||||
|| strcmp(abbr(&newtm), ab) != 0))) {
|
||||
newt = hunt(tz, argv[i], t, newt);
|
||||
newtmp = localtime_rz(tz, &newt, &newtm);
|
||||
newtm_ok = newtmp != NULL;
|
||||
@ -685,17 +679,15 @@ hunt(timezone_t tz, char *name, time_t lot, time_t hit)
|
||||
}
|
||||
|
||||
/*
|
||||
** Thanks to Paul Eggert for logic used in delta.
|
||||
** Thanks to Paul Eggert for logic used in delta_nonneg.
|
||||
*/
|
||||
|
||||
static intmax_t
|
||||
delta(struct tm * newp, struct tm *oldp)
|
||||
delta_nonneg(struct tm *newp, struct tm *oldp)
|
||||
{
|
||||
register intmax_t result;
|
||||
register int tmy;
|
||||
|
||||
if (newp->tm_year < oldp->tm_year)
|
||||
return -delta(oldp, newp);
|
||||
result = 0;
|
||||
for (tmy = oldp->tm_year; tmy < newp->tm_year; ++tmy)
|
||||
result += DAYSPERNYEAR + isleap_sum(tmy, TM_YEAR_BASE);
|
||||
@ -709,6 +701,14 @@ delta(struct tm * newp, struct tm *oldp)
|
||||
return result;
|
||||
}
|
||||
|
||||
static intmax_t
|
||||
delta(struct tm *newp, struct tm *oldp)
|
||||
{
|
||||
return (newp->tm_year < oldp->tm_year
|
||||
? -delta_nonneg(oldp, newp)
|
||||
: delta_nonneg(newp, oldp));
|
||||
}
|
||||
|
||||
#ifndef TM_GMTOFF
|
||||
/* Return A->tm_yday, adjusted to compare it fairly to B->tm_yday.
|
||||
Assume A and B differ by at most one year. */
|
||||
@ -722,8 +722,8 @@ adjusted_yday(struct tm const *a, struct tm const *b)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If A is the broken-down local time and B the broken-down UTC for
|
||||
the same instant, return A's UTC offset in seconds, where positive
|
||||
/* If A is the broken-down local time and B the broken-down UT for
|
||||
the same instant, return A's UT offset in seconds, where positive
|
||||
offsets are east of Greenwich. On failure, return LONG_MIN.
|
||||
|
||||
If T is nonnull, *T is the timestamp that corresponds to A; call
|
||||
@ -787,6 +787,40 @@ show(timezone_t tz, char *zone, time_t t, bool v)
|
||||
abbrok(abbr(tmp), zone);
|
||||
}
|
||||
|
||||
#if HAVE_SNPRINTF
|
||||
# define my_snprintf snprintf
|
||||
#else
|
||||
# include <stdarg.h>
|
||||
|
||||
/* A substitute for snprintf that is good enough for zdump. */
|
||||
static int ATTRIBUTE_FORMAT((printf, 3, 4))
|
||||
my_snprintf(char *s, size_t size, char const *format, ...)
|
||||
{
|
||||
int n;
|
||||
va_list args;
|
||||
char const *arg;
|
||||
size_t arglen, slen;
|
||||
char buf[1024];
|
||||
va_start(args, format);
|
||||
if (strcmp(format, "%s") == 0) {
|
||||
arg = va_arg(args, char const *);
|
||||
arglen = strlen(arg);
|
||||
} else {
|
||||
n = vsprintf(buf, format, args);
|
||||
if (n < 0)
|
||||
return n;
|
||||
arg = buf;
|
||||
arglen = n;
|
||||
}
|
||||
slen = arglen < size ? arglen : size - 1;
|
||||
memcpy(s, arg, slen);
|
||||
s[slen] = '\0';
|
||||
n = arglen <= INT_MAX ? arglen : -1;
|
||||
va_end(args);
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Store into BUF, of size SIZE, a formatted local time taken from *TM.
|
||||
Use ISO 8601 format +HH:MM:SS. Omit :SS if SS is zero, and omit
|
||||
:MM too if MM is also zero.
|
||||
@ -799,16 +833,16 @@ format_local_time(char *buf, size_t size, struct tm const *tm)
|
||||
{
|
||||
int ss = tm->tm_sec, mm = tm->tm_min, hh = tm->tm_hour;
|
||||
return (ss
|
||||
? snprintf(buf, size, "%02d:%02d:%02d", hh, mm, ss)
|
||||
? my_snprintf(buf, size, "%02d:%02d:%02d", hh, mm, ss)
|
||||
: mm
|
||||
? snprintf(buf, size, "%02d:%02d", hh, mm)
|
||||
: snprintf(buf, size, "%02d", hh));
|
||||
? my_snprintf(buf, size, "%02d:%02d", hh, mm)
|
||||
: my_snprintf(buf, size, "%02d", hh));
|
||||
}
|
||||
|
||||
/* Store into BUF, of size SIZE, a formatted UTC offset for the
|
||||
/* Store into BUF, of size SIZE, a formatted UT offset for the
|
||||
localtime *TM corresponding to time T. Use ISO 8601 format
|
||||
+HHMMSS, or -HHMMSS for timestamps west of Greenwich; use the
|
||||
format -00 for unknown UTC offsets. If the hour needs more than
|
||||
format -00 for unknown UT offsets. If the hour needs more than
|
||||
two digits to represent, extend the length of HH as needed.
|
||||
Otherwise, omit SS if SS is zero, and omit MM too if MM is also
|
||||
zero.
|
||||
@ -837,10 +871,10 @@ format_utc_offset(char *buf, size_t size, struct tm const *tm, time_t t)
|
||||
mm = off / 60 % 60;
|
||||
hh = off / 60 / 60;
|
||||
return (ss || 100 <= hh
|
||||
? snprintf(buf, size, "%c%02ld%02d%02d", sign, hh, mm, ss)
|
||||
? my_snprintf(buf, size, "%c%02ld%02d%02d", sign, hh, mm, ss)
|
||||
: mm
|
||||
? snprintf(buf, size, "%c%02ld%02d", sign, hh, mm)
|
||||
: snprintf(buf, size, "%c%02ld", sign, hh));
|
||||
? my_snprintf(buf, size, "%c%02ld%02d", sign, hh, mm)
|
||||
: my_snprintf(buf, size, "%c%02ld", sign, hh));
|
||||
}
|
||||
|
||||
/* Store into BUF (of size SIZE) a quoted string representation of P.
|
||||
@ -883,7 +917,7 @@ format_quoted_string(char *buf, size_t size, char const *p)
|
||||
|
||||
%f zone name
|
||||
%L local time as per format_local_time
|
||||
%Q like "U\t%Z\tD" where U is the UTC offset as for format_utc_offset
|
||||
%Q like "U\t%Z\tD" where U is the UT offset as for format_utc_offset
|
||||
and D is the isdst flag; except omit D if it is zero, omit %Z if
|
||||
it equals U, quote and escape %Z if it contains nonalphabetics,
|
||||
and omit any trailing tabs. */
|
||||
@ -943,15 +977,16 @@ istrftime(char *buf, size_t size, char const *time_fmt,
|
||||
for (abp = ab; is_alpha(*abp); abp++)
|
||||
continue;
|
||||
len = (!*abp && *ab
|
||||
? snprintf(b, s, "%s", ab)
|
||||
? my_snprintf(b, s, "%s", ab)
|
||||
: format_quoted_string(b, s, ab));
|
||||
if (s <= len)
|
||||
return false;
|
||||
b += len, s -= len;
|
||||
}
|
||||
formatted_len = (tm->tm_isdst
|
||||
? snprintf(b, s, &"\t\t%d"[show_abbr], tm->tm_isdst)
|
||||
: 0);
|
||||
formatted_len
|
||||
= (tm->tm_isdst
|
||||
? my_snprintf(b, s, &"\t\t%d"[show_abbr], tm->tm_isdst)
|
||||
: 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -993,9 +1028,11 @@ abbr(struct tm const *tmp)
|
||||
#ifdef TM_ZONE
|
||||
return tmp->TM_ZONE;
|
||||
#else
|
||||
return (0 <= tmp->tm_isdst && tzname[0 < tmp->tm_isdst]
|
||||
? tzname[0 < tmp->tm_isdst]
|
||||
: "");
|
||||
# if HAVE_TZNAME
|
||||
if (0 <= tmp->tm_isdst && tzname[0 < tmp->tm_isdst])
|
||||
return tzname[0 < tmp->tm_isdst];
|
||||
# endif
|
||||
return "";
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1030,10 +1067,10 @@ tformat(void)
|
||||
static void
|
||||
dumptime(register const struct tm *timeptr)
|
||||
{
|
||||
static const char wday_name[][3] = {
|
||||
static const char wday_name[][4] = {
|
||||
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
||||
};
|
||||
static const char mon_name[][3] = {
|
||||
static const char mon_name[][4] = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
@ -1059,7 +1096,7 @@ dumptime(register const struct tm *timeptr)
|
||||
(int) (sizeof mon_name / sizeof mon_name[0]))
|
||||
mn = "???";
|
||||
else mn = mon_name[timeptr->tm_mon];
|
||||
printf("%.3s %.3s%3d %.2d:%.2d:%.2d ",
|
||||
printf("%s %s%3d %.2d:%.2d:%.2d ",
|
||||
wn, mn,
|
||||
timeptr->tm_mday, timeptr->tm_hour,
|
||||
timeptr->tm_min, timeptr->tm_sec);
|
||||
|
Reference in New Issue
Block a user