Blame gnulib-tests/test-strftime.c

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