|
Packit |
33f14e |
/* Test that posixtime works as required.
|
|
Packit |
33f14e |
Copyright (C) 2011-2017 Free Software Foundation, Inc.
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
This program is free software: you can redistribute it and/or modify
|
|
Packit |
33f14e |
it under the terms of the GNU General Public License as published by
|
|
Packit |
33f14e |
the Free Software Foundation; either version 3 of the License, or
|
|
Packit |
33f14e |
(at your option) any later version.
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
This program is distributed in the hope that it will be useful,
|
|
Packit |
33f14e |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
33f14e |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
33f14e |
GNU General Public License for more details.
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
You should have received a copy of the GNU General Public License
|
|
Packit |
33f14e |
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
/* Written by Jim Meyering. */
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include <config.h>
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include "strftime.h"
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include <errno.h>
|
|
Packit |
33f14e |
#include <stdio.h>
|
|
Packit |
33f14e |
#include <time.h>
|
|
Packit |
33f14e |
#include <string.h>
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
#include "macros.h"
|
|
Packit |
33f14e |
#define STREQ(a, b) (strcmp (a, b) == 0)
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
struct posixtm_test
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
time_t in;
|
|
Packit |
33f14e |
int in_ns;
|
|
Packit |
33f14e |
char const *fmt;
|
|
Packit |
33f14e |
char const *exp;
|
|
Packit |
33f14e |
};
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
static struct posixtm_test const T[] =
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
{ 1300000000, 0, "%F", "2011-03-13" },
|
|
Packit |
33f14e |
{ 0, 10, "%T.%N", "00:00:00.000000010" },
|
|
Packit |
33f14e |
{ 0, 0, NULL, NULL }
|
|
Packit |
33f14e |
};
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
static int
|
|
Packit |
33f14e |
posixtm_test (void)
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
int fail = 0;
|
|
Packit |
33f14e |
unsigned int i;
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
for (i = 0; T[i].fmt; i++)
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
char buf[1000];
|
|
Packit |
33f14e |
time_t t = T[i].in;
|
|
Packit |
33f14e |
struct tm *tm = gmtime (&t);
|
|
Packit |
33f14e |
size_t n;
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
ASSERT (tm);
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
n = nstrftime (buf, sizeof buf, T[i].fmt, tm, 0, T[i].in_ns);
|
|
Packit |
33f14e |
if (n == 0)
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
fail = 1;
|
|
Packit |
33f14e |
printf ("nstrftime failed with format %s\n", T[i].fmt);
|
|
Packit |
33f14e |
}
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
if (! STREQ (buf, T[i].exp))
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
fail = 1;
|
|
Packit |
33f14e |
printf ("%s: result mismatch: got %s, expected %s\n",
|
|
Packit |
33f14e |
T[i].fmt, buf, T[i].exp);
|
|
Packit |
33f14e |
}
|
|
Packit |
33f14e |
}
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
return fail;
|
|
Packit |
33f14e |
}
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
struct tzalloc_test
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
timezone_t tz;
|
|
Packit |
33f14e |
char const *setting;
|
|
Packit |
33f14e |
};
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
static struct tzalloc_test TZ[] =
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
#define Pacific 0
|
|
Packit |
33f14e |
{ 0, "PST8PDT,M3.2.0,M11.1.0" },
|
|
Packit |
33f14e |
#define Arizona 1
|
|
Packit |
33f14e |
{ 0, "MST7" },
|
|
Packit |
33f14e |
#define UTC 2
|
|
Packit |
33f14e |
{ 0, 0 },
|
|
Packit |
33f14e |
#define CentEur 3
|
|
Packit |
33f14e |
{ 0, "CET-1CEST,M3.5.0,M10.5.0/3" },
|
|
Packit |
33f14e |
#define Japan 4
|
|
Packit |
33f14e |
{ 0, "JST-9" },
|
|
Packit |
33f14e |
#define NZ 5
|
|
Packit |
33f14e |
{ 0, "NZST-12NZDT,M9.5.0,M4.1.0/3" },
|
|
Packit |
33f14e |
#define Unknown 6
|
|
Packit |
33f14e |
{ 0, "<-00>0" },
|
|
Packit |
33f14e |
{ 0 }
|
|
Packit |
33f14e |
};
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
struct localtime_rz_test
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
/* Input parameters. */
|
|
Packit |
33f14e |
struct tzalloc_test *tza;
|
|
Packit |
33f14e |
time_t t;
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
/* Expected result. */
|
|
Packit |
33f14e |
char const *exp;
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
/* Determines if an incorrectly unset tm_isdst
|
|
Packit |
33f14e |
results in failure or just a warning. */
|
|
Packit |
33f14e |
int ahistorical;
|
|
Packit |
33f14e |
};
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
static struct localtime_rz_test LT[] =
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
{ TZ+Pacific, 0, "1969-12-31 16:00:00 -0800 (PST)", 0 },
|
|
Packit |
33f14e |
{ TZ+Arizona, 0, "1969-12-31 17:00:00 -0700 (MST)", 0 },
|
|
Packit |
33f14e |
{ TZ+UTC , 0, "1970-01-01 00:00:00 +0000 (UTC)", 0 },
|
|
Packit |
33f14e |
{ TZ+CentEur, 0, "1970-01-01 01:00:00 +0100 (CET)", 0 },
|
|
Packit |
33f14e |
{ TZ+Japan , 0, "1970-01-01 09:00:00 +0900 (JST)", 0 },
|
|
Packit |
33f14e |
{ TZ+NZ , 0, "1970-01-01 13:00:00 +1300 (NZDT)", 1 },
|
|
Packit |
33f14e |
{ TZ+Unknown, 0, "1970-01-01 00:00:00 -0000 (-00)", 0 },
|
|
Packit |
33f14e |
{ TZ+Pacific, 500000001, "1985-11-04 16:53:21 -0800 (PST)", 0 },
|
|
Packit |
33f14e |
{ TZ+Arizona, 500000001, "1985-11-04 17:53:21 -0700 (MST)", 0 },
|
|
Packit |
33f14e |
{ TZ+UTC , 500000001, "1985-11-05 00:53:21 +0000 (UTC)", 0 },
|
|
Packit |
33f14e |
{ TZ+CentEur, 500000001, "1985-11-05 01:53:21 +0100 (CET)", 1 },
|
|
Packit |
33f14e |
{ TZ+Japan , 500000001, "1985-11-05 09:53:21 +0900 (JST)", 0 },
|
|
Packit |
33f14e |
{ TZ+NZ , 500000001, "1985-11-05 13:53:21 +1300 (NZDT)", 0 },
|
|
Packit |
33f14e |
{ TZ+Unknown, 500000001, "1985-11-05 00:53:21 -0000 (-00)", 0 },
|
|
Packit |
33f14e |
{ TZ+Pacific, 1000000002, "2001-09-08 18:46:42 -0700 (PDT)", 0 },
|
|
Packit |
33f14e |
{ TZ+Arizona, 1000000002, "2001-09-08 18:46:42 -0700 (MST)", 0 },
|
|
Packit |
33f14e |
{ TZ+UTC , 1000000002, "2001-09-09 01:46:42 +0000 (UTC)", 0 },
|
|
Packit |
33f14e |
{ TZ+CentEur, 1000000002, "2001-09-09 03:46:42 +0200 (CEST)", 0 },
|
|
Packit |
33f14e |
{ TZ+Japan , 1000000002, "2001-09-09 10:46:42 +0900 (JST)", 0 },
|
|
Packit |
33f14e |
{ TZ+NZ , 1000000002, "2001-09-09 13:46:42 +1200 (NZST)", 0 },
|
|
Packit |
33f14e |
{ TZ+Unknown, 1000000002, "2001-09-09 01:46:42 -0000 (-00)", 0 },
|
|
Packit |
33f14e |
{ 0 }
|
|
Packit |
33f14e |
};
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
static int
|
|
Packit |
33f14e |
tzalloc_test (void)
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
int fail = 0;
|
|
Packit |
33f14e |
int i;
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
for (i = 0; LT[i].tza; i++)
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
struct tzalloc_test *tza = LT[i].tza;
|
|
Packit |
33f14e |
long lt = LT[i].t;
|
|
Packit |
33f14e |
timezone_t tz = tza->tz;
|
|
Packit |
33f14e |
char const *setting;
|
|
Packit |
33f14e |
static char const format[] = "%Y-%m-%d %H:%M:%S %z (%Z)";
|
|
Packit |
33f14e |
char buf[1000];
|
|
Packit |
33f14e |
struct tm tm;
|
|
Packit |
33f14e |
size_t n;
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
if (!tz && tza->setting)
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
tz = tzalloc (tza->setting);
|
|
Packit |
33f14e |
if (!tz)
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
fail = 1;
|
|
Packit |
33f14e |
printf ("%s: tzalloc: %s\n", TZ[i].setting, strerror (errno));
|
|
Packit |
33f14e |
continue;
|
|
Packit |
33f14e |
}
|
|
Packit |
33f14e |
tza->tz = tz;
|
|
Packit |
33f14e |
}
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
setting = tza->setting ? tza->setting : "UTC0";
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
if (!localtime_rz (tz, <[i].t, &tm))
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
fail = 1;
|
|
Packit |
33f14e |
printf ("%s: %ld: localtime_rz: %s\n", setting, lt,
|
|
Packit |
33f14e |
strerror (errno));
|
|
Packit |
33f14e |
continue;
|
|
Packit |
33f14e |
}
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
n = nstrftime (buf, sizeof buf, format, &tm, tz, 0);
|
|
Packit |
33f14e |
if (n == 0)
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
fail = 1;
|
|
Packit |
33f14e |
printf ("%s: %ld: nstrftime failed\n", setting, lt);
|
|
Packit |
33f14e |
continue;
|
|
Packit |
33f14e |
}
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
if (! (STREQ (buf, LT[i].exp)
|
|
Packit |
33f14e |
|| (!tz && n == strlen (LT[i].exp)
|
|
Packit |
33f14e |
&& memcmp (buf, LT[i].exp, n - sizeof "(GMT)" + 1) == 0
|
|
Packit |
33f14e |
&& STREQ (buf + n - sizeof "(GMT)" + 1, "(GMT)"))))
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
/* Don't fail for unhandled dst in ahistorical entries,
|
|
Packit |
33f14e |
as gnulib doesn't currently fix that issue, seen on Darwin 14. */
|
|
Packit |
33f14e |
if (!LT[i].ahistorical || tm.tm_isdst)
|
|
Packit |
33f14e |
fail = 1;
|
|
Packit |
33f14e |
printf ("%s: expected \"%s\", got \"%s\"\n",
|
|
Packit |
33f14e |
setting, LT[i].exp, buf);
|
|
Packit |
33f14e |
}
|
|
Packit |
33f14e |
}
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
return fail;
|
|
Packit |
33f14e |
}
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
static int
|
|
Packit |
33f14e |
quarter_test (void)
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
int result = 0;
|
|
Packit |
33f14e |
size_t mon;
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
/* Check %q. */
|
|
Packit |
33f14e |
for (mon = 1; mon <= 12; mon++)
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
char out[2];
|
|
Packit |
33f14e |
char exp[2] = {0,};
|
|
Packit |
33f14e |
struct tm qtm = { .tm_mon = mon - 1 };
|
|
Packit |
33f14e |
char fmt[3] = {'%','q','\0'};
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
size_t r = nstrftime (out, sizeof (out), fmt, &qtm, 0, 0);
|
|
Packit |
33f14e |
if (r == 0)
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
puts ("nstrftime(\"%q\") failed");
|
|
Packit |
33f14e |
result = 1;
|
|
Packit |
33f14e |
break;
|
|
Packit |
33f14e |
}
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
exp[0] = mon < 4 ? '1' : mon < 7 ? '2' : mon < 10 ? '3' : '4';
|
|
Packit |
33f14e |
if (strcmp (out, exp) != 0)
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
printf ("nstrftime %%q: expected \"%s\", got \"%s\"\n", exp, out);
|
|
Packit |
33f14e |
result = 1;
|
|
Packit |
33f14e |
break;
|
|
Packit |
33f14e |
}
|
|
Packit |
33f14e |
}
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
return result;
|
|
Packit |
33f14e |
}
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
int
|
|
Packit |
33f14e |
main (void)
|
|
Packit |
33f14e |
{
|
|
Packit |
33f14e |
int fail = 0;
|
|
Packit |
33f14e |
fail |= posixtm_test ();
|
|
Packit |
33f14e |
fail |= tzalloc_test ();
|
|
Packit |
33f14e |
fail |= quarter_test ();
|
|
Packit |
33f14e |
return fail;
|
|
Packit |
33f14e |
}
|
|
Packit |
33f14e |
|
|
Packit |
33f14e |
/*
|
|
Packit |
33f14e |
Local Variables:
|
|
Packit |
33f14e |
indent-tabs-mode: nil
|
|
Packit |
33f14e |
End:
|
|
Packit |
33f14e |
*/
|