From b9eb05d6bfd4c42c8ea614b77cbc50d95fee51d1 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sun, 12 Sep 1999 08:28:56 +0000 Subject: Update. 1999-09-12 Ulrich Drepper * locale/programs/ld-address.c: Fix handling of non-existing definitions for this category. Correctly ignore content of this category is this is necessary. * locale/programs/ld-collate.c: Likewise. * locale/programs/ld-ctype.c: Likewise. * locale/programs/ld-identification.c: Likewise. * locale/programs/ld-measurement.c: Likewise. * locale/programs/ld-messages.c: Likewise. * locale/programs/ld-monetary.c: Likewise. * locale/programs/ld-name.c: Likewise. * locale/programs/ld-numeric.c: Likewise. * locale/programs/ld-paper.c: Likewise. * locale/programs/ld-telephone.c: Likewise. * locale/programs/ld-time.c: Likewise. * locale/programs/locfile.h (handle_copy): Take extra parameter with result pointer. Fill in name of locale from which to copy. Correctly read token after `END'. * locale/programs/localedef.c (main): Correct handling copy. (add_to_readlist): Take extra parameter which says whether we are supposed to read the file or not. (find_locale): Call add_to_readlist with extra parameter set to 0. * locale/programs/localedef.h (struct localedef_t): Use __LC_LAST instead of wrong number in array definitions. (add_to_readlist): Update prototype. * locale/programs/locfile.c (locfile_read): Mark categories not available in source file as read. (write_all_categories): Fix typo. --- locale/programs/ld-address.c | 77 ++++++++++-- locale/programs/ld-collate.c | 122 +++++++++++++++++-- locale/programs/ld-ctype.c | 126 +++++++++++++++++++- locale/programs/ld-identification.c | 106 +++++++++++++++-- locale/programs/ld-measurement.c | 57 ++++++++- locale/programs/ld-messages.c | 57 ++++++++- locale/programs/ld-monetary.c | 93 +++++++++++++-- locale/programs/ld-name.c | 55 ++++++++- locale/programs/ld-numeric.c | 66 +++++++++-- locale/programs/ld-paper.c | 58 ++++++++- locale/programs/ld-telephone.c | 60 ++++++++-- locale/programs/ld-time.c | 99 ++++++++++++++-- locale/programs/localedef.c | 27 ++++- locale/programs/localedef.h | 9 +- locale/programs/locales.h | 229 ------------------------------------ locale/programs/locfile.c | 19 ++- locale/programs/locfile.h | 31 +++-- 17 files changed, 949 insertions(+), 342 deletions(-) delete mode 100644 locale/programs/locales.h (limited to 'locale/programs') diff --git a/locale/programs/ld-address.c b/locale/programs/ld-address.c index 805330cfaf..49900bd471 100644 --- a/locale/programs/ld-address.c +++ b/locale/programs/ld-address.c @@ -87,8 +87,11 @@ address_startup (struct linereader *lr, struct localedef_t *locale, (struct locale_address_t *) xcalloc (1, sizeof (struct locale_address_t)); - lr->translate_strings = 1; - lr->return_widestr = 0; + if (lr != NULL) + { + lr->translate_strings = 1; + lr->return_widestr = 0; + } } @@ -98,11 +101,45 @@ address_finish (struct localedef_t *locale, struct charmap_t *charmap) struct locale_address_t *address = locale->categories[LC_ADDRESS].address; size_t cnt; int helper; + int nothing = 0; + + /* Now resolve copying and also handle completely missing definitions. */ + if (address == NULL) + { + /* First see whether we were supposed to copy. If yes, find the + actual definition. */ + if (locale->copy_name[LC_ADDRESS] != NULL) + { + /* Find the copying locale. This has to happen transitively since + the locale we are copying from might also copying another one. */ + struct localedef_t *from = locale; + + do + from = find_locale (LC_ADDRESS, from->copy_name[LC_ADDRESS], + from->repertoire_name, charmap); + while (from->categories[LC_ADDRESS].address == NULL + && from->copy_name[LC_ADDRESS] != NULL); + + address = locale->categories[LC_ADDRESS].address + = from->categories[LC_ADDRESS].address; + } + + /* If there is still no definition issue an warning and create an + empty one. */ + if (address == NULL) + { + error (0, 0, _("No definition for %s category found"), "LC_ADDRESS"); + address_startup (NULL, locale, 0); + address = locale->categories[LC_ADDRESS].address; + nothing = 1; + } + } if (address->postal_fmt == NULL) { - error (0, 0, _("%s: field `%s' not defined"), - "LC_ADDRESS", "postal_fmt"); + if (! nothing) + error (0, 0, _("%s: field `%s' not defined"), + "LC_ADDRESS", "postal_fmt"); /* Use as the default value the value of the i18n locale. */ address->postal_fmt = "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N"; } @@ -138,7 +175,7 @@ address_finish (struct localedef_t *locale, struct charmap_t *charmap) #define TEST_ELEM(cat) \ if (address->cat == NULL) \ { \ - if (verbose) \ + if (verbose && ! nothing) \ error (0, 0, _("%s: field `%s' not defined"), "LC_ADDRESS", #cat); \ address->cat = ""; \ } @@ -155,7 +192,7 @@ address_finish (struct localedef_t *locale, struct charmap_t *charmap) helper = 1; if (address->lang_term == NULL) { - if (verbose) + if (verbose && ! nothing) error (0, 0, _("%s: field `%s' not defined"), "LC_ADDRESS", "lang_term"); address->lang_term = ""; @@ -182,7 +219,7 @@ address_finish (struct localedef_t *locale, struct charmap_t *charmap) if (address->lang_ab == NULL) { - if (verbose) + if (verbose && ! nothing) error (0, 0, _("%s: field `%s' not defined"), "LC_ADDRESS", "lang_ab"); address->lang_ab = ""; } @@ -242,7 +279,7 @@ address_finish (struct localedef_t *locale, struct charmap_t *charmap) if (address->country_num == 0) { - if (verbose) + if (verbose && ! nothing) error (0, 0, _("%s: field `%s' not defined"), "LC_ADDRESS", "country_num"); cnt = sizeof (iso3166) / sizeof (iso3166[0]); @@ -262,7 +299,7 @@ address_finish (struct localedef_t *locale, struct charmap_t *charmap) if (address->country_ab2 == NULL) { - if (verbose) + if (verbose && ! nothing) error (0, 0, _("%s: field `%s' not defined"), "LC_ADDRESS", "country_ab2"); address->country_ab2 = " "; @@ -274,7 +311,7 @@ address_finish (struct localedef_t *locale, struct charmap_t *charmap) if (address->country_ab3 == NULL) { - if (verbose) + if (verbose && ! nothing) error (0, 0, _("%s: field `%s' not defined"), "LC_ADDRESS", "country_ab3"); address->country_ab3 = " "; @@ -416,8 +453,8 @@ address_read (struct linereader *ldfile, struct localedef_t *result, /* If we see `copy' now we are almost done. */ if (nowtok == tok_copy) { - handle_copy (ldfile, charmap, repertoire, tok_lc_address, LC_ADDRESS, - "LC_ADDRESS", ignore_content); + handle_copy (ldfile, charmap, repertoire, result, tok_lc_address, + LC_ADDRESS, "LC_ADDRESS", ignore_content); return; } @@ -443,6 +480,14 @@ address_read (struct linereader *ldfile, struct localedef_t *result, { #define STR_ELEM(cat) \ case tok_##cat: \ + /* Ignore the rest of the line if we don't need the input of \ + this line. */ \ + if (ignore_content) \ + { \ + lr_ignore_rest (ldfile, 0); \ + break; \ + } \ + \ arg = lr_token (ldfile, charmap, NULL); \ if (arg->tok != tok_string) \ goto err_label; \ @@ -473,6 +518,14 @@ address_read (struct linereader *ldfile, struct localedef_t *result, #define INT_ELEM(cat) \ case tok_##cat: \ + /* Ignore the rest of the line if we don't need the input of \ + this line. */ \ + if (ignore_content) \ + { \ + lr_ignore_rest (ldfile, 0); \ + break; \ + } \ + \ arg = lr_token (ldfile, charmap, NULL); \ if (arg->tok != tok_number) \ goto err_label; \ diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c index 3c1267420c..20a8776f93 100644 --- a/locale/programs/ld-collate.c +++ b/locale/programs/ld-collate.c @@ -601,6 +601,14 @@ collate_read (struct linereader *ldfile, struct localedef_t *result, switch (nowtok) { case tok_coll_weight_max: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + if (state != 0) goto err_label; @@ -616,6 +624,14 @@ collate_read (struct linereader *ldfile, struct localedef_t *result, break; case tok_section_symbol: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + if (state != 0) goto err_label; @@ -652,6 +668,14 @@ collate_read (struct linereader *ldfile, struct localedef_t *result, break; case tok_collating_element: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + if (state != 0) goto err_label; @@ -732,6 +756,14 @@ error while adding collating element")); break; case tok_collating_symbol: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + if (state != 0) goto err_label; @@ -774,6 +806,14 @@ error while adding collating symbol")); break; case tok_symbol_equivalence: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + if (state != 0) goto err_label; @@ -853,6 +893,14 @@ error while adding equivalent collating symbol")); break; case tok_order_start: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + if (state != 0 && state != 1) goto err_label; state = 1; @@ -933,6 +981,14 @@ error while adding equivalent collating symbol")); break; case tok_order_end: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + if (state != 1) goto err_label; state = 2; @@ -940,6 +996,14 @@ error while adding equivalent collating symbol")); break; case tok_reorder_after: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + if (state != 2 && state != 3) goto err_label; state = 3; @@ -947,6 +1011,11 @@ error while adding equivalent collating symbol")); break; case tok_reorder_end: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + break; + if (state != 3) goto err_label; state = 4; @@ -954,6 +1023,14 @@ error while adding equivalent collating symbol")); break; case tok_bsymbol: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + if (state != 1 && state != 3) goto err_label; @@ -996,12 +1073,28 @@ error while adding equivalent collating symbol")); break; case tok_undefined: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + if (state != 1) goto err_label; /* XXX handle UNDEFINED weight */ break; case tok_ellipsis3: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + if (state != 1 && state != 3) goto err_label; @@ -1012,16 +1105,21 @@ error while adding equivalent collating symbol")); case tok_end: /* Next we assume `LC_COLLATE'. */ - if (state == 0) - /* We must either see a copy statement or have ordering values. */ - lr_error (ldfile, _("%s: empty category description not allowed"), - "LC_COLLATE"); - else if (state == 1) - lr_error (ldfile, _("%s: missing `order_end' keyword"), - "LC_COLLATE"); - else if (state == 3) - error (0, 0, _("%s: missing `reorder-end' keyword"), - "LC_COLLATE"); + if (!ignore_content) + { + if (state == 0) + /* We must either see a copy statement or have + ordering values. */ + lr_error (ldfile, + _("%s: empty category description not allowed"), + "LC_COLLATE"); + else if (state == 1) + lr_error (ldfile, _("%s: missing `order_end' keyword"), + "LC_COLLATE"); + else if (state == 3) + error (0, 0, _("%s: missing `reorder-end' keyword"), + "LC_COLLATE"); + } arg = lr_token (ldfile, charmap, NULL); if (arg->tok == tok_eof) break; @@ -3007,8 +3105,8 @@ read_lc_collate (struct linereader *ldfile, struct localedef_t *result, /* If we see `copy' now we are almost done. */ if (nowtok == tok_copy) { - handle_copy (ldfile, charmap, tok_lc_collate, LC_COLLATE, "LC_COLLATE", - ignore_content); + handle_copy (ldfile, charmap, repertoire, result, tok_lc_collate, + LC_COLLATE, "LC_COLLATE", ignore_content); did_copy = 1; } diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c index 6743c1837c..6dea9d0dd8 100644 --- a/locale/programs/ld-ctype.c +++ b/locale/programs/ld-ctype.c @@ -322,6 +322,37 @@ ctype_finish (struct localedef_t *locale, struct charmap_t *charmap) struct locale_ctype_t *ctype = locale->categories[LC_CTYPE].ctype; int warned; + /* Now resolve copying and also handle completely missing definitions. */ + if (ctype == NULL) + { + /* First see whether we were supposed to copy. If yes, find the + actual definition. */ + if (locale->copy_name[LC_CTYPE] != NULL) + { + /* Find the copying locale. This has to happen transitively since + the locale we are copying from might also copying another one. */ + struct localedef_t *from = locale; + + do + from = find_locale (LC_CTYPE, from->copy_name[LC_CTYPE], + from->repertoire_name, charmap); + while (from->categories[LC_CTYPE].ctype == NULL + && from->copy_name[LC_CTYPE] != NULL); + + ctype = locale->categories[LC_CTYPE].ctype + = from->categories[LC_CTYPE].ctype; + } + + /* If there is still no definition issue an warning and create an + empty one. */ + if (ctype == NULL) + { + error (0, 0, _("No definition for %s category found"), "LC_CTYPE"); + ctype_startup (NULL, locale, charmap, 0); + ctype = locale->categories[LC_CTYPE].ctype; + } + } + /* Set default value for classes not specified. */ set_class_defaults (ctype, charmap, ctype->repertoire); @@ -1732,7 +1763,7 @@ ctype_read (struct linereader *ldfile, struct localedef_t *result, /* If we see `copy' now we are almost done. */ if (nowtok == tok_copy) { - handle_copy (ldfile, charmap, repertoire, tok_lc_ctype, LC_CTYPE, + handle_copy (ldfile, charmap, repertoire, result, tok_lc_ctype, LC_CTYPE, "LC_CTYPE", ignore_content); return; } @@ -1766,6 +1797,14 @@ ctype_read (struct linereader *ldfile, struct localedef_t *result, switch (nowtok) { case tok_class: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + /* We simply forget the `class' keyword and use the following operand to determine the bit. */ now = lr_token (ldfile, charmap, NULL); @@ -1829,6 +1868,14 @@ unknown character class `%s' in category `LC_CTYPE'"), case tok_print: case tok_xdigit: case tok_blank: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + class_bit = BITw (now->tok); class256_bit = BIT (now->tok); handle_digits = 0; @@ -1871,11 +1918,11 @@ unknown character class `%s' in category `LC_CTYPE'"), /* We must store the digit values. */ if (ctype->mbdigits_act == ctype->mbdigits_max) { - ctype->mbdigits_max *= 2; + ctype->mbdigits_max += 10; ctype->mbdigits = xrealloc (ctype->mbdigits, (ctype->mbdigits_max * sizeof (char *))); - ctype->wcdigits_max *= 2; + ctype->wcdigits_max += 10; ctype->wcdigits = xrealloc (ctype->wcdigits, (ctype->wcdigits_max * sizeof (uint32_t))); @@ -1987,6 +2034,11 @@ with character code range values one must use the absolute ellipsis `...'")); break; case tok_digit: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + break; + handle_tok_digit: class_bit = _ISwdigit; class256_bit = _ISdigit; @@ -1994,6 +2046,14 @@ with character code range values one must use the absolute ellipsis `...'")); goto read_charclass; case tok_outdigit: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + if (ctype->outdigits_act != 0) lr_error (ldfile, _("\ %s: field `%s' declared more than once"), @@ -2004,14 +2064,38 @@ with character code range values one must use the absolute ellipsis `...'")); goto read_charclass; case tok_toupper: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + mapidx = 0; goto read_mapping; case tok_tolower: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + mapidx = 1; goto read_mapping; case tok_map: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + /* We simply forget the `map' keyword and use the following operand to determine the mapping. */ now = lr_token (ldfile, charmap, NULL); @@ -2113,6 +2197,14 @@ with character code range values one must use the absolute ellipsis `...'")); break; case tok_translit_start: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + /* The rest of the line better should be empty. */ lr_ignore_rest (ldfile, 1); @@ -2186,6 +2278,14 @@ with character code range values one must use the absolute ellipsis `...'")); break; case tok_ident: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + /* This could mean one of several things. First test whether it's a character class name. */ for (cnt = 0; cnt < ctype->nr_charclass; ++cnt) @@ -2787,6 +2887,26 @@ no output digits defined and none of the standard names in the charmap")); ctype->mboutdigits[cnt]->nbytes = 1; } } + + ctype->wcoutdigits[cnt] = repertoire_find_value (repertoire, + digits + cnt, 1); + + if (ctype->wcoutdigits[cnt] == ILLEGAL_CHAR_VALUE) + { + ctype->wcoutdigits[cnt] = repertoire_find_value (repertoire, + longnames[cnt], + strlen (longnames[cnt])); + + if (ctype->wcoutdigits[cnt] == ILLEGAL_CHAR_VALUE) + { + /* Provide a replacement. */ + error (0, 0, _("\ +no output digits defined and none of the standard names in the repertoire")); + + /* This is better than nothing. */ + ctype->wcoutdigits[cnt] = (uint32_t) digits[cnt]; + } + } } ctype->outdigits_act = 10; diff --git a/locale/programs/ld-identification.c b/locale/programs/ld-identification.c index 79bcd44328..b536ac8070 100644 --- a/locale/programs/ld-identification.c +++ b/locale/programs/ld-identification.c @@ -54,6 +54,24 @@ struct locale_identification_t }; +static const char *category_name[__LC_LAST] = +{ + [LC_CTYPE] = "LC_CTYPE", + [LC_NUMERIC] = "LC_NUMERIC", + [LC_TIME] = "LC_TIME", + [LC_COLLATE] = "LC_COLLATE", + [LC_MONETARY] = "LC_MONETARY", + [LC_MESSAGES] = "LC_MESSAGES", + [LC_ALL] = "LC_ALL", + [LC_PAPER] = "LC_PAPER", + [LC_NAME] = "LC_NAME", + [LC_ADDRESS] = "LC_ADDRESS", + [LC_TELEPHONE] = "LC_TELEPHONE", + [LC_MEASUREMENT] = "LC_MEASUREMENT", + [LC_IDENTIFICATION] = "LC_IDENTIFICATION" +}; + + static void identification_startup (struct linereader *lr, struct localedef_t *locale, int ignore_content) @@ -68,8 +86,11 @@ identification_startup (struct linereader *lr, struct localedef_t *locale, ""; } - lr->translate_strings = 1; - lr->return_widestr = 0; + if (lr != NULL) + { + lr->translate_strings = 1; + lr->return_widestr = 0; + } } @@ -78,11 +99,48 @@ identification_finish (struct localedef_t *locale, struct charmap_t *charmap) { struct locale_identification_t *identification = locale->categories[LC_IDENTIFICATION].identification; + int nothing = 0; + size_t num; + + /* Now resolve copying and also handle completely missing definitions. */ + if (identification == NULL) + { + /* First see whether we were supposed to copy. If yes, find the + actual definition. */ + if (locale->copy_name[LC_IDENTIFICATION] != NULL) + { + /* Find the copying locale. This has to happen transitively since + the locale we are copying from might also copying another one. */ + struct localedef_t *from = locale; + + do + from = find_locale (LC_IDENTIFICATION, + from->copy_name[LC_IDENTIFICATION], + from->repertoire_name, charmap); + while (from->categories[LC_IDENTIFICATION].identification == NULL + && from->copy_name[LC_IDENTIFICATION] != NULL); + + identification = locale->categories[LC_IDENTIFICATION].identification + = from->categories[LC_IDENTIFICATION].identification; + } + + /* If there is still no definition issue an warning and create an + empty one. */ + if (identification == NULL) + { + error (0, 0, _("No definition for %s category found"), + "LC_IDENTIFICATION"); + identification_startup (NULL, locale, 0); + identification + = locale->categories[LC_IDENTIFICATION].identification; + nothing = 1; + } + } #define TEST_ELEM(cat) \ if (identification->cat == NULL) \ { \ - if (verbose) \ + if (verbose && ! nothing) \ error (0, 0, _("%s: field `%s' not defined"), \ "LC_IDENTIFICATION", #cat); \ identification->cat = ""; \ @@ -102,6 +160,15 @@ identification_finish (struct localedef_t *locale, struct charmap_t *charmap) TEST_ELEM (abbreviation); TEST_ELEM (revision); TEST_ELEM (date); + + for (num = 0; num < __LC_LAST; ++num) + if (num != LC_ALL && identification->category[num] == NULL) + { + if (verbose && ! nothing) + error (0, 0, _("%s: no identification for category `%s'"), + "LC_IDENTIFICATION", category_name[num]); + identification->category[num] = ""; + } } @@ -112,7 +179,7 @@ identification_output (struct localedef_t *locale, struct charmap_t *charmap, struct locale_identification_t *identification = locale->categories[LC_IDENTIFICATION].identification; struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION) - + (__LC_LAST - 1)]; + + (__LC_LAST - 2)]; struct locale_file data; uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION)]; size_t cnt = 0; @@ -200,14 +267,15 @@ identification_output (struct localedef_t *locale, struct charmap_t *charmap, idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len; for (num = 0; num < __LC_LAST; ++num) - { - iov[cnt].iov_base = (void *) identification->category[num]; - iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; - ++cnt; - } + if (num != LC_ALL) + { + iov[cnt].iov_base = (void *) identification->category[num]; + iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1; + ++cnt; + } assert (cnt == (2 + _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION) - + (__LC_LAST - 1))); + + (__LC_LAST - 2))); write_locale_data (output_path, "LC_IDENTIFICATION", 2 + _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION), iov); @@ -245,7 +313,7 @@ identification_read (struct linereader *ldfile, struct localedef_t *result, /* If we see `copy' now we are almost done. */ if (nowtok == tok_copy) { - handle_copy (ldfile, charmap, repertoire, tok_lc_identification, + handle_copy (ldfile, charmap, repertoire, result, tok_lc_identification, LC_IDENTIFICATION, "LC_IDENTIFICATION", ignore_content); return; } @@ -272,6 +340,14 @@ identification_read (struct linereader *ldfile, struct localedef_t *result, { #define STR_ELEM(cat) \ case tok_##cat: \ + /* Ignore the rest of the line if we don't need the input of \ + this line. */ \ + if (ignore_content) \ + { \ + lr_ignore_rest (ldfile, 0); \ + break; \ + } \ + \ arg = lr_token (ldfile, charmap, NULL); \ if (arg->tok != tok_string) \ goto err_label; \ @@ -304,6 +380,14 @@ identification_read (struct linereader *ldfile, struct localedef_t *result, STR_ELEM (date); case tok_category: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + /* We expect two operands. */ arg = lr_token (ldfile, charmap, NULL); if (arg->tok != tok_string && arg->tok != tok_ident) diff --git a/locale/programs/ld-measurement.c b/locale/programs/ld-measurement.c index 38a6160b26..610eb5e09c 100644 --- a/locale/programs/ld-measurement.c +++ b/locale/programs/ld-measurement.c @@ -48,8 +48,11 @@ measurement_startup (struct linereader *lr, struct localedef_t *locale, (struct locale_measurement_t *) xcalloc (1, sizeof (struct locale_measurement_t)); - lr->translate_strings = 1; - lr->return_widestr = 0; + if (lr != NULL) + { + lr->translate_strings = 1; + lr->return_widestr = 0; + } } @@ -58,11 +61,47 @@ measurement_finish (struct localedef_t *locale, struct charmap_t *charmap) { struct locale_measurement_t *measurement = locale->categories[LC_MEASUREMENT].measurement; + int nothing = 0; + + /* Now resolve copying and also handle completely missing definitions. */ + if (measurement == NULL) + { + /* First see whether we were supposed to copy. If yes, find the + actual definition. */ + if (locale->copy_name[LC_MEASUREMENT] != NULL) + { + /* Find the copying locale. This has to happen transitively since + the locale we are copying from might also copying another one. */ + struct localedef_t *from = locale; + + do + from = find_locale (LC_MEASUREMENT, + from->copy_name[LC_MEASUREMENT], + from->repertoire_name, charmap); + while (from->categories[LC_MEASUREMENT].measurement == NULL + && from->copy_name[LC_MEASUREMENT] != NULL); + + measurement = locale->categories[LC_MEASUREMENT].measurement + = from->categories[LC_MEASUREMENT].measurement; + } + + /* If there is still no definition issue an warning and create an + empty one. */ + if (measurement == NULL) + { + error (0, 0, _("No definition for %s category found"), + "LC_MEASUREMENT"); + measurement_startup (NULL, locale, 0); + measurement = locale->categories[LC_MEASUREMENT].measurement; + nothing = 1; + } + } if (measurement->measurement == 0) { - error (0, 0, _("%s: field `%s' not defined"), - "LC_MEASUREMENT", "measurement"); + if (! nothing) + error (0, 0, _("%s: field `%s' not defined"), + "LC_MEASUREMENT", "measurement"); /* Use as the default value the value of the i18n locale. */ measurement->measurement = 1; } @@ -137,7 +176,7 @@ measurement_read (struct linereader *ldfile, struct localedef_t *result, /* If we see `copy' now we are almost done. */ if (nowtok == tok_copy) { - handle_copy (ldfile, charmap, repertoire, tok_lc_measurement, + handle_copy (ldfile, charmap, repertoire, result, tok_lc_measurement, LC_MEASUREMENT, "LC_MEASUREMENT", ignore_content); return; } @@ -164,6 +203,14 @@ measurement_read (struct linereader *ldfile, struct localedef_t *result, { #define INT_ELEM(cat) \ case tok_##cat: \ + /* Ignore the rest of the line if we don't need the input of \ + this line. */ \ + if (ignore_content) \ + { \ + lr_ignore_rest (ldfile, 0); \ + break; \ + } \ + \ arg = lr_token (ldfile, charmap, NULL); \ if (arg->tok != tok_number) \ goto err_label; \ diff --git a/locale/programs/ld-messages.c b/locale/programs/ld-messages.c index 33b7735b7d..159c9c7897 100644 --- a/locale/programs/ld-messages.c +++ b/locale/programs/ld-messages.c @@ -54,8 +54,11 @@ messages_startup (struct linereader *lr, struct localedef_t *locale, (struct locale_messages_t *) xcalloc (1, sizeof (struct locale_messages_t)); - lr->translate_strings = 1; - lr->return_widestr = 0; + if (lr != NULL) + { + lr->translate_strings = 1; + lr->return_widestr = 0; + } } @@ -64,6 +67,40 @@ messages_finish (struct localedef_t *locale, struct charmap_t *charmap) { struct locale_messages_t *messages = locale->categories[LC_MESSAGES].messages; + int nothing = 0; + + /* Now resolve copying and also handle completely missing definitions. */ + if (messages == NULL) + { + /* First see whether we were supposed to copy. If yes, find the + actual definition. */ + if (locale->copy_name[LC_MESSAGES] != NULL) + { + /* Find the copying locale. This has to happen transitively since + the locale we are copying from might also copying another one. */ + struct localedef_t *from = locale; + + do + from = find_locale (LC_MESSAGES, from->copy_name[LC_MESSAGES], + from->repertoire_name, charmap); + while (from->categories[LC_MESSAGES].messages == NULL + && from->copy_name[LC_MESSAGES] != NULL); + + messages = locale->categories[LC_MESSAGES].messages + = from->categories[LC_MESSAGES].messages; + } + + /* If there is still no definition issue an warning and create an + empty one. */ + if (messages == NULL) + { + error (0, 0, _("No definition for %s category found"), + "LC_MESSAGES"); + messages_startup (NULL, locale, 0); + messages = locale->categories[LC_MESSAGES].messages; + nothing = 1; + } + } /* The fields YESSTR and NOSTR are optional. */ if (messages->yesstr == NULL) @@ -73,7 +110,7 @@ messages_finish (struct localedef_t *locale, struct charmap_t *charmap) if (messages->yesexpr == NULL) { - if (!be_quiet) + if (! be_quiet && ! nothing) error (0, 0, _("%s: field `%s' undefined"), "LC_MESSAGES", "yesexpr"); messages->yesexpr = ""; } @@ -106,7 +143,7 @@ messages_finish (struct localedef_t *locale, struct charmap_t *charmap) if (messages->noexpr == NULL) { - if (!be_quiet) + if (! be_quiet && ! nothing) error (0, 0, _("%s: field `%s' undefined"), "LC_MESSAGES", "noexpr"); messages->noexpr = ""; } @@ -215,8 +252,8 @@ messages_read (struct linereader *ldfile, struct localedef_t *result, /* 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); + handle_copy (ldfile, charmap, repertoire, result, tok_lc_messages, + LC_MESSAGES, "LC_MESSAGES", ignore_content); return; } @@ -244,6 +281,14 @@ messages_read (struct linereader *ldfile, struct localedef_t *result, { #define STR_ELEM(cat) \ case tok_##cat: \ + /* Ignore the rest of the line if we don't need the input of \ + this line. */ \ + if (ignore_content) \ + { \ + lr_ignore_rest (ldfile, 0); \ + break; \ + } \ + \ if (messages->cat != NULL) \ { \ lr_error (ldfile, _("\ diff --git a/locale/programs/ld-monetary.c b/locale/programs/ld-monetary.c index 61f9f8dc6c..a6dd3ac7b4 100644 --- a/locale/programs/ld-monetary.c +++ b/locale/programs/ld-monetary.c @@ -148,8 +148,11 @@ monetary_startup (struct linereader *lr, struct localedef_t *locale, monetary->duo_int_n_sign_posn = -2; } - lr->translate_strings = 1; - lr->return_widestr = 0; + if (lr != NULL) + { + lr->translate_strings = 1; + lr->return_widestr = 0; + } } @@ -158,12 +161,47 @@ monetary_finish (struct localedef_t *locale, struct charmap_t *charmap) { struct locale_monetary_t *monetary = locale->categories[LC_MONETARY].monetary; + int nothing = 0; + + /* Now resolve copying and also handle completely missing definitions. */ + if (monetary == NULL) + { + /* First see whether we were supposed to copy. If yes, find the + actual definition. */ + if (locale->copy_name[LC_MONETARY] != NULL) + { + /* Find the copying locale. This has to happen transitively since + the locale we are copying from might also copying another one. */ + struct localedef_t *from = locale; + + do + from = find_locale (LC_MONETARY, from->copy_name[LC_MONETARY], + from->repertoire_name, charmap); + while (from->categories[LC_MONETARY].monetary == NULL + && from->copy_name[LC_MONETARY] != NULL); + + monetary = locale->categories[LC_MONETARY].monetary + = from->categories[LC_MONETARY].monetary; + } + + /* If there is still no definition issue an warning and create an + empty one. */ + if (monetary == NULL) + { + error (0, 0, _("No definition for %s category found"), + "LC_MONETARY"); + monetary_startup (NULL, locale, 0); + monetary = locale->categories[LC_MONETARY].monetary; + nothing = 1; + } + } #define TEST_ELEM(cat) \ if (monetary->cat == NULL && !be_quiet) \ { \ - error (0, 0, _("%s: field `%s' not defined"), \ - "LC_MONETARY", #cat); \ + if (! nothing) \ + error (0, 0, _("%s: field `%s' not defined"), \ + "LC_MONETARY", #cat); \ monetary->cat = ""; \ } @@ -197,20 +235,20 @@ not correspond to a valid name in ISO 4217"), /* The decimal point must not be empty. This is not said explicitly in POSIX but ANSI C (ISO/IEC 9899) says in 4.4.2.1 it has to be != "". */ - if (monetary->mon_decimal_point[0] == '\0' && !be_quiet) + if (monetary->mon_decimal_point[0] == '\0' && ! be_quiet && ! nothing) { error (0, 0, _("\ %s: value for field `%s' must not be the empty string"), "LC_MONETARY", "mon_decimal_point"); } - if (monetary->mon_grouping_len == 0 && !be_quiet) + if (monetary->mon_grouping_len == 0 && ! be_quiet && ! nothing) error (0, 0, _("%s: field `%s' not defined"), "LC_MONETARY", "mon_grouping"); #undef TEST_ELEM #define TEST_ELEM(cat, min, max) \ - if (monetary->cat == -2 && !be_quiet) \ + if (monetary->cat == -2 && ! be_quiet && ! nothing) \ error (0, 0, _("%s: field `%s' not defined"), \ "LC_MONETARY", #cat); \ else if ((monetary->cat < min || monetary->cat > max) && !be_quiet) \ @@ -244,9 +282,10 @@ not correspond to a valid name in ISO 4217"), #undef TEST_ELEM #define TEST_ELEM(cat, alt, min, max) \ - if (monetary->cat == -2 && !be_quiet) \ + if (monetary->cat == -2) \ monetary->cat = monetary->alt; \ - else if ((monetary->cat < min || monetary->cat > max) && !be_quiet) \ + else if ((monetary->cat < min || monetary->cat > max) && !be_quiet \ + && ! nothing) \ error (0, 0, _("\ %s: value for field `%s' must be in range %d...%d"), \ "LC_MONETARY", #cat, min, max) @@ -577,8 +616,8 @@ monetary_read (struct linereader *ldfile, struct localedef_t *result, /* If we see `copy' now we are almost done. */ if (nowtok == tok_copy) { - handle_copy (ldfile, charmap, repertoire, tok_lc_monetary, LC_MONETARY, - "LC_MONETARY", ignore_content); + handle_copy (ldfile, charmap, repertoire, result, tok_lc_monetary, + LC_MONETARY, "LC_MONETARY", ignore_content); return; } @@ -604,6 +643,14 @@ monetary_read (struct linereader *ldfile, struct localedef_t *result, { #define STR_ELEM(cat) \ case tok_##cat: \ + /* Ignore the rest of the line if we don't need the input of \ + this line. */ \ + if (ignore_content) \ + { \ + lr_ignore_rest (ldfile, 0); \ + break; \ + } \ + \ now = lr_token (ldfile, charmap, NULL); \ if (now->tok != tok_string) \ goto err_label; \ @@ -632,6 +679,14 @@ monetary_read (struct linereader *ldfile, struct localedef_t *result, #define INT_ELEM(cat) \ case tok_##cat: \ + /* Ignore the rest of the line if we don't need the input of \ + this line. */ \ + if (ignore_content) \ + { \ + lr_ignore_rest (ldfile, 0); \ + break; \ + } \ + \ now = lr_token (ldfile, charmap, NULL); \ if (now->tok != tok_minus1 && now->tok != tok_number) \ goto err_label; \ @@ -676,6 +731,14 @@ monetary_read (struct linereader *ldfile, struct localedef_t *result, INT_ELEM (duo_valid_to); case tok_mon_grouping: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + now = lr_token (ldfile, charmap, NULL); if (now->tok != tok_minus1 && now->tok != tok_number) goto err_label; @@ -746,6 +809,14 @@ monetary_read (struct linereader *ldfile, struct localedef_t *result, break; case tok_conversion_rate: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + now = lr_token (ldfile, charmap, NULL); if (now->tok != tok_number) goto err_label; diff --git a/locale/programs/ld-name.c b/locale/programs/ld-name.c index 85acb413ec..4ab0916373 100644 --- a/locale/programs/ld-name.c +++ b/locale/programs/ld-name.c @@ -51,8 +51,11 @@ name_startup (struct linereader *lr, struct localedef_t *locale, locale->categories[LC_NAME].name = (struct locale_name_t *) xcalloc (1, sizeof (struct locale_name_t)); - lr->translate_strings = 1; - lr->return_widestr = 0; + if (lr != NULL) + { + lr->translate_strings = 1; + lr->return_widestr = 0; + } } @@ -60,10 +63,44 @@ void name_finish (struct localedef_t *locale, struct charmap_t *charmap) { struct locale_name_t *name = locale->categories[LC_NAME].name; + int nothing = 0; + + /* Now resolve copying and also handle completely missing definitions. */ + if (name == NULL) + { + /* First see whether we were supposed to copy. If yes, find the + actual definition. */ + if (locale->copy_name[LC_NAME] != NULL) + { + /* Find the copying locale. This has to happen transitively since + the locale we are copying from might also copying another one. */ + struct localedef_t *from = locale; + + do + from = find_locale (LC_NAME, from->copy_name[LC_NAME], + from->repertoire_name, charmap); + while (from->categories[LC_NAME].name == NULL + && from->copy_name[LC_NAME] != NULL); + + name = locale->categories[LC_NAME].name + = from->categories[LC_NAME].name; + } + + /* If there is still no definition issue an warning and create an + empty one. */ + if (name == NULL) + { + error (0, 0, _("No definition for %s category found"), "LC_NAME"); + name_startup (NULL, locale, 0); + name = locale->categories[LC_NAME].name; + nothing = 1; + } + } if (name->name_fmt == NULL) { - error (0, 0, _("%s: field `%s' not defined"), "LC_NAME", "name_fmt"); + if (! nothing) + error (0, 0, _("%s: field `%s' not defined"), "LC_NAME", "name_fmt"); /* Use as the default value the value of the i18n locale. */ name->name_fmt = "%p%t%g%t%m%t%f"; } @@ -99,7 +136,7 @@ name_finish (struct localedef_t *locale, struct charmap_t *charmap) #define TEST_ELEM(cat) \ if (name->cat == NULL) \ { \ - if (verbose) \ + if (verbose && ! nothing) \ error (0, 0, _("%s: field `%s' not defined"), "LC_NAME", #cat); \ name->cat = ""; \ } @@ -198,7 +235,7 @@ name_read (struct linereader *ldfile, struct localedef_t *result, /* If we see `copy' now we are almost done. */ if (nowtok == tok_copy) { - handle_copy (ldfile, charmap, repertoire, tok_lc_name, LC_NAME, + handle_copy (ldfile, charmap, repertoire, result, tok_lc_name, LC_NAME, "LC_NAME", ignore_content); return; } @@ -225,6 +262,14 @@ name_read (struct linereader *ldfile, struct localedef_t *result, { #define STR_ELEM(cat) \ case tok_##cat: \ + /* Ignore the rest of the line if we don't need the input of \ + this line. */ \ + if (ignore_content) \ + { \ + lr_ignore_rest (ldfile, 0); \ + break; \ + } \ + \ arg = lr_token (ldfile, charmap, NULL); \ if (arg->tok != tok_string) \ goto err_label; \ diff --git a/locale/programs/ld-numeric.c b/locale/programs/ld-numeric.c index 3e51aba7e2..697ad35bb9 100644 --- a/locale/programs/ld-numeric.c +++ b/locale/programs/ld-numeric.c @@ -58,8 +58,11 @@ numeric_startup (struct linereader *lr, struct localedef_t *locale, numeric->grouping_len = 0; } - lr->translate_strings = 1; - lr->return_widestr = 0; + if (lr != NULL) + { + lr->translate_strings = 1; + lr->return_widestr = 0; + } } @@ -67,9 +70,42 @@ void numeric_finish (struct localedef_t *locale, struct charmap_t *charmap) { struct locale_numeric_t *numeric = locale->categories[LC_NUMERIC].numeric; + int nothing = 0; + + /* Now resolve copying and also handle completely missing definitions. */ + if (numeric == NULL) + { + /* First see whether we were supposed to copy. If yes, find the + actual definition. */ + if (locale->copy_name[LC_NUMERIC] != NULL) + { + /* Find the copying locale. This has to happen transitively since + the locale we are copying from might also copying another one. */ + struct localedef_t *from = locale; + + do + from = find_locale (LC_NUMERIC, from->copy_name[LC_NUMERIC], + from->repertoire_name, charmap); + while (from->categories[LC_NUMERIC].numeric == NULL + && from->copy_name[LC_NUMERIC] != NULL); + + numeric = locale->categories[LC_NUMERIC].numeric + = from->categories[LC_NUMERIC].numeric; + } + + /* If there is still no definition issue an warning and create an + empty one. */ + if (numeric == NULL) + { + error (0, 0, _("No definition for %s category found"), "LC_NUMERIC"); + numeric_startup (NULL, locale, 0); + numeric = locale->categories[LC_NUMERIC].numeric; + nothing = 1; + } + } #define TEST_ELEM(cat) \ - if (numeric->cat == NULL && !be_quiet) \ + if (numeric->cat == NULL && ! be_quiet && ! nothing) \ error (0, 0, _("%s: field `%s' not defined"), "LC_NUMERIC", #cat) TEST_ELEM (decimal_point); @@ -78,14 +114,14 @@ numeric_finish (struct localedef_t *locale, struct charmap_t *charmap) /* The decimal point must not be empty. This is not said explicitly in POSIX but ANSI C (ISO/IEC 9899) says in 4.4.2.1 it has to be != "". */ - if (numeric->decimal_point[0] == '\0' && !be_quiet) + if (numeric->decimal_point[0] == '\0' && ! be_quiet && ! nothing) { error (0, 0, _("\ %s: value for field `%s' must not be the empty string"), "LC_NUMERIC", "decimal_point"); } - if (numeric->grouping_len == 0 && !be_quiet) + if (numeric->grouping_len == 0 && ! be_quiet && ! nothing) error (0, 0, _("%s: field `%s' not defined"), "LC_NUMERIC", "grouping"); } @@ -160,8 +196,8 @@ numeric_read (struct linereader *ldfile, struct localedef_t *result, /* If we see `copy' now we are almost done. */ if (nowtok == tok_copy) { - handle_copy (ldfile, charmap, repertoire, tok_lc_numeric, LC_NUMERIC, - "LC_NUMERIC", ignore_content); + handle_copy (ldfile, charmap, repertoire, result, tok_lc_numeric, + LC_NUMERIC, "LC_NUMERIC", ignore_content); return; } @@ -187,6 +223,14 @@ numeric_read (struct linereader *ldfile, struct localedef_t *result, { #define STR_ELEM(cat) \ case tok_##cat: \ + /* Ignore the rest of the line if we don't need the input of \ + this line. */ \ + if (ignore_content) \ + { \ + lr_ignore_rest (ldfile, 0); \ + break; \ + } \ + \ now = lr_token (ldfile, charmap, NULL); \ if (now->tok != tok_string) \ goto err_label; \ @@ -207,6 +251,14 @@ numeric_read (struct linereader *ldfile, struct localedef_t *result, STR_ELEM (thousands_sep); case tok_grouping: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + now = lr_token (ldfile, charmap, NULL); if (now->tok != tok_minus1 && now->tok != tok_number) goto err_label; diff --git a/locale/programs/ld-paper.c b/locale/programs/ld-paper.c index 5d834eb1bd..642ca41380 100644 --- a/locale/programs/ld-paper.c +++ b/locale/programs/ld-paper.c @@ -51,8 +51,11 @@ paper_startup (struct linereader *lr, struct localedef_t *locale, locale->categories[LC_PAPER].paper = (struct locale_paper_t *) xcalloc (1, sizeof (struct locale_paper_t)); - lr->translate_strings = 1; - lr->return_widestr = 0; + if (lr != NULL) + { + lr->translate_strings = 1; + lr->return_widestr = 0; + } } @@ -60,10 +63,44 @@ void paper_finish (struct localedef_t *locale, struct charmap_t *charmap) { struct locale_paper_t *paper = locale->categories[LC_PAPER].paper; + int nothing = 0; + + /* Now resolve copying and also handle completely missing definitions. */ + if (paper == NULL) + { + /* First see whether we were supposed to copy. If yes, find the + actual definition. */ + if (locale->copy_name[LC_PAPER] != NULL) + { + /* Find the copying locale. This has to happen transitively since + the locale we are copying from might also copying another one. */ + struct localedef_t *from = locale; + + do + from = find_locale (LC_PAPER, from->copy_name[LC_PAPER], + from->repertoire_name, charmap); + while (from->categories[LC_PAPER].paper == NULL + && from->copy_name[LC_PAPER] != NULL); + + paper = locale->categories[LC_PAPER].paper + = from->categories[LC_PAPER].paper; + } + + /* If there is still no definition issue an warning and create an + empty one. */ + if (paper == NULL) + { + error (0, 0, _("No definition for %s category found"), "LC_PAPER"); + paper_startup (NULL, locale, 0); + paper = locale->categories[LC_PAPER].paper; + nothing = 1; + } + } if (paper->height == 0) { - error (0, 0, _("%s: field `%s' not defined"), "LC_PAPER", "height"); + if (! nothing) + error (0, 0, _("%s: field `%s' not defined"), "LC_PAPER", "height"); /* Use as default values the values from the i18n locale. */ paper->height = 297; } @@ -71,7 +108,8 @@ paper_finish (struct localedef_t *locale, struct charmap_t *charmap) if (paper->width == 0) { - error (0, 0, _("%s: field `%s' not defined"), "LC_PAPER", "width"); + if (! nothing) + error (0, 0, _("%s: field `%s' not defined"), "LC_PAPER", "width"); /* Use as default values the values from the i18n locale. */ paper->width = 210; } @@ -167,8 +205,8 @@ paper_read (struct linereader *ldfile, struct localedef_t *result, /* If we see `copy' now we are almost done. */ if (nowtok == tok_copy) { - handle_copy (ldfile, charmap, repertoire, tok_lc_paper, LC_PAPER, - "LC_PAPER", ignore_content); + handle_copy (ldfile, charmap, repertoire, result, tok_lc_paper, + LC_PAPER, "LC_PAPER", ignore_content); return; } @@ -194,6 +232,14 @@ paper_read (struct linereader *ldfile, struct localedef_t *result, { #define INT_ELEM(cat) \ case tok_##cat: \ + /* Ignore the rest of the line if we don't need the input of \ + this line. */ \ + if (ignore_content) \ + { \ + lr_ignore_rest (ldfile, 0); \ + break; \ + } \ + \ arg = lr_token (ldfile, charmap, NULL); \ if (arg->tok != tok_number) \ goto err_label; \ diff --git a/locale/programs/ld-telephone.c b/locale/programs/ld-telephone.c index 2d75fea6b6..5d2ea490ad 100644 --- a/locale/programs/ld-telephone.c +++ b/locale/programs/ld-telephone.c @@ -50,8 +50,11 @@ telephone_startup (struct linereader *lr, struct localedef_t *locale, locale->categories[LC_TELEPHONE].telephone = (struct locale_telephone_t *) xcalloc (1, sizeof (struct locale_telephone_t)); - lr->translate_strings = 1; - lr->return_widestr = 0; + if (lr != NULL) + { + lr->translate_strings = 1; + lr->return_widestr = 0; + } } @@ -60,11 +63,46 @@ telephone_finish (struct localedef_t *locale, struct charmap_t *charmap) { struct locale_telephone_t *telephone = locale->categories[LC_TELEPHONE].telephone; + int nothing = 0; + + /* Now resolve copying and also handle completely missing definitions. */ + if (telephone == NULL) + { + /* First see whether we were supposed to copy. If yes, find the + actual definition. */ + if (locale->copy_name[LC_TELEPHONE] != NULL) + { + /* Find the copying locale. This has to happen transitively since + the locale we are copying from might also copying another one. */ + struct localedef_t *from = locale; + + do + from = find_locale (LC_TELEPHONE, from->copy_name[LC_TELEPHONE], + from->repertoire_name, charmap); + while (from->categories[LC_TELEPHONE].telephone == NULL + && from->copy_name[LC_TELEPHONE] != NULL); + + telephone = locale->categories[LC_TELEPHONE].telephone + = from->categories[LC_TELEPHONE].telephone; + } + + /* If there is still no definition issue an warning and create an + empty one. */ + if (telephone == NULL) + { + error (0, 0, _("No definition for %s category found"), + "LC_TELEPHONE"); + telephone_startup (NULL, locale, 0); + telephone = locale->categories[LC_TELEPHONE].telephone; + nothing = 1; + } + } if (telephone->tel_int_fmt == NULL) { - error (0, 0, _("%s: field `%s' not defined"), - "LC_TELEPHONE", "tel_int_fmt"); + if (! nothing) + error (0, 0, _("%s: field `%s' not defined"), + "LC_TELEPHONE", "tel_int_fmt"); /* Use as the default value the value of the i18n locale. */ telephone->tel_int_fmt = "+%c %a %l"; } @@ -120,7 +158,7 @@ telephone_finish (struct localedef_t *locale, struct charmap_t *charmap) #define TEST_ELEM(cat) \ if (telephone->cat == NULL) \ { \ - if (verbose) \ + if (verbose && ! nothing) \ error (0, 0, _("%s: field `%s' not defined"), "LC_TELEPHONE", #cat); \ telephone->cat = ""; \ } @@ -207,8 +245,8 @@ telephone_read (struct linereader *ldfile, struct localedef_t *result, /* If we see `copy' now we are almost done. */ if (nowtok == tok_copy) { - handle_copy (ldfile, charmap, repertoire, tok_lc_telephone, LC_TELEPHONE, - "LC_TELEPHONE", ignore_content); + handle_copy (ldfile, charmap, repertoire, result, tok_lc_telephone, + LC_TELEPHONE, "LC_TELEPHONE", ignore_content); return; } @@ -234,6 +272,14 @@ telephone_read (struct linereader *ldfile, struct localedef_t *result, { #define STR_ELEM(cat) \ case tok_##cat: \ + /* Ignore the rest of the line if we don't need the input of \ + this line. */ \ + if (ignore_content) \ + { \ + lr_ignore_rest (ldfile, 0); \ + break; \ + } \ + \ arg = lr_token (ldfile, charmap, NULL); \ if (arg->tok != tok_string) \ goto err_label; \ diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c index bae38fcaea..88d98e2c21 100644 --- a/locale/programs/ld-time.c +++ b/locale/programs/ld-time.c @@ -131,8 +131,11 @@ time_startup (struct linereader *lr, struct localedef_t *locale, locale->categories[LC_TIME].time = (struct locale_time_t *) xcalloc (1, sizeof (struct locale_time_t)); - lr->translate_strings = 1; - lr->return_widestr = 0; + if (time != NULL) + { + lr->translate_strings = 1; + lr->return_widestr = 0; + } } @@ -141,10 +144,46 @@ time_finish (struct localedef_t *locale, struct charmap_t *charmap) { struct locale_time_t *time = locale->categories[LC_TIME].time; size_t cnt; + int nothing = 0; + + /* Now resolve copying and also handle completely missing definitions. */ + if (time == NULL) + { + /* First see whether we were supposed to copy. If yes, find the + actual definition. */ + if (locale->copy_name[LC_TIME] != NULL) + { + /* Find the copying locale. This has to happen transitively since + the locale we are copying from might also copying another one. */ + struct localedef_t *from = locale; + + do + from = find_locale (LC_TIME, from->copy_name[LC_TIME], + from->repertoire_name, charmap); + while (from->categories[LC_TIME].time == NULL + && from->copy_name[LC_TIME] != NULL); + + time = locale->categories[LC_TIME].time + = from->categories[LC_TIME].time; + } + + /* If there is still no definition issue an warning and create an + empty one. */ + if (time == NULL) + { + error (0, 0, _("No definition for %s category found"), "LC_TIME"); + time_startup (NULL, locale, 0); + time = locale->categories[LC_TIME].time; + nothing = 1; + } + } #define TESTARR_ELEM(cat) \ - if (!time->cat##_defined && !be_quiet) \ - error (0, 0, _("%s: field `%s' not defined"), "LC_TIME", #cat); \ + if (!time->cat##_defined) \ + { \ + if(! be_quiet && ! nothing) \ + error (0, 0, _("%s: field `%s' not defined"), "LC_TIME", #cat); \ + } \ else if (time->w##cat != NULL) \ { \ size_t n; \ @@ -169,8 +208,11 @@ time_finish (struct localedef_t *locale, struct charmap_t *charmap) TESTARR_ELEM (am_pm); #define TEST_ELEM(cat) \ - if (time->cat == NULL && !be_quiet) \ - error (0, 0, _("%s: field `%s' not defined"), "LC_TIME", #cat); \ + if (time->cat == NULL) \ + { \ + if (! be_quiet && ! nothing) \ + error (0, 0, _("%s: field `%s' not defined"), "LC_TIME", #cat); \ + } \ else if (time->w##cat != NULL) \ { \ size_t len = wcslen ((wchar_t *) time->w##cat) + 1; \ @@ -1154,7 +1196,6 @@ time_output (struct localedef_t *locale, struct charmap_t *charmap, iov[2 + cnt].iov_base = (void *) time->timezone; iov[2 + cnt].iov_len = strlen (time->timezone) + 1; - idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len; ++cnt; ++last_idx; @@ -1198,8 +1239,8 @@ time_read (struct linereader *ldfile, struct localedef_t *result, /* If we see `copy' now we are almost done. */ if (nowtok == tok_copy) { - handle_copy (ldfile, charmap, repertoire, tok_lc_time, LC_TIME, - "LC_TIME", ignore_content); + handle_copy (ldfile, charmap, repertoire, result, tok_lc_time, + LC_TIME, "LC_TIME", ignore_content); return; } @@ -1225,6 +1266,14 @@ time_read (struct linereader *ldfile, struct localedef_t *result, { #define STRARR_ELEM(cat, min, max) \ case tok_##cat: \ + /* Ignore the rest of the line if we don't need the input of \ + this line. */ \ + if (ignore_content) \ + { \ + lr_ignore_rest (ldfile, 0); \ + break; \ + } \ + \ for (cnt = 0; cnt < max; ++cnt) \ { \ now = lr_token (ldfile, charmap, repertoire); \ @@ -1300,6 +1349,14 @@ time_read (struct linereader *ldfile, struct localedef_t *result, STRARR_ELEM (alt_digits, 0, 100); case tok_era: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + do { now = lr_token (ldfile, charmap, NULL); @@ -1335,6 +1392,14 @@ time_read (struct linereader *ldfile, struct localedef_t *result, #define STR_ELEM(cat) \ case tok_##cat: \ + /* Ignore the rest of the line if we don't need the input of \ + this line. */ \ + if (ignore_content) \ + { \ + lr_ignore_rest (ldfile, 0); \ + break; \ + } \ + \ now = lr_token (ldfile, charmap, NULL); \ if (now->tok != tok_string) \ goto err_label; \ @@ -1368,6 +1433,14 @@ time_read (struct linereader *ldfile, struct localedef_t *result, #define INT_ELEM(cat) \ case tok_##cat: \ + /* Ignore the rest of the line if we don't need the input of \ + this line. */ \ + if (ignore_content) \ + { \ + lr_ignore_rest (ldfile, 0); \ + break; \ + } \ + \ now = lr_token (ldfile, charmap, NULL); \ if (now->tok != tok_number) \ goto err_label; \ @@ -1383,6 +1456,14 @@ time_read (struct linereader *ldfile, struct localedef_t *result, INT_ELEM (cal_direction); case tok_week: + /* Ignore the rest of the line if we don't need the input of + this line. */ + if (ignore_content) + { + lr_ignore_rest (ldfile, 0); + break; + } + now = lr_token (ldfile, charmap, NULL); if (now->tok != tok_number) goto err_label; diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c index 5eadbf3570..4fe3a28943 100644 --- a/locale/programs/localedef.c +++ b/locale/programs/localedef.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -134,6 +135,9 @@ main (int argc, char *argv[]) struct localedef_t global; int remaining; + /* Enable `malloc' debugging. */ + mcheck (NULL); + /* Set initial values for global variables. */ copy_list = NULL; posix_conformance = getenv ("POSIXLY_CORRECT") != NULL; @@ -196,7 +200,7 @@ main (int argc, char *argv[]) { struct localedef_t *runp = locales; - while (runp != NULL && runp->needed == runp->avail) + while (runp != NULL && (runp->needed & runp->avail) == runp->needed) runp = runp->next; if (runp == NULL) @@ -429,7 +433,8 @@ normalize_codeset (codeset, name_len) struct localedef_t * -add_to_readlist (int locale, const char *name, const char *repertoire_name) +add_to_readlist (int locale, const char *name, const char *repertoire_name, + int generate) { struct localedef_t *runp = locales; @@ -439,7 +444,11 @@ add_to_readlist (int locale, const char *name, const char *repertoire_name) if (runp == NULL) { /* Add a new entry at the end. */ - struct localedef_t *newp = xcalloc (1, sizeof (struct localedef_t)); + struct localedef_t *newp; + + assert (generate == 1); + + newp = xcalloc (1, sizeof (struct localedef_t)); newp->name = name; newp->repertoire_name = repertoire_name; @@ -454,7 +463,7 @@ add_to_readlist (int locale, const char *name, const char *repertoire_name) } } - if ((runp->needed & (1 << locale)) != 0) + if (generate && (runp->needed & (1 << locale)) != 0) error (5, 0, _("circular dependencies between locale definitions")); runp->needed |= 1 << locale; @@ -467,9 +476,15 @@ struct localedef_t * find_locale (int locale, const char *name, const char *repertoire_name, struct charmap_t *charmap) { - struct localedef_t *result = add_to_readlist (locale, name, repertoire_name); + struct localedef_t *result; + + /* Find the locale, but do not generate it since this would be a bug. */ + result = add_to_readlist (locale, name, repertoire_name, 0); + + assert (result != NULL); - if (locfile_read (result, charmap) != 0) + if ((result->avail & (1 << locale)) == 0 + && locfile_read (result, charmap) != 0) error (4, errno, _("cannot open locale definition file `%s'"), result->name); diff --git a/locale/programs/localedef.h b/locale/programs/localedef.h index 075cf8982f..31721c5353 100644 --- a/locale/programs/localedef.h +++ b/locale/programs/localedef.h @@ -98,9 +98,11 @@ struct localedef_t struct locale_telephone_t *telephone; struct locale_measurement_t *measurement; struct locale_identification_t *identification; - } categories[12]; + } categories[__LC_LAST]; - size_t len[12]; + size_t len[__LC_LAST]; + + const char *copy_name[__LC_LAST]; const char *repertoire_name; }; @@ -121,7 +123,8 @@ extern char *xstrdup (const char *__str); /* Mark given locale as to be read. */ extern struct localedef_t *add_to_readlist (int locale, const char *name, - const char *repertoire_name); + const char *repertoire_name, + int generate); /* Find the information for the locale NAME. */ extern struct localedef_t *find_locale (int locale, const char *name, diff --git a/locale/programs/locales.h b/locale/programs/locales.h deleted file mode 100644 index 1cd3a3f92e..0000000000 --- a/locale/programs/locales.h +++ /dev/null @@ -1,229 +0,0 @@ -/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 1996. - - 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 - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABIL