summary refs log tree commit diff
path: root/locale/programs/ld-collate.c
diff options
context:
space:
mode:
Diffstat (limited to 'locale/programs/ld-collate.c')
-rw-r--r--locale/programs/ld-collate.c148
1 files changed, 137 insertions, 11 deletions
diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
index 982462f7b3..e1c4d14f9e 100644
--- a/locale/programs/ld-collate.c
+++ b/locale/programs/ld-collate.c
@@ -721,20 +721,22 @@ collate_startup (struct linereader *ldfile, struct localedef_t *locale,
       struct locale_collate_t *collate;
 
       if (copy_locale == NULL)
-	collate = locale->categories[LC_COLLATE].collate =
-	  (struct locale_collate_t *) xcalloc (1,
-					       sizeof (struct locale_collate_t));
+	{
+	  collate = locale->categories[LC_COLLATE].collate =
+	    (struct locale_collate_t *)
+	    xcalloc (1, sizeof (struct locale_collate_t));
+
+	  /* Init the various data structures.  */
+	  init_hash (&collate->elem_table, 100);
+	  init_hash (&collate->sym_table, 100);
+	  init_hash (&collate->seq_table, 500);
+	  obstack_init (&collate->mempool);
+
+	  collate->col_weight_max = -1;
+	}
       else
 	collate = locale->categories[LC_COLLATE].collate =
 	  copy_locale->categories[LC_COLLATE].collate;
-
-      /* Init the various data structures.  */
-      init_hash (&collate->elem_table, 100);
-      init_hash (&collate->sym_table, 100);
-      init_hash (&collate->seq_table, 500);
-      obstack_init (&collate->mempool);
-
-      collate->col_weight_max = -1;
     }
 
   ldfile->translate_strings = 0;
@@ -1302,6 +1304,81 @@ error while adding equivalent collating symbol"));
 	  lr_ignore_rest (ldfile, 1);
 	  break;
 
+	case tok_reorder_sections_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 != 4)
+	    goto err_label;
+	  state = 5;
+
+	  /* Get the name of the sections we are adding after.  */
+	  arg = lr_token (ldfile, charmap, repertoire);
+	  if (arg->tok == tok_bsymbol)
+	    {
+	      /* Now find a section with this name.  */
+	      struct section_list *runp = collate->sections;
+
+	      while (runp != NULL)
+		{
+		  if (runp->name != NULL
+		      && strlen (runp->name) == arg->val.str.lenmb
+		      && memcmp (runp->name, arg->val.str.startmb,
+				 arg->val.str.lenmb) == 0)
+		    break;
+
+		  runp = runp->next;
+		}
+
+	      if (runp != NULL)
+		collate->current_section = runp;
+	      else
+		{
+		  /* This is bad.  The section after which we have to
+                     reorder does not exist.  Therefore we cannot
+                     process the whole rest of this reorder
+                     specification.  */
+		  lr_error (ldfile, _("%s: section `%.*s' not known"),
+			    "LC_COLLATE", arg->val.str.lenmb,
+			    arg->val.str.startmb);
+
+		  do
+		    {
+		      lr_ignore_rest (ldfile, 0);
+
+		      now = lr_token (ldfile, charmap, NULL);
+		    }
+		  while (now->tok == tok_reorder_sections_after
+			 || now->tok == tok_reorder_sections_end
+			 || now->tok == tok_end);
+
+		  /* Process the token we just saw.  */
+		  nowtok = now->tok;
+		  continue;
+		}
+	    }
+	  else
+	    /* This must not happen.  */
+	    goto err_label;
+	  break;
+
+	case tok_reorder_sections_end:
+	  /* Ignore the rest of the line if we don't need the input of
+	     this line.  */
+	  if (ignore_content)
+	    break;
+
+	  if (state != 5)
+	    goto err_label;
+	  state = 6;
+	  lr_ignore_rest (ldfile, 1);
+	  break;
+
 	case tok_bsymbol:
 	  /* Ignore the rest of the line if we don't need the input of
 	     this line.  */
@@ -1368,6 +1445,52 @@ error while adding equivalent collating symbol"));
 
 	      /* Otherwise we just add a new entry.  */
 	    }
+	  else if (state == 5)
+	    {
+	      /* We are reordering sections.  Find the named section.  */
+	      struct section_list *runp = collate->sections;
+	      struct section_list *prevp = NULL;
+
+	      while (runp != NULL)
+		{
+		  if (runp->name != NULL
+		      && strlen (runp->name) == arg->val.str.lenmb
+		      && memcmp (runp->name, arg->val.str.startmb,
+				 arg->val.str.lenmb) == 0)
+		    break;
+
+		  prevp = runp;
+		  runp = runp->next;
+		}
+
+	      if (runp == NULL)
+		{
+		  lr_error (ldfile, _("%s: section `%.*s' not known"),
+			    "LC_COLLATE", arg->val.str.lenmb,
+			    arg->val.str.startmb);
+		  lr_ignore_rest (ldfile, 0);
+		}
+	      else
+		{
+		  if (runp != collate->current_section)
+		    {
+		      /* Remove the named section from the old place and
+			 insert it in the new one.  */
+		      prevp->next = runp->next;
+
+		      runp->next = collate->current_section->next;
+		      collate->current_section->next = runp;
+		      collate->current_section = runp;
+		    }
+
+		  /* Process the rest of the line which might change
+                     the collation rules.  */
+		  arg = lr_token (ldfile, charmap, repertoire);
+		  if (arg->tok != tok_eof && arg->tok != tok_eol)
+		    read_directions (ldfile, arg, charmap, repertoire,
+				     collate);
+		}
+	    }
 
 	  /* Now insert in the new place.  */
 	  insert_value (ldfile, arg, charmap, repertoire, collate);
@@ -1434,6 +1557,9 @@ error while adding equivalent collating symbol"));
 	      else if (state == 3)
 		error (0, 0, _("%s: missing `reorder-end' keyword"),
 		       "LC_COLLATE");
+	      else if (state == 5)
+		error (0, 0, _("%s: missing `reorder-sections-end' keyword"),
+		       "LC_COLLATE");
 	    }
 	  arg = lr_token (ldfile, charmap, NULL);
 	  if (arg->tok == tok_eof)