aboutsummaryrefslogtreecommitdiff
path: root/locale/programs/locfile.c
diff options
context:
space:
mode:
Diffstat (limited to 'locale/programs/locfile.c')
-rw-r--r--locale/programs/locfile.c1088
1 files changed, 161 insertions, 927 deletions
diff --git a/locale/programs/locfile.c b/locale/programs/locfile.c
index 79d6ab1..fd858e2 100644
--- a/locale/programs/locfile.c
+++ b/locale/programs/locfile.c
@@ -23,63 +23,36 @@
#include <errno.h>
#include <fcntl.h>
-#include <locale.h>
-#include <malloc.h>
-#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#include <unistd.h>
-#include <libintl.h>
+#include <sys/param.h>
#include <sys/stat.h>
-#include <sys/uio.h>
+#include "localedef.h"
#include "locfile.h"
-#include "linereader.h"
-#include "localeinfo.h"
-#include "locales.h"
-
-/* Uncomment the following line in the production version. */
-/* #define NDEBUG 1 */
-#include <assert.h>
-
-/* Define the lookup function. */
#include "locfile-kw.h"
-/* Some useful macros. */
-#define MIN(a, b) (__extension__ ({ typeof (a) _a = (a); \
- typeof (b) _b = (b); \
- _a < _b ? _a : _b; }))
-
-
-void *xmalloc (size_t __n);
-char *xstrdup (const char *__str);
-
-struct localedef_t *
-locfile_read (const char *filename, struct charset_t *charset)
+int
+locfile_read (struct localedef_t *result, struct charmap_t *charmap)
{
- struct repertoire_t *repertoire = NULL;
+ const char *filename = result->name;
+ const char *repertoire_name = result->repertoire_name;
+ int locale_mask = result->needed ^ result->avail;
struct linereader *ldfile;
- struct localedef_t *result;
- int state;
- enum token_t expected_tok = tok_none;
- const char *expected_str = NULL;
- enum token_t ctype_tok_sym = tok_none;
- const char *ctype_tok_str = NULL;
- int copy_category = 0;
- int cnt;
- /* Allocate space for result. */
- result = (struct localedef_t *) xmalloc (sizeof (struct localedef_t));
- memset (result, '\0', sizeof (struct localedef_t));
+ /* If no repertoire name was specified use the global one. */
+ if (repertoire_name == NULL)
+ repertoire_name = repertoire_global;
+ /* Open the locale definition file. */
ldfile = lr_open (filename, locfile_hash);
if (ldfile == NULL)
{
if (filename[0] != '/')
{
- char *i18npath = __secure_getenv ("I18NPATH");
+ char *i18npath = getenv ("I18NPATH");
if (i18npath != NULL && *i18npath != '\0')
{
char path[strlen (filename) + 1 + strlen (i18npath)
@@ -94,6 +67,13 @@ locfile_read (const char *filename, struct charset_t *charset)
stpcpy (stpcpy (stpcpy (path, next), "/locales/"), filename);
ldfile = lr_open (path, locfile_hash);
+
+ if (ldfile == NULL)
+ {
+ stpcpy (stpcpy (path, next), filename);
+
+ ldfile = lr_open (path, locfile_hash);
+ }
}
}
@@ -108,965 +88,219 @@ locfile_read (const char *filename, struct charset_t *charset)
}
if (ldfile == NULL)
- {
- result->failed = 1;
- return result;
- }
+ return 1;
}
-#define HANDLE_COPY(category, token, string) \
- if (nowtok == tok_copy) \
- { \
- copy_posix.mask &= ~(1 << category); \
- copy_category = category; \
- expected_tok = token; \
- expected_str = string; \
- state = 8; \
- continue; \
- } \
- ++state
-
-#define LOCALE_PROLOG(token, string) \
- if (nowtok == tok_eol) \
- /* Ignore empty lines. */ \
- continue; \
- if (nowtok == tok_end) \
- { \
- expected_tok = token; \
- expected_str = string; \
- state = 4; \
- continue; \
- } \
- if (nowtok == tok_copy) \
- goto only_copy;
-
-
-#define READ_STRING(fn, errlabel) \
- do \
- { \
- arg = lr_token (ldfile, charset); \
- if (arg->tok != tok_string) \
- goto errlabel; \
- fn (ldfile, result, nowtok, arg, charset); \
- lr_ignore_rest (ldfile, 1); \
- } \
- while (0)
-
-#define READ_STRING_LIST(fn, errlabel) \
- do \
- { \
- arg = lr_token (ldfile, charset); \
- while (arg->tok == tok_string) \
- { \
- fn (ldfile, result, nowtok, arg, charset); \
- arg = lr_token (ldfile, charset); \
- if (arg->tok != tok_semicolon) \
- break; \
- arg = lr_token (ldfile, charset); \
- } \
- if (arg->tok != tok_eol) \
- goto errlabel; \
- } \
- while (0)
-
-#define READ_NUMBER(fn, errlabel) \
- do \
- { \
- arg = lr_token (ldfile, charset); \
- if (arg->tok != tok_minus1 && arg->tok != tok_number) \
- goto errlabel; \
- fn (ldfile, result, nowtok, arg, charset); \
- lr_ignore_rest (ldfile, 1); \
- } \
- while (0)
-
-#define READ_NUMBER_LIST(fn, errlabel) \
- do \
- { \
- arg = lr_token (ldfile, charset); \
- while (arg->tok == tok_minus1 || arg->tok == tok_number) \
- { \
- fn (ldfile, result, nowtok, arg, charset); \
- arg = lr_token (ldfile, charset); \
- if (arg->tok != tok_semicolon) \
- break; \
- arg = lr_token (ldfile, charset); \
- } \
- if (arg->tok != tok_eol) \
- goto errlabel; \
- } \
- while (0)
-
-#define SYNTAX_ERROR(string) \
- lr_error (ldfile, string); \
- lr_ignore_rest (ldfile, 0);
-
-
- /* Parse locale definition file and store result in RESULT. */
- state = 1;
+ /* Parse locale definition file and store result in RESULT. */
while (1)
{
- /* What's on? */
- struct token *now = lr_token (ldfile, charset);
+ struct token *now = lr_token (ldfile, charmap, NULL);
enum token_t nowtok = now->tok;
struct token *arg;
if (nowtok == tok_eof)
break;
- switch (state)
- {
- case 1:
- /* The beginning. We expect the special declarations, EOL or
- the start of any locale. */
- if (nowtok == tok_eol)
- /* Ignore empty lines. */
- continue;
-
- switch (nowtok)
- {
- case tok_escape_char:
- case tok_comment_char:
- /* We need an argument. */
- arg = lr_token (ldfile, charset);
-
- if (arg->tok != tok_ident)
- {
- SYNTAX_ERROR (_("bad argument"));
- continue;
- }
-
- if (arg->val.str.len != 1)
- {
- lr_error (ldfile, _("\
-argument to `%s' must be a single character"),
- nowtok == tok_escape_char ? "escape_char"
- : "comment_char");
-
- lr_ignore_rest (ldfile, 0);
- continue;
- }
-
- if (nowtok == tok_escape_char)
- ldfile->escape_char = *arg->val.str.start;
- else
- ldfile->comment_char = *arg->val.str.start;
- break;
-
- case tok_repertoiremap:
- /* We need an argument. */
- arg = lr_token (ldfile, charset);
-
- if (arg->tok != tok_ident)
- {
- SYNTAX_ERROR (_("bad argument"));
- continue;
- }
-
- if (repertoiremap == NULL)
- {
- repertoiremap = memcpy (xmalloc (arg->val.str.len + 1),
- arg->val.str.start,
- arg->val.str.len);
- ((char *) repertoiremap)[arg->val.str.len] = '\0';
- }
-
- lr_ignore_rest (ldfile, 1);
- continue;
-
- case tok_lc_ctype:
- if (repertoire == NULL)
- {
- /* Read the repertoire map now. */
- if (repertoiremap == NULL)
- /* This is fatal. */
- error (4, 0,
- _("no repertoire map specified: cannot proceed"));
-
- repertoire = repertoire_read (repertoiremap);
- if (repertoire == NULL)
- /* This is also fatal. */
- error (4, errno, _("cannot read repertoire map `%s'"),
- repertoiremap);
- }
- state = 2;
- break;
-
- case tok_lc_collate:
- if (repertoire == NULL)
- {
- /* Read the repertoire map now. */
- if (repertoiremap == NULL)
- /* This is fatal. */
- error (4, 0,
- _("no repertoire map specified: cannot proceed"));
-
- repertoire = repertoire_read (repertoiremap);
- if (repertoire == NULL)
- /* This is also fatal. */
- error (4, errno, _("cannot read repertoire map `%s'"),
- repertoiremap);
- }
- state = 10;
- break;
-
- case tok_lc_monetary:
- if (repertoire == NULL)
- {
- /* Read the repertoire map now. */
- if (repertoiremap == NULL)
- /* This is fatal. */
- error (4, 0,
- _("no repertoire map specified: cannot proceed"));
-
- repertoire = repertoire_read (repertoiremap);
- if (repertoire == NULL)
- /* This is also fatal. */
- error (4, errno, _("cannot read repertoire map `%s'"),
- repertoiremap);
- }
- state = 20;
- break;
+ if (nowtok == tok_eol)
+ /* Ignore empty lines. */
+ continue;
- case tok_lc_numeric:
- if (repertoire == NULL)
- {
- /* Read the repertoire map now. */
- if (repertoiremap == NULL)
- /* This is fatal. */
- error (4, 0,
- _("no repertoire map specified: cannot proceed"));
-
- repertoire = repertoire_read (repertoiremap);
- if (repertoire == NULL)
- /* This is also fatal. */
- error (4, errno, _("cannot read repertoire map `%s'"),
- repertoiremap);
- }
- state = 30;
- break;
-
- case tok_lc_time:
- if (repertoire == NULL)
- {
- /* Read the repertoire map now. */
- if (repertoiremap == NULL)
- /* This is fatal. */
- error (4, 0,
- _("no repertoire map specified: cannot proceed"));
-
- repertoire = repertoire_read (repertoiremap);
- if (repertoire == NULL)
- /* This is also fatal. */
- error (4, errno, _("cannot read repertoire map `%s'"),
- repertoiremap);
- }
- state = 40;
- break;
-
- case tok_lc_messages:
- if (repertoire == NULL)
- {
- /* Read the repertoire map now. */
- if (repertoiremap == NULL)
- /* This is fatal. */
- error (4, 0,
- _("no repertoire map specified: cannot proceed"));
-
- repertoire = repertoire_read (repertoiremap);
- if (repertoire == NULL)
- /* This is also fatal. */
- error (4, errno, _("cannot read repertoire map `%s'"),
- repertoiremap);
- }
- state = 50;
- break;
-
- default:
- SYNTAX_ERROR (_("\
-syntax error: not inside a locale definition section"));
- continue;
- }
- lr_ignore_rest (ldfile, 1);
- continue;
-
- case 2:
- HANDLE_COPY (LC_CTYPE, tok_lc_ctype, "LC_CTYPE");
-
- ctype_startup (ldfile, result, charset);
- /* FALLTHROUGH */
-
- case 3:
- /* Here we accept all the character classes, tolower/toupper,
- and following ANSI C:1995 self-defined classes. */
- LOCALE_PROLOG (tok_lc_ctype, "LC_CTYPE");
+ switch (nowtok)
+ {
+ case tok_escape_char:
+ case tok_comment_char:
+ /* We need an argument. */
+ arg = lr_token (ldfile, charmap, NULL);
- if (nowtok == tok_charclass)
+ if (arg->tok != tok_ident)
{
- READ_STRING_LIST (ctype_class_new, bad_new_charclass);
- continue;
- bad_new_charclass:
- SYNTAX_ERROR (_("\
-syntax error in definition of new character class"));
+ SYNTAX_ERROR (_("bad argument"));
continue;
}
- if (nowtok == tok_charconv)
+ if (arg->val.str.lenmb != 1)
{
- READ_STRING_LIST (ctype_map_new, bad_new_charconv);
- continue;
- bad_new_charconv:
- SYNTAX_ERROR (_("\
-syntax error in definition of new character map"));
- continue;
- }
+ lr_error (ldfile, _("\
+argument to `%s' must be a single character"),
+ nowtok == tok_escape_char
+ ? "escape_char" : "comment_char");
- if (nowtok == tok_upper || nowtok == tok_lower
- || nowtok == tok_alpha || nowtok == tok_digit
- || nowtok == tok_alnum || nowtok == tok_space
- || nowtok == tok_cntrl || nowtok == tok_punct
- || nowtok == tok_graph || nowtok == tok_print
- || nowtok == tok_xdigit || nowtok == tok_blank)
- {
- ctype_tok_sym = nowtok;
- ctype_tok_str = NULL;
- state = 5;
+ lr_ignore_rest (ldfile, 0);
continue;
}
- if (nowtok == tok_toupper|| nowtok == tok_tolower)
- {
- ctype_tok_sym = nowtok;
- ctype_tok_str = NULL;
- state = 6;
- continue;
- }
+ if (nowtok == tok_escape_char)
+ ldfile->escape_char = *arg->val.str.startmb;
+ else
+ ldfile->comment_char = *arg->val.str.startmb;
+ break;
- if (nowtok != tok_ident)
- goto bad_charclass;
+ case tok_repertoiremap:
+ /* We need an argument. */
+ arg = lr_token (ldfile, charmap, NULL);
- /* We possibly have a self-defined character class. */
- if (ctype_is_charclass (ldfile, result, now->val.str.start))
+ if (arg->tok != tok_ident)
{
- ctype_tok_sym = nowtok;
- ctype_tok_str = now->val.str.start;
- state = 5;
+ SYNTAX_ERROR (_("bad argument"));
continue;
}
- /* ...or a self-defined character map. */
- if (ctype_is_charconv (ldfile, result, now->val.str.start))
+ if (repertoire_name == NULL)
{
- ctype_tok_sym = nowtok;
- ctype_tok_str = now->val.str.start;
- state = 6;
- continue;
+ repertoire_name = memcpy (xmalloc (arg->val.str.lenmb + 1),
+ arg->val.str.startmb,
+ arg->val.str.lenmb);
+ ((char *) repertoire_name)[arg->val.str.lenmb] = '\0';
}
+ break;
- SYNTAX_ERROR (_("syntax error in definition of LC_CTYPE category"));
+ case tok_lc_ctype:
+ ctype_read (ldfile, result, charmap, repertoire_name,
+ (locale_mask & CTYPE_LOCALE) == 0);
+ result->avail |= locale_mask & CTYPE_LOCALE;
continue;
- case 4:
- /* Handle `END xxx'. */
- if (nowtok != expected_tok)
- lr_error (ldfile, _("\
-`%1$s' definition does not end with `END %1$s'"), expected_str);
-
- lr_ignore_rest (ldfile, nowtok == expected_tok);
- state = 1;
+ case tok_lc_collate:
+ collate_read (ldfile, result, charmap, repertoire_name,
+ (locale_mask & COLLATE_LOCALE) == 0);
+ result->avail |= locale_mask & COLLATE_LOCALE;
continue;
- case 5:
- /* Here we expect a semicolon separated list of bsymbols. The
- bit to be set in the word is given in CHARCLASS_BIT. */
- arg = now;
-
- ctype_class_start (ldfile, result, ctype_tok_sym, ctype_tok_str,
- charset);
-
- while (arg->tok != tok_eol)
- {
- /* Any token other than a bsymbol is an error. */
- if (arg->tok != tok_bsymbol)
- {
- bad_charclass:
- SYNTAX_ERROR (_("\
-syntax error in character class definition"));
- break;
- }
-
- /* Lookup value for token and write into array. */
- ctype_class_from (ldfile, result, arg, charset);
-
- arg = lr_token (ldfile, charset);
- if (arg->tok == tok_semicolon)
- arg = lr_token (ldfile, charset);
- else if (arg->tok != tok_eol)
- goto bad_charclass;
-
- /* Look for ellipsis. */
- if (arg->tok == tok_ellipsis)
- {
- arg = lr_token (ldfile, charset);
- if (arg->tok != tok_semicolon)
- goto bad_charclass;
-
- arg = lr_token (ldfile, charset);
- if (arg->tok != tok_bsymbol)
- goto bad_charclass;
-
- /* Write range starting at LAST to ARG->VAL. */
- ctype_class_to (ldfile, result, arg, charset);
-
- arg = lr_token (ldfile, charset);
- if (arg->tok == tok_semicolon)
- arg = lr_token (ldfile, charset);
- else if (arg->tok != tok_eol)
- goto bad_charclass;
- }
- }
-
- /* Mark class as already seen. */
- ctype_class_end (ldfile, result);
- state = 3;
-
+ case tok_lc_monetary:
+ monetary_read (ldfile, result, charmap, repertoire_name,
+ (locale_mask & MONETARY_LOCALE) == 0);
+ result->avail |= locale_mask & MONETARY_LOCALE;
continue;
- case 6:
- /* Here we expect a list of character mappings. Note: the
- first opening brace is already matched. */
- ctype_map_start (ldfile, result, ctype_tok_sym, ctype_tok_str,
- charset);
-
- while (1)
- {
- /* Match ( bsymbol , bsymbol ) */
- if (now->tok != tok_open_brace)
- goto bad_charconv;
-
- now = lr_token (ldfile, charset);
- if (now->tok != tok_bsymbol)
- {
- bad_charconv:
- SYNTAX_ERROR (_("\
-syntax error in character conversion definition"));
- state = 3;
- break;
- }
-
- /* Lookup arg and assign to FROM. */
- ctype_map_from (ldfile, result, now, charset);
-
- now = lr_token (ldfile, charset);
- if (now->tok != tok_comma)
- goto bad_charconv;
-
- now = lr_token (ldfile, charset);
- if (now->tok != tok_bsymbol)
- goto bad_charconv;
-
- /* Lookup arg and assign to TO. */
- ctype_map_to (ldfile, result, now, charset);
-
- now = lr_token (ldfile, charset);
- if (now->tok != tok_close_brace)
- goto bad_charconv;
-
- now = lr_token (ldfile, charset);
- if (now->tok == tok_eol)
- {
- state = 3;
- break;
- }
- if (now->tok != tok_semicolon)
- goto bad_charconv;
-
- now = lr_token (ldfile, charset);
- }
-
- ctype_map_end (ldfile, result);
+ case tok_lc_numeric:
+ numeric_read (ldfile, result, charmap, repertoire_name,
+ (locale_mask & NUMERIC_LOCALE) == 0);
+ result->avail |= locale_mask & NUMERIC_LOCALE;
continue;
- case 8:
- {
- /* We have seen `copy'. First match the argument. */
- int warned = 0;
-
- if (nowtok != tok_string)
- lr_error (ldfile, _("expect string argument for `copy'"));
- else
- def_to_process (now->val.str.start, 1 << copy_category);
-
- lr_ignore_rest (ldfile, nowtok == tok_string);
-
- /* The rest of the line must be empty
- and the next keyword must be `END xxx'. */
-
- while (lr_token (ldfile, charset)->tok != tok_end)
- {
- if (warned == 0)
- {
- only_copy:
- lr_error (ldfile, _("\
-no other keyword shall be specified when `copy' is used"));
- warned = 1;
- }
-
- lr_ignore_rest (ldfile, 0);
- }
-
- state = 4;
- }
+ case tok_lc_time:
+ time_read (ldfile, result, charmap, repertoire_name,
+ (locale_mask & TIME_LOCALE) == 0);
+ result->avail |= locale_mask & TIME_LOCALE;
continue;
- case 10:
- HANDLE_COPY (LC_COLLATE, tok_lc_collate, "LC_COLLATE");
-
- collate_startup (ldfile, result, charset);
- /* FALLTHROUGH */
-
- case 11:
- /* Process the LC_COLLATE section. We expect `END LC_COLLATE'
- any of the collation specifications, or any bsymbol. */
- LOCALE_PROLOG (tok_lc_collate, "LC_COLLATE");
-
- if (nowtok == tok_order_start)
- {
- state = 12;
- continue;
- }
-
- if (nowtok != tok_collating_element
- && nowtok != tok_collating_symbol)
- {
- bad_collation:
- lr_error (ldfile, _("\
-syntax error in collation definition"));
- lr_ignore_rest (ldfile, 0);
- continue;
- }
-
- /* Get argument. */
- arg = lr_token (ldfile, charset);
- if (arg->tok != tok_bsymbol)
- {
- lr_error (ldfile, _("\
-collation symbol expected after `%s'"),
- nowtok == tok_collating_element
- ? "collating-element" : "collating-symbol");
- lr_ignore_rest (ldfile, 0);
- continue;
- }
-
- if (nowtok == tok_collating_element)
- {
- /* Save to-value as new name. */
- collate_element_to (ldfile, result, arg, charset);
-
- arg = lr_token (ldfile, charset);
- if (arg->tok != tok_from)
- {
- lr_error (ldfile, _("\
-`from' expected after first argument to `collating-element'"));
- lr_ignore_rest (ldfile, 0);
- continue;
- }
-
- arg = lr_token (ldfile, charset);
- if (arg->tok != tok_string)
- {
- lr_error (ldfile, _("\
-from-value of `collating-element' must be a string"));
- lr_ignore_rest (ldfile, 0);
- continue;
- }
-
- /* Enter new collating element. */
- collate_element_from (ldfile, result, arg, charset);
- }
- else
- /* Enter new collating symbol into table. */
- collate_symbol (ldfile, result, arg, charset);
-
- lr_ignore_rest (ldfile, 1);
- continue;
-
- case 12:
- /* We parse the rest of the line containing `order_start'.
- In any case we continue with parsing the symbols. */
- state = 13;
-
- cnt = 0;
- while (now->tok != tok_eol)
- {
- int collation_method = 0;
-
- ++cnt;
-
- do
- {
- if (now->tok == tok_forward)
- collation_method |= sort_forward;
- else if (now->tok == tok_backward)
- collation_method |= sort_backward;
- else if (now->tok == tok_position)
- collation_method |= sort_position;
- else
- {
- lr_error (ldfile, _("unknown collation directive"));
- lr_ignore_rest (ldfile, 0);
- continue;
- }
-
- now = lr_token (ldfile, charset);
- }
- while (now->tok == tok_comma
- && ((now = lr_token (ldfile, charset)) != tok_none));
-
- /* Check for consistency: forward and backwards are
- mutually exclusive. */
- if ((collation_method & sort_forward) != 0
- && (collation_method & sort_backward) != 0)
- {
- lr_error (ldfile, _("\
-sorting order `forward' and `backward' are mutually exclusive"));
- /* The recover clear the backward flag. */
- collation_method &= ~sort_backward;
- }
-
- /* ??? I don't know whether this is correct but while
- thinking about the `strcoll' functions I found that I
- need a direction when performing position depended
- collation. So I assume here that implicitly the
- direction `forward' is given when `position' alone is
- written. --drepper */
- if (collation_method == sort_position)
- collation_method |= sort_forward;
-
- /* Enter info about next collation order. */
- collate_new_order (ldfile, result, collation_method);
-
- if (now->tok != tok_eol && now->tok != tok_semicolon)
- {
- lr_error (ldfile, _("\
-syntax error in `order_start' directive"));
- lr_ignore_rest (ldfile, 0);
- break;
- }
-
- if (now->tok == tok_semicolon)
- now = lr_token (ldfile, charset);
- }
-
- /* If no argument to `order_start' is given, one `forward'
- argument is implicitly assumed. */
- if (cnt == 0)
- collate_new_order (ldfile, result, sort_forward);
-
-
- /* We now know about all sorting rules. */
- collate_build_arrays (ldfile, result);
-
+ case tok_lc_messages:
+ messages_read (ldfile, result, charmap, repertoire_name,
+ (locale_mask & MESSAGES_LOCALE) == 0);
+ result->avail |= locale_mask & MESSAGES_LOCALE;
continue;
- case 13:
- /* We read one symbol a line until `order_end' is found. */
- {
- static int last_correct = 1;
-
- if (nowtok == tok_order_end)
- {
- state = 14;
- lr_ignore_rest (ldfile, 1);
- continue;
- }
-
- /* Ignore empty lines. */
- if (nowtok == tok_eol)
- continue;
-
- if (nowtok != tok_bsymbol && nowtok != tok_undefined
- && nowtok != tok_ellipsis)
- {
- if (last_correct == 1)
- {
- lr_error (ldfile, _("\
-syntax error in collating order definition"));
- last_correct = 0;
- }
- lr_ignore_rest (ldfile, 0);
- continue;
- }
- else
- {
- last_correct = 1;
-
- /* Remember current token. */
- if (collate_order_elem (ldfile, result, now, charset) < 0)
- continue;
- }
-
- /* Read optional arguments. */
- arg = lr_token (ldfile, charset);
- while (arg->tok != tok_eol)
- {
- if (arg->tok != tok_ignore && arg->tok != tok_ellipsis
- && arg->tok != tok_bsymbol && arg->tok != tok_string)
- break;
-
- if (arg->tok == tok_ignore || arg->tok == tok_ellipsis
- || arg->tok == tok_string)
- {
- /* Call handler for simple weights. */
- if (collate_simple_weight (ldfile, result, arg, charset)
- < 0)
- goto illegal_weight;
-
- arg = lr_token (ldfile, charset);
- }
- else
- do
- {
- /* Collect char. */
- int ok = collate_weight_bsymbol (ldfile, result, arg,
- charset);
- if (ok < 0)
- goto illegal_weight;
-
- arg = lr_token (ldfile, charset);
- }
- while (arg->tok == tok_bsymbol);
-
- /* Are there more weights? */
- if (arg->tok != tok_semicolon)
- break;
-
- /* Yes, prepare next weight. */
- if (collate_next_weight (ldfile, result) < 0)
- goto illegal_weight;
-
- arg = lr_token (ldfile, charset);
- }
-
- if (arg->tok != tok_eol)
- {
- SYNTAX_ERROR (_("syntax error in order specification"));
- }
-
- collate_end_weight (ldfile, result);
- illegal_weight:
- }
+ case tok_lc_paper:
+ paper_read (ldfile, result, charmap, repertoire_name,
+ (locale_mask & PAPER_LOCALE) == 0);
+ result->avail |= locale_mask & PAPER_LOCALE;
continue;
- case 14:
- /* Following to the `order_end' keyword we don't expect
- anything but the `END'. */
- if (nowtok == tok_eol)
- continue;
-
- if (nowtok != tok_end)
- goto bad_collation;
-
- expected_tok = tok_lc_collate;
- expected_str = "LC_COLLATE";
- state = 4;
-
- ldfile->translate_strings = 1;
+ case tok_lc_name:
+ name_read (ldfile, result, charmap, repertoire_name,
+ (locale_mask & NAME_LOCALE) == 0);
+ result->avail |= locale_mask & NAME_LOCALE;
continue;
- case 20:
- HANDLE_COPY (LC_MONETARY, tok_lc_monetary, "LC_MONETARY");
-
- monetary_startup (ldfile, result, charset);
- /* FALLTHROUGH */
-
- case 21:
- LOCALE_PROLOG (tok_lc_monetary, "LC_MONETARY");
-
- switch (nowtok)
- {
- case tok_int_curr_symbol:
- case tok_currency_symbol:
- case tok_mon_decimal_point:
- case tok_mon_thousands_sep:
- case tok_positive_sign:
- case tok_negative_sign:
- READ_STRING (monetary_add, bad_monetary);
- break;
-
- case tok_int_frac_digits:
- case tok_frac_digits:
- case tok_p_cs_precedes:
- case tok_p_sep_by_space:
- case tok_n_cs_precedes:
- case tok_n_sep_by_space:
- case tok_p_sign_posn:
- case tok_n_sign_posn:
- READ_NUMBER (monetary_add, bad_monetary);
- break;
-
- case tok_mon_grouping:
- /* We have a semicolon separated list of integers. */
- READ_NUMBER_LIST (monetary_add, bad_monetary);
- break;
-
- default:
- bad_monetary:
- SYNTAX_ERROR (_("syntax error in monetary locale definition"));
- }
+ case tok_lc_address:
+ address_read (ldfile, result, charmap, repertoire_name,
+ (locale_mask & ADDRESS_LOCALE) == 0);
+ result->avail |= locale_mask & ADDRESS_LOCALE;
continue;
- case 30:
- HANDLE_COPY (LC_NUMERIC, tok_lc_numeric, "LC_NUMERIC");
-
- numeric_startup (ldfile, result, charset);
- /* FALLTHROUGH */
-
- case 31:
- LOCALE_PROLOG (tok_lc_numeric, "LC_NUMERIC");
-
- switch (nowtok)
- {
- case tok_decimal_point:
- case tok_thousands_sep:
- READ_STRING (numeric_add, bad_numeric);
- break;
-
- case tok_grouping:
- /* We have a semicolon separated list of integers. */
- READ_NUMBER_LIST (numeric_add, bad_numeric);
- break;
-
- default:
- bad_numeric:
- SYNTAX_ERROR (_("syntax error in numeric locale definition"));
- }
+ case tok_lc_telephone:
+ telephone_read (ldfile, result, charmap, repertoire_name,
+ (locale_mask & TELEPHONE_LOCALE) == 0);
+ result->avail |= locale_mask & TELEPHONE_LOCALE;
continue;
- case 40:
- HANDLE_COPY (LC_TIME, tok_lc_time, "LC_TIME");
-
- time_startup (ldfile, result, charset);
- /* FALLTHROUGH */
-
- case 41:
- LOCALE_PROLOG (tok_lc_time, "LC_TIME");
-
- switch (nowtok)
- {
- case tok_abday:
- case tok_day:
- case tok_abmon:
- case tok_mon:
- case tok_am_pm:
- case tok_alt_digits:
- case tok_era:
- READ_STRING_LIST (time_add, bad_time);
- continue;
-
- case tok_d_t_fmt:
- case tok_d_fmt:
- case tok_t_fmt:
- case tok_t_fmt_ampm:
- case tok_era_year:
- case tok_era_d_t_fmt:
- case tok_era_d_fmt:
- case tok_era_t_fmt:
- READ_STRING (time_add, bad_time);
- break;
-
- default:
- bad_time:
- SYNTAX_ERROR (_("syntax error in time locale definition"));
- }
+ case tok_lc_measurement:
+ measurement_read (ldfile, result, charmap, repertoire_name,
+ (locale_mask & MEASUREMENT_LOCALE) == 0);
+ result->avail |= locale_mask & MEASUREMENT_LOCALE;
continue;
- case 50:
- HANDLE_COPY (LC_MESSAGES, tok_lc_messages, "LC_MESSAGES");
-
- messages_startup (ldfile, result, charset);
- /* FALLTHROUGH */
-
- case 51:
- LOCALE_PROLOG (tok_lc_messages, "LC_MESSAGES");
-
- switch (nowtok)
- {
- case tok_yesexpr:
- case tok_noexpr:
- case tok_yesstr:
- case tok_nostr:
- READ_STRING (messages_add, bad_message);
- break;
-
- default:
- bad_message:
- SYNTAX_ERROR (_("syntax error in message locale definition"));
- }
+ case tok_lc_identification:
+ identification_read (ldfile, result, charmap, repertoire_name,
+ (locale_mask & IDENTIFICATION_LOCALE) == 0);
+ result->avail |= locale_mask & IDENTIFICATION_LOCALE;
continue;
default:
- error (5, 0, _("%s: error in state machine"), __FILE__);
- /* NOTREACHED */
+ SYNTAX_ERROR (_("\
+syntax error: not inside a locale definition section"));
+ continue;
}
- break;
+ /* The rest of the line must be empty. */
+ lr_ignore_rest (ldfile, 1);
}
/* We read all of the file. */
lr_close (ldfile);
- /* Let's see what information is available. */
- for (cnt = LC_CTYPE; cnt <= LC_MESSAGES; ++cnt)
- if (result->categories[cnt].generic != NULL)
- result->avail |= 1 << cnt;
-
- return result;
+ return 0;
}
+static void (*const check_funcs[]) (struct localedef_t *,
+ struct charmap_t *) =
+{
+ [LC_CTYPE] = ctype_finish,
+ [LC_COLLATE] = collate_finish,
+ [LC_MESSAGES] = messages_finish,
+ [LC_MONETARY] = monetary_finish,
+ [LC_NUMERIC] = numeric_finish,
+ [LC_TIME] = time_finish,
+ [LC_PAPER] = paper_finish,
+ [LC_NAME] = name_finish,
+ [LC_ADDRESS] = address_finish,
+ [LC_TELEPHONE] = telephone_finish,
+ [LC_MEASUREMENT] = measurement_finish,
+ [LC_IDENTIFICATION] = identification_finish
+};
+
+
void
-check_all_categories (struct localedef_t *locale, struct charset_t *charset)
+check_all_categories (struct localedef_t *definitions,
+ struct charmap_t *charmap)
{
- /* Call the finishing functions for all locales. */
- if ((locale->avail & (1 << LC_CTYPE)) != 0
- && (locale->binary & (1 << LC_CTYPE)) == 0)
- ctype_finish (locale, charset);
- if ((locale->avail & (1 << LC_COLLATE)) != 0
- && (locale->binary & (1 << LC_COLLATE)) == 0)
- collate_finish (locale, charset);
- if ((locale->avail & (1 << LC_MONETARY)) != 0
- && (locale->binary & (1 << LC_MONETARY)) == 0)
- monetary_finish (locale);
- if ((locale->avail & (1 << LC_NUMERIC)) != 0
- && (locale->binary & (1 << LC_NUMERIC)) == 0)
- numeric_finish (locale);
- if ((locale->avail & (1 << LC_TIME)) != 0
- && (locale->binary & (1 << LC_TIME)) == 0)
- time_finish (locale);
- if ((locale->avail & (1 << LC_MESSAGES)) != 0
- && (locale->binary & (1 << LC_MESSAGES)) == 0)
- messages_finish (locale);
+ int cnt;
+
+ for (cnt = 0; cnt < sizeof (check_funcs) / sizeof (check_funcs[0]); ++cnt)
+ if (check_funcs[cnt] != NULL)
+ check_funcs[cnt] (definitions, charmap);
}
+static void (*const write_funcs[]) (struct localedef_t *, struct charmap_t *,
+ const char *) =
+{
+ [LC_CTYPE] = ctype_output,
+ [LC_COLLATE] = collate_output,
+ [LC_MESSAGES] = messages_output,
+ [LC_MONETARY] = monetary_output,
+ [LC_NUMERIC] = numeric_output,
+ [LC_TIME] = time_output,
+ [LC_PAPER] = paper_output,
+ [LC_NAME] = name_output,
+ [LC_ADDRESS] = address_output,
+ [LC_TELEPHONE] = telephone_output,
+ [LC_MEASUREMENT] = measurement_output,
+ [LC_IDENTIFICATION] = identification_output
+};
+
+
void
-write_all_categories (struct localedef_t *locale, struct charset_t *charset,
+write_all_categories (struct localedef_t *definitions,
+ struct charmap_t *charmap,
const char *output_path)
{
- /* Call all functions to write locale data. */
- if ((locale->avail & (1 << LC_CTYPE)) != 0)
- ctype_output (locale, charset, output_path);
- if ((locale->avail & (1 << LC_COLLATE)) != 0)
- collate_output (locale, charset, output_path);
- if ((locale->avail & (1 << LC_MONETARY)) != 0)
- monetary_output (locale, output_path);
- if ((locale->avail & (1 << LC_NUMERIC)) != 0)
- numeric_output (locale, output_path);
- if ((locale->avail & (1 << LC_TIME)) != 0)
- time_output (locale, output_path);
- if ((locale->avail & (1 << LC_MESSAGES)) != 0)
- messages_output (locale, output_path);
+ int cnt;
+
+ for (cnt = 0; cnt < sizeof (write_funcs) / sizeof (write_funcs[0]); ++cnt)
+ if (check_funcs[cnt] != NULL)
+ write_funcs[cnt] (definitions, charmap, output_path);
}
@@ -1086,7 +320,7 @@ write_locale_data (const char *output_path, const char *category,
But for LC_MESSAGES we have to take care for the translation
data. This means we need to have a directory LC_MESSAGES in
which we place the file under the name SYS_LC_MESSAGES. */
- sprintf (fname, "%s%s", output_path, category);
+ sprintf (fname, "%s/%s", output_path, category);
if (strcmp (category, "LC_MESSAGES") == 0)
{
struct stat st;
@@ -1118,7 +352,7 @@ write_locale_data (const char *output_path, const char *category,
if (errno == EISDIR)
{
- sprintf (fname, "%1$s%2$s/SYS_%2$s", output_path, category);
+ sprintf (fname, "%1$s/%2$s/SYS_%2$s", output_path, category);
fd = creat (fname, 0666);
if (fd == -1)
save_err = errno;