1 /* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If
17 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
27 /* Undefine following line in production version. */
28 /* #define NDEBUG 1 */
32 #include "localeinfo.h"
33 #include "stringtrans.h"
36 void *xmalloc (size_t __n
);
39 /* The real definition of the struct for the LC_TIME locale. */
46 const char *abmon
[12];
55 const char *t_fmt_ampm
;
58 const char *era_d_t_fmt
;
59 const char *era_t_fmt
;
60 const char *era_d_fmt
;
61 const char *alt_digits
[100];
62 size_t cur_num_alt_digits
;
67 time_startup (struct linereader
*lr
, struct localedef_t
*locale
,
68 struct charset_t
*charset
)
70 struct locale_time_t
*time
;
72 /* It is important that we always use UCS1 encoding for strings now. */
73 encoding_method
= ENC_UCS1
;
75 locale
->categories
[LC_TIME
].time
= time
=
76 (struct locale_time_t
*) xmalloc (sizeof (struct locale_time_t
));
78 memset (time
, '\0', sizeof (struct locale_time_t
));
83 time_finish (struct localedef_t
*locale
)
85 struct locale_time_t
*time
= locale
->categories
[LC_TIME
].time
;
87 #define TESTARR_ELEM(cat, max) \
88 if (time->cur_num_##cat == 0) \
89 error (0, 0, _("field `%s' in category `%s' not defined"), \
91 else if (time->cur_num_##cat != max) \
92 error (0, 0, _("field `%s' in category `%s' has not enough values"), \
95 TESTARR_ELEM (abday
, 7);
96 TESTARR_ELEM (day
, 7);
97 TESTARR_ELEM (abmon
, 12);
98 TESTARR_ELEM (mon
, 12);
99 TESTARR_ELEM (am_pm
, 2);
101 #define TEST_ELEM(cat) \
102 if (time->cat == NULL) \
103 error (0, 0, _("field `%s' in category `%s' not defined"), \
109 TEST_ELEM (t_fmt_ampm
);
114 time_output (struct localedef_t
*locale
, const char *output_path
)
116 struct locale_time_t
*time
= locale
->categories
[LC_TIME
].time
;
117 struct iovec iov
[2 + _NL_ITEM_INDEX (_NL_NUM_LC_TIME
)
118 + time
->cur_num_alt_digits
];
119 struct locale_file data
;
120 u_int32_t idx
[_NL_ITEM_INDEX (_NL_NUM_LC_TIME
)];
121 size_t cnt
, last_idx
, num
;
123 if ((locale
->binary
& (1 << LC_TIME
)) != 0)
125 iov
[0].iov_base
= time
;
126 iov
[0].iov_len
= locale
->len
[LC_TIME
];
128 write_locale_data (output_path
, "LC_TIME", 1, iov
);
133 data
.magic
= LIMAGIC (LC_TIME
);
134 data
.n
= _NL_ITEM_INDEX (_NL_NUM_LC_TIME
);
135 iov
[0].iov_base
= (void *) &data
;
136 iov
[0].iov_len
= sizeof (data
);
138 iov
[1].iov_base
= (void *) idx
;
139 iov
[1].iov_len
= sizeof (idx
);
141 idx
[0] = iov
[0].iov_len
+ iov
[1].iov_len
;
144 for (cnt
= 0; cnt
<= _NL_ITEM_INDEX (ABDAY_7
); ++cnt
)
146 iov
[2 + cnt
].iov_base
=
147 (void *) (time
->abday
[cnt
- _NL_ITEM_INDEX (ABDAY_1
)] ?: "");
148 iov
[2 + cnt
].iov_len
= strlen (iov
[2 + cnt
].iov_base
) + 1;
149 idx
[1 + cnt
] = idx
[cnt
] + iov
[2 + cnt
].iov_len
;
153 for (; cnt
<= _NL_ITEM_INDEX (DAY_7
); ++cnt
)
155 iov
[2 + cnt
].iov_base
=
156 (void *) (time
->day
[cnt
- _NL_ITEM_INDEX (DAY_1
)] ?: "");
157 iov
[2 + cnt
].iov_len
= strlen (iov
[2 + cnt
].iov_base
) + 1;
158 idx
[1 + cnt
] = idx
[cnt
] + iov
[2 + cnt
].iov_len
;
162 for (; cnt
<= _NL_ITEM_INDEX (ABMON_12
); ++cnt
)
164 iov
[2 + cnt
].iov_base
=
165 (void *) (time
->abmon
[cnt
- _NL_ITEM_INDEX (ABMON_1
)] ?: "");
166 iov
[2 + cnt
].iov_len
= strlen (iov
[2 + cnt
].iov_base
) + 1;
167 idx
[1 + cnt
] = idx
[cnt
] + iov
[2 + cnt
].iov_len
;
171 for (; cnt
<= _NL_ITEM_INDEX (MON_12
); ++cnt
)
173 iov
[2 + cnt
].iov_base
=
174 (void *) (time
->mon
[cnt
- _NL_ITEM_INDEX (MON_1
)] ?: "");
175 iov
[2 + cnt
].iov_len
= strlen (iov
[2 + cnt
].iov_base
) + 1;
176 idx
[1 + cnt
] = idx
[cnt
] + iov
[2 + cnt
].iov_len
;
180 for (; cnt
<= _NL_ITEM_INDEX (PM_STR
); ++cnt
)
182 iov
[2 + cnt
].iov_base
=
183 (void *) (time
->am_pm
[cnt
- _NL_ITEM_INDEX (AM_STR
)] ?: "");
184 iov
[2 + cnt
].iov_len
= strlen (iov
[2 + cnt
].iov_base
) + 1;
185 idx
[1 + cnt
] = idx
[cnt
] + iov
[2 + cnt
].iov_len
;
188 iov
[2 + cnt
].iov_base
= (void *) (time
->d_t_fmt
?: "");
189 iov
[2 + cnt
].iov_len
= strlen (iov
[2 + cnt
].iov_base
) + 1;
190 idx
[1 + cnt
] = idx
[cnt
] + iov
[2 + cnt
].iov_len
;
193 iov
[2 + cnt
].iov_base
= (void *) (time
->d_fmt
?: "");
194 iov
[2 + cnt
].iov_len
= strlen (iov
[2 + cnt
].iov_base
) + 1;
195 idx
[1 + cnt
] = idx
[cnt
] + iov
[2 + cnt
].iov_len
;
198 iov
[2 + cnt
].iov_base
= (void *) (time
->t_fmt
?: "");
199 iov
[2 + cnt
].iov_len
= strlen (iov
[2 + cnt
].iov_base
) + 1;
200 idx
[1 + cnt
] = idx
[cnt
] + iov
[2 + cnt
].iov_len
;
203 iov
[2 + cnt
].iov_base
= (void *) (time
->t_fmt_ampm
?: "");
204 iov
[2 + cnt
].iov_len
= strlen (iov
[2 + cnt
].iov_base
) + 1;
205 idx
[1 + cnt
] = idx
[cnt
] + iov
[2 + cnt
].iov_len
;
208 iov
[2 + cnt
].iov_base
= (void *) (time
->era
?: "");
209 iov
[2 + cnt
].iov_len
= strlen (iov
[2 + cnt
].iov_base
) + 1;
210 idx
[1 + cnt
] = idx
[cnt
] + iov
[2 + cnt
].iov_len
;
213 iov
[2 + cnt
].iov_base
= (void *) (time
->era_year
?: "");
214 iov
[2 + cnt
].iov_len
= strlen (iov
[2 + cnt
].iov_base
) + 1;
215 idx
[1 + cnt
] = idx
[cnt
] + iov
[2 + cnt
].iov_len
;
218 iov
[2 + cnt
].iov_base
= (void *) (time
->era_d_fmt
?: "");
219 iov
[2 + cnt
].iov_len
= strlen (iov
[2 + cnt
].iov_base
) + 1;
220 idx
[1 + cnt
] = idx
[cnt
] + iov
[2 + cnt
].iov_len
;
223 idx
[1 + last_idx
] = idx
[last_idx
];
224 for (num
= 0; num
< time
->cur_num_alt_digits
; ++num
, ++cnt
)
226 iov
[2 + cnt
].iov_base
= (void *) (time
->alt_digits
[num
] ?: "");
227 iov
[2 + cnt
].iov_len
= strlen (iov
[2 + cnt
].iov_base
) + 1;
228 idx
[1 + last_idx
] += iov
[2 + cnt
].iov_len
;
232 iov
[2 + cnt
].iov_base
= (void *) (time
->era_d_t_fmt
?: "");
233 iov
[2 + cnt
].iov_len
= strlen (iov
[2 + cnt
].iov_base
) + 1;
234 idx
[1 + last_idx
] = idx
[last_idx
] + iov
[2 + cnt
].iov_len
;
237 iov
[2 + cnt
].iov_base
= (void *) (time
->era_d_fmt
?: "");
238 iov
[2 + cnt
].iov_len
= strlen (iov
[2 + cnt
].iov_base
) + 1;
241 assert (cnt
== (_NL_ITEM_INDEX (_NL_NUM_LC_TIME
) - 1
242 + time
->cur_num_alt_digits
));
244 write_locale_data (output_path
, "LC_TIME", 2 + cnt
, iov
);
249 time_add (struct linereader
*lr
, struct localedef_t
*locale
,
250 enum token_t tok
, struct token
*code
,
251 struct charset_t
*charset
)
253 struct locale_time_t
*time
= locale
->categories
[LC_TIME
].time
;
257 #define STRARR_ELEM(cat, max) \
259 if (time->cur_num_##cat >= max) \
261 too many values for field `%s' in category `LC_TIME'"), \
263 else if (code->val.str.start == NULL) \
265 lr_error (lr, _("unknown character in field `%s' of category `%s'"),\
267 time->cat[time->cur_num_##cat++] = ""; \
270 time->cat[time->cur_num_##cat++] \
271 = code->val.str.start; \
274 STRARR_ELEM (abday
, 7);
275 STRARR_ELEM (day
, 7);
276 STRARR_ELEM (abmon
, 12);
277 STRARR_ELEM (mon
, 12);
278 STRARR_ELEM (am_pm
, 2);
279 STRARR_ELEM (alt_digits
, 100);
281 #define STR_ELEM(cat) \
283 if (time->cat != NULL) \
285 field `%s' in category `%s' declared more than once"), \
287 else if (code->val.str.start == NULL) \
289 lr_error (lr, _("unknown character in field `%s' of category `%s'"),\
294 time->cat = code->val.str.start; \
300 STR_ELEM (t_fmt_ampm
);
303 STR_ELEM (era_d_t_fmt
);
304 STR_ELEM (era_d_fmt
);
305 STR_ELEM (era_t_fmt
);
308 assert (! "unknown token in category `LC_TIME': should not happen");