Fix handling of non-existing definitions for this category. Correctly
authordrepper <drepper>
Sun, 12 Sep 1999 08:20:49 +0000 (08:20 +0000)
committerdrepper <drepper>
Sun, 12 Sep 1999 08:20:49 +0000 (08:20 +0000)
ignore content of this category is this is necessary.

12 files changed:
locale/programs/ld-address.c
locale/programs/ld-collate.c
locale/programs/ld-ctype.c
locale/programs/ld-identification.c
locale/programs/ld-measurement.c
locale/programs/ld-messages.c
locale/programs/ld-monetary.c
locale/programs/ld-name.c
locale/programs/ld-numeric.c
locale/programs/ld-paper.c
locale/programs/ld-telephone.c
locale/programs/ld-time.c

index 805330c..49900bd 100644 (file)
@@ -87,8 +87,11 @@ address_startup (struct linereader *lr, struct localedef_t *locale,
       (struct locale_address_t *) xcalloc (1,
                                           sizeof (struct locale_address_t));
 
       (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;
   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)
     {
 
   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";
     }
       /* 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)                                                  \
     {                                                                        \
 #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 = "";                                                     \
     }
        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)
     {
   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 = "";
        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 (address->lang_ab == NULL)
     {
-      if (verbose)
+      if (verbose && ! nothing)
        error (0, 0, _("%s: field `%s' not defined"), "LC_ADDRESS", "lang_ab");
       address->lang_ab = "";
     }
        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 (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]);
        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 (address->country_ab2 == NULL)
     {
-      if (verbose)
+      if (verbose && ! nothing)
        error (0, 0, _("%s: field `%s' not defined"),
               "LC_ADDRESS", "country_ab2");
       address->country_ab2 = "  ";
        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 (address->country_ab3 == NULL)
     {
-      if (verbose)
+      if (verbose && ! nothing)
        error (0, 0, _("%s: field `%s' not defined"),
               "LC_ADDRESS", "country_ab3");
       address->country_ab3 = "   ";
        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)
     {
   /* 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;
     }
 
       return;
     }
 
@@ -443,6 +480,14 @@ address_read (struct linereader *ldfile, struct localedef_t *result,
        {
 #define STR_ELEM(cat) \
        case tok_##cat:                                                       \
        {
 #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;                                                   \
          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:                                                       \
 
 #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;                                                   \
          arg = lr_token (ldfile, charmap, NULL);                             \
          if (arg->tok != tok_number)                                         \
            goto err_label;                                                   \
index 3c12674..20a8776 100644 (file)
@@ -601,6 +601,14 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
       switch (nowtok)
        {
        case tok_coll_weight_max:
       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;
 
          if (state != 0)
            goto err_label;
 
@@ -616,6 +624,14 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
          break;
 
        case tok_section_symbol:
          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;
 
          if (state != 0)
            goto err_label;
 
@@ -652,6 +668,14 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
          break;
 
        case tok_collating_element:
          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;
 
          if (state != 0)
            goto err_label;
 
@@ -732,6 +756,14 @@ error while adding collating element"));
          break;
 
        case tok_collating_symbol:
          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;
 
          if (state != 0)
            goto err_label;
 
@@ -774,6 +806,14 @@ error while adding collating symbol"));
          break;
 
        case tok_symbol_equivalence:
          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;
 
          if (state != 0)
            goto err_label;
 
@@ -853,6 +893,14 @@ error while adding equivalent collating symbol"));
          break;
 
        case tok_order_start:
          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;
          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:
          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;
          if (state != 1)
            goto err_label;
          state = 2;
@@ -940,6 +996,14 @@ error while adding equivalent collating symbol"));
          break;
 
        case tok_reorder_after:
          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;
          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:
          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;
          if (state != 3)
            goto err_label;
          state = 4;
@@ -954,6 +1023,14 @@ error while adding equivalent collating symbol"));
          break;
 
        case tok_bsymbol:
          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;
 
          if (state != 1 && state != 3)
            goto err_label;
 
@@ -996,12 +1073,28 @@ error while adding equivalent collating symbol"));
          break;
 
        case tok_undefined:
          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:
          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;
 
          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'.  */
 
        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;
          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)
     {
   /* 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;
     }
 
       did_copy = 1;
     }
 
index 6743c18..6dea9d0 100644 (file)
@@ -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;
 
   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);
 
   /* 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)
     {
   /* 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;
     }
                   "LC_CTYPE", ignore_content);
       return;
     }
@@ -1766,6 +1797,14 @@ ctype_read (struct linereader *ldfile, struct localedef_t *result,
       switch (nowtok)
        {
        case tok_class:
       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);
          /* 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:
        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;
          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)
                        {
                      /* 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->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)));
                          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:
          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;
        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:
          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"),
          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:
          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:
          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:
          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);
          /* 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:
          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);
 
          /* 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:
          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)
          /* 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->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;
        }
 
       ctype->outdigits_act = 10;
index 79bcd44..b536ac8 100644 (file)
@@ -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)
 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;
 {
   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)                                           \
     {                                                                        \
 
 #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 = "";                                                      \
        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);
   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)
   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;
   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)
 
   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)
 
   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);
 
   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)
     {
   /* 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;
     }
                   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:                                                       \
        {
 #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;                                                   \
          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:
          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)
          /* We expect two operands.  */
          arg = lr_token (ldfile, charmap, NULL);
          if (arg->tok != tok_string && arg->tok != tok_ident)
index 38a6160..610eb5e 100644 (file)
@@ -48,8 +48,11 @@ measurement_startup (struct linereader *lr, struct localedef_t *locale,
       (struct locale_measurement_t *)
       xcalloc (1, sizeof (struct locale_measurement_t));
 
       (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;
 {
   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)
     {
 
   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;
     }
       /* 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)
     {
   /* 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;
     }
                   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:                                                       \
        {
 #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;                                                   \
          arg = lr_token (ldfile, charmap, NULL);                             \
          if (arg->tok != tok_number)                                         \
            goto err_label;                                                   \
index 33b7735..159c9c7 100644 (file)
@@ -54,8 +54,11 @@ messages_startup (struct linereader *lr, struct localedef_t *locale,
       (struct locale_messages_t *) xcalloc (1,
                                            sizeof (struct locale_messages_t));
 
       (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;
 {
   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)
 
   /* 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 (messages->yesexpr == NULL)
     {
-      if (!be_quiet)
+      if (! be_quiet && ! nothing)
        error (0, 0, _("%s: field `%s' undefined"), "LC_MESSAGES", "yesexpr");
       messages->yesexpr = "";
     }
        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 (messages->noexpr == NULL)
     {
-      if (!be_quiet)
+      if (! be_quiet && ! nothing)
        error (0, 0, _("%s: field `%s' undefined"), "LC_MESSAGES", "noexpr");
       messages->noexpr = "";
     }
        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)
     {
   /* 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;
     }
 
       return;
     }
 
@@ -244,6 +281,14 @@ messages_read (struct linereader *ldfile, struct localedef_t *result,
        {
 #define STR_ELEM(cat) \
        case tok_##cat:                                                       \
        {
 #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, _("\
          if (messages->cat != NULL)                                          \
            {                                                                 \
              lr_error (ldfile, _("\
index 61f9f8d..a6dd3ac 100644 (file)
@@ -148,8 +148,11 @@ monetary_startup (struct linereader *lr, struct localedef_t *locale,
       monetary->duo_int_n_sign_posn = -2;
     }
 
       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;
 {
   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)                                    \
     {                                                                        \
 
 #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 = "";                                                    \
     }
 
       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
      != "".  */
   /* 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");
     }
 
     {
       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) \
     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)        \
     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) \
 
 #undef TEST_ELEM
 #define TEST_ELEM(cat, alt, min, max) \
-  if (monetary->cat == -2 && !be_quiet)                                              \
+  if (monetary->cat == -2)                                                   \
     monetary->cat = monetary->alt;                                           \
     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)
     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)
     {
   /* 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;
     }
 
       return;
     }
 
@@ -604,6 +643,14 @@ monetary_read (struct linereader *ldfile, struct localedef_t *result,
        {
 #define STR_ELEM(cat) \
        case tok_##cat:                                                       \
        {
 #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;                                                   \
          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:                                                       \
 
 #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;                                                   \
          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:
          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;
          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:
          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;
          now = lr_token (ldfile, charmap, NULL);
          if (now->tok != tok_number)
            goto err_label;
index 85acb41..4ab0916 100644 (file)
@@ -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));
 
     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;
 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)
     {
 
   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";
     }
       /* 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)                                                     \
     {                                                                        \
 #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 = "";                                                        \
     }
        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)
     {
   /* 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;
     }
                   "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:                                                       \
        {
 #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;                                                   \
          arg = lr_token (ldfile, charmap, NULL);                             \
          if (arg->tok != tok_string)                                         \
            goto err_label;                                                   \
index 3e51aba..697ad35 100644 (file)
@@ -58,8 +58,11 @@ numeric_startup (struct linereader *lr, struct localedef_t *locale,
       numeric->grouping_len = 0;
     }
 
       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;
 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)                                                       \
 
 #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);
     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
      != "".  */
   /* 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");
     }
 
     {
       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");
 }
 
     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)
     {
   /* 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;
     }
 
       return;
     }
 
@@ -187,6 +223,14 @@ numeric_read (struct linereader *ldfile, struct localedef_t *result,
        {
 #define STR_ELEM(cat) \
        case tok_##cat:                                                       \
        {
 #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;                                                   \
          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:
          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;
          now = lr_token (ldfile, charmap, NULL);
          if (now->tok != tok_minus1 && now->tok != tok_number)
            goto err_label;
index 5d834eb..642ca41 100644 (file)
@@ -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));
 
     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;
 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)
     {
 
   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;
     }
       /* 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)
     {
 
   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;
     }
       /* 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)
     {
   /* 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;
     }
 
       return;
     }
 
@@ -194,6 +232,14 @@ paper_read (struct linereader *ldfile, struct localedef_t *result,
        {
 #define INT_ELEM(cat) \
        case tok_##cat:                                                       \
        {
 #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;                                                   \
          arg = lr_token (ldfile, charmap, NULL);                             \
          if (arg->tok != tok_number)                                         \
            goto err_label;                                                   \
index 2d75fea..5d2ea49 100644 (file)
@@ -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));
 
     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;
 {
   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)
     {
 
   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";
     }
       /* 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)                                                \
     {                                                                        \
 #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 = "";                                                   \
     }
        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)
     {
   /* 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;
     }
 
       return;
     }
 
@@ -234,6 +272,14 @@ telephone_read (struct linereader *ldfile, struct localedef_t *result,
        {
 #define STR_ELEM(cat) \
        case tok_##cat:                                                       \
        {
 #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;                                                   \
          arg = lr_token (ldfile, charmap, NULL);                             \
          if (arg->tok != tok_string)                                         \
            goto err_label;                                                   \
index bae38fc..88d98e2 100644 (file)
@@ -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));
 
     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;
 {
   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) \
 
 #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;                                                                      \
   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) \
   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;                    \
   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;
 
   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;
 
   ++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)
     {
   /* 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;
     }
 
       return;
     }
 
@@ -1225,6 +1266,14 @@ time_read (struct linereader *ldfile, struct localedef_t *result,
        {
 #define STRARR_ELEM(cat, min, max) \
        case tok_##cat:                                                       \
        {
 #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);                   \
          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:
          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);
          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:                                                       \
 
 #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;                                                   \
          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:                                                       \
 
 #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;                                                   \
          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:
          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;
          now = lr_token (ldfile, charmap, NULL);
          if (now->tok != tok_number)
            goto err_label;