Blame locale/programs/ld-time.c

Packit Service 82fcde
/* Copyright (C) 1995-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
   Contributed by Ulrich Drepper <drepper@gnu.org>, 1995.
Packit Service 82fcde
Packit Service 82fcde
   This program is free software; you can redistribute it and/or modify
Packit Service 82fcde
   it under the terms of the GNU General Public License as published
Packit Service 82fcde
   by the Free Software Foundation; version 2 of the License, or
Packit Service 82fcde
   (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   This program is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 82fcde
   GNU General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU General Public License
Packit Service 82fcde
   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#ifdef HAVE_CONFIG_H
Packit Service 82fcde
# include <config.h>
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#include <byteswap.h>
Packit Service 82fcde
#include <langinfo.h>
Packit Service 82fcde
#include <stdlib.h>
Packit Service 82fcde
#include <string.h>
Packit Service 82fcde
#include <wchar.h>
Packit Service 82fcde
#include <stdint.h>
Packit Service 82fcde
#include <sys/uio.h>
Packit Service 82fcde
Packit Service 82fcde
#include <assert.h>
Packit Service 82fcde
Packit Service 82fcde
#include "localedef.h"
Packit Service 82fcde
#include "linereader.h"
Packit Service 82fcde
#include "localeinfo.h"
Packit Service 82fcde
#include "locfile.h"
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* Entry describing an entry of the era specification.  */
Packit Service 82fcde
struct era_data
Packit Service 82fcde
{
Packit Service 82fcde
  int32_t direction;
Packit Service 82fcde
  int32_t offset;
Packit Service 82fcde
  int32_t start_date[3];
Packit Service 82fcde
  int32_t stop_date[3];
Packit Service 82fcde
  const char *name;
Packit Service 82fcde
  const char *format;
Packit Service 82fcde
  uint32_t *wname;
Packit Service 82fcde
  uint32_t *wformat;
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* The real definition of the struct for the LC_TIME locale.  */
Packit Service 82fcde
struct locale_time_t
Packit Service 82fcde
{
Packit Service 82fcde
  const char *abday[7];
Packit Service 82fcde
  const uint32_t *wabday[7];
Packit Service 82fcde
  int abday_defined;
Packit Service 82fcde
  const char *day[7];
Packit Service 82fcde
  const uint32_t *wday[7];
Packit Service 82fcde
  int day_defined;
Packit Service 82fcde
  const char *abmon[12];
Packit Service 82fcde
  const uint32_t *wabmon[12];
Packit Service 82fcde
  int abmon_defined;
Packit Service 82fcde
  const char *mon[12];
Packit Service 82fcde
  const uint32_t *wmon[12];
Packit Service 82fcde
  int mon_defined;
Packit Service 82fcde
  const char *am_pm[2];
Packit Service 82fcde
  const uint32_t *wam_pm[2];
Packit Service 82fcde
  int am_pm_defined;
Packit Service 82fcde
  const char *d_t_fmt;
Packit Service 82fcde
  const uint32_t *wd_t_fmt;
Packit Service 82fcde
  const char *d_fmt;
Packit Service 82fcde
  const uint32_t *wd_fmt;
Packit Service 82fcde
  const char *t_fmt;
Packit Service 82fcde
  const uint32_t *wt_fmt;
Packit Service 82fcde
  const char *t_fmt_ampm;
Packit Service 82fcde
  const uint32_t *wt_fmt_ampm;
Packit Service 82fcde
  const char **era;
Packit Service 82fcde
  const uint32_t **wera;
Packit Service 82fcde
  uint32_t num_era;
Packit Service 82fcde
  const char *era_year;
Packit Service 82fcde
  const uint32_t *wera_year;
Packit Service 82fcde
  const char *era_d_t_fmt;
Packit Service 82fcde
  const uint32_t *wera_d_t_fmt;
Packit Service 82fcde
  const char *era_t_fmt;
Packit Service 82fcde
  const uint32_t *wera_t_fmt;
Packit Service 82fcde
  const char *era_d_fmt;
Packit Service 82fcde
  const uint32_t *wera_d_fmt;
Packit Service 82fcde
  const char *alt_digits[100];
Packit Service 82fcde
  const uint32_t *walt_digits[100];
Packit Service 82fcde
  const char *date_fmt;
Packit Service 82fcde
  const uint32_t *wdate_fmt;
Packit Service 82fcde
  int alt_digits_defined;
Packit Service 82fcde
  const char *alt_mon[12];
Packit Service 82fcde
  const uint32_t *walt_mon[12];
Packit Service 82fcde
  int alt_mon_defined;
Packit Service 82fcde
  const char *ab_alt_mon[12];
Packit Service 82fcde
  const uint32_t *wab_alt_mon[12];
Packit Service 82fcde
  int ab_alt_mon_defined;
Packit Service 82fcde
  unsigned char week_ndays;
Packit Service 82fcde
  uint32_t week_1stday;
Packit Service 82fcde
  unsigned char week_1stweek;
Packit Service 82fcde
  unsigned char first_weekday;
Packit Service 82fcde
  unsigned char first_workday;
Packit Service 82fcde
  unsigned char cal_direction;
Packit Service 82fcde
  const char *timezone;
Packit Service 82fcde
  const uint32_t *wtimezone;
Packit Service 82fcde
Packit Service 82fcde
  struct era_data *era_entries;
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* This constant is used to represent an empty wide character string.  */
Packit Service 82fcde
static const uint32_t empty_wstr[1] = { 0 };
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
time_startup (struct linereader *lr, struct localedef_t *locale,
Packit Service 82fcde
	      int ignore_content)
Packit Service 82fcde
{
Packit Service 82fcde
  if (!ignore_content)
Packit Service 82fcde
    locale->categories[LC_TIME].time =
Packit Service 82fcde
      (struct locale_time_t *) xcalloc (1, sizeof (struct locale_time_t));
Packit Service 82fcde
Packit Service 82fcde
  if (lr != NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      lr->translate_strings = 1;
Packit Service 82fcde
      lr->return_widestr = 1;
Packit Service 82fcde
    }
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
void
Packit Service 82fcde
time_finish (struct localedef_t *locale, const struct charmap_t *charmap)
Packit Service 82fcde
{
Packit Service 82fcde
  struct locale_time_t *time = locale->categories[LC_TIME].time;
Packit Service 82fcde
  int nothing = 0;
Packit Service 82fcde
Packit Service 82fcde
  /* Now resolve copying and also handle completely missing definitions.  */
Packit Service 82fcde
  if (time == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* First see whether we were supposed to copy.  If yes, find the
Packit Service 82fcde
	 actual definition.  */
Packit Service 82fcde
      if (locale->copy_name[LC_TIME] != NULL)
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* Find the copying locale.  This has to happen transitively since
Packit Service 82fcde
	     the locale we are copying from might also copying another one.  */
Packit Service 82fcde
	  struct localedef_t *from = locale;
Packit Service 82fcde
Packit Service 82fcde
	  do
Packit Service 82fcde
	    from = find_locale (LC_TIME, from->copy_name[LC_TIME],
Packit Service 82fcde
				from->repertoire_name, charmap);
Packit Service 82fcde
	  while (from->categories[LC_TIME].time == NULL
Packit Service 82fcde
		 && from->copy_name[LC_TIME] != NULL);
Packit Service 82fcde
Packit Service 82fcde
	  time = locale->categories[LC_TIME].time
Packit Service 82fcde
	    = from->categories[LC_TIME].time;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* If there is still no definition issue an warning and create an
Packit Service 82fcde
	 empty one.  */
Packit Service 82fcde
      if (time == NULL)
Packit Service 82fcde
	{
Packit Service 82fcde
	  record_warning (_("\
Packit Service 82fcde
No definition for %s category found"), "LC_TIME");
Packit Service 82fcde
	  time_startup (NULL, locale, 0);
Packit Service 82fcde
	  time = locale->categories[LC_TIME].time;
Packit Service 82fcde
	  nothing = 1;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
#define noparen(arg1, argn...) arg1, ##argn
Packit Service 82fcde
#define TESTARR_ELEM(cat, val) \
Packit Service 82fcde
  if (!time->cat##_defined)						      \
Packit Service 82fcde
    {									      \
Packit Service 82fcde
      const char *initval[] = { noparen val };				      \
Packit Service 82fcde
      unsigned int i;							      \
Packit Service 82fcde
									      \
Packit Service 82fcde
      if (! nothing)					    		      \
Packit Service 82fcde
	record_error (0, 0, _("%s: field `%s' not defined"),	      	      \
Packit Service 82fcde
		      "LC_TIME", #cat);          			      \
Packit Service 82fcde
									      \
Packit Service 82fcde
      for (i = 0; i < sizeof (initval) / sizeof (initval[0]); ++i)	      \
Packit Service 82fcde
	time->cat[i] = initval[i];					      \
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  TESTARR_ELEM (abday, ( "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ));
Packit Service 82fcde
  TESTARR_ELEM (day, ( "Sunday", "Monday", "Tuesday", "Wednesday",
Packit Service 82fcde
		        "Thursday", "Friday", "Saturday" ));
Packit Service 82fcde
  TESTARR_ELEM (abmon, ( "Jan", "Feb", "Mar", "Apr", "May", "Jun",
Packit Service 82fcde
			  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ));
Packit Service 82fcde
  TESTARR_ELEM (mon, ( "January", "February", "March", "April",
Packit Service 82fcde
			"May", "June", "July", "August",
Packit Service 82fcde
			"September", "October", "November", "December" ));
Packit Service 82fcde
  TESTARR_ELEM (am_pm, ( "AM", "PM" ));
Packit Service 82fcde
Packit Service 82fcde
#define TEST_ELEM(cat, initval) \
Packit Service 82fcde
  if (time->cat == NULL)						      \
Packit Service 82fcde
    {									      \
Packit Service 82fcde
      if (! nothing)							      \
Packit Service 82fcde
	record_error (0, 0, _("%s: field `%s' not defined"),		      \
Packit Service 82fcde
		      "LC_TIME", #cat);          			      \
Packit Service 82fcde
									      \
Packit Service 82fcde
      time->cat = initval;						      \
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  TEST_ELEM (d_t_fmt, "%a %b %e %H:%M:%S %Y");
Packit Service 82fcde
  TEST_ELEM (d_fmt, "%m/%d/%y");
Packit Service 82fcde
  TEST_ELEM (t_fmt, "%H:%M:%S");
Packit Service 82fcde
Packit Service 82fcde
  /* According to C.Y.Alexis Cheng <alexis@vnet.ibm.com> the T_FMT_AMPM
Packit Service 82fcde
     field is optional.  */
Packit Service 82fcde
  if (time->t_fmt_ampm == NULL)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (time->am_pm[0][0] == '\0' && time->am_pm[1][0] == '\0')
Packit Service 82fcde
	{
Packit Service 82fcde
	  /* No AM/PM strings defined, use the 24h format as default.  */
Packit Service 82fcde
	  time->t_fmt_ampm = time->t_fmt;
Packit Service 82fcde
	  time->wt_fmt_ampm = time->wt_fmt;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	{
Packit Service 82fcde
	  time->t_fmt_ampm = "%I:%M:%S %p";
Packit Service 82fcde
	  time->wt_fmt_ampm = (const uint32_t *) L"%I:%M:%S %p";
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* Now process the era entries.  */
Packit Service 82fcde
  if (time->num_era != 0)
Packit Service 82fcde
    {
Packit Service 82fcde
      const int days_per_month[12] = { 31, 29, 31, 30, 31, 30,
Packit Service 82fcde
				       31, 31, 30, 31 ,30, 31 };
Packit Service 82fcde
      size_t idx;
Packit Service 82fcde
      wchar_t *wstr;
Packit Service 82fcde
Packit Service 82fcde
      time->era_entries =
Packit Service 82fcde
	(struct era_data *) xmalloc (time->num_era
Packit Service 82fcde
				     * sizeof (struct era_data));
Packit Service 82fcde
Packit Service 82fcde
      for (idx = 0; idx < time->num_era; ++idx)
Packit Service 82fcde
	{
Packit Service 82fcde
	  size_t era_len = strlen (time->era[idx]);
Packit Service 82fcde
	  char *str = xmalloc ((era_len + 1 + 3) & ~3);
Packit Service 82fcde
	  char *endp;
Packit Service 82fcde
Packit Service 82fcde
	  memcpy (str, time->era[idx], era_len + 1);
Packit Service 82fcde
Packit Service 82fcde
	  /* First character must be + or - for the direction.  */
Packit Service 82fcde
	  if (*str != '+' && *str != '-')
Packit Service 82fcde
	    {
Packit Service 82fcde
	      record_error (0, 0, _("\
Packit Service 82fcde
%s: direction flag in string %Zd in `era' field is not '+' nor '-'"),
Packit Service 82fcde
			    "LC_TIME", idx + 1);
Packit Service 82fcde
	      /* Default arbitrarily to '+'.  */
Packit Service 82fcde
	      time->era_entries[idx].direction = '+';
Packit Service 82fcde
	    }
Packit Service 82fcde
	  else
Packit Service 82fcde
	    time->era_entries[idx].direction = *str;
Packit Service 82fcde
	  if (*++str != ':')
Packit Service 82fcde
	    {
Packit Service 82fcde
	      record_error (0, 0, _("\
Packit Service 82fcde
%s: direction flag in string %Zd in `era' field is not a single character"),
Packit Service 82fcde
			    "LC_TIME", idx + 1);
Packit Service 82fcde
	      (void) strsep (&str, ":");
Packit Service 82fcde
	    }
Packit Service 82fcde
	  else
Packit Service 82fcde
	    ++str;
Packit Service 82fcde
Packit Service 82fcde
	  /* Now the offset year.  */
Packit Service 82fcde
	  time->era_entries[idx].offset = strtol (str, &endp, 10);
Packit Service 82fcde
	  if (endp == str)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      record_error (0, 0, _("\
Packit Service 82fcde
%s: invalid number for offset in string %Zd in `era' field"),
Packit Service 82fcde
			    "LC_TIME", idx + 1);
Packit Service 82fcde
	      (void) strsep (&str, ":");
Packit Service 82fcde
	    }
Packit Service 82fcde
	  else if (*endp != ':')
Packit Service 82fcde
	    {
Packit Service 82fcde
	      record_error (0, 0, _("\
Packit Service 82fcde
%s: garbage at end of offset value in string %Zd in `era' field"),
Packit Service 82fcde
			    "LC_TIME", idx + 1);
Packit Service 82fcde
	      (void) strsep (&str, ":");
Packit Service 82fcde
	    }
Packit Service 82fcde
	  else
Packit Service 82fcde
	    str = endp + 1;
Packit Service 82fcde
Packit Service 82fcde
	  /* Next is the starting date in ISO format.  */
Packit Service 82fcde
	  if (strncmp (str, "-*", 2) == 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      time->era_entries[idx].start_date[0] =
Packit Service 82fcde
		time->era_entries[idx].start_date[1] =
Packit Service 82fcde
		time->era_entries[idx].start_date[2] = 0x80000000;
Packit Service 82fcde
	      if (str[2] != ':')
Packit Service 82fcde
		goto garbage_start_date;
Packit Service 82fcde
	      str += 3;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  else if (strncmp (str, "+*", 2) == 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      time->era_entries[idx].start_date[0] =
Packit Service 82fcde
		time->era_entries[idx].start_date[1] =
Packit Service 82fcde
		time->era_entries[idx].start_date[2] = 0x7fffffff;
Packit Service 82fcde
	      if (str[2] != ':')
Packit Service 82fcde
		goto garbage_start_date;
Packit Service 82fcde
	      str += 3;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  else
Packit Service 82fcde
	    {
Packit Service 82fcde
	      time->era_entries[idx].start_date[0] = strtol (str, &endp, 10);
Packit Service 82fcde
	      if (endp == str || *endp != '/')
Packit Service 82fcde
		goto invalid_start_date;
Packit Service 82fcde
	      else
Packit Service 82fcde
		str = endp + 1;
Packit Service 82fcde
	      time->era_entries[idx].start_date[0] -= 1900;
Packit Service 82fcde
	      /* year -1 represent 1 B.C. (not -1 A.D.) */
Packit Service 82fcde
	      if (time->era_entries[idx].start_date[0] < -1900)
Packit Service 82fcde
		++time->era_entries[idx].start_date[0];
Packit Service 82fcde
Packit Service 82fcde
	      time->era_entries[idx].start_date[1] = strtol (str, &endp, 10);
Packit Service 82fcde
	      if (endp == str || *endp != '/')
Packit Service 82fcde
		goto invalid_start_date;
Packit Service 82fcde
	      else
Packit Service 82fcde
		str = endp + 1;
Packit Service 82fcde
	      time->era_entries[idx].start_date[1] -= 1;
Packit Service 82fcde
Packit Service 82fcde
	      time->era_entries[idx].start_date[2] = strtol (str, &endp, 10);
Packit Service 82fcde
	      if (endp == str)
Packit Service 82fcde
		{
Packit Service 82fcde
		invalid_start_date:
Packit Service 82fcde
		  record_error (0, 0, _("\
Packit Service 82fcde
%s: invalid starting date in string %Zd in `era' field"),
Packit Service 82fcde
				"LC_TIME", idx + 1);
Packit Service 82fcde
		  (void) strsep (&str, ":");
Packit Service 82fcde
		}
Packit Service 82fcde
	      else if (*endp != ':')
Packit Service 82fcde
		{
Packit Service 82fcde
		garbage_start_date:
Packit Service 82fcde
		  record_error (0, 0, _("\
Packit Service 82fcde
%s: garbage at end of starting date in string %Zd in `era' field "),
Packit Service 82fcde
				"LC_TIME", idx + 1);
Packit Service 82fcde
		  (void) strsep (&str, ":");
Packit Service 82fcde
		}
Packit Service 82fcde
	      else
Packit Service 82fcde
		{
Packit Service 82fcde
		  str = endp + 1;
Packit Service 82fcde
Packit Service 82fcde
		  /* Check for valid value.  */
Packit Service 82fcde
		  if ((time->era_entries[idx].start_date[1] < 0
Packit Service 82fcde
		       || time->era_entries[idx].start_date[1] >= 12
Packit Service 82fcde
		       || time->era_entries[idx].start_date[2] < 0
Packit Service 82fcde
		       || (time->era_entries[idx].start_date[2]
Packit Service 82fcde
			   > days_per_month[time->era_entries[idx].start_date[1]])
Packit Service 82fcde
		       || (time->era_entries[idx].start_date[1] == 2
Packit Service 82fcde
			   && time->era_entries[idx].start_date[2] == 29
Packit Service 82fcde
			   && !__isleap (time->era_entries[idx].start_date[0]))))
Packit Service 82fcde
		    record_error (0, 0, _("\
Packit Service 82fcde
%s: starting date is invalid in string %Zd in `era' field"),
Packit Service 82fcde
				  "LC_TIME", idx + 1);
Packit Service 82fcde
		}
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  /* Next is the stopping date in ISO format.  */
Packit Service 82fcde
	  if (strncmp (str, "-*", 2) == 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      time->era_entries[idx].stop_date[0] =
Packit Service 82fcde
		time->era_entries[idx].stop_date[1] =
Packit Service 82fcde
		time->era_entries[idx].stop_date[2] = 0x80000000;
Packit Service 82fcde
	      if (str[2] != ':')
Packit Service 82fcde
		goto garbage_stop_date;
Packit Service 82fcde
	      str += 3;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  else if (strncmp (str, "+*", 2) == 0)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      time->era_entries[idx].stop_date[0] =
Packit Service 82fcde
		time->era_entries[idx].stop_date[1] =
Packit Service 82fcde
		time->era_entries[idx].stop_date[2] = 0x7fffffff;
Packit Service 82fcde
	      if (str[2] != ':')
Packit Service 82fcde
		goto garbage_stop_date;
Packit Service 82fcde
	      str += 3;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  else
Packit Service 82fcde
	    {
Packit Service 82fcde
	      time->era_entries[idx].stop_date[0] = strtol (str, &endp, 10);
Packit Service 82fcde
	      if (endp == str || *endp != '/')
Packit Service 82fcde
		goto invalid_stop_date;
Packit Service 82fcde
	      else
Packit Service 82fcde
		str = endp + 1;
Packit Service 82fcde
	      time->era_entries[idx].stop_date[0] -= 1900;
Packit Service 82fcde
	      /* year -1 represent 1 B.C. (not -1 A.D.) */
Packit Service 82fcde
	      if (time->era_entries[idx].stop_date[0] < -1900)
Packit Service 82fcde
		++time->era_entries[idx].stop_date[0];
Packit Service 82fcde
Packit Service 82fcde
	      time->era_entries[idx].stop_date[1] = strtol (str, &endp, 10);
Packit Service 82fcde
	      if (endp == str || *endp != '/')
Packit Service 82fcde
		goto invalid_stop_date;
Packit Service 82fcde
	      else
Packit Service 82fcde
		str = endp + 1;
Packit Service 82fcde
	      time->era_entries[idx].stop_date[1] -= 1;
Packit Service 82fcde
Packit Service 82fcde
	      time->era_entries[idx].stop_date[2] = strtol (str, &endp, 10);
Packit Service 82fcde
	      if (endp == str)
Packit Service 82fcde
		{
Packit Service 82fcde
		invalid_stop_date:
Packit Service 82fcde
		  record_error (0, 0, _("\
Packit Service 82fcde
%s: invalid stopping date in string %Zd in `era' field"),
Packit Service 82fcde
				"LC_TIME", idx + 1);
Packit Service 82fcde
		  (void) strsep (&str, ":");
Packit Service 82fcde
		}
Packit Service 82fcde
	      else if (*endp != ':')
Packit Service 82fcde
		{
Packit Service 82fcde
		garbage_stop_date:
Packit Service 82fcde
		  record_error (0, 0, _("\
Packit Service 82fcde
%s: garbage at end of stopping date in string %Zd in `era' field"),
Packit Service 82fcde
				"LC_TIME", idx + 1);
Packit Service 82fcde
		  (void) strsep (&str, ":");
Packit Service 82fcde
		}
Packit Service 82fcde
	      else
Packit Service 82fcde
		{
Packit Service 82fcde
		  str = endp + 1;
Packit Service 82fcde
Packit Service 82fcde
		  /* Check for valid value.  */
Packit Service 82fcde
		  if ((time->era_entries[idx].stop_date[1] < 0
Packit Service 82fcde
		       || time->era_entries[idx].stop_date[1] >= 12
Packit Service 82fcde
		       || time->era_entries[idx].stop_date[2] < 0
Packit Service 82fcde
		       || (time->era_entries[idx].stop_date[2]
Packit Service 82fcde
			   > days_per_month[time->era_entries[idx].stop_date[1]])
Packit Service 82fcde
		       || (time->era_entries[idx].stop_date[1] == 2
Packit Service 82fcde
			   && time->era_entries[idx].stop_date[2] == 29
Packit Service 82fcde
			   && !__isleap (time->era_entries[idx].stop_date[0]))))
Packit Service 82fcde
		    record_error (0, 0, _("\
Packit Service 82fcde
%s: invalid stopping date in string %Zd in `era' field"),
Packit Service 82fcde
				  "LC_TIME", idx + 1);
Packit Service 82fcde
		}
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  if (str == NULL || *str == '\0')
Packit Service 82fcde
	    {
Packit Service 82fcde
	      record_error (0, 0, _("\
Packit Service 82fcde
%s: missing era name in string %Zd in `era' field"), "LC_TIME", idx + 1);
Packit Service 82fcde
	      time->era_entries[idx].name =
Packit Service 82fcde
		time->era_entries[idx].format = "";
Packit Service 82fcde
	    }
Packit Service 82fcde
	  else
Packit Service 82fcde
	    {
Packit Service 82fcde
	      time->era_entries[idx].name = strsep (&str, ":");
Packit Service 82fcde
Packit Service 82fcde
	      if (str == NULL || *str == '\0')
Packit Service 82fcde
		{
Packit Service 82fcde
		  record_error (0, 0, _("\
Packit Service 82fcde
%s: missing era format in string %Zd in `era' field"),
Packit Service 82fcde
				"LC_TIME", idx + 1);
Packit Service 82fcde
		  time->era_entries[idx].name =
Packit Service 82fcde
		    time->era_entries[idx].format = "";
Packit Service 82fcde
		}
Packit Service 82fcde
	      else
Packit Service 82fcde
		time->era_entries[idx].format = str;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  /* Now generate the wide character name and format.  */
Packit Service 82fcde
	  wstr = wcschr ((wchar_t *) time->wera[idx], L':');/* end direction */
Packit Service 82fcde
	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end offset */
Packit Service 82fcde
	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end start */
Packit Service 82fcde
	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end end */
Packit Service 82fcde
	  if (wstr != NULL)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      time->era_entries[idx].wname = (uint32_t *) wstr + 1;
Packit Service 82fcde
	      wstr = wcschr (wstr + 1, L':');	/* end name */
Packit Service 82fcde
	      if (wstr != NULL)
Packit Service 82fcde
		{
Packit Service 82fcde
		  *wstr = L'\0';
Packit Service 82fcde
		  time->era_entries[idx].wformat = (uint32_t *) wstr + 1;
Packit Service 82fcde
		}
Packit Service 82fcde
	      else
Packit Service 82fcde
		time->era_entries[idx].wname =
Packit Service 82fcde
		  time->era_entries[idx].wformat = (uint32_t *) L"";
Packit Service 82fcde
	    }
Packit Service 82fcde
	  else
Packit Service 82fcde
	    time->era_entries[idx].wname =
Packit Service 82fcde
	      time->era_entries[idx].wformat = (uint32_t *) L"";
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* Set up defaults based on ISO 30112 WD10 [2014].  */
Packit Service 82fcde
  if (time->week_ndays == 0)
Packit Service 82fcde
    time->week_ndays = 7;
Packit Service 82fcde
Packit Service 82fcde
  if (time->week_1stday == 0)
Packit Service 82fcde
    time->week_1stday = 19971130;
Packit Service 82fcde
Packit Service 82fcde
  if (time->week_1stweek == 0)
Packit Service 82fcde
    time->week_1stweek = 7;
Packit Service 82fcde
Packit Service 82fcde
  if (time->week_1stweek > time->week_ndays)
Packit Service 82fcde
    record_error (0, 0, _("\
Packit Service 82fcde
%s: third operand for value of field `%s' must not be larger than %d"),
Packit Service 82fcde
		  "LC_TIME", "week", 7);
Packit Service 82fcde
Packit Service 82fcde
  if (time->first_weekday == '\0')
Packit Service 82fcde
    /* The definition does not specify this so the default is used.  */
Packit Service 82fcde
    time->first_weekday = 1;
Packit Service 82fcde
  else if (time->first_weekday > time->week_ndays)
Packit Service 82fcde
    record_error (0, 0, _("\
Packit Service 82fcde
%s: values for field `%s' must not be larger than %d"),
Packit Service 82fcde
		  "LC_TIME", "first_weekday", 7);
Packit Service 82fcde
Packit Service 82fcde
  if (time->first_workday == '\0')
Packit Service 82fcde
    /* The definition does not specify this so the default is used.  */
Packit Service 82fcde
    time->first_workday = 2;
Packit Service 82fcde
  else if (time->first_workday > time->week_ndays)
Packit Service 82fcde
    record_error (0, 0, _("\
Packit Service 82fcde
%s: values for field `%s' must not be larger than %d"),
Packit Service 82fcde
		  "LC_TIME", "first_workday", 7);
Packit Service 82fcde
Packit Service 82fcde
  if (time->cal_direction == '\0')
Packit Service 82fcde
    /* The definition does not specify this so the default is used.  */
Packit Service 82fcde
    time->cal_direction = 1;
Packit Service 82fcde
  else if (time->cal_direction > 3)
Packit Service 82fcde
    record_error (0, 0, _("\
Packit Service 82fcde
%s: values for field `%s' must not be larger than %d"),
Packit Service 82fcde
		  "LC_TIME", "cal_direction", 3);
Packit Service 82fcde
Packit Service 82fcde
  /* XXX We don't perform any tests on the timezone value since this is
Packit Service 82fcde
     simply useless, stupid $&$!@...  */
Packit Service 82fcde
  if (time->timezone == NULL)
Packit Service 82fcde
    time->timezone = "";
Packit Service 82fcde
Packit Service 82fcde
  if (time->date_fmt == NULL)
Packit Service 82fcde
    time->date_fmt = "%a %b %e %H:%M:%S %Z %Y";
Packit Service 82fcde
  if (time->wdate_fmt == NULL)
Packit Service 82fcde
    time->wdate_fmt = (const uint32_t *) L"%a %b %e %H:%M:%S %Z %Y";
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
void
Packit Service 82fcde
time_output (struct localedef_t *locale, const struct charmap_t *charmap,
Packit Service 82fcde
	     const char *output_path)
Packit Service 82fcde
{
Packit Service 82fcde
  struct locale_time_t *time = locale->categories[LC_TIME].time;
Packit Service 82fcde
  struct locale_file file;
Packit Service 82fcde
  size_t num, n;
Packit Service 82fcde
Packit Service 82fcde
  init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_TIME));
Packit Service 82fcde
Packit Service 82fcde
  /* The ab'days.  */
Packit Service 82fcde
  for (n = 0; n < 7; ++n)
Packit Service 82fcde
    add_locale_string (&file, time->abday[n] ?: "");
Packit Service 82fcde
Packit Service 82fcde
  /* The days.  */
Packit Service 82fcde
  for (n = 0; n < 7; ++n)
Packit Service 82fcde
    add_locale_string (&file, time->day[n] ?: "");
Packit Service 82fcde
Packit Service 82fcde
  /* The ab'mons.  */
Packit Service 82fcde
  for (n = 0; n < 12; ++n)
Packit Service 82fcde
    add_locale_string (&file, time->abmon[n] ?: "");
Packit Service 82fcde
Packit Service 82fcde
  /* The mons.  */
Packit Service 82fcde
  for (n = 0; n < 12; ++n)
Packit Service 82fcde
    add_locale_string (&file, time->mon[n] ?: "");
Packit Service 82fcde
Packit Service 82fcde
  /* AM/PM.  */
Packit Service 82fcde
  for (n = 0; n < 2; ++n)
Packit Service 82fcde
    add_locale_string (&file, time->am_pm[n]);
Packit Service 82fcde
Packit Service 82fcde
  add_locale_string (&file, time->d_t_fmt ?: "");
Packit Service 82fcde
  add_locale_string (&file, time->d_fmt ?: "");
Packit Service 82fcde
  add_locale_string (&file, time->t_fmt ?: "");
Packit Service 82fcde
  add_locale_string (&file, time->t_fmt_ampm ?: "");
Packit Service 82fcde
Packit Service 82fcde
  start_locale_structure (&file;;
Packit Service 82fcde
  for (num = 0; num < time->num_era; ++num)
Packit Service 82fcde
    add_locale_string (&file, time->era[num]);
Packit Service 82fcde
  end_locale_structure (&file;;
Packit Service 82fcde
Packit Service 82fcde
  add_locale_string (&file, time->era_year ?: "");
Packit Service 82fcde
  add_locale_string (&file, time->era_d_fmt ?: "");
Packit Service 82fcde
Packit Service 82fcde
  start_locale_structure (&file;;
Packit Service 82fcde
  for (num = 0; num < 100; ++num)
Packit Service 82fcde
    add_locale_string (&file, time->alt_digits[num] ?: "");
Packit Service 82fcde
  end_locale_structure (&file;;
Packit Service 82fcde
Packit Service 82fcde
  add_locale_string (&file, time->era_d_t_fmt ?: "");
Packit Service 82fcde
  add_locale_string (&file, time->era_t_fmt ?: "");
Packit Service 82fcde
  add_locale_uint32 (&file, time->num_era);
Packit Service 82fcde
Packit Service 82fcde
  start_locale_structure (&file;;
Packit Service 82fcde
  for (num = 0; num < time->num_era; ++num)
Packit Service 82fcde
    {
Packit Service 82fcde
      add_locale_uint32 (&file, time->era_entries[num].direction);
Packit Service 82fcde
      add_locale_uint32 (&file, time->era_entries[num].offset);
Packit Service 82fcde
      add_locale_uint32 (&file, time->era_entries[num].start_date[0]);
Packit Service 82fcde
      add_locale_uint32 (&file, time->era_entries[num].start_date[1]);
Packit Service 82fcde
      add_locale_uint32 (&file, time->era_entries[num].start_date[2]);
Packit Service 82fcde
      add_locale_uint32 (&file, time->era_entries[num].stop_date[0]);
Packit Service 82fcde
      add_locale_uint32 (&file, time->era_entries[num].stop_date[1]);
Packit Service 82fcde
      add_locale_uint32 (&file, time->era_entries[num].stop_date[2]);
Packit Service 82fcde
      add_locale_string (&file, time->era_entries[num].name);
Packit Service 82fcde
      add_locale_string (&file, time->era_entries[num].format);
Packit Service 82fcde
      add_locale_wstring (&file, time->era_entries[num].wname);
Packit Service 82fcde
      add_locale_wstring (&file, time->era_entries[num].wformat);
Packit Service 82fcde
    }
Packit Service 82fcde
  end_locale_structure (&file;;
Packit Service 82fcde
Packit Service 82fcde
  /* The wide character ab'days.  */
Packit Service 82fcde
  for (n = 0; n < 7; ++n)
Packit Service 82fcde
    add_locale_wstring (&file, time->wabday[n] ?: empty_wstr);
Packit Service 82fcde
Packit Service 82fcde
  /* The wide character days.  */
Packit Service 82fcde
  for (n = 0; n < 7; ++n)
Packit Service 82fcde
    add_locale_wstring (&file, time->wday[n] ?: empty_wstr);
Packit Service 82fcde
Packit Service 82fcde
  /* The wide character ab'mons.  */
Packit Service 82fcde
  for (n = 0; n < 12; ++n)
Packit Service 82fcde
    add_locale_wstring (&file, time->wabmon[n] ?: empty_wstr);
Packit Service 82fcde
Packit Service 82fcde
  /* The wide character mons.  */
Packit Service 82fcde
  for (n = 0; n < 12; ++n)
Packit Service 82fcde
    add_locale_wstring (&file, time->wmon[n] ?: empty_wstr);
Packit Service 82fcde
Packit Service 82fcde
  /* Wide character AM/PM.  */
Packit Service 82fcde
  for (n = 0; n < 2; ++n)
Packit Service 82fcde
    add_locale_wstring (&file, time->wam_pm[n] ?: empty_wstr);
Packit Service 82fcde
Packit Service 82fcde
  add_locale_wstring (&file, time->wd_t_fmt ?: empty_wstr);
Packit Service 82fcde
  add_locale_wstring (&file, time->wd_fmt ?: empty_wstr);
Packit Service 82fcde
  add_locale_wstring (&file, time->wt_fmt ?: empty_wstr);
Packit Service 82fcde
  add_locale_wstring (&file, time->wt_fmt_ampm ?: empty_wstr);
Packit Service 82fcde
  add_locale_wstring (&file, time->wera_year ?: empty_wstr);
Packit Service 82fcde
  add_locale_wstring (&file, time->wera_d_fmt ?: empty_wstr);
Packit Service 82fcde
Packit Service 82fcde
  start_locale_structure (&file;;
Packit Service 82fcde
  for (num = 0; num < 100; ++num)
Packit Service 82fcde
    add_locale_wstring (&file, time->walt_digits[num] ?: empty_wstr);
Packit Service 82fcde
  end_locale_structure (&file;;
Packit Service 82fcde
Packit Service 82fcde
  add_locale_wstring (&file, time->wera_d_t_fmt ?: empty_wstr);
Packit Service 82fcde
  add_locale_wstring (&file, time->wera_t_fmt ?: empty_wstr);
Packit Service 82fcde
  add_locale_char (&file, time->week_ndays);
Packit Service 82fcde
  add_locale_uint32 (&file, time->week_1stday);
Packit Service 82fcde
  add_locale_char (&file, time->week_1stweek);
Packit Service 82fcde
  add_locale_char (&file, time->first_weekday);
Packit Service 82fcde
  add_locale_char (&file, time->first_workday);
Packit Service 82fcde
  add_locale_char (&file, time->cal_direction);
Packit Service 82fcde
  add_locale_string (&file, time->timezone);
Packit Service 82fcde
  add_locale_string (&file, time->date_fmt);
Packit Service 82fcde
  add_locale_wstring (&file, time->wdate_fmt);
Packit Service 82fcde
  add_locale_string (&file, charmap->code_set_name);
Packit Service 82fcde
Packit Service 82fcde
  /* The alt'mons.  */
Packit Service 82fcde
  for (n = 0; n < 12; ++n)
Packit Service 82fcde
    add_locale_string (&file, time->alt_mon[n] ?: "");
Packit Service 82fcde
Packit Service 82fcde
  /* The wide character alt'mons.  */
Packit Service 82fcde
  for (n = 0; n < 12; ++n)
Packit Service 82fcde
    add_locale_wstring (&file, time->walt_mon[n] ?: empty_wstr);
Packit Service 82fcde
Packit Service 82fcde
  /* The ab'alt'mons.  */
Packit Service 82fcde
  for (n = 0; n < 12; ++n)
Packit Service 82fcde
    add_locale_string (&file, time->ab_alt_mon[n] ?: "");
Packit Service 82fcde
Packit Service 82fcde
  /* The wide character ab'alt'mons.  */
Packit Service 82fcde
  for (n = 0; n < 12; ++n)
Packit Service 82fcde
    add_locale_wstring (&file, time->wab_alt_mon[n] ?: empty_wstr);
Packit Service 82fcde
Packit Service 82fcde
  write_locale_data (output_path, LC_TIME, "LC_TIME", &file;;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
/* The parser for the LC_TIME section of the locale definition.  */
Packit Service 82fcde
void
Packit Service 82fcde
time_read (struct linereader *ldfile, struct localedef_t *result,
Packit Service 82fcde
	   const struct charmap_t *charmap, const char *repertoire_name,
Packit Service 82fcde
	   int ignore_content)
Packit Service 82fcde
{
Packit Service 82fcde
  struct repertoire_t *repertoire = NULL;
Packit Service 82fcde
  struct locale_time_t *time;
Packit Service 82fcde
  struct token *now;
Packit Service 82fcde
  enum token_t nowtok;
Packit Service 82fcde
  size_t cnt;
Packit Service 82fcde
Packit Service 82fcde
  /* Get the repertoire we have to use.  */
Packit Service 82fcde
  if (repertoire_name != NULL)
Packit Service 82fcde
    repertoire = repertoire_read (repertoire_name);
Packit Service 82fcde
Packit Service 82fcde
  /* The rest of the line containing `LC_TIME' must be free.  */
Packit Service 82fcde
  lr_ignore_rest (ldfile, 1);
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
  do
Packit Service 82fcde
    {
Packit Service 82fcde
      now = lr_token (ldfile, charmap, result, repertoire, verbose);
Packit Service 82fcde
      nowtok = now->tok;
Packit Service 82fcde
    }
Packit Service 82fcde
  while (nowtok == tok_eol);
Packit Service 82fcde
Packit Service 82fcde
  /* If we see `copy' now we are almost done.  */
Packit Service 82fcde
  if (nowtok == tok_copy)
Packit Service 82fcde
    {
Packit Service 82fcde
      handle_copy (ldfile, charmap, repertoire_name, result, tok_lc_time,
Packit Service 82fcde
		   LC_TIME, "LC_TIME", ignore_content);
Packit Service 82fcde
      return;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* Prepare the data structures.  */
Packit Service 82fcde
  time_startup (ldfile, result, ignore_content);
Packit Service 82fcde
  time = result->categories[LC_TIME].time;
Packit Service 82fcde
Packit Service 82fcde
  while (1)
Packit Service 82fcde
    {
Packit Service 82fcde
      /* Of course we don't proceed beyond the end of file.  */
Packit Service 82fcde
      if (nowtok == tok_eof)
Packit Service 82fcde
	break;
Packit Service 82fcde
Packit Service 82fcde
      /* Ingore empty lines.  */
Packit Service 82fcde
      if (nowtok == tok_eol)
Packit Service 82fcde
	{
Packit Service 82fcde
	  now = lr_token (ldfile, charmap, result, repertoire, verbose);
Packit Service 82fcde
	  nowtok = now->tok;
Packit Service 82fcde
	  continue;
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      switch (nowtok)
Packit Service 82fcde
	{
Packit Service 82fcde
#define STRARR_ELEM(cat, min, max) \
Packit Service 82fcde
	case tok_##cat:							      \
Packit Service 82fcde
	  /* Ignore the rest of the line if we don't need the input of	      \
Packit Service 82fcde
	     this line.  */						      \
Packit Service 82fcde
	  if (ignore_content)						      \
Packit Service 82fcde
	    {								      \
Packit Service 82fcde
	      lr_ignore_rest (ldfile, 0);				      \
Packit Service 82fcde
	      break;							      \
Packit Service 82fcde
	    }								      \
Packit Service 82fcde
									      \
Packit Service 82fcde
	  for (cnt = 0; cnt < max; ++cnt)				      \
Packit Service 82fcde
	    {								      \
Packit Service 82fcde
	      now = lr_token (ldfile, charmap, result, repertoire, verbose);  \
Packit Service 82fcde
	      if (now->tok == tok_eol)					      \
Packit Service 82fcde
		{							      \
Packit Service 82fcde
		  if (cnt < min)					      \
Packit Service 82fcde
		    lr_error (ldfile, _("%s: too few values for field `%s'"), \
Packit Service 82fcde
			      "LC_TIME", #cat);				      \
Packit Service 82fcde
		  if (!ignore_content)					      \
Packit Service 82fcde
		    do							      \
Packit Service 82fcde
		      {							      \
Packit Service 82fcde
			time->cat[cnt] = "";				      \
Packit Service 82fcde
			time->w##cat[cnt] = empty_wstr;			      \
Packit Service 82fcde
		      }							      \
Packit Service 82fcde
		    while (++cnt < max);				      \
Packit Service 82fcde
		  break;						      \
Packit Service 82fcde
		}							      \
Packit Service 82fcde
	      else if (now->tok != tok_string)				      \
Packit Service 82fcde
		goto err_label;						      \
Packit Service 82fcde
	      else if (!ignore_content && (now->val.str.startmb == NULL	      \
Packit Service 82fcde
					   || now->val.str.startwc == NULL))  \
Packit Service 82fcde
		{							      \
Packit Service 82fcde
		  lr_error (ldfile, _("%s: unknown character in field `%s'"), \
Packit Service 82fcde
			    "LC_TIME", #cat);				      \
Packit Service 82fcde
		  time->cat[cnt] = "";					      \
Packit Service 82fcde
		  time->w##cat[cnt] = empty_wstr;			      \
Packit Service 82fcde
		}							      \
Packit Service 82fcde
	      else if (!ignore_content)					      \
Packit Service 82fcde
		{							      \
Packit Service 82fcde
		  time->cat[cnt] = now->val.str.startmb;		      \
Packit Service 82fcde
		  time->w##cat[cnt] = now->val.str.startwc;		      \
Packit Service 82fcde
		}							      \
Packit Service 82fcde
									      \
Packit Service 82fcde
	      /* Match the semicolon.  */				      \
Packit Service 82fcde
	      now = lr_token (ldfile, charmap, result, repertoire, verbose);  \
Packit Service 82fcde
	      if (now->tok != tok_semicolon && now->tok != tok_eol)	      \
Packit Service 82fcde
		break;							      \
Packit Service 82fcde
	    }								      \
Packit Service 82fcde
	  if (now->tok != tok_eol)					      \
Packit Service 82fcde
	    {								      \
Packit Service 82fcde
	      while (!ignore_content && cnt < min)			      \
Packit Service 82fcde
		{							      \
Packit Service 82fcde
		  time->cat[cnt] = "";					      \
Packit Service 82fcde
		  time->w##cat[cnt++] = empty_wstr;			      \
Packit Service 82fcde
		}							      \
Packit Service 82fcde
									      \
Packit Service 82fcde
	      if (now->tok == tok_semicolon)				      \
Packit Service 82fcde
		{							      \
Packit Service 82fcde
		  now = lr_token (ldfile, charmap, result, repertoire,	      \
Packit Service 82fcde
				  verbose);				      \
Packit Service 82fcde
		  if (now->tok == tok_eol)				      \
Packit Service 82fcde
		    lr_error (ldfile, _("extra trailing semicolon"));	      \
Packit Service 82fcde
		  else if (now->tok == tok_string)			      \
Packit Service 82fcde
		    {							      \
Packit Service 82fcde
		      lr_error (ldfile, _("\
Packit Service 82fcde
%s: too many values for field `%s'"),					      \
Packit Service 82fcde
				"LC_TIME", #cat);			      \
Packit Service 82fcde
		      lr_ignore_rest (ldfile, 0);			      \
Packit Service 82fcde
		    }							      \
Packit Service 82fcde
		  else							      \
Packit Service 82fcde
		    goto err_label;					      \
Packit Service 82fcde
		}							      \
Packit Service 82fcde
	      else							      \
Packit Service 82fcde
		goto err_label;						      \
Packit Service 82fcde
	    }								      \
Packit Service 82fcde
	  time->cat##_defined = 1;					      \
Packit Service 82fcde
	  break
Packit Service 82fcde
Packit Service 82fcde
	  STRARR_ELEM (abday, 7, 7);
Packit Service 82fcde
	  STRARR_ELEM (day, 7, 7);
Packit Service 82fcde
	  STRARR_ELEM (abmon, 12, 12);
Packit Service 82fcde
	  STRARR_ELEM (mon, 12, 12);
Packit Service 82fcde
	  STRARR_ELEM (am_pm, 2, 2);
Packit Service 82fcde
	  STRARR_ELEM (alt_digits, 0, 100);
Packit Service 82fcde
	  STRARR_ELEM (alt_mon, 12, 12);
Packit Service 82fcde
	  STRARR_ELEM (ab_alt_mon, 12, 12);
Packit Service 82fcde
Packit Service 82fcde
	case tok_era:
Packit Service 82fcde
	  /* Ignore the rest of the line if we don't need the input of
Packit Service 82fcde
	     this line.  */
Packit Service 82fcde
	  if (ignore_content)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      lr_ignore_rest (ldfile, 0);
Packit Service 82fcde
	      break;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  do
Packit Service 82fcde
	    {
Packit Service 82fcde
	      now = lr_token (ldfile, charmap, result, repertoire, verbose);
Packit Service 82fcde
	      if (now->tok != tok_string)
Packit Service 82fcde
		goto err_label;
Packit Service 82fcde
	      if (!ignore_content && (now->val.str.startmb == NULL
Packit Service 82fcde
				      || now->val.str.startwc == NULL))
Packit Service 82fcde
		{
Packit Service 82fcde
		  lr_error (ldfile, _("%s: unknown character in field `%s'"),
Packit Service 82fcde
			    "LC_TIME", "era");
Packit Service 82fcde
		  lr_ignore_rest (ldfile, 0);
Packit Service 82fcde
		  break;
Packit Service 82fcde
		}
Packit Service 82fcde
	      if (!ignore_content)
Packit Service 82fcde
		{
Packit Service 82fcde
		  time->era = xrealloc (time->era,
Packit Service 82fcde
					(time->num_era + 1) * sizeof (char *));
Packit Service 82fcde
		  time->era[time->num_era] = now->val.str.startmb;
Packit Service 82fcde
Packit Service 82fcde
		  time->wera = xrealloc (time->wera,
Packit Service 82fcde
					 (time->num_era + 1)
Packit Service 82fcde
					 * sizeof (char *));
Packit Service 82fcde
		  time->wera[time->num_era++] = now->val.str.startwc;
Packit Service 82fcde
		}
Packit Service 82fcde
	      now = lr_token (ldfile, charmap, result, repertoire, verbose);
Packit Service 82fcde
	      if (now->tok != tok_eol && now->tok != tok_semicolon)
Packit Service 82fcde
		goto err_label;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  while (now->tok == tok_semicolon);
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
#define STR_ELEM(cat) \
Packit Service 82fcde
	case tok_##cat:							      \
Packit Service 82fcde
	  /* Ignore the rest of the line if we don't need the input of	      \
Packit Service 82fcde
	     this line.  */						      \
Packit Service 82fcde
	  if (ignore_content)						      \
Packit Service 82fcde
	    {								      \
Packit Service 82fcde
	      lr_ignore_rest (ldfile, 0);				      \
Packit Service 82fcde
	      break;							      \
Packit Service 82fcde
	    }								      \
Packit Service 82fcde
									      \
Packit Service 82fcde
	  now = lr_token (ldfile, charmap, result, repertoire, verbose);      \
Packit Service 82fcde
	  if (now->tok != tok_string)					      \
Packit Service 82fcde
	    goto err_label;						      \
Packit Service 82fcde
	  else if (time->cat != NULL)					      \
Packit Service 82fcde
	    lr_error (ldfile, _("\
Packit Service 82fcde
%s: field `%s' declared more than once"), "LC_TIME", #cat);		      \
Packit Service 82fcde
	  else if (!ignore_content && (now->val.str.startmb == NULL	      \
Packit Service 82fcde
				       || now->val.str.startwc == NULL))      \
Packit Service 82fcde
	    {								      \
Packit Service 82fcde
	      lr_error (ldfile, _("%s: unknown character in field `%s'"),     \
Packit Service 82fcde
			"LC_TIME", #cat);				      \
Packit Service 82fcde
	      time->cat = "";						      \
Packit Service 82fcde
	      time->w##cat = empty_wstr;				      \
Packit Service 82fcde
	    }								      \
Packit Service 82fcde
	  else if (!ignore_content)					      \
Packit Service 82fcde
	    {								      \
Packit Service 82fcde
	      time->cat = now->val.str.startmb;				      \
Packit Service 82fcde
	      time->w##cat = now->val.str.startwc;			      \
Packit Service 82fcde
	    }								      \
Packit Service 82fcde
	  break
Packit Service 82fcde
Packit Service 82fcde
	  STR_ELEM (d_t_fmt);
Packit Service 82fcde
	  STR_ELEM (d_fmt);
Packit Service 82fcde
	  STR_ELEM (t_fmt);
Packit Service 82fcde
	  STR_ELEM (t_fmt_ampm);
Packit Service 82fcde
	  STR_ELEM (era_year);
Packit Service 82fcde
	  STR_ELEM (era_d_t_fmt);
Packit Service 82fcde
	  STR_ELEM (era_d_fmt);
Packit Service 82fcde
	  STR_ELEM (era_t_fmt);
Packit Service 82fcde
	  STR_ELEM (timezone);
Packit Service 82fcde
	  STR_ELEM (date_fmt);
Packit Service 82fcde
Packit Service 82fcde
#define INT_ELEM(cat) \
Packit Service 82fcde
	case tok_##cat:							      \
Packit Service 82fcde
	  /* Ignore the rest of the line if we don't need the input of	      \
Packit Service 82fcde
	     this line.  */						      \
Packit Service 82fcde
	  if (ignore_content)						      \
Packit Service 82fcde
	    {								      \
Packit Service 82fcde
	      lr_ignore_rest (ldfile, 0);				      \
Packit Service 82fcde
	      break;							      \
Packit Service 82fcde
	    }								      \
Packit Service 82fcde
									      \
Packit Service 82fcde
	  now = lr_token (ldfile, charmap, result, repertoire, verbose);      \
Packit Service 82fcde
	  if (now->tok != tok_number)					      \
Packit Service 82fcde
	    goto err_label;						      \
Packit Service 82fcde
	  else if (time->cat != 0)					      \
Packit Service 82fcde
	    lr_error (ldfile, _("%s: field `%s' declared more than once"),    \
Packit Service 82fcde
		      "LC_TIME", #cat);					      \
Packit Service 82fcde
	  else if (!ignore_content)					      \
Packit Service 82fcde
	    time->cat = now->val.num;					      \
Packit Service 82fcde
	  break
Packit Service 82fcde
Packit Service 82fcde
	  INT_ELEM (first_weekday);
Packit Service 82fcde
	  INT_ELEM (first_workday);
Packit Service 82fcde
	  INT_ELEM (cal_direction);
Packit Service 82fcde
Packit Service 82fcde
	case tok_week:
Packit Service 82fcde
	  /* Ignore the rest of the line if we don't need the input of
Packit Service 82fcde
	     this line.  */
Packit Service 82fcde
	  if (ignore_content)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      lr_ignore_rest (ldfile, 0);
Packit Service 82fcde
	      break;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
	  now = lr_token (ldfile, charmap, result, repertoire, verbose);
Packit Service 82fcde
	  if (now->tok != tok_number)
Packit Service 82fcde
	    goto err_label;
Packit Service 82fcde
	  time->week_ndays = now->val.num;
Packit Service 82fcde
Packit Service 82fcde
	  now = lr_token (ldfile, charmap, result, repertoire, verbose);
Packit Service 82fcde
	  if (now->tok != tok_semicolon)
Packit Service 82fcde
	    goto err_label;
Packit Service 82fcde
Packit Service 82fcde
	  now = lr_token (ldfile, charmap, result, repertoire, verbose);
Packit Service 82fcde
	  if (now->tok != tok_number)
Packit Service 82fcde
	    goto err_label;
Packit Service 82fcde
	  time->week_1stday = now->val.num;
Packit Service 82fcde
Packit Service 82fcde
	  now = lr_token (ldfile, charmap, result, repertoire, verbose);
Packit Service 82fcde
	  if (now->tok != tok_semicolon)
Packit Service 82fcde
	    goto err_label;
Packit Service 82fcde
Packit Service 82fcde
	  now = lr_token (ldfile, charmap, result, repertoire, verbose);
Packit Service 82fcde
	  if (now->tok != tok_number)
Packit Service 82fcde
	    goto err_label;
Packit Service 82fcde
	  time->week_1stweek = now->val.num;
Packit Service 82fcde
Packit Service 82fcde
	  lr_ignore_rest (ldfile,  1);
Packit Service 82fcde
	  break;
Packit Service 82fcde
Packit Service 82fcde
	case tok_end:
Packit Service 82fcde
	  /* Next we assume `LC_TIME'.  */
Packit Service 82fcde
	  now = lr_token (ldfile, charmap, result, repertoire, verbose);
Packit Service 82fcde
	  if (now->tok == tok_eof)
Packit Service 82fcde
	    break;
Packit Service 82fcde
	  if (now->tok == tok_eol)
Packit Service 82fcde
	    lr_error (ldfile, _("%s: incomplete `END' line"), "LC_TIME");
Packit Service 82fcde
	  else if (now->tok != tok_lc_time)
Packit Service 82fcde
	    lr_error (ldfile, _("\
Packit Service 82fcde
%1$s: definition does not end with `END %1$s'"), "LC_TIME");
Packit Service 82fcde
	  lr_ignore_rest (ldfile, now->tok == tok_lc_time);
Packit Service 82fcde
Packit Service 82fcde
	  /* If alt_mon was not specified, make it a copy of mon.  */
Packit Service 82fcde
	  if (!ignore_content && !time->alt_mon_defined)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      memcpy (time->alt_mon, time->mon, sizeof (time->mon));
Packit Service 82fcde
	      memcpy (time->walt_mon, time->wmon, sizeof (time->wmon));
Packit Service 82fcde
	      time->alt_mon_defined = 1;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  /* The same for abbreviated versions.  */
Packit Service 82fcde
	  if (!ignore_content && !time->ab_alt_mon_defined)
Packit Service 82fcde
	    {
Packit Service 82fcde
	      memcpy (time->ab_alt_mon, time->abmon, sizeof (time->abmon));
Packit Service 82fcde
	      memcpy (time->wab_alt_mon, time->wabmon, sizeof (time->wabmon));
Packit Service 82fcde
	      time->ab_alt_mon_defined = 1;
Packit Service 82fcde
	    }
Packit Service 82fcde
	  return;
Packit Service 82fcde
Packit Service 82fcde
	default:
Packit Service 82fcde
	err_label:
Packit Service 82fcde
	  SYNTAX_ERROR (_("%s: syntax error"), "LC_TIME");
Packit Service 82fcde
	}
Packit Service 82fcde
Packit Service 82fcde
      /* Prepare for the next round.  */
Packit Service 82fcde
      now = lr_token (ldfile, charmap, result, repertoire, verbose);
Packit Service 82fcde
      nowtok = now->tok;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* When we come here we reached the end of the file.  */
Packit Service 82fcde
  lr_error (ldfile, _("%s: premature end of file"), "LC_TIME");
Packit Service 82fcde
}