about 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.c85
1 files changed, 56 insertions, 29 deletions
diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
index f7aaf0d34f..da3cfa7744 100644
--- a/locale/programs/ld-collate.c
+++ b/locale/programs/ld-collate.c
@@ -65,7 +65,9 @@ struct element_t;
 /* Data type for list of strings.  */
 struct section_list
 {
+  /* Successor in the known_sections list.  */
   struct section_list *def_next;
+  /* Successor in the sections list.  */
   struct section_list *next;
   /* Name of the section.  */
   const char *name;
@@ -291,6 +293,7 @@ make_seclist_elem (struct locale_collate_t *collate, const char *string,
   newp->next = next;
   newp->name = string;
   newp->first = NULL;
+  newp->last = NULL;
 
   return newp;
 }
@@ -336,6 +339,10 @@ new_element (struct locale_collate_t *collate, const char *mbs, size_t mbslen,
   newp->used_in_level = 0;
   newp->is_character = is_character;
 
+  /* Will be assigned later.  XXX  */
+  newp->mbseqorder = 0;
+  newp->wcseqorder = 0;
+
   /* Will be allocated later.  */
   newp->weights = NULL;
 
@@ -350,6 +357,9 @@ new_element (struct locale_collate_t *collate, const char *mbs, size_t mbslen,
   newp->mbnext = NULL;
   newp->mblast = NULL;
 
+  newp->wcnext = NULL;
+  newp->wclast = NULL;
+
   return newp;
 }
 
@@ -619,9 +629,8 @@ find_element (struct linereader *ldfile, struct locale_collate_t *collate,
 	  /* It's also no collation element.  So it is a character
 	     element defined later.  */
 	  result = new_element (collate, NULL, 0, NULL, str, len, 1);
-	  if (result != NULL)
-	    /* Insert it into the sequence table.  */
-	    insert_entry (&collate->seq_table, str, len, result);
+	  /* Insert it into the sequence table.  */
+	  insert_entry (&collate->seq_table, str, len, result);
 	}
     }
 
@@ -660,11 +669,11 @@ insert_weights (struct linereader *ldfile, struct element_t *elem,
   /* Initialize all the fields.  */
   elem->file = ldfile->fname;
   elem->line = ldfile->lineno;
+
   elem->last = collate->cursor;
   elem->next = collate->cursor ? collate->cursor->next : NULL;
   if (collate->cursor != NULL && collate->cursor->next != NULL)
     collate->cursor->next->last = elem;
-  elem->section = collate->current_section;
   if (collate->cursor != NULL)
     collate->cursor->next = elem;
   if (collate->start == NULL)
@@ -672,9 +681,8 @@ insert_weights (struct linereader *ldfile, struct element_t *elem,
       assert (collate->cursor == NULL);
       collate->start = elem;
     }
-  elem->weights = (struct element_list_t *)
-    obstack_alloc (&collate->mempool, nrules * sizeof (struct element_list_t));
-  memset (elem->weights, '\0', nrules * sizeof (struct element_list_t));
+
+  elem->section = collate->current_section;
 
   if (collate->current_section->first == NULL)
     collate->current_section->first = elem;
@@ -683,6 +691,10 @@ insert_weights (struct linereader *ldfile, struct element_t *elem,
 
   collate->cursor = elem;
 
+  elem->weights = (struct element_list_t *)
+    obstack_alloc (&collate->mempool, nrules * sizeof (struct element_list_t));
+  memset (elem->weights, '\0', nrules * sizeof (struct element_list_t));
+
   weight_cnt = 0;
 
   arg = lr_token (ldfile, charmap, repertoire);
@@ -839,8 +851,8 @@ insert_weights (struct linereader *ldfile, struct element_t *elem,
 %s: weights must use the same ellipsis symbol as the name"),
 		      "LC_COLLATE");
 
-	  /* The weight for this level has to be ignored.  We use the
-	     null pointer to indicate this.  */
+	  /* The weight for this level will depend on the element
+	     iterating over the range.  Put a placeholder.  */
 	  elem->weights[weight_cnt].w = (struct element_t **)
 	    obstack_alloc (&collate->mempool, sizeof (struct element_t *));
 	  elem->weights[weight_cnt].w[0] = ELEMENT_ELLIPSIS2;
@@ -988,8 +1000,7 @@ insert_value (struct linereader *ldfile, const char *symstr, size_t symlen,
     }
 
   /* Test whether this element is not already in the list.  */
-  if (elem->next != NULL || (collate->cursor != NULL
-			     && elem->next == collate->cursor))
+  if (elem->next != NULL || elem == collate->cursor)
     {
       lr_error (ldfile, _("order for `%.*s' already defined at %s:%Zu"),
 		(int) symlen, symstr, elem->file, elem->line);
@@ -1434,6 +1445,7 @@ collate_startup (struct linereader *ldfile, struct localedef_t *locale,
 	  collate->col_weight_max = -1;
 	}
       else
+	/* Reuse the copy_locale's data structures.  */
 	collate = locale->categories[LC_COLLATE].collate =
 	  copy_locale->categories[LC_COLLATE].collate;
     }
@@ -1788,9 +1800,9 @@ collate_finish (struct localedef_t *locale, struct charmap_t *charmap)
       while (sect != NULL && sect->rules == NULL);
     }
   while (sect != NULL);
-  /* We are currently not prepared for more than 256 rulesets.  But this
+  /* We are currently not prepared for more than 128 rulesets.  But this
      should never really be a problem.  */
-  assert (ruleidx <= 256);
+  assert (ruleidx <= 128);
 }
 
 
@@ -2529,9 +2541,18 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
   struct token *now;
   struct token *arg = NULL;
   enum token_t nowtok;
-  int state = 0;
   enum token_t was_ellipsis = tok_none;
   struct localedef_t *copy_locale = NULL;
+  /* Parsing state:
+     0 - start
+     1 - between `order-start' and `order-end'
+     2 - after `order-end'
+     3 - after `reorder-after', waiting for `reorder-end'
+     4 - after `reorder-end'
+     5 - after `reorder-sections-after', waiting for `reorder-sections-end'
+     6 - after `reorder-sections-end'
+  */
+  int state = 0;
 
   /* Get the repertoire we have to use.  */
   if (repertoire_name != NULL)
@@ -2828,9 +2849,10 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
 		    }
 		  else if (ellipsis == tok_none)
 		    {
-		      /* The name is already defined.  */
+		      /* A single symbol, no ellipsis.  */
 		      if (check_duplicate (ldfile, collate, charmap,
 					   repertoire, symbol, symbol_len))
+			/* The name is already defined.  */
 			goto col_sym_free;
 
 		      insert_entry (&collate->sym_table, symbol, symbol_len,
@@ -2884,13 +2906,13 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
 			  /* Create the name.  */
 			  sprintf (symbuf,
 				   ellipsis == tok_ellipsis2
-				   ? "%.*s%.*lX" : "%.*s%.*lX",
+				   ? "%.*s%.*lX" : "%.*s%.*lu",
 				   (int) prefixlen, symbol,
 				   (int) (symbol_len - prefixlen), from);
 
-			  /* The name is already defined.  */
 			  if (check_duplicate (ldfile, collate, charmap,
 					       repertoire, symbuf, symbol_len))
+			    /* The name is already defined.  */
 			    goto col_sym_free;
 
 			  insert_entry (&collate->sym_table, symbuf,
@@ -3021,8 +3043,8 @@ error while adding equivalent collating symbol"));
 		}
 
 	      runp = (struct section_list *) xcalloc (1, sizeof (*runp));
-	      name = strncpy (xmalloc (arg->val.str.lenmb + 1),
-			      arg->val.str.startmb, arg->val.str.lenmb);
+	      name = (char *) xmalloc (arg->val.str.lenmb + 1);
+	      memcpy (name, arg->val.str.startmb, arg->val.str.lenmb);
 	      name[arg->val.str.lenmb] = '\0';
 	      runp->name = name;
 
@@ -3070,6 +3092,8 @@ error while adding equivalent collating symbol"));
 
 		  if (collate->error_section.first == NULL)
 		    {
+		      /* Insert &collate->error_section at the end of
+			 the collate->sections list.  */
 		      if (collate->sections == NULL)
 			collate->sections = &collate->error_section;
 		      else
@@ -3078,9 +3102,9 @@ error while adding equivalent collating symbol"));
 			  while (sp->next != NULL)
 			    sp = sp->next;
 
-			  collate->error_section.next = NULL;
 			  sp->next = &collate->error_section;
 			}
+		      collate->error_section.next = NULL;
 		    }
 		}
 	      else
@@ -3093,6 +3117,8 @@ error while adding equivalent collating symbol"));
 			      "LC_COLLATE", sp->name);
 		  else
 		    {
+		      /* Insert sp in the collate->sections list,
+			 right after collate->current_section.  */
 		      if (collate->current_section == NULL)
 			collate->current_section = sp;
 		      else
@@ -3141,6 +3167,8 @@ error while adding equivalent collating symbol"));
 			  "LC_COLLATE");
 	      else
 		{
+		  /* Insert &collate->unnamed_section at the beginning of
+		     the collate->sections list.  */
 		  collate->unnamed_section.next = collate->sections;
 		  collate->sections = &collate->unnamed_section;
 		}
@@ -3149,7 +3177,7 @@ error while adding equivalent collating symbol"));
 	  /* Now read the direction names.  */
 	  read_directions (ldfile, arg, charmap, repertoire, collate);
 
-	  /* From now be need the strings untranslated.  */
+	  /* From now we need the strings untranslated.  */
 	  ldfile->translate_strings = 0;
 	  break;
 
@@ -3231,7 +3259,7 @@ error while adding equivalent collating symbol"));
 			      (void **) &insp) == 0)
 		/* Yes, the symbol exists.  Simply point the cursor
 		   to it.  */
-		  collate->cursor = insp;
+		collate->cursor = insp;
 	      else
 		{
 		  struct symbol_t *symbp;
@@ -3428,7 +3456,7 @@ error while adding equivalent collating symbol"));
 	      /* We are outside an `order_start' region.  This means
                  we must only accept definitions of values for
                  collation symbols since these are purely abstract
-                 values and don't need dorections associated.  */
+                 values and don't need directions associated.  */
 	      struct element_t *seqp;
 
 	      if (find_entry (&collate->seq_table, symstr, symlen,
@@ -3510,7 +3538,7 @@ error while adding equivalent collating symbol"));
 		  if (seqp->section->first == seqp)
 		    {
 		      if (seqp->section->first == seqp->section->last)
-			/* This setion has no content anymore.  */
+			/* This section has no content anymore.  */
 			seqp->section->first = seqp->section->last = NULL;
 		      else
 			seqp->section->first = seqp->next;
@@ -3616,8 +3644,7 @@ error while adding equivalent collating symbol"));
 
 	  /* See whether UNDEFINED already appeared somewhere.  */
 	  if (collate->undefined.next != NULL
-	      || (collate->cursor != NULL
-		  && collate->undefined.next == collate->cursor))
+	      || &collate->undefined == collate->cursor)
 	    {
 	      lr_error (ldfile,
 			_("%s: order for `%.*s' already defined at %s:%Zu"),
@@ -3632,9 +3659,9 @@ error while adding equivalent collating symbol"));
 			     repertoire, collate, tok_none);
 	  break;
 
-	case tok_ellipsis2:
-	case tok_ellipsis3:
-	case tok_ellipsis4:
+	case tok_ellipsis2: /* symbolic hexadecimal ellipsis */
+	case tok_ellipsis3: /* absolute ellipsis */
+	case tok_ellipsis4: /* symbolic decimal ellipsis */
 	  /* This is the symbolic (decimal or hexadecimal) or absolute
              ellipsis.  */
 	  if (was_ellipsis != tok_none)