error (0, 0, _("%s: direction flag in string %d in `era' field"
error (0, 0, _("%s: direction flag in string %zd in `era' field"
time_finish (struct localedef_t *locale, struct charmap_t *charmap){  struct locale_time_t *time = locale->categories[LC_TIME].time;  int nothing = 0;  /* Now resolve copying and also handle completely missing definitions.  */  if (time == NULL)    {      /* First see whether we were supposed to copy.  If yes, find the	 actual definition.  */      if (locale->copy_name[LC_TIME] != NULL)	{	  /* Find the copying locale.  This has to happen transitively since	     the locale we are copying from might also copying another one.  */	  struct localedef_t *from = locale;	  do	    from = find_locale (LC_TIME, from->copy_name[LC_TIME],				from->repertoire_name, charmap);	  while (from->categories[LC_TIME].time == NULL		 && from->copy_name[LC_TIME] != NULL);	  time = locale->categories[LC_TIME].time	    = from->categories[LC_TIME].time;	}      /* If there is still no definition issue an warning and create an	 empty one.  */      if (time == NULL)	{	  if (! be_quiet)	    error (0, 0, _("No definition for %s category found"), "LC_TIME");	  time_startup (NULL, locale, 0);	  time = locale->categories[LC_TIME].time;	  nothing = 1;	}    }#define TESTARR_ELEM(cat) \  if (!time->cat##_defined)						      \    {									      \      if(! be_quiet && ! nothing)					      \	error (0, 0, _("%s: field `%s' not defined"), "LC_TIME", #cat);	      \    }  TESTARR_ELEM (abday);  TESTARR_ELEM (day);  TESTARR_ELEM (abmon);  TESTARR_ELEM (mon);  TESTARR_ELEM (am_pm);#define TEST_ELEM(cat) \  if (time->cat == NULL)						      \    {									      \      if (! be_quiet && ! nothing)					      \	error (0, 0, _("%s: field `%s' not defined"), "LC_TIME", #cat);	      \    }  TEST_ELEM (d_t_fmt);  TEST_ELEM (d_fmt);  TEST_ELEM (t_fmt);  /* According to C.Y.Alexis Cheng <alexis@vnet.ibm.com> the T_FMT_AMPM     field is optional.  */  if (time->t_fmt_ampm == NULL)    {      /* Use the 24h format as default.  */      time->t_fmt_ampm = time->t_fmt;      time->wt_fmt_ampm = time->wt_fmt;    }  /* Now process the era entries.  */  if (time->num_era != 0)    {      const int days_per_month[12] = { 31, 29, 31, 30, 31, 30,				       31, 31, 30, 31 ,30, 31 };      size_t idx;      wchar_t *wstr;      time->era_entries =	(struct era_data *) xmalloc (time->num_era				     * sizeof (struct era_data));      for (idx = 0; idx < time->num_era; ++idx)	{	  size_t era_len = strlen (time->era[idx]);	  char *str = xmalloc ((era_len + 1 + 3) & ~3);	  char *endp;	  memcpy (str, time->era[idx], era_len + 1);	  /* First character must be + or - for the direction.  */	  if (*str != '+' && *str != '-')	    {	      if (!be_quiet)		error (0, 0, _("%s: direction flag in string %d in `era' field"			       " is not '+' nor '-'"),		       "LC_TIME", idx + 1);	      /* Default arbitrarily to '+'.  */	      time->era_entries[idx].direction = '+';	    }	  else	    time->era_entries[idx].direction = *str;	  if (*++str != ':')	    {	      if (!be_quiet)		error (0, 0, _("%s: direction flag in string %d in `era' field"			       " is not a single character"),		       "LC_TIME", idx + 1);	      (void) strsep (&str, ":");	    }	  else	    ++str;	  /* Now the offset year.  */	  time->era_entries[idx].offset = strtol (str, &endp, 10);	  if (endp == str)	    {	      if (!be_quiet)		error (0, 0, _("%s: invalid number for offset in string %d in"			       " `era' field"),		       "LC_TIME", idx + 1);	      (void) strsep (&str, ":");	    }	  else if (*endp != ':')	    {	      if (!be_quiet)		error (0, 0, _("%s: garbage at end of offset value in"			       " string %d in `era' field"),		       "LC_TIME", idx + 1);	      (void) strsep (&str, ":");	    }	  else	    str = endp + 1;	  /* Next is the starting date in ISO format.  */	  if (strncmp (str, "-*", 2) == 0)	    {	      time->era_entries[idx].start_date[0] =		time->era_entries[idx].start_date[1] =		time->era_entries[idx].start_date[2] = 0x80000000;	      if (str[2] != ':')		goto garbage_start_date;	      str += 3;	    }	  else if (strncmp (str, "+*", 2) == 0)	    {	      time->era_entries[idx].start_date[0] =		time->era_entries[idx].start_date[1] =		time->era_entries[idx].start_date[2] = 0x7fffffff;	      if (str[2] != ':')		goto garbage_start_date;	      str += 3;	    }	  else	    {	      time->era_entries[idx].start_date[0] = strtol (str, &endp, 10);	      if (endp == str || *endp != '/')		goto invalid_start_date;	      else		str = endp + 1;	      time->era_entries[idx].start_date[0] -= 1900;	      /* year -1 represent 1 B.C. (not -1 A.D.) */	      if (time->era_entries[idx].start_date[0] < -1900)		++time->era_entries[idx].start_date[0];	      time->era_entries[idx].start_date[1] = strtol (str, &endp, 10);	      if (endp == str || *endp != '/')		goto invalid_start_date;	      else		str = endp + 1;	      time->era_entries[idx].start_date[1] -= 1;	      time->era_entries[idx].start_date[2] = strtol (str, &endp, 10);	      if (endp == str)		{		invalid_start_date:		  if (!be_quiet)		    error (0, 0, _("%s: invalid starting date in string %d in"				   " `era' field"),			   "LC_TIME", idx + 1);		  (void) strsep (&str, ":");		}	      else if (*endp != ':')		{		garbage_start_date:		  if (!be_quiet)		    error (0, 0, _("%s: garbage at end of starting date "				   "in string %d in `era' field "),			   "LC_TIME", idx + 1);		  (void) strsep (&str, ":");		}	      else		{		  str = endp + 1;		  /* Check for valid value.  */		  if ((time->era_entries[idx].start_date[1] < 0		       || time->era_entries[idx].start_date[1] >= 12		       || time->era_entries[idx].start_date[2] < 0		       || (time->era_entries[idx].start_date[2]			   > days_per_month[time->era_entries[idx].start_date[1]])		       || (time->era_entries[idx].start_date[1] == 2			   && time->era_entries[idx].start_date[2] == 29			   && !__isleap (time->era_entries[idx].start_date[0])))		      && !be_quiet)			  error (0, 0, _("%s: starting date is invalid in"					 " string %d in `era' field"),				 "LC_TIME", idx + 1);		}	    }	  /* Next is the stopping date in ISO format.  */	  if (strncmp (str, "-*", 2) == 0)	    {	      time->era_entries[idx].stop_date[0] =		time->era_entries[idx].stop_date[1] =		time->era_entries[idx].stop_date[2] = 0x80000000;	      if (str[2] != ':')		goto garbage_stop_date;	      str += 3;	    }	  else if (strncmp (str, "+*", 2) == 0)	    {	      time->era_entries[idx].stop_date[0] =		time->era_entries[idx].stop_date[1] =		time->era_entries[idx].stop_date[2] = 0x7fffffff;	      if (str[2] != ':')		goto garbage_stop_date;	      str += 3;	    }	  else	    {	      time->era_entries[idx].stop_date[0] = strtol (str, &endp, 10);	      if (endp == str || *endp != '/')		goto invalid_stop_date;	      else		str = endp + 1;	      time->era_entries[idx].stop_date[0] -= 1900;	      /* year -1 represent 1 B.C. (not -1 A.D.) */	      if (time->era_entries[idx].stop_date[0] < -1900)		++time->era_entries[idx].stop_date[0];	      time->era_entries[idx].stop_date[1] = strtol (str, &endp, 10);	      if (endp == str || *endp != '/')		goto invalid_stop_date;	      else		str = endp + 1;	      time->era_entries[idx].stop_date[1] -= 1;	      time->era_entries[idx].stop_date[2] = strtol (str, &endp, 10);	      if (endp == str)		{		invalid_stop_date:		  if (!be_quiet)		    error (0, 0, _("%s: invalid stopping date in string %d in"				   " `era' field"),			   "LC_TIME", idx + 1);		  (void) strsep (&str, ":");		}	      else if (*endp != ':')		{		garbage_stop_date:		  if (!be_quiet)		    error (0, 0, _("%s: garbage at end of stopping date "				   "in string %d in `era' field"),			   "LC_TIME", idx + 1);		  (void) strsep (&str, ":");		}	      else		{		  str = endp + 1;		  /* Check for valid value.  */		  if ((time->era_entries[idx].stop_date[1] < 0		       || time->era_entries[idx].stop_date[1] >= 12		       || time->era_entries[idx].stop_date[2] < 0		       || (time->era_entries[idx].stop_date[2]			   > days_per_month[time->era_entries[idx].stop_date[1]])		       || (time->era_entries[idx].stop_date[1] == 2			   && time->era_entries[idx].stop_date[2] == 29			   && !__isleap (time->era_entries[idx].stop_date[0])))		      && !be_quiet)			  error (0, 0, _("%s: stopping date is invalid in"					 " string %d in `era' field"),				 "LC_TIME", idx + 1);		}	    }	  if (str == NULL || *str == '\0')	    {	      if (!be_quiet)		error (0, 0, _("%s: missing era name in string %d in `era'"			       " field"), "LC_TIME", idx + 1);	      time->era_entries[idx].name =		time->era_entries[idx].format = "";	    }	  else	    {	      time->era_entries[idx].name = strsep (&str, ":");	      if (str == NULL || *str == '\0')		{		  if (!be_quiet)		    error (0, 0, _("%s: missing era format in string %d"				   " in `era' field"),			   "LC_TIME", idx + 1);		  time->era_entries[idx].name =		    time->era_entries[idx].format = "";		}	      else		time->era_entries[idx].format = str;	    }	  /* Now generate the wide character name and format.  */	  wstr = wcschr ((wchar_t *) time->wera[idx], L':');/* end direction */	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end offset */	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end start */	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end end */	  time->era_entries[idx].wname = (uint32_t *) wstr + 1;	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end name */	  *wstr = L'\0';	  time->era_entries[idx].wformat = (uint32_t *) wstr + 1;	}    }  if (time->week_ndays == 0)    time->week_ndays = 7;  if (time->week_1stday == 0)    time->week_1stday = 19971130;  if (time->week_1stweek > time->week_ndays)    error (0, 0, _("\%s: third operand for value of field `%s' must not be larger than %d"),	   "LC_TIME", "week", 7);  if (time->first_weekday == '\0')    /* The definition does not specify this so the default is used.  */    time->first_weekday = 1;  else if (time->first_weekday > time->week_ndays)    error (0, 0, _("\%s: values of field `%s' must not be larger than %d"),	   "LC_TIME", "first_weekday", 7);  if (time->first_workday == '\0')    /* The definition does not specify this so the default is used.  */    time->first_workday = 1;  else if (time->first_workday > time->week_ndays)    error (0, 0, _("\%s: values of field `%s' must not be larger than %d"),	   "LC_TIME", "first_workday", 7);  if (time->cal_direction == '\0')    /* The definition does not specify this so the default is used.  */    time->cal_direction = 1;  else if (time->cal_direction > 3)    error (0, 0, _("\%s: values for field `%s' must not be larger than %d"),	   "LC_TIME", "cal_direction", 3);  /* XXX We don't perform any tests on the timezone value since this is     simply useless, stupid $&$!@...  */  if (time->timezone == NULL)    time->timezone = "";}