NULL, 0, NULL, symbol, symbol_len)) < 0)
arg->val.str.startmb, arg->val.str.lenmb - 1, arg->val.str.startwc, symbol, symbol_len, 0)) < 0)
collate_read (struct linereader *ldfile, struct localedef_t *result,	      struct charmap_t *charmap, const char *repertoire_name,	      int ignore_content){  struct repertoire_t *repertoire = NULL;  struct locale_collate_t *collate;  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;  /* Get the repertoire we have to use.  */  if (repertoire_name != NULL)    repertoire = repertoire_read (repertoire_name);  /* The rest of the line containing `LC_COLLATE' must be free.  */  lr_ignore_rest (ldfile, 1);  do    {      now = lr_token (ldfile, charmap, NULL);      nowtok = now->tok;    }  while (nowtok == tok_eol);  if (nowtok == tok_copy)    {      state = 2;      now = lr_token (ldfile, charmap, NULL);      if (now->tok != tok_string)	{	  SYNTAX_ERROR (_("%s: syntax error"), "LC_COLLATE");	skip_category:	  do	    now = lr_token (ldfile, charmap, NULL);	  while (now->tok != tok_eof && now->tok != tok_end);	  if (now->tok != tok_eof	      || (now = lr_token (ldfile, charmap, NULL), now->tok == tok_eof))	    lr_error (ldfile, _("%s: premature end of file"), "LC_COLLATE");	  else if (now->tok != tok_lc_collate)	    {	      lr_error (ldfile, _("\%1$s: definition does not end with `END %1$s'"), "LC_COLLATE");	      lr_ignore_rest (ldfile, 0);	    }	  else	    lr_ignore_rest (ldfile, 1);	  return;	}      /* Get the locale definition.  */      copy_locale = find_locale (LC_COLLATE, now->val.str.startmb,				 repertoire_name, charmap);      if ((copy_locale->avail & COLLATE_LOCALE) == 0)	{	  /* Not yet loaded.  So do it now.  */	  if (locfile_read (copy_locale, charmap) != 0)	    goto skip_category;	}      lr_ignore_rest (ldfile, 1);      now = lr_token (ldfile, charmap, NULL);      nowtok = now->tok;    }  /* Prepare the data structures.  */  collate_startup (ldfile, result, copy_locale, ignore_content);  collate = result->categories[LC_COLLATE].collate;  while (1)    {      /* Of course we don't proceed beyond the end of file.  */      if (nowtok == tok_eof)	break;      /* Ingore empty lines.  */      if (nowtok == tok_eol)	{	  now = lr_token (ldfile, charmap, NULL);	  nowtok = now->tok;	  continue;	}      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;	  arg = lr_token (ldfile, charmap, NULL);	  if (arg->tok != tok_number)	    goto err_label;	  if (collate->col_weight_max != -1)	    lr_error (ldfile, _("%s: duplicate definition of `%s'"),		      "LC_COLLATE", "col_weight_max");	  else	    collate->col_weight_max = arg->val.num;	  lr_ignore_rest (ldfile, 1);	  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;	  arg = lr_token (ldfile, charmap, repertoire);	  if (arg->tok != tok_bsymbol)	    goto err_label;	  else if (!ignore_content)	    {	      /* Check whether this section is already known.  */	      struct section_list *known = collate->sections;	      while (known != NULL)		if (strcmp (known->name, arg->val.str.startmb) == 0)		  break;	      if (known != NULL)		{		  lr_error (ldfile,			    _("%s: duplicate declaration of section `%s'"),			    "LC_COLLATE", arg->val.str.startmb);		  free (arg->val.str.startmb);		}	      else		collate->sections = make_seclist_elem (collate,						       arg->val.str.startmb,						       collate->sections);	      lr_ignore_rest (ldfile, known == NULL);	    }	  else	    {	      free (arg->val.str.startmb);	      lr_ignore_rest (ldfile, 0);	    }	  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;	  arg = lr_token (ldfile, charmap, repertoire);	  if (arg->tok != tok_bsymbol)	    goto err_label;	  else	    {	      const char *symbol = arg->val.str.startmb;	      size_t symbol_len = arg->val.str.lenmb;	      /* Next the `from' keyword.  */	      arg = lr_token (ldfile, charmap, repertoire);	      if (arg->tok != tok_from)		{		  free ((char *) symbol);		  goto err_label;		}	      ldfile->return_widestr = 1;	      /* Finally the string with the replacement.  */	      arg = lr_token (ldfile, charmap, repertoire);	      ldfile->return_widestr = 0;	      if (arg->tok != tok_string)		goto err_label;	      if (!ignore_content)		{		  if (symbol == NULL)		    lr_error (ldfile, _("\%s: unknown character in collating element name"),			      "LC_COLLATE");		  if (arg->val.str.startmb == NULL)		    lr_error (ldfile, _("\%s: unknown character in collating element definition"),			      "LC_COLLATE");		  if (arg->val.str.startwc == NULL)		    lr_error (ldfile, _("\%s: unknown wide character in collating element definition"),			      "LC_COLLATE");		  else if (arg->val.str.lenwc < 2)		    lr_error (ldfile, _("\%s: substitution string in collating element definition must have at least two characters"),			      "LC_COLLATE");		  if (symbol != NULL)		    {		      /* The name is already defined.  */		      if (check_duplicate (ldfile, collate, charmap,					   repertoire, symbol, symbol_len))			goto col_elem_free;		      if (insert_entry (&collate->elem_table,					symbol, symbol_len,					new_element (collate,						     NULL, 0, NULL, symbol,						     symbol_len)) < 0)			lr_error (ldfile, _("\error while adding collating element"));		    }		  else		    goto col_elem_free;		}	      else		{		col_elem_free:		  if (symbol != NULL)		    free ((char *) symbol);		  if (arg->val.str.startmb != NULL)		    free (arg->val.str.startmb);		  if (arg->val.str.startwc != NULL)		    free (arg->val.str.startwc);		}	      lr_ignore_rest (ldfile, 1);	    }	  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;	  arg = lr_token (ldfile, charmap, repertoire);	  if (arg->tok != tok_bsymbol)	    goto err_label;	  else	    {	      const char *symbol = arg->val.str.startmb;	      size_t symbol_len = arg->val.str.lenmb;	      if (!ignore_content)		{		  if (symbol == NULL)		    lr_error (ldfile, _("\%s: unknown character in collating symbol name"),			      "LC_COLLATE");		  else		    {		      /* The name is already defined.  */		      if (check_duplicate (ldfile, collate, charmap,					   repertoire, symbol, symbol_len))			goto col_sym_free;		      if (insert_entry (&collate->sym_table,					symbol, symbol_len,					new_symbol (collate)) < 0)			lr_error (ldfile, _("\error while adding collating symbol"));		    }		}	      else		{		col_sym_free:		  if (symbol != NULL)		    free ((char *) symbol);		}	      lr_ignore_rest (ldfile, 1);	    }	  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;	  arg = lr_token (ldfile, charmap, repertoire);	  if (arg->tok != tok_bsymbol)	    goto err_label;	  else	    {	      const char *newname = arg->val.str.startmb;	      size_t newname_len = arg->val.str.lenmb;	      const char *symname;	      size_t symname_len;	      struct symbol_t *symval;	      arg = lr_token (ldfile, charmap, repertoire);	      if (arg->tok != tok_bsymbol)		{		  if (newname != NULL)		    free ((char *) newname);		  goto err_label;		}	      symname = arg->val.str.startmb;	      symname_len = arg->val.str.lenmb;	      if (!ignore_content)		{		  if (newname == NULL)		    {		      lr_error (ldfile, _("\%s: unknown character in equivalent definition name"),				"LC_COLLATE");		      goto sym_equiv_free;		    }		  if (symname == NULL)		    {		      lr_error (ldfile, _("\%s: unknown character in equivalent definition value"),				"LC_COLLATE");		      goto sym_equiv_free;		    }		  /* The name is already defined.  */		  if (check_duplicate (ldfile, collate, charmap,				       repertoire, symname, symname_len))		    goto col_sym_free;		  /* See whether the symbol name is already defined.  */		  if (find_entry (&collate->sym_table, symname, symname_len,				  (void **) &symval) != 0)		    {		      lr_error (ldfile, _("\%s: unknown symbol `%s' in equivalent definition"),				"LC_COLLATE", symname);		      goto col_sym_free;		    }		  if (insert_entry (&collate->sym_table,				    newname, newname_len, symval) < 0)		    {		      lr_error (ldfile, _("\error while adding equivalent collating symbol"));		      goto sym_equiv_free;		    }		  free ((char *) symname);		}	      else		{		sym_equiv_free:		  if (newname != NULL)		    free ((char *) newname);		  if (symname != NULL)		    free ((char *) symname);		}	      lr_ignore_rest (ldfile, 1);	    }	  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;	  /* The 14652 draft does not specify whether all `order_start' lines	     must contain the same number of sort-rules, but 14651 does.  So	     we require this here as well.  */	  arg = lr_token (ldfile, charmap, repertoire);	  if (arg->tok == tok_bsymbol)	    {	      /* This better should be a section name.  */	      struct section_list *sp = collate->sections;	      while (sp != NULL		     && strcmp (sp->name, arg->val.str.startmb) != 0)		sp = sp->next;	      if (sp == NULL)		{		  lr_error (ldfile, _("\%s: unknown section name `%s'"),			    "LC_COLLATE", arg->val.str.startmb);		  /* We use the error section.  */		  collate->current_section = &collate->error_section;		  if (collate->error_section.first == NULL)		    {		      collate->error_section.next = collate->sections;		      collate->sections = &collate->error_section;		    }		}	      else		{		  /* Remember this section.  */		  collate->current_section = sp;		  /* One should not be allowed to open the same                     section twice.  */		  if (sp->first != NULL)		    lr_error (ldfile, _("\%s: multiple order definitions for section `%s'"),			      "LC_COLLATE", sp->name);		  else		    {		      sp->next = collate->sections;		      collate->sections = sp;		    }		  /* Next should come the end of the line or a semicolon.  */		  arg = lr_token (ldfile, charmap, repertoire);		  if (arg->tok == tok_eol)		    {		      uint32_t cnt;		      /* This means we have exactly one rule: `forward'.  */		      if (nrules > 1)			lr_error (ldfile, _("\%s: invalid number of sorting rules"),				  "LC_COLLATE");		      else			nrules = 1;		      sp->rules = obstack_alloc (&collate->mempool,						 (sizeof (enum coll_sort_rule)						  * nrules));		      for (cnt = 0; cnt < nrules; ++cnt)			sp->rules[cnt] = sort_forward;		      /* Next line.  */		      break;		    }		  /* Get the next token.  */		  arg = lr_token (ldfile, charmap, repertoire);		}	    }	  else	    {	      /* There is no section symbol.  Therefore we use the unnamed		 section.  */	      collate->current_section = &collate->unnamed_section;	      if (collate->unnamed_section.first != NULL)		lr_error (ldfile, _("\%s: multiple order definitions for unnamed section"),			  "LC_COLLATE");	      else		{		  collate->unnamed_section.next = collate->sections;		  collate->sections = &collate->unnamed_section;		}	    }	  /* Now read the direction names.  */	  read_directions (ldfile, arg, charmap, repertoire, collate);	  /* From now be need the strings untranslated.  */	  ldfile->translate_strings = 0;	  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;	  /* Handle ellipsis at end of list.  */	  if (was_ellipsis != tok_none)	    {	      handle_ellipsis (ldfile, NULL, was_ellipsis, charmap, repertoire,			       collate);	      was_ellipsis = tok_none;	    }	  state = 2;	  lr_ignore_rest (ldfile, 1);	  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 == 1)	    {	      lr_error (ldfile, _("%s: missing `order_end' keyword"),			"LC_COLLATE");	      state = 2;	      /* Handle ellipsis at end of list.  */	      if (was_ellipsis != tok_none)		{		  handle_ellipsis (ldfile, arg, was_ellipsis, charmap,				   repertoire, collate);		  was_ellipsis = tok_none;		}	    }	  else if (state != 2 && state != 3)	    goto err_label;	  state = 3;	  arg = lr_token (ldfile, charmap, repertoire);	  if (arg->tok == tok_bsymbol)	    {	      /* Find this symbol in the sequence table.  */	      struct element_t *insp;	      int no_error = 1;	      if (find_entry (&collate->seq_table, arg->val.str.startmb,			      arg->val.str.lenmb, (void **) &insp) == 0)		/* Yes, the symbol exists.  Simply point the cursor		   to it.  */		  collate->cursor = insp;	      else		{		  /* This is bad.  The symbol after which we have to                     insert does not exist.  */		  lr_error (ldfile, _("\%s: cannot reorder after %.*s: symbol not known"),			    "LC_COLLATE", (int) arg->val.str.lenmb,			    arg->val.str.startmb);		  collate->cursor = NULL;		  no_error = 0;		}	      lr_ignore_rest (ldfile, no_error);	    }	  else	    /* This must not happen.  */	    goto err_label;	  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;	  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 == 1)	    {	      lr_error (ldfile, _("%s: missing `order_end' keyword"),			"LC_COLLATE");	      state = 2;	      /* Handle ellipsis at end of list.  */	      if (was_ellipsis != tok_none)		{		  handle_ellipsis (ldfile, NULL, was_ellipsis, charmap,				   repertoire, collate);		  was_ellipsis = tok_none;		}	    }	  else if (state == 3)	    {	      error (0, 0, _("%s: missing `reorder-end' keyword"),		     "LC_COLLATE");	      state = 4;	    }	  else 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", (int) 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.  */	  if (ignore_content)	    {	      lr_ignore_rest (ldfile, 0);	      break;	    }	  if (state != 1 && state != 3)	    goto err_label;	  if (state == 3)	    {	      /* It is possible that we already have this collation sequence.		 In this case we move the entry.  */	      struct element_t *seqp;	      /* If the symbol after which we have to insert was not found		 ignore all entries.  */	      if (collate->cursor == NULL)		{		  lr_ignore_rest (ldfile, 0);		  break;		}	      if (find_entry (&collate->seq_table, arg->val.str.startmb,			      arg->val.str.lenmb, (void **) &seqp) == 0)		{		  /* Remove the entry from the old position.  */		  if (seqp->last == NULL)		    collate->start = seqp->next;		  else		    seqp->last->next = seqp->next;		  if (seqp->next != NULL)		    seqp->next->last = seqp->last;		  /* We also have to check whether this entry is the                     first or last of a section.  */		  if (seqp->section->first == seqp)		    {		      if (seqp->section->first == seqp->section->last)			/* This setion has no content anymore.  */			seqp->section->first = seqp->section->last = NULL;		      else			seqp->section->first = seqp->next;		    }		  else if (seqp->section->last == seqp)		    seqp->section->last = seqp->last;		  /* Now insert it in the new place.  */		  seqp->next = collate->cursor->next;		  seqp->last = collate->cursor;		  collate->cursor->next = seqp;		  if (seqp->next != NULL)		    seqp->next->last = seqp;		  seqp->section = collate->cursor->section;		  if (seqp->section->last == collate->cursor)		    seqp->section->last = seqp;		  break;		}	      /* 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", (int) 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);		}	      break;	    }	  else if (was_ellipsis != tok_none)	    {	      /* Using the information in the `ellipsis_weight'                 element and this and the last value we have to handle                 the ellipsis now.  */	      assert (state == 1);	      handle_ellipsis (ldfile, arg, was_ellipsis, charmap, repertoire,			       collate);	      /* Remember that we processed the ellipsis.  */	      was_ellipsis = tok_none;	      /* And don't add the value a second time.  */	      break;	    }	  /* Now insert in the new place.  */	  insert_value (ldfile, arg, charmap, repertoire, collate);	  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;	  if (was_ellipsis != tok_none)	    {	      lr_error (ldfile,			_("%s: cannot have `%s' as end of ellipsis range"),			"LC_COLLATE", "UNDEFINED");	      unlink_element (collate);	      was_ellipsis = tok_none;	    }	  /* See whether UNDEFINED already appeared somewhere.  */	  if (collate->undefined.next != NULL	      || (collate->cursor != NULL		  && collate->undefined.next == collate->cursor))	    {	      lr_error (ldfile,			_("%s: order for `%.*s' already defined at %s:%zu"),			"LC_COLLATE", 9, "UNDEFINED", collate->undefined.file,			collate->undefined.line);	      lr_ignore_rest (ldfile, 0);	    }	  else	    /* Parse the weights.  */	     insert_weights (ldfile, &collate->undefined, charmap,			     repertoire, collate, tok_none);	  break;	case tok_ellipsis2:	case tok_ellipsis3:	case tok_ellipsis4:	  /* This is the symbolic (decimal or hexadecimal) or absolute             ellipsis.  */	  if (was_ellipsis != tok_none)	    goto err_label;	  if (state != 1 && state != 3)	    goto err_label;	  was_ellipsis = nowtok;	  insert_weights (ldfile, &collate->ellipsis_weight, charmap,			  repertoire, collate, nowtok);	  break;	case tok_end:	  /* Next we assume `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");		  /* Handle ellipsis at end of list.  */		  if (was_ellipsis != tok_none)		    {		      handle_ellipsis (ldfile, NULL, was_ellipsis, charmap,				       repertoire, collate);		      was_ellipsis = tok_none;		    }		}	      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)	    break;	  if (arg->tok == tok_eol)	    lr_error (ldfile, _("%s: incomplete `END' line"), "LC_COLLATE");	  else if (arg->tok != tok_lc_collate)	    lr_error (ldfile, _("\%1$s: definition does not end with `END %1$s'"), "LC_COLLATE");	  lr_ignore_rest (ldfile, arg->tok == tok_lc_collate);	  return;	default:	err_label:	  SYNTAX_ERROR (_("%s: syntax error"), "LC_COLLATE");	}      /* Prepare for the next round.  */      now = lr_token (ldfile, charmap, NULL);      nowtok = now->tok;    }  /* When we come here we reached the end of the file.  */  lr_error (ldfile, _("%s: premature end of file"), "LC_COLLATE");}