diff options
author | Ulrich Drepper <drepper@redhat.com> | 1999-08-31 07:04:41 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 1999-08-31 07:04:41 +0000 |
commit | 4b10dd6c1959577f57850ca427a94fe22b9f3299 (patch) | |
tree | b385d9b27e5a40d5baf7cd7e27c7cc5ef7129b5b /locale/programs/ld-messages.c | |
parent | 1d1740d6b12894ed6a430e2e98bf73c5243b2925 (diff) | |
download | glibc-4b10dd6c1959577f57850ca427a94fe22b9f3299.tar.gz glibc-4b10dd6c1959577f57850ca427a94fe22b9f3299.tar.xz glibc-4b10dd6c1959577f57850ca427a94fe22b9f3299.zip |
Update.
* locale/Makefile (distribute): Add iso-639.def and iso-3166.def. Change charset.h to charmap.h. (categories): Add new categories. Leave out collate for now. Update build rules. * locale/categories.def: Add definitions for new categories. * locale/langinfo.h: Likewise. * locale/locale.h: Likewise. * locale/C-address.c: New file. * locale/C-identification.c: New file. * locale/C-measurement.c: New file. * locale/C-name.c: New file. * locale/C-paper.c: New file. * locale/C-telephone.c: New file. * locale/lc-address.c: Likewise. * locale/lc-identification.c: Likewise. * locale/lc-measurement.c: Likewise. * locale/lc-name.c: Likewise. * locale/lc-paper.c: Likewise. * locale/lc-telephone.c: Likewise. * locale/C-ctype.c: Update for locale rewrite. * locale/C-messages.c: Likewise. * locale/C-monetary.c: Likewise. * locale/C-time.c: Likewise. * locale/lc-collate.c: Likewise. * locale/lc-ctype.c: Likewise. * locale/lc-monetary.c: Likewise. * locale/lc-time.c: Likewise. * locale/localeinfo.h: Likewise. * locale/newlocale.c: Likewise. * locale/setlocale.c: Likewise. * locale/weight.h: Likewise. * locale/findlocale.c: Unconditionally use mmap. Handle new categories. * locale/loadlocale.c: Likewise. * locale/iso-3166.def: New file. * locale/iso-639.def: New file. * locale/programs/charmap-kw.gperf: Add new keywords. * locale/programs/locfile-kw.gperf: Likewise. * locale/programs/locfile-token.h: Define new tokens. * locale/programs/charmap.c: Rewrite to handle multibyte charsets. * locale/programs/charmap.h: New file. * locale/programs/charset.h: Removed. * locale/programs/config.h: Add __LC_LAST. * locale/programs/lc-address.c: New file. * locale/programs/lc-identification.c: New file. * locale/programs/lc-measurement.c: New file. * locale/programs/lc-name.c: New file. * locale/programs/lc-paper.c: New file. * locale/programs/lc-telephone.c: New file. * locale/programs/lc-collate.c: Update for locale rewrite. * locale/programs/lc-ctype.c: Likewise. * locale/programs/lc-messages.c: Likewise. * locale/programs/lc-monetary.c: Likewise. * locale/programs/lc-numeric.c: Likewise. * locale/programs/lc-time.c: Likewise. * locale/programs/locale.c: Likewise. * locale/programs/localedef.c: Likewise. * locale/programs/locfile.c: Likewise. * locale/programs/repertoire.c: Likewise. * locale/programs/repertoire.h: Likewise. * locale/programs/locfile.c: Update prototypes. Update handle_copy definition. * locale/programs/linereader.c: Add handling of wide char strings and new definition file syntax. * locale/programs/linereader.h (struct token): Add elements for wide character strings. * locale/programs/locale-spec.c: Disable handling of collation elements for now. * locale/programs/simple-hash.h: Cleanup. * locale/programs/stringtrans.h: Handle quite of end of line. * string/strcoll.c: Fall back on strcmp for now. * string/strxfrm.c: Fall back on strncpy/strlen for now. * time/strftime.c: Use new wide character data for wcsftime. * time/strptime.c: Remove _nl_C_LC_TIME declaration. * wctype/cname-lookup.h: Update for new LC_CTYPE data.
Diffstat (limited to 'locale/programs/ld-messages.c')
-rw-r--r-- | locale/programs/ld-messages.c | 252 |
1 files changed, 151 insertions, 101 deletions
diff --git a/locale/programs/ld-messages.c b/locale/programs/ld-messages.c index 69e411c8d6..33b7735b7d 100644 --- a/locale/programs/ld-messages.c +++ b/locale/programs/ld-messages.c @@ -1,6 +1,6 @@ -/* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +/* Copyright (C) 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. This file is part of the GNU C Library. - Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. + Contributed by Ulrich Drepper <drepper@gnu.org>, 1995. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as @@ -21,28 +21,18 @@ # include <config.h> #endif -#include <alloca.h> #include <langinfo.h> +#include <sys/types.h> +#include <regex.h> #include <string.h> -#include <libintl.h> #include <sys/uio.h> -#ifdef HAVE_REGEX -# include <regex.h> -#else -# include <rx.h> -#endif - -/* Undefine following line in production version. */ -/* #define NDEBUG 1 */ #include <assert.h> -#include "locales.h" -#include "stringtrans.h" +#include "linereader.h" +#include "localedef.h" #include "localeinfo.h" - - -extern void *xmalloc (size_t __n); +#include "locfile.h" /* The real definition of the struct for the LC_MESSAGES locale. */ @@ -55,44 +45,51 @@ struct locale_messages_t }; -void +static void messages_startup (struct linereader *lr, struct localedef_t *locale, - struct charset_t *charset) + int ignore_content) { - struct locale_messages_t *messages; + if (!ignore_content) + locale->categories[LC_MESSAGES].messages = + (struct locale_messages_t *) xcalloc (1, + sizeof (struct locale_messages_t)); - /* We have a definition for LC_MESSAGES. */ - copy_posix.mask &= ~(1 << LC_MESSAGES); - - /* It is important that we always use UCS1 encoding for strings now. */ - encoding_method = ENC_UCS1; - - locale->categories[LC_MESSAGES].messages = messages = - (struct locale_messages_t *) xmalloc (sizeof (struct locale_messages_t)); - - memset (messages, '\0', sizeof (struct locale_messages_t)); + lr->translate_strings = 1; + lr->return_widestr = 0; } void -messages_finish (struct localedef_t *locale) +messages_finish (struct localedef_t *locale, struct charmap_t *charmap) { struct locale_messages_t *messages = locale->categories[LC_MESSAGES].messages; /* The fields YESSTR and NOSTR are optional. */ + if (messages->yesstr == NULL) + messages->yesstr = ""; + if (messages->nostr == NULL) + messages->nostr = ""; + if (messages->yesexpr == NULL) { if (!be_quiet) - error (0, 0, _("field `%s' in category `%s' undefined"), - "yesexpr", "LC_MESSAGES"); + error (0, 0, _("%s: field `%s' undefined"), "LC_MESSAGES", "yesexpr"); + messages->yesexpr = ""; + } + else if (messages->yesexpr[0] == '\0') + { + if (!be_quiet) + error (0, 0, _("\ +%s: value for field `%s' must not be an empty string"), + "LC_MESSAGES", "yesexpr"); } else { int result; regex_t re; - /* Test whether it is a correct regular expression. */ + /* Test whether it are correct regular expressions. */ result = regcomp (&re, messages->yesexpr, REG_EXTENDED); if (result != 0 && !be_quiet) { @@ -100,23 +97,32 @@ messages_finish (struct localedef_t *locale) (void) regerror (result, &re, errbuf, BUFSIZ); error (0, 0, _("\ -no correct regular expression for field `%s' in category `%s': %s"), - "yesexpr", "LC_MESSAGES", errbuf); +%s: no correct regular expression for field `%s': %s"), + "LC_MESSAGES", "yesexpr", errbuf); } + else if (result != 0) + regfree (&re); } if (messages->noexpr == NULL) { if (!be_quiet) - error (0, 0, _("field `%s' in category `%s' undefined"), - "noexpr", "LC_MESSAGES"); + error (0, 0, _("%s: field `%s' undefined"), "LC_MESSAGES", "noexpr"); + messages->noexpr = ""; + } + else if (messages->noexpr[0] == '\0') + { + if (!be_quiet) + error (0, 0, _("\ +%s: value for field `%s' must not be an empty string"), + "LC_MESSAGES", "noexpr"); } else { int result; regex_t re; - /* Test whether it is a correct regular expression. */ + /* Test whether it are correct regular expressions. */ result = regcomp (&re, messages->noexpr, REG_EXTENDED); if (result != 0 && !be_quiet) { @@ -124,33 +130,26 @@ no correct regular expression for field `%s' in category `%s': %s"), (void) regerror (result, &re, errbuf, BUFSIZ); error (0, 0, _("\ -no correct regular expression for field `%s' in category `%s': %s"), - "noexpr", "LC_MESSAGES", errbuf); +%s: no correct regular expression for field `%s': %s"), + "LC_MESSAGES", "noexpr", errbuf); } + else if (result != 0) + regfree (&re); } } void -messages_output (struct localedef_t *locale, const char *output_path) +messages_output (struct localedef_t *locale, struct charmap_t *charmap, + const char *output_path) { struct locale_messages_t *messages = locale->categories[LC_MESSAGES].messages; struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)]; struct locale_file data; - u_int32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)]; + uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)]; size_t cnt = 0; - if ((locale->binary & (1 << LC_MESSAGES)) != 0) - { - iov[0].iov_base = messages; - iov[0].iov_len = locale->len[LC_MESSAGES]; - - write_locale_data (output_path, "LC_MESSAGES", 1, iov); - - return; - } - data.magic = LIMAGIC (LC_MESSAGES); data.n = _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES); iov[cnt].iov_base = (void *) &data; @@ -162,22 +161,22 @@ messages_output (struct localedef_t *locale, const char *output_path) ++cnt; idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len; - iov[cnt].iov_base = (void *) (messages->yesexpr ?: ""); + iov[cnt].iov_base = (char *) messages->yesexpr; iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; ++cnt; idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) (messages->noexpr ?: ""); + iov[cnt].iov_base = (char *) messages->noexpr; iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; ++cnt; idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) (messages->yesstr ?: ""); + iov[cnt].iov_base = (char *) messages->yesstr; iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; ++cnt; idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; - iov[cnt].iov_base = (void *) (messages->nostr ?: ""); + iov[cnt].iov_base = (char *) messages->nostr; iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; assert (cnt + 1 == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)); @@ -187,61 +186,112 @@ messages_output (struct localedef_t *locale, const char *output_path) } +/* The parser for the LC_MESSAGES section of the locale definition. */ void -messages_add (struct linereader *lr, struct localedef_t *locale, - enum token_t tok, struct token *code, - struct charset_t *charset) +messages_read (struct linereader *ldfile, struct localedef_t *result, + struct charmap_t *charmap, const char *repertoire_name, + int ignore_content) { - struct locale_messages_t *messages - = locale->categories[LC_MESSAGES].messages; + struct repertoire_t *repertoire = NULL; + struct locale_messages_t *messages; + struct token *now; + enum token_t nowtok; + + /* Get the repertoire we have to use. */ + if (repertoire_name != NULL) + repertoire = repertoire_read (repertoire_name); - switch (tok) + /* The rest of the line containing `LC_MESSAGES' must be free. */ + lr_ignore_rest (ldfile, 1); + + + do { - case tok_yesexpr: - if (code->val.str.start == NULL) - { - lr_error (lr, _("unknown character in field `%s' of category `%s'"), - "yesexpr", "LC_MESSAGES"); - messages->yesexpr = ""; - } - else - messages->yesexpr = code->val.str.start; - break; + now = lr_token (ldfile, charmap, NULL); + nowtok = now->tok; + } + while (nowtok == tok_eol); - case tok_noexpr: - if (code->val.str.start == NULL) - { - lr_error (lr, _("unknown character in field `%s' of category `%s'"), - "noexpr", "LC_MESSAGES"); - messages->noexpr = ""; - } - else - messages->noexpr = code->val.str.start; - break; + /* If we see `copy' now we are almost done. */ + if (nowtok == tok_copy) + { + handle_copy (ldfile, charmap, repertoire, tok_lc_messages, LC_MESSAGES, + "LC_MESSAGES", ignore_content); + return; + } - case tok_yesstr: - if (code->val.str.start == NULL) + /* Prepare the data structures. */ + messages_startup (ldfile, result, ignore_content); + messages = result->categories[LC_MESSAGES].messages; + + while (1) + { + struct token *arg; + + /* Of course we don't proceed beyond the end of file. */ + if (nowtok == tok_eof) + break; + + /* Ingore empty lines. */ + if (nowtok == tok_eol) { - lr_error (lr, _("unknown character in field `%s' of category `%s'"), - "yesstr", "LC_MESSAGES"); - messages->yesstr = ""; + now = lr_token (ldfile, charmap, NULL); + nowtok = now->tok; + continue; } - else - messages->yesstr = code->val.str.start; - break; - case tok_nostr: - if (code->val.str.start == NULL) + switch (nowtok) { - lr_error (lr, _("unknown character in field `%s' of category `%s'"), - "nostr", "LC_MESSAGES"); - messages->nostr = ""; +#define STR_ELEM(cat) \ + case tok_##cat: \ + if (messages->cat != NULL) \ + { \ + lr_error (ldfile, _("\ +%s: field `%s' declared more than once"), "LC_MESSAGES", #cat); \ + lr_ignore_rest (ldfile, 0); \ + break; \ + } \ + now = lr_token (ldfile, charmap, repertoire); \ + if (now->tok != tok_string) \ + goto syntax_error; \ + else if (!ignore_content && now->val.str.startmb == NULL) \ + { \ + lr_error (ldfile, _("\ +%s: unknown character in field `%s'"), "LC_MESSAGES", #cat); \ + messages->cat = ""; \ + } \ + else if (!ignore_content) \ + messages->cat = now->val.str.startmb; \ + break + + STR_ELEM (yesexpr); + STR_ELEM (noexpr); + STR_ELEM (yesstr); + STR_ELEM (nostr); + + case tok_end: + /* Next we assume `LC_MESSAGES'. */ + arg = lr_token (ldfile, charmap, NULL); + if (arg->tok == tok_eof) + break; + if (arg->tok == tok_eol) + lr_error (ldfile, _("%s: incomplete `END' line"), "LC_MESSAGES"); + else if (arg->tok != tok_lc_messages) + lr_error (ldfile, _("\ +%1$s: definition does not end with `END %1$s'"), "LC_MESSAGES"); + lr_ignore_rest (ldfile, arg->tok == tok_lc_messages); + return; + + default: + syntax_error: + SYNTAX_ERROR (_("%s: syntax error"), "LC_MESSAGES"); } - else - messages->nostr = code->val.str.start; - break; - default: - assert (! "unknown token in category `LC_MESSAGES': should not happen"); + /* Prepare for the next round. */ + now = lr_token (ldfile, charmap, NULL); + nowtok = now->tok; } + + /* When we come here we reached the end of the file. */ + lr_error (ldfile, _("%s: premature end of file"), "LC_MESSAGES"); } |