Blame gnulib-tests/test-strftime.c

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, &LT[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
*/