[BZ #1254]
[glibc.git] / locale / programs / ld-name.c
blob80b42f70484809027eb7a01d350050a74dee4461
1 /* Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the 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 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
24 #include <langinfo.h>
25 #include <string.h>
26 #include <sys/uio.h>
28 #include <assert.h>
30 #include "localedef.h"
31 #include "localeinfo.h"
32 #include "locfile.h"
35 /* The real definition of the struct for the LC_NAME locale. */
36 struct locale_name_t
38 const char *name_fmt;
39 const char *name_gen;
40 const char *name_mr;
41 const char *name_mrs;
42 const char *name_miss;
43 const char *name_ms;
47 static void
48 name_startup (struct linereader *lr, struct localedef_t *locale,
49 int ignore_content)
51 if (!ignore_content)
52 locale->categories[LC_NAME].name =
53 (struct locale_name_t *) xcalloc (1, sizeof (struct locale_name_t));
55 if (lr != NULL)
57 lr->translate_strings = 1;
58 lr->return_widestr = 0;
63 void
64 name_finish (struct localedef_t *locale, const struct charmap_t *charmap)
66 struct locale_name_t *name = locale->categories[LC_NAME].name;
67 int nothing = 0;
69 /* Now resolve copying and also handle completely missing definitions. */
70 if (name == NULL)
72 /* First see whether we were supposed to copy. If yes, find the
73 actual definition. */
74 if (locale->copy_name[LC_NAME] != NULL)
76 /* Find the copying locale. This has to happen transitively since
77 the locale we are copying from might also copying another one. */
78 struct localedef_t *from = locale;
81 from = find_locale (LC_NAME, from->copy_name[LC_NAME],
82 from->repertoire_name, charmap);
83 while (from->categories[LC_NAME].name == NULL
84 && from->copy_name[LC_NAME] != NULL);
86 name = locale->categories[LC_NAME].name
87 = from->categories[LC_NAME].name;
90 /* If there is still no definition issue an warning and create an
91 empty one. */
92 if (name == NULL)
94 if (! be_quiet)
95 WITH_CUR_LOCALE (error (0, 0, _("\
96 No definition for %s category found"), "LC_NAME"));
97 name_startup (NULL, locale, 0);
98 name = locale->categories[LC_NAME].name;
99 nothing = 1;
103 if (name->name_fmt == NULL)
105 if (! nothing)
106 WITH_CUR_LOCALE (error (0, 0, _("%s: field `%s' not defined"),
107 "LC_NAME", "name_fmt"));
108 /* Use as the default value the value of the i18n locale. */
109 name->name_fmt = "%p%t%g%t%m%t%f";
111 else
113 /* We must check whether the format string contains only the
114 allowed escape sequences. */
115 const char *cp = name->name_fmt;
117 if (*cp == '\0')
118 WITH_CUR_LOCALE (error (0, 0, _("%s: field `%s' must not be empty"),
119 "LC_NAME", "name_fmt"));
120 else
121 while (*cp != '\0')
123 if (*cp == '%')
125 if (*++cp == 'R')
126 /* Romanize-flag. */
127 ++cp;
128 if (strchr ("dfFgGlomMpsSt", *cp) == NULL)
130 WITH_CUR_LOCALE (error (0, 0, _("\
131 %s: invalid escape sequence in field `%s'"), "LC_NAME", "name_fmt"));
132 break;
135 ++cp;
139 #define TEST_ELEM(cat) \
140 if (name->cat == NULL) \
142 if (verbose && ! nothing) \
143 WITH_CUR_LOCALE (error (0, 0, _("%s: field `%s' not defined"), \
144 "LC_NAME", #cat)); \
145 name->cat = ""; \
148 TEST_ELEM (name_gen);
149 TEST_ELEM (name_mr);
150 TEST_ELEM (name_mrs);
151 TEST_ELEM (name_miss);
152 TEST_ELEM (name_ms);
156 void
157 name_output (struct localedef_t *locale, const struct charmap_t *charmap,
158 const char *output_path)
160 struct locale_name_t *name = locale->categories[LC_NAME].name;
161 struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME)];
162 struct locale_file data;
163 uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_NAME)];
164 size_t cnt = 0;
166 data.magic = LIMAGIC (LC_NAME);
167 data.n = _NL_ITEM_INDEX (_NL_NUM_LC_NAME);
168 iov[cnt].iov_base = (void *) &data;
169 iov[cnt].iov_len = sizeof (data);
170 ++cnt;
172 iov[cnt].iov_base = (void *) idx;
173 iov[cnt].iov_len = sizeof (idx);
174 ++cnt;
176 idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len;
177 iov[cnt].iov_base = (void *) name->name_fmt;
178 iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
179 ++cnt;
181 idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
182 iov[cnt].iov_base = (void *) name->name_gen;
183 iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
184 ++cnt;
186 idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
187 iov[cnt].iov_base = (void *) name->name_mr;
188 iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
189 ++cnt;
191 idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
192 iov[cnt].iov_base = (void *) name->name_mrs;
193 iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
194 ++cnt;
196 idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
197 iov[cnt].iov_base = (void *) name->name_miss;
198 iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
199 ++cnt;
201 idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
202 iov[cnt].iov_base = (void *) name->name_ms;
203 iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
204 ++cnt;
206 idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
207 iov[cnt].iov_base = (void *) charmap->code_set_name;
208 iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
209 ++cnt;
211 assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME));
213 write_locale_data (output_path, LC_NAME, "LC_NAME",
214 2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME), iov);
218 /* The parser for the LC_NAME section of the locale definition. */
219 void
220 name_read (struct linereader *ldfile, struct localedef_t *result,
221 const struct charmap_t *charmap, const char *repertoire_name,
222 int ignore_content)
224 struct locale_name_t *name;
225 struct token *now;
226 struct token *arg;
227 enum token_t nowtok;
229 /* The rest of the line containing `LC_NAME' must be empty. */
230 lr_ignore_rest (ldfile, 1);
234 now = lr_token (ldfile, charmap, result, NULL, verbose);
235 nowtok = now->tok;
237 while (nowtok == tok_eol);
239 /* If we see `copy' now we are almost done. */
240 if (nowtok == tok_copy)
242 handle_copy (ldfile, charmap, repertoire_name, result, tok_lc_name,
243 LC_NAME, "LC_NAME", ignore_content);
244 return;
247 /* Prepare the data structures. */
248 name_startup (ldfile, result, ignore_content);
249 name = result->categories[LC_NAME].name;
251 while (1)
253 /* Of course we don't proceed beyond the end of file. */
254 if (nowtok == tok_eof)
255 break;
257 /* Ignore empty lines. */
258 if (nowtok == tok_eol)
260 now = lr_token (ldfile, charmap, result, NULL, verbose);
261 nowtok = now->tok;
262 continue;
265 switch (nowtok)
267 #define STR_ELEM(cat) \
268 case tok_##cat: \
269 /* Ignore the rest of the line if we don't need the input of \
270 this line. */ \
271 if (ignore_content) \
273 lr_ignore_rest (ldfile, 0); \
274 break; \
277 arg = lr_token (ldfile, charmap, result, NULL, verbose); \
278 if (arg->tok != tok_string) \
279 goto err_label; \
280 if (name->cat != NULL) \
281 lr_error (ldfile, _("%s: field `%s' declared more than once"), \
282 "LC_NAME", #cat); \
283 else if (!ignore_content && arg->val.str.startmb == NULL) \
285 lr_error (ldfile, _("%s: unknown character in field `%s'"), \
286 "LC_NAME", #cat); \
287 name->cat = ""; \
289 else if (!ignore_content) \
290 name->cat = arg->val.str.startmb; \
291 break
293 STR_ELEM (name_fmt);
294 STR_ELEM (name_gen);
295 STR_ELEM (name_mr);
296 STR_ELEM (name_mrs);
297 STR_ELEM (name_miss);
298 STR_ELEM (name_ms);
300 case tok_end:
301 /* Next we assume `LC_NAME'. */
302 arg = lr_token (ldfile, charmap, result, NULL, verbose);
303 if (arg->tok == tok_eof)
304 break;
305 if (arg->tok == tok_eol)
306 lr_error (ldfile, _("%s: incomplete `END' line"), "LC_NAME");
307 else if (arg->tok != tok_lc_name)
308 lr_error (ldfile, _("\
309 %1$s: definition does not end with `END %1$s'"), "LC_NAME");
310 lr_ignore_rest (ldfile, arg->tok == tok_lc_name);
311 return;
313 default:
314 err_label:
315 SYNTAX_ERROR (_("%s: syntax error"), "LC_NAME");
318 /* Prepare for the next round. */
319 now = lr_token (ldfile, charmap, result, NULL, verbose);
320 nowtok = now->tok;
323 /* When we come here we reached the end of the file. */
324 lr_error (ldfile, _("%s: premature end of file"), "LC_NAME");