diff options
Diffstat (limited to 'locale')
-rw-r--r-- | locale/programs/ld-address.c | 77 | ||||
-rw-r--r-- | locale/programs/ld-collate.c | 122 | ||||
-rw-r--r-- | locale/programs/ld-ctype.c | 126 | ||||
-rw-r--r-- | locale/programs/ld-identification.c | 106 | ||||
-rw-r--r-- | locale/programs/ld-measurement.c | 57 | ||||
-rw-r--r-- | locale/programs/ld-messages.c | 57 | ||||
-rw-r--r-- | locale/programs/ld-monetary.c | 93 | ||||
-rw-r--r-- | locale/programs/ld-name.c | 55 | ||||
-rw-r--r-- | locale/programs/ld-numeric.c | 66 | ||||
-rw-r--r-- | locale/programs/ld-paper.c | 58 | ||||
-rw-r--r-- | locale/programs/ld-telephone.c | 60 | ||||
-rw-r--r-- | locale/programs/ld-time.c | 99 | ||||
-rw-r--r-- | locale/programs/localedef.c | 27 | ||||
-rw-r--r-- | locale/programs/localedef.h | 9 | ||||
-rw-r--r-- | locale/programs/locales.h | 229 | ||||
-rw-r--r-- | locale/programs/locfile.c | 19 | ||||
-rw-r--r-- | locale/programs/locfile.h | 31 |
17 files changed, 949 insertions, 342 deletions
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 <fcntl.h> #include <libintl.h> #include <locale.h> +#include <mcheck.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -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 <drepper@gnu.ai.mit.edu>, 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 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#ifndef _LOCALES_H -#define _LOCALES_H - -#include <ctype.h> - -/* Undefine following line in production version. */ -/* #define NDEBUG 1 */ -#include <assert.h> - -#include "linereader.h" -#include "locfile-token.h" -#include "charset.h" -#include "locfile.h" -#include "localeinfo.h" - - -/* List of locale definition files which are used in `copy' instructions. */ -struct copy_def_list_t -{ - struct copy_def_list_t *next; - - const char *name; - int mask; - - struct localedef_t *locale; - - struct - { - void *data; - size_t len; - } binary[6]; -}; - -extern struct copy_def_list_t copy_posix; - - -/* Header of the locale data files. */ -struct locale_file -{ - int magic; - int n; -}; - - -/* Handle LC_CTYPE category. */ - -static inline unsigned int -charclass_to_bit (enum token_t tok) -{ - static unsigned int lastbit = _ISalnum; - - switch (tok) - { -#define CLASS(name) case tok_##name: return _IS##name - CLASS (upper); - CLASS (lower); - CLASS (alpha); - CLASS (digit); - CLASS (alnum); - CLASS (space); - CLASS (cntrl); - CLASS (punct); - CLASS (graph); - CLASS (print); - CLASS (xdigit); - CLASS (blank); -#undef CLASS - case tok_string: - lastbit <<= 1; - if (lastbit == 0ul) - /* Exit status 2 means a limitation in the implementation is - exceeded. */ - error (2, 0, _("too many character classes defined")); - return lastbit; - default: - assert (1 == 0); - } - return 0; -} - -/* Remember name of newly created charclass. */ -void ctype_startup (struct linereader *lr, struct localedef_t *locale, - struct charset_t *charset); -void ctype_finish (struct localedef_t *locale, struct charset_t *charset); - -void ctype_output (struct localedef_t *locale, struct charset_t *charset, - const char *output_path); - -int ctype_is_charclass (struct linereader *lr, struct localedef_t *locale, - const char *name); -void ctype_class_new (struct linereader *lr, struct localedef_t *locale, - enum token_t tok, struct token *code, - struct charset_t *charset); -void ctype_class_start (struct linereader *lr, struct localedef_t *locale, - enum token_t tok, const char *name, - struct charset_t *charset); -void ctype_class_from (struct linereader *lr, struct localedef_t *locale, - struct token *code, struct charset_t *charset); -void ctype_class_to (struct linereader *lr, struct localedef_t *locale, - struct token *code, struct charset_t *charset); -void ctype_class_end (struct linereader *lr, struct localedef_t *locale); - -int ctype_is_charconv (struct linereader *lr, struct localedef_t *locale, - const char *name); -void ctype_map_new (struct linereader *lr, struct localedef_t *locale, - enum token_t tok, struct token *code, - struct charset_t *charset); -void ctype_map_start (struct linereader *lr, struct localedef_t *locale, - enum token_t tok, const char *name, - struct charset_t *charset); -void ctype_map_from (struct linereader *lr, struct localedef_t *locale, - struct token *code, struct charset_t *charset); -void ctype_map_to (struct linereader *lr, struct localedef_t *locale, - struct token *code, struct charset_t *charset); -void ctype_map_end (struct linereader *lr, struct localedef_t *locale); - - -/* Handle LC_COLLATE category. */ - -void collate_startup (struct linereader *lr, struct localedef_t *locale, - struct charset_t *charset); - -void collate_finish (struct localedef_t *locale, - struct charset_t *charset); - -void collate_output (struct localedef_t *locale, struct charset_t *charset, - const char *output_path); - -void collate_element_to (struct linereader *lr, struct localedef_t *locale, - struct token *code, struct charset_t *charset); -void collate_element_from (struct linereader *lr, - struct localedef_t *locale, struct token *code, - struct charset_t *charset); -void collate_symbol (struct linereader *lr, struct localedef_t *locale, - struct token *code, struct charset_t *charset); -void collate_new_order (struct linereader *lr, struct localedef_t *locale, - enum coll_sort_rule sort_rule); -void collate_build_arrays (struct linereader *lr, - struct localedef_t *locale); -int collate_order_elem (struct linereader *lr, struct localedef_t *locale, - struct token *code, struct charset_t *charset); -int collate_weight_bsymbol (struct linereader *lr, - struct localedef_t *locale, - struct token *code, struct charset_t *charset); -int collate_next_weight (struct linereader *lr, - struct localedef_t *locale); -int collate_simple_weight (struct linereader *lr, - struct localedef_t *locale, - struct token *code, struct charset_t *charset); -void collate_end_weight (struct linereader *lr, - struct localedef_t *locale); - - -/* Handle LC_MONETARY category. */ - -void monetary_startup (struct linereader *lr, struct localedef_t *locale, - struct charset_t *charset); - -void monetary_finish (struct localedef_t *locale); - -void monetary_output (struct localedef_t *locale, const char *output_path); - -void monetary_add (struct linereader *lr, struct localedef_t *locale, - enum token_t tok, struct token *code, - struct charset_t *charset); - - -/* Handle LC_NUMERIC category. */ - -void numeric_startup (struct linereader *lr, struct localedef_t *locale, - struct charset_t *charset); - -void numeric_finish (struct localedef_t *locale); - -void numeric_output (struct localedef_t *locale, const char *output_path); - -void numeric_add (struct linereader *lr, struct localedef_t *locale, - enum token_t tok, struct token *code, - struct charset_t *charset); - - -/* Handle LC_TIME category. */ - -void time_startup (struct linereader *lr, struct localedef_t *locale, - struct charset_t *charset); - -void time_finish (struct localedef_t *locale); - -void time_output (struct localedef_t *locale, const char *output_path); - -void time_add (struct linereader *lr, struct localedef_t *locale, - enum token_t tok, struct token *code, - struct charset_t *charset); - - -/* Handle LC_MESSAGES category. */ - -void messages_startup (struct linereader *lr, struct localedef_t *locale, - struct charset_t *charset); - -void messages_finish (struct localedef_t *locale); - -void messages_output (struct localedef_t *locale, const char *output_path); - -void messages_add (struct linereader *lr, struct localedef_t *locale, - enum token_t tok, struct token *code, - struct charset_t *charset); - - -#endif /* locales.h */ diff --git a/locale/programs/locfile.c b/locale/programs/locfile.c index fd858e2541..024590b7e4 100644 --- a/locale/programs/locfile.c +++ b/locale/programs/locfile.c @@ -41,6 +41,7 @@ locfile_read (struct localedef_t *result, struct charmap_t *charmap) const char *repertoire_name = result->repertoire_name; int locale_mask = result->needed ^ result->avail; struct linereader *ldfile; + int not_here = ALL_LOCALES; /* If no repertoire name was specified use the global one. */ if (repertoire_name == NULL) @@ -158,72 +159,84 @@ argument to `%s' must be a single character"), ctype_read (ldfile, result, charmap, repertoire_name, (locale_mask & CTYPE_LOCALE) == 0); result->avail |= locale_mask & CTYPE_LOCALE; + not_here ^= CTYPE_LOCALE; continue; case tok_lc_collate: collate_read (ldfile, result, charmap, repertoire_name, (locale_mask & COLLATE_LOCALE) == 0); result->avail |= locale_mask & COLLATE_LOCALE; + not_here ^= COLLATE_LOCALE; continue; case tok_lc_monetary: monetary_read (ldfile, result, charmap, repertoire_name, (locale_mask & MONETARY_LOCALE) == 0); result->avail |= locale_mask & MONETARY_LOCALE; + not_here ^= MONETARY_LOCALE; continue; case tok_lc_numeric: numeric_read (ldfile, result, charmap, repertoire_name, (locale_mask & NUMERIC_LOCALE) == 0); result->avail |= locale_mask & NUMERIC_LOCALE; + not_here ^= NUMERIC_LOCALE; continue; case tok_lc_time: time_read (ldfile, result, charmap, repertoire_name, (locale_mask & TIME_LOCALE) == 0); result->avail |= locale_mask & TIME_LOCALE; + not_here ^= TIME_LOCALE; continue; case tok_lc_messages: messages_read (ldfile, result, charmap, repertoire_name, (locale_mask & MESSAGES_LOCALE) == 0); result->avail |= locale_mask & MESSAGES_LOCALE; + not_here ^= MESSAGES_LOCALE; continue; case tok_lc_paper: paper_read (ldfile, result, charmap, repertoire_name, (locale_mask & PAPER_LOCALE) == 0); result->avail |= locale_mask & PAPER_LOCALE; + not_here ^= PAPER_LOCALE; continue; case tok_lc_name: name_read (ldfile, result, charmap, repertoire_name, (locale_mask & NAME_LOCALE) == 0); result->avail |= locale_mask & NAME_LOCALE; + not_here ^= NAME_LOCALE; continue; case tok_lc_address: address_read (ldfile, result, charmap, repertoire_name, (locale_mask & ADDRESS_LOCALE) == 0); result->avail |= locale_mask & ADDRESS_LOCALE; + not_here ^= ADDRESS_LOCALE; continue; case tok_lc_telephone: telephone_read (ldfile, result, charmap, repertoire_name, (locale_mask & TELEPHONE_LOCALE) == 0); result->avail |= locale_mask & TELEPHONE_LOCALE; + not_here ^= TELEPHONE_LOCALE; continue; case tok_lc_measurement: measurement_read (ldfile, result, charmap, repertoire_name, (locale_mask & MEASUREMENT_LOCALE) == 0); result->avail |= locale_mask & MEASUREMENT_LOCALE; + not_here ^= MEASUREMENT_LOCALE; continue; case tok_lc_identification: identification_read (ldfile, result, charmap, repertoire_name, (locale_mask & IDENTIFICATION_LOCALE) == 0); result->avail |= locale_mask & IDENTIFICATION_LOCALE; + not_here ^= IDENTIFICATION_LOCALE; continue; default: @@ -239,6 +252,10 @@ syntax error: not inside a locale definition section")); /* We read all of the file. */ lr_close (ldfile); + /* Mark the categories which are not contained in the file. We assume + them to be available and the default data will be used. */ + result->avail |= not_here; + return 0; } @@ -299,7 +316,7 @@ write_all_categories (struct localedef_t *definitions, int cnt; for (cnt = 0; cnt < sizeof (write_funcs) / sizeof (write_funcs[0]); ++cnt) - if (check_funcs[cnt] != NULL) + if (write_funcs[cnt] != NULL) write_funcs[cnt] (definitions, charmap, output_path); } diff --git a/locale/programs/locfile.h b/locale/programs/locfile.h index 6f670398c0..8117259502 100644 --- a/locale/programs/locfile.h +++ b/locale/programs/locfile.h @@ -47,8 +47,9 @@ struct locale_file /* General handling of `copy'. */ static inline void handle_copy (struct linereader *ldfile, struct charmap_t *charmap, - struct repertoire_t *repertoire, enum token_t token, int locale, - const char *locale_name, int ignore_content) + struct repertoire_t *repertoire, struct localedef_t *result, + enum token_t token, int locale, const char *locale_name, + int ignore_content) { struct token *now; int warned = 0; @@ -62,15 +63,19 @@ handle_copy (struct linereader *ldfile, struct charmap_t *charmap, lr_error (ldfile, _("\ locale name should consist only of portable characters")); else - (void) add_to_readlist (locale, now->val.str.startmb, - repertoire->name); + { + (void) add_to_readlist (locale, now->val.str.startmb, + repertoire->name, 1); + result->copy_name[locale] = now->val.str.startmb; + } } lr_ignore_rest (ldfile, now->tok == tok_string); /* The rest of the line must be empty and the next keyword must be `END xxx'. */ - while (lr_token (ldfile, charmap, NULL)->tok != tok_end) + while ((now = lr_token (ldfile, charmap, NULL))->tok != tok_end + && now->tok != tok_eof) { if (warned == 0) { @@ -82,12 +87,20 @@ no other keyword shall be specified when `copy' is used")); lr_ignore_rest (ldfile, 0); } - /* Handle `END xxx'. */ - if (now->tok != token) - lr_error (ldfile, _("\ + if (now->tok != tok_eof) + { + /* Handle `END xxx'. */ + now = lr_token (ldfile, charmap, NULL); + + if (now->tok != token) + lr_error (ldfile, _("\ `%1$s' definition does not end with `END %1$s'"), locale_name); - lr_ignore_rest (ldfile, now->tok == token); + lr_ignore_rest (ldfile, now->tok == token); + } + else + /* When we come here we reached the end of the file. */ + lr_error (ldfile, _("%s: premature end of file"), locale_name); } |