-/* Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@gnu.org>, 1995.
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License version 2 as
+ published by the Free Software Foundation.
- The GNU C Library is distributed in the hope that it will be useful,
+ This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#include <assert.h>
-#include "linereader.h"
#include "localedef.h"
+#include "linereader.h"
#include "localeinfo.h"
#include "locfile.h"
void
-time_finish (struct localedef_t *locale, struct charmap_t *charmap)
+time_finish (struct localedef_t *locale, const struct charmap_t *charmap)
{
struct locale_time_t *time = locale->categories[LC_TIME].time;
int nothing = 0;
if (time == NULL)
{
if (! be_quiet)
- error (0, 0, _("No definition for %s category found"), "LC_TIME");
+ WITH_CUR_LOCALE (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) \
+#define noparen(arg1, argn...) arg1, ##argn
+#define TESTARR_ELEM(cat, val) \
if (!time->cat##_defined) \
{ \
- if(! be_quiet && ! nothing) \
- error (0, 0, _("%s: field `%s' not defined"), "LC_TIME", #cat); \
+ const char *initval[] = { noparen val }; \
+ unsigned int i; \
+ \
+ if (! be_quiet && ! nothing) \
+ WITH_CUR_LOCALE (error (0, 0, _("%s: field `%s' not defined"), \
+ "LC_TIME", #cat)); \
+ \
+ for (i = 0; i < sizeof (initval) / sizeof (initval[0]); ++i) \
+ time->cat[i] = initval[i]; \
}
- TESTARR_ELEM (abday);
- TESTARR_ELEM (day);
- TESTARR_ELEM (abmon);
- TESTARR_ELEM (mon);
- TESTARR_ELEM (am_pm);
-
-#define TEST_ELEM(cat) \
+ TESTARR_ELEM (abday, ( "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" ));
+ TESTARR_ELEM (day, ( "Sunday", "Monday", "Tuesday", "Wednesday",
+ "Thursday", "Friday", "Saturday" ));
+ TESTARR_ELEM (abmon, ( "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ));
+ TESTARR_ELEM (mon, ( "January", "February", "March", "April",
+ "May", "June", "July", "August",
+ "September", "October", "November", "December" ));
+ TESTARR_ELEM (am_pm, ( "AM", "PM" ));
+
+#define TEST_ELEM(cat, initval) \
if (time->cat == NULL) \
{ \
if (! be_quiet && ! nothing) \
- error (0, 0, _("%s: field `%s' not defined"), "LC_TIME", #cat); \
+ WITH_CUR_LOCALE (error (0, 0, _("%s: field `%s' not defined"), \
+ "LC_TIME", #cat)); \
+ \
+ time->cat = initval; \
}
- TEST_ELEM (d_t_fmt);
- TEST_ELEM (d_fmt);
- TEST_ELEM (t_fmt);
+ TEST_ELEM (d_t_fmt, "%a %b %e %H:%M:%S %Y");
+ TEST_ELEM (d_fmt, "%m/%d/%y");
+ TEST_ELEM (t_fmt, "%H:%M:%S");
/* 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;
+ if (time->am_pm[0][0] == '\0' && time->am_pm[1][0] == '\0')
+ {
+ /* No AM/PM strings defined, use the 24h format as default. */
+ time->t_fmt_ampm = time->t_fmt;
+ time->wt_fmt_ampm = time->wt_fmt;
+ }
+ else
+ {
+ time->t_fmt_ampm = "%I:%M:%S %p";
+ time->wt_fmt_ampm = (const uint32_t *) L"%I:%M:%S %p";
+ }
}
/* Now process the era entries. */
if (*str != '+' && *str != '-')
{
if (!be_quiet)
- error (0, 0,
- _("%s: direction flag in string %Zd in `era' field"
- " is not '+' nor '-'"),
- "LC_TIME", idx + 1);
+ WITH_CUR_LOCALE (error (0, 0, _("\
+%s: direction flag in string %Zd in `era' field is not '+' nor '-'"),
+ "LC_TIME", idx + 1));
/* Default arbitrarily to '+'. */
time->era_entries[idx].direction = '+';
}
if (*++str != ':')
{
if (!be_quiet)
- error (0, 0,
- _("%s: direction flag in string %Zd in `era' field"
- " is not a single character"),
- "LC_TIME", idx + 1);
+ WITH_CUR_LOCALE (error (0, 0, _("\
+%s: direction flag in string %Zd in `era' field is not a single character"),
+ "LC_TIME", idx + 1));
(void) strsep (&str, ":");
}
else
if (endp == str)
{
if (!be_quiet)
- error (0, 0, _("%s: invalid number for offset in string %Zd in"
- " `era' field"),
- "LC_TIME", idx + 1);
+ WITH_CUR_LOCALE (error (0, 0, _("\
+%s: invalid number for offset in string %Zd 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 %Zd in `era' field"),
- "LC_TIME", idx + 1);
+ WITH_CUR_LOCALE (error (0, 0, _("\
+%s: garbage at end of offset value in string %Zd in `era' field"),
+ "LC_TIME", idx + 1));
(void) strsep (&str, ":");
}
else
{
invalid_start_date:
if (!be_quiet)
- error (0, 0, _("%s: invalid starting date in string %Zd in"
- " `era' field"),
- "LC_TIME", idx + 1);
+ WITH_CUR_LOCALE (error (0, 0, _("\
+%s: invalid starting date in string %Zd 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 %Zd in `era' field "),
- "LC_TIME", idx + 1);
+ WITH_CUR_LOCALE (error (0, 0, _("\
+%s: garbage at end of starting date in string %Zd in `era' field "),
+ "LC_TIME", idx + 1));
(void) strsep (&str, ":");
}
else
&& 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 %Zd in `era' field"),
- "LC_TIME", idx + 1);
+ WITH_CUR_LOCALE (error (0, 0, _("\
+%s: starting date is invalid in string %Zd in `era' field"),
+ "LC_TIME", idx + 1));
}
}
{
invalid_stop_date:
if (!be_quiet)
- error (0, 0, _("%s: invalid stopping date in string %Zd in"
- " `era' field"),
- "LC_TIME", idx + 1);
+ WITH_CUR_LOCALE (error (0, 0, _("\
+%s: invalid stopping date in string %Zd 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 %Zd in `era' field"),
- "LC_TIME", idx + 1);
+ WITH_CUR_LOCALE (error (0, 0, _("\
+%s: garbage at end of stopping date in string %Zd in `era' field"),
+ "LC_TIME", idx + 1));
(void) strsep (&str, ":");
}
else
&& 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 %Zd in `era' field"),
- "LC_TIME", idx + 1);
+ WITH_CUR_LOCALE (error (0, 0, _("\
+%s: stopping date is invalid in string %Zd in `era' field"),
+ "LC_TIME", idx + 1));
}
}
if (str == NULL || *str == '\0')
{
if (!be_quiet)
- error (0, 0, _("%s: missing era name in string %Zd in `era'"
- " field"), "LC_TIME", idx + 1);
+ WITH_CUR_LOCALE (error (0, 0, _("\
+%s: missing era name in string %Zd in `era' field"), "LC_TIME", idx + 1));
time->era_entries[idx].name =
time->era_entries[idx].format = "";
}
if (str == NULL || *str == '\0')
{
if (!be_quiet)
- error (0, 0, _("%s: missing era format in string %Zd"
- " in `era' field"),
- "LC_TIME", idx + 1);
+ WITH_CUR_LOCALE (error (0, 0, _("\
+%s: missing era format in string %Zd in `era' field"),
+ "LC_TIME", idx + 1));
time->era_entries[idx].name =
time->era_entries[idx].format = "";
}
time->week_1stday = 19971130;
if (time->week_1stweek > time->week_ndays)
- error (0, 0, _("\
+ WITH_CUR_LOCALE (error (0, 0, _("\
%s: third operand for value of field `%s' must not be larger than %d"),
- "LC_TIME", "week", 7);
+ "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, _("\
+ WITH_CUR_LOCALE (error (0, 0, _("\
%s: values of field `%s' must not be larger than %d"),
- "LC_TIME", "first_weekday", 7);
+ "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, _("\
+ WITH_CUR_LOCALE (error (0, 0, _("\
%s: values of field `%s' must not be larger than %d"),
- "LC_TIME", "first_workday", 7);
+ "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, _("\
+ WITH_CUR_LOCALE (error (0, 0, _("\
%s: values for field `%s' must not be larger than %d"),
- "LC_TIME", "cal_direction", 3);
+ "LC_TIME", "cal_direction", 3));
/* XXX We don't perform any tests on the timezone value since this is
simply useless, stupid $&$!@... */
void
-time_output (struct localedef_t *locale, struct charmap_t *charmap,
+time_output (struct localedef_t *locale, const struct charmap_t *charmap,
const char *output_path)
{
struct locale_time_t *time = locale->categories[LC_TIME].time;
- struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_TIME)
- + time->num_era - 1
- + 2 * 99
- + 2 + time->num_era * 10 - 1];
+ struct iovec *iov = alloca (sizeof *iov
+ * (2 + _NL_ITEM_INDEX (_NL_NUM_LC_TIME)
+ + time->num_era - 1
+ + 2 * 99
+ + 2 + time->num_era * 10 - 1));
struct locale_file data;
uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_TIME)];
size_t cnt, last_idx, num, n;
idx[1 + last_idx] = idx[last_idx];
for (num = 0; num < time->num_era; ++num)
{
- size_t l;
+ size_t l, l2;
iov[2 + cnt].iov_base = (void *) &time->era_entries[num].direction;
iov[2 + cnt].iov_len = sizeof (int32_t);
iov[2 + cnt].iov_len = sizeof (int32_t);
++cnt;
- l = (strchr (time->era_entries[num].format, '\0')
+ l = ((char *) rawmemchr (time->era_entries[num].format, '\0')
- time->era_entries[num].name) + 1;
- l = (l + 3) & ~3;
- iov[2 + cnt].iov_base = (void *) time->era_entries[num].name;
- iov[2 + cnt].iov_len = l;
+ l2 = (l + 3) & ~3;
+ iov[2 + cnt].iov_base = alloca (l2);
+ memset (mempcpy (iov[2 + cnt].iov_base, time->era_entries[num].name, l),
+ '\0', l2 - l);
+ iov[2 + cnt].iov_len = l2;
++cnt;
- idx[1 + last_idx] += 8 * sizeof (int32_t) + l;
+ idx[1 + last_idx] += 8 * sizeof (int32_t) + l2;
assert (idx[1 + last_idx] % 4 == 0);
+ 2 + time->num_era * 10 - 1));
assert (last_idx == _NL_ITEM_INDEX (_NL_NUM_LC_TIME));
- write_locale_data (output_path, "LC_TIME", 2 + cnt, iov);
+ write_locale_data (output_path, LC_TIME, "LC_TIME", 2 + cnt, iov);
}
/* The parser for the LC_TIME section of the locale definition. */
void
time_read (struct linereader *ldfile, struct localedef_t *result,
- struct charmap_t *charmap, const char *repertoire_name,
+ const struct charmap_t *charmap, const char *repertoire_name,
int ignore_content)
{
struct repertoire_t *repertoire = NULL;
do
{
- now = lr_token (ldfile, charmap, repertoire, verbose);
+ now = lr_token (ldfile, charmap, result, repertoire, verbose);
nowtok = now->tok;
}
while (nowtok == tok_eol);
/* Ingore empty lines. */
if (nowtok == tok_eol)
{
- now = lr_token (ldfile, charmap, repertoire, verbose);
+ now = lr_token (ldfile, charmap, result, repertoire, verbose);
nowtok = now->tok;
continue;
}
\
for (cnt = 0; cnt < max; ++cnt) \
{ \
- now = lr_token (ldfile, charmap, repertoire, verbose); \
+ now = lr_token (ldfile, charmap, result, repertoire, verbose); \
if (now->tok == tok_eol) \
{ \
if (cnt < min) \
} \
\
/* Match the semicolon. */ \
- now = lr_token (ldfile, charmap, repertoire, verbose); \
+ now = lr_token (ldfile, charmap, result, repertoire, verbose); \
if (now->tok != tok_semicolon && now->tok != tok_eol) \
break; \
} \
\
if (now->tok == tok_semicolon) \
{ \
- now = lr_token (ldfile, charmap, repertoire, verbose); \
+ now = lr_token (ldfile, charmap, result, repertoire, \
+ verbose); \
if (now->tok == tok_eol) \
lr_error (ldfile, _("extra trailing semicolon")); \
else if (now->tok == tok_string) \
}
do
{
- now = lr_token (ldfile, charmap, repertoire, verbose);
+ now = lr_token (ldfile, charmap, result, repertoire, verbose);
if (now->tok != tok_string)
goto err_label;
if (!ignore_content && (now->val.str.startmb == NULL
* sizeof (char *));
time->wera[time->num_era++] = now->val.str.startwc;
}
- now = lr_token (ldfile, charmap, repertoire, verbose);
+ now = lr_token (ldfile, charmap, result, repertoire, verbose);
if (now->tok != tok_eol && now->tok != tok_semicolon)
goto err_label;
}
break; \
} \
\
- now = lr_token (ldfile, charmap, repertoire, verbose); \
+ now = lr_token (ldfile, charmap, result, repertoire, verbose); \
if (now->tok != tok_string) \
goto err_label; \
else if (time->cat != NULL) \
break; \
} \
\
- now = lr_token (ldfile, charmap, repertoire, verbose); \
+ now = lr_token (ldfile, charmap, result, repertoire, verbose); \
if (now->tok != tok_number) \
goto err_label; \
else if (time->cat != 0) \
break;
}
- now = lr_token (ldfile, charmap, repertoire, verbose);
+ now = lr_token (ldfile, charmap, result, repertoire, verbose);
if (now->tok != tok_number)
goto err_label;
time->week_ndays = now->val.num;
- now = lr_token (ldfile, charmap, repertoire, verbose);
+ now = lr_token (ldfile, charmap, result, repertoire, verbose);
if (now->tok != tok_semicolon)
goto err_label;
- now = lr_token (ldfile, charmap, repertoire, verbose);
+ now = lr_token (ldfile, charmap, result, repertoire, verbose);
if (now->tok != tok_number)
goto err_label;
time->week_1stday = now->val.num;
- now = lr_token (ldfile, charmap, repertoire, verbose);
+ now = lr_token (ldfile, charmap, result, repertoire, verbose);
if (now->tok != tok_semicolon)
goto err_label;
- now = lr_token (ldfile, charmap, repertoire, verbose);
+ now = lr_token (ldfile, charmap, result, repertoire, verbose);
if (now->tok != tok_number)
goto err_label;
time->week_1stweek = now->val.num;
case tok_end:
/* Next we assume `LC_TIME'. */
- now = lr_token (ldfile, charmap, repertoire, verbose);
+ now = lr_token (ldfile, charmap, result, repertoire, verbose);
if (now->tok == tok_eof)
break;
if (now->tok == tok_eol)
}
/* Prepare for the next round. */
- now = lr_token (ldfile, charmap, repertoire, verbose);
+ now = lr_token (ldfile, charmap, result, repertoire, verbose);
nowtok = now->tok;
}