Correctly handle m68k long double format.
[glibc/pb-stable.git] / locale / programs / ld-name.c
blob7940c0362a772b19d22ffbdcd96b93db8f500585
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 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 not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 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 assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME));
205 write_locale_data (output_path, "LC_NAME",
206 2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME), iov);
210 /* The parser for the LC_NAME section of the locale definition. */
211 void
212 name_read (struct linereader *ldfile, struct localedef_t *result,
213 struct charmap_t *charmap, const char *repertoire_name,
214 int ignore_content)
216 struct locale_name_t *name;
217 struct token *now;
218 struct token *arg;
219 enum token_t nowtok;
221 /* The rest of the line containing `LC_NAME' must be empty. */
222 lr_ignore_rest (ldfile, 1);
226 now = lr_token (ldfile, charmap, NULL, verbose);
227 nowtok = now->tok;
229 while (nowtok == tok_eol);
231 /* If we see `copy' now we are almost done. */
232 if (nowtok == tok_copy)
234 handle_copy (ldfile, charmap, repertoire_name, result, tok_lc_name,
235 LC_NAME, "LC_NAME", ignore_content);
236 return;
239 /* Prepare the data structures. */
240 name_startup (ldfile, result, ignore_content);
241 name = result->categories[LC_NAME].name;
243 while (1)
245 /* Of course we don't proceed beyond the end of file. */
246 if (nowtok == tok_eof)
247 break;
249 /* Ignore empty lines. */
250 if (nowtok == tok_eol)
252 now = lr_token (ldfile, charmap, NULL, verbose);
253 nowtok = now->tok;
254 continue;
257 switch (nowtok)
259 #define STR_ELEM(cat) \
260 case tok_##cat: \
261 /* Ignore the rest of the line if we don't need the input of \
262 this line. */ \
263 if (ignore_content) \
265 lr_ignore_rest (ldfile, 0); \
266 break; \
269 arg = lr_token (ldfile, charmap, NULL, verbose); \
270 if (arg->tok != tok_string) \
271 goto err_label; \
272 if (name->cat != NULL) \
273 lr_error (ldfile, _("%s: field `%s' declared more than once"), \
274 "LC_NAME", #cat); \
275 else if (!ignore_content && arg->val.str.startmb == NULL) \
277 lr_error (ldfile, _("%s: unknown character in field `%s'"), \
278 "LC_NAME", #cat); \
279 name->cat = ""; \
281 else if (!ignore_content) \
282 name->cat = arg->val.str.startmb; \
283 break
285 STR_ELEM (name_fmt);
286 STR_ELEM (name_gen);
287 STR_ELEM (name_mr);
288 STR_ELEM (name_mrs);
289 STR_ELEM (name_miss);
290 STR_ELEM (name_ms);
292 case tok_end:
293 /* Next we assume `LC_NAME'. */
294 arg = lr_token (ldfile, charmap, NULL, verbose);
295 if (arg->tok == tok_eof)
296 break;
297 if (arg->tok == tok_eol)
298 lr_error (ldfile, _("%s: incomplete `END' line"), "LC_NAME");
299 else if (arg->tok != tok_lc_name)
300 lr_error (ldfile, _("\
301 %1$s: definition does not end with `END %1$s'"), "LC_NAME");
302 lr_ignore_rest (ldfile, arg->tok == tok_lc_name);
303 return;
305 default:
306 err_label:
307 SYNTAX_ERROR (_("%s: syntax error"), "LC_NAME");
310 /* Prepare for the next round. */
311 now = lr_token (ldfile, charmap, NULL, verbose);
312 nowtok = now->tok;
315 /* When we come here we reached the end of the file. */
316 lr_error (ldfile, _("%s: premature end of file"), "LC_NAME");