Declare wcs functions only if compiling with MBS_SUPPORT. Don't use #elif for tradi...
[glibc.git] / locale / programs / ld-name.c
blob423f1707c29229a7c56ad867c882e47135070247
1 /* Copyright (C) 1998, 1999, 2000, 2001 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 "localeinfo.h"
31 #include "locfile.h"
34 /* The real definition of the struct for the LC_NAME locale. */
35 struct locale_name_t
37 const char *name_fmt;
38 const char *name_gen;
39 const char *name_mr;
40 const char *name_mrs;
41 const char *name_miss;
42 const char *name_ms;
46 static void
47 name_startup (struct linereader *lr, struct localedef_t *locale,
48 int ignore_content)
50 if (!ignore_content)
51 locale->categories[LC_NAME].name =
52 (struct locale_name_t *) xcalloc (1, sizeof (struct locale_name_t));
54 if (lr != NULL)
56 lr->translate_strings = 1;
57 lr->return_widestr = 0;
62 void
63 name_finish (struct localedef_t *locale, struct charmap_t *charmap)
65 struct locale_name_t *name = locale->categories[LC_NAME].name;
66 int nothing = 0;
68 /* Now resolve copying and also handle completely missing definitions. */
69 if (name == NULL)
71 /* First see whether we were supposed to copy. If yes, find the
72 actual definition. */
73 if (locale->copy_name[LC_NAME] != NULL)
75 /* Find the copying locale. This has to happen transitively since
76 the locale we are copying from might also copying another one. */
77 struct localedef_t *from = locale;
80 from = find_locale (LC_NAME, from->copy_name[LC_NAME],
81 from->repertoire_name, charmap);
82 while (from->categories[LC_NAME].name == NULL
83 && from->copy_name[LC_NAME] != NULL);
85 name = locale->categories[LC_NAME].name
86 = from->categories[LC_NAME].name;
89 /* If there is still no definition issue an warning and create an
90 empty one. */
91 if (name == NULL)
93 if (! be_quiet)
94 error (0, 0, _("No definition for %s category found"), "LC_NAME");
95 name_startup (NULL, locale, 0);
96 name = locale->categories[LC_NAME].name;
97 nothing = 1;
101 if (name->name_fmt == NULL)
103 if (! nothing)
104 error (0, 0, _("%s: field `%s' not defined"), "LC_NAME", "name_fmt");
105 /* Use as the default value the value of the i18n locale. */
106 name->name_fmt = "%p%t%g%t%m%t%f";
108 else
110 /* We must check whether the format string contains only the
111 allowed escape sequences. */
112 const char *cp = name->name_fmt;
114 if (*cp == '\0')
115 error (0, 0, _("%s: field `%s' must not be empty"),
116 "LC_NAME", "name_fmt");
117 else
118 while (*cp != '\0')
120 if (*cp == '%')
122 if (*++cp == 'R')
123 /* Romanize-flag. */
124 ++cp;
125 if (strchr ("dfFgGlomMpsSt", *cp) == NULL)
127 error (0, 0, _("\
128 %s: invalid escape sequence in field `%s'"),
129 "LC_NAME", "name_fmt");
130 break;
133 ++cp;
137 #define TEST_ELEM(cat) \
138 if (name->cat == NULL) \
140 if (verbose && ! nothing) \
141 error (0, 0, _("%s: field `%s' not defined"), "LC_NAME", #cat); \
142 name->cat = ""; \
145 TEST_ELEM (name_gen);
146 TEST_ELEM (name_mr);
147 TEST_ELEM (name_mrs);
148 TEST_ELEM (name_miss);
149 TEST_ELEM (name_ms);
153 void
154 name_output (struct localedef_t *locale, struct charmap_t *charmap,
155 const char *output_path)
157 struct locale_name_t *name = locale->categories[LC_NAME].name;
158 struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME)];
159 struct locale_file data;
160 uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_NAME)];
161 size_t cnt = 0;
163 data.magic = LIMAGIC (LC_NAME);
164 data.n = _NL_ITEM_INDEX (_NL_NUM_LC_NAME);
165 iov[cnt].iov_base = (void *) &data;
166 iov[cnt].iov_len = sizeof (data);
167 ++cnt;
169 iov[cnt].iov_base = (void *) idx;
170 iov[cnt].iov_len = sizeof (idx);
171 ++cnt;
173 idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len;
174 iov[cnt].iov_base = (void *) name->name_fmt;
175 iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
176 ++cnt;
178 idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
179 iov[cnt].iov_base = (void *) name->name_gen;
180 iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
181 ++cnt;
183 idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
184 iov[cnt].iov_base = (void *) name->name_mr;
185 iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
186 ++cnt;
188 idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
189 iov[cnt].iov_base = (void *) name->name_mrs;
190 iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
191 ++cnt;
193 idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
194 iov[cnt].iov_base = (void *) name->name_miss;
195 iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
196 ++cnt;
198 idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
199 iov[cnt].iov_base = (void *) name->name_ms;
200 iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
201 ++cnt;
203 idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
204 iov[cnt].iov_base = (void *) charmap->code_set_name;
205 iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
206 ++cnt;
208 assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME));
210 write_locale_data (output_path, "LC_NAME",
211 2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME), iov);
215 /* The parser for the LC_NAME section of the locale definition. */
216 void
217 name_read (struct linereader *ldfile, struct localedef_t *result,
218 struct charmap_t *charmap, const char *repertoire_name,
219 int ignore_content)
221 struct locale_name_t *name;
222 struct token *now;
223 struct token *arg;
224 enum token_t nowtok;
226 /* The rest of the line containing `LC_NAME' must be empty. */
227 lr_ignore_rest (ldfile, 1);
231 now = lr_token (ldfile, charmap, NULL, verbose);
232 nowtok = now->tok;
234 while (nowtok == tok_eol);
236 /* If we see `copy' now we are almost done. */
237 if (nowtok == tok_copy)
239 handle_copy (ldfile, charmap, repertoire_name, result, tok_lc_name,
240 LC_NAME, "LC_NAME", ignore_content);
241 return;
244 /* Prepare the data structures. */
245 name_startup (ldfile, result, ignore_content);
246 name = result->categories[LC_NAME].name;
248 while (1)
250 /* Of course we don't proceed beyond the end of file. */
251 if (nowtok == tok_eof)
252 break;
254 /* Ignore empty lines. */
255 if (nowtok == tok_eol)
257 now = lr_token (ldfile, charmap, NULL, verbose);
258 nowtok = now->tok;
259 continue;
262 switch (nowtok)
264 #define STR_ELEM(cat) \
265 case tok_##cat: \
266 /* Ignore the rest of the line if we don't need the input of \
267 this line. */ \
268 if (ignore_content) \
270 lr_ignore_rest (ldfile, 0); \
271 break; \
274 arg = lr_token (ldfile, charmap, NULL, verbose); \
275 if (arg->tok != tok_string) \
276 goto err_label; \
277 if (name->cat != NULL) \
278 lr_error (ldfile, _("%s: field `%s' declared more than once"), \
279 "LC_NAME", #cat); \
280 else if (!ignore_content && arg->val.str.startmb == NULL) \
282 lr_error (ldfile, _("%s: unknown character in field `%s'"), \
283 "LC_NAME", #cat); \
284 name->cat = ""; \
286 else if (!ignore_content) \
287 name->cat = arg->val.str.startmb; \
288 break
290 STR_ELEM (name_fmt);
291 STR_ELEM (name_gen);
292 STR_ELEM (name_mr);
293 STR_ELEM (name_mrs);
294 STR_ELEM (name_miss);
295 STR_ELEM (name_ms);
297 case tok_end:
298 /* Next we assume `LC_NAME'. */
299 arg = lr_token (ldfile, charmap, NULL, verbose);
300 if (arg->tok == tok_eof)
301 break;
302 if (arg->tok == tok_eol)
303 lr_error (ldfile, _("%s: incomplete `END' line"), "LC_NAME");
304 else if (arg->tok != tok_lc_name)
305 lr_error (ldfile, _("\
306 %1$s: definition does not end with `END %1$s'"), "LC_NAME");
307 lr_ignore_rest (ldfile, arg->tok == tok_lc_name);
308 return;
310 default:
311 err_label:
312 SYNTAX_ERROR (_("%s: syntax error"), "LC_NAME");
315 /* Prepare for the next round. */
316 now = lr_token (ldfile, charmap, NULL, verbose);
317 nowtok = now->tok;
320 /* When we come here we reached the end of the file. */
321 lr_error (ldfile, _("%s: premature end of file"), "LC_NAME");