about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog41
-rw-r--r--NEWS5
-rw-r--r--iconv/Makefile1
-rw-r--r--include/locale.h3
-rw-r--r--locale/localeinfo.h4
-rw-r--r--locale/programs/charmap.c16
-rw-r--r--locale/programs/ld-address.c20
-rw-r--r--locale/programs/ld-collate.c128
-rw-r--r--locale/programs/ld-ctype.c228
-rw-r--r--locale/programs/ld-identification.c24
-rw-r--r--locale/programs/ld-measurement.c19
-rw-r--r--locale/programs/ld-messages.c16
-rw-r--r--locale/programs/ld-monetary.c32
-rw-r--r--locale/programs/ld-name.c16
-rw-r--r--locale/programs/ld-numeric.c22
-rw-r--r--locale/programs/ld-paper.c16
-rw-r--r--locale/programs/ld-telephone.c16
-rw-r--r--locale/programs/ld-time.c39
-rw-r--r--locale/programs/linereader.c83
-rw-r--r--locale/programs/linereader.h6
-rw-r--r--locale/programs/localedef.c4
-rw-r--r--locale/programs/localedef.h6
-rw-r--r--locale/programs/locfile.c18
-rw-r--r--locale/programs/locfile.h90
-rw-r--r--locale/programs/repertoire.c4
-rw-r--r--localedata/ChangeLog4
-rw-r--r--localedata/charmaps/TCVN5712-158
27 files changed, 594 insertions, 325 deletions
diff --git a/ChangeLog b/ChangeLog
index 06a70982de..6a8ec41417 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,44 @@
+2001-12-09  Ulrich Drepper  <drepper@redhat.com>
+
+	Implement transliteration of characters in strings of the locale
+	definitions.
+	* locale/programs/linereader.c: Adjust for additional parameter to
+	lr_token.
+	(get_string): If character <Uxxxx> is not found try to transliterate
+	it.
+	* locale/programs/ld-ctype.c: Adjust for additional parameter to
+	lr_token.  Add const to charmap parameter of all functions.
+	(find_translit, find_translit2): New functions.
+	* locale/programs/charmap.c: Adjust for additional parameter to
+	lr_token.
+	* locale/programs/repertoire.c: Likewise.
+	* locale/programs/linereader.h: Likewise.
+	* locale/programs/ld-address.c: Likewise.  Add const to charmap
+	parameter of all functions.
+	* locale/programs/ld-collate.c: Likewise.
+	* locale/programs/ld-identification.c: Likewise.
+	* locale/programs/ld-measurement.c: Likewise.
+	* locale/programs/ld-messages.c: Likewise.
+	* locale/programs/ld-monetary.c: Likewise.
+	* locale/programs/ld-name.c: Likewise.
+	* locale/programs/ld-numeric.c: Likewise.
+	* locale/programs/ld-paper.c: Likewise.
+	* locale/programs/ld-paper.c: Likewise.
+	* locale/programs/ld-telephone.c: Likewise.
+	* locale/programs/ld-time.c: Likewise.
+	* locale/programs/locfile.c: Likewise.
+	* locale/programs/localedef.c: Likewise.
+	* locale/programs/localedef.h: Likewise.
+	* locale/programs/locfile.h: Likewise.  Add declaration for
+	find_translit.
+	* locale/programs/simple-hash.c: Add const to first parameter of
+	find_entry, iterate_table, and lookup.
+	* locale/programs/simple-hash.h: Likewise.
+	* locale/localeinfo.h: Don't define __LC_LAST here.  Include <locale.h>
+	instead.
+	* include/locale.h: Define __LC_LAST.
+	* iconv/Makefile (CFLAGS-linereader.c): Define to -DNO_TRANSLITERATION.
+
 2001-12-07  Geoff Keating  <geoffk@redhat.com>
 
 	* sysdeps/powerpc/Dist: Update for recent FP changes.
diff --git a/NEWS b/NEWS
index 032fcd5001..0ed344196a 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU C Library NEWS -- history of user-visible changes.  2001-11-28
+GNU C Library NEWS -- history of user-visible changes.  2001-12-09
 Copyright (C) 1992-2000, 2001 Free Software Foundation, Inc.
 See the end for copying conditions.
 
@@ -12,6 +12,9 @@ Version 2.3
 
 * iconv (the program and the interface) now accepts empty names (excluding
   options like //TRANSLIT) to mean "use charset of current locale".
+
+* localedef now can transliterate characters in strings which are not in
+  the provided charmap.  The information from the input locale is used.
 
 Version 2.2.5
 
diff --git a/iconv/Makefile b/iconv/Makefile
index c5d0cd3833..155089b183 100644
--- a/iconv/Makefile
+++ b/iconv/Makefile
@@ -46,6 +46,7 @@ CFLAGS-iconv_charmap.c = -I../locale/programs
 CFLAGS-dummy-repertoire.c = -I../locale/programs
 CFLAGS-charmap.c = -DCHARMAP_PATH='"$(i18ndir)/charmaps"' \
 		   -DDEFAULT_CHARMAP=null_pointer -DNEED_NULL_POINTER
+CFLAGS-linereader.c = -DNO_TRANSLITERATION
 
 tests	= tst-iconv1 tst-iconv2 tst-iconv3
 
diff --git a/include/locale.h b/include/locale.h
index 4374792d14..0877a48775 100644
--- a/include/locale.h
+++ b/include/locale.h
@@ -1,6 +1,9 @@
 #ifndef	_LOCALE_H
 #include <locale/locale.h>
 
+/* This has to be changed whenever a new locale is defined.  */
+#define __LC_LAST	13
+
 /* Locale object for C locale.  */
 extern struct __locale_struct _nl_C_locobj;
 
diff --git a/locale/localeinfo.h b/locale/localeinfo.h
index e7528e9edb..6cd7f0dca2 100644
--- a/locale/localeinfo.h
+++ b/locale/localeinfo.h
@@ -23,13 +23,11 @@
 #include <stddef.h>
 #include <langinfo.h>
 #include <limits.h>
+#include <locale.h>
 #include <time.h>
 #include <stdint.h>
 #include <sys/types.h>
 
-/* This has to be changed whenever a new locale is defined.  */
-#define __LC_LAST	13
-
 #include <intl/loadinfo.h>	/* For loaded_l10nfile definition.  */
 
 /* Magic number at the beginning of a locale data file for CATEGORY.  */
diff --git a/locale/programs/charmap.c b/locale/programs/charmap.c
index 5d2441d17a..7840242d8d 100644
--- a/locale/programs/charmap.c
+++ b/locale/programs/charmap.c
@@ -117,18 +117,14 @@ charmap_read (const char *filename, int verbose, int be_quiet, int use_default)
 		      cmfile = cmlr_open (path, filename, charmap_hash);
 
 		      if (cmfile == NULL)
-			{
-			  /* Try without the "/charmaps" part.  */
-			  cmfile = cmlr_open (next, filename, charmap_hash);
-			}
+			/* Try without the "/charmaps" part.  */
+			cmfile = cmlr_open (next, filename, charmap_hash);
 		    }
 		}
 
 	      if (cmfile == NULL)
-		{
-		  /* Try the default directory.  */
-		  cmfile = cmlr_open (CHARMAP_PATH, filename, charmap_hash);
-		}
+		/* Try the default directory.  */
+		cmfile = cmlr_open (CHARMAP_PATH, filename, charmap_hash);
 	    }
 	}
 
@@ -298,7 +294,7 @@ parse_charmap (struct linereader *cmfile, int verbose, int be_quiet)
   while (1)
     {
       /* What's on?  */
-      struct token *now = lr_token (cmfile, NULL, NULL, verbose);
+      struct token *now = lr_token (cmfile, NULL, NULL, NULL, verbose);
       enum token_t nowtok = now->tok;
       struct token *arg;
 
@@ -356,7 +352,7 @@ parse_charmap (struct linereader *cmfile, int verbose, int be_quiet)
 	    }
 
 	  /* We know that we need an argument.  */
-	  arg = lr_token (cmfile, NULL, NULL, verbose);
+	  arg = lr_token (cmfile, NULL, NULL, NULL, verbose);
 
 	  switch (nowtok)
 	    {
diff --git a/locale/programs/ld-address.c b/locale/programs/ld-address.c
index 96866a2ef6..adf6bbeb28 100644
--- a/locale/programs/ld-address.c
+++ b/locale/programs/ld-address.c
@@ -95,7 +95,7 @@ address_startup (struct linereader *lr, struct localedef_t *locale,
 
 
 void
-address_finish (struct localedef_t *locale, struct charmap_t *charmap)
+address_finish (struct localedef_t *locale, const struct charmap_t *charmap)
 {
   struct locale_address_t *address = locale->categories[LC_ADDRESS].address;
   size_t cnt;
@@ -324,7 +324,7 @@ address_finish (struct localedef_t *locale, struct charmap_t *charmap)
 
 
 void
-address_output (struct localedef_t *locale, struct charmap_t *charmap,
+address_output (struct localedef_t *locale, const struct charmap_t *charmap,
 		const char *output_path)
 {
   struct locale_address_t *address = locale->categories[LC_ADDRESS].address;
@@ -425,7 +425,7 @@ address_output (struct localedef_t *locale, struct charmap_t *charmap,
 /* The parser for the LC_ADDRESS section of the locale definition.  */
 void
 address_read (struct linereader *ldfile, struct localedef_t *result,
-	      struct charmap_t *charmap, const char *repertoire_name,
+	      const struct charmap_t *charmap, const char *repertoire_name,
 	      int ignore_content)
 {
   struct locale_address_t *address;
@@ -439,7 +439,7 @@ address_read (struct linereader *ldfile, struct localedef_t *result,
 
   do
     {
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
   while (nowtok == tok_eol);
@@ -465,7 +465,7 @@ address_read (struct linereader *ldfile, struct localedef_t *result,
       /* Ignore empty lines.  */
       if (nowtok == tok_eol)
 	{
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  nowtok = now->tok;
 	  continue;
 	}
@@ -482,7 +482,7 @@ address_read (struct linereader *ldfile, struct localedef_t *result,
 	      break;							      \
 	    }								      \
 									      \
-	  arg = lr_token (ldfile, charmap, NULL, verbose);		      \
+	  arg = lr_token (ldfile, charmap, result, NULL, verbose);	      \
 	  if (arg->tok != tok_string)					      \
 	    goto err_label;						      \
 	  if (address->cat != NULL)					      \
@@ -519,7 +519,7 @@ address_read (struct linereader *ldfile, struct localedef_t *result,
 	      break;							      \
 	    }								      \
 									      \
-	  arg = lr_token (ldfile, charmap, NULL, verbose);		      \
+	  arg = lr_token (ldfile, charmap, result, NULL, verbose);	      \
 	  if (arg->tok != tok_string && arg->tok != tok_number)		      \
 	    goto err_label;						      \
 	  if (address->cat != NULL)					      \
@@ -557,7 +557,7 @@ address_read (struct linereader *ldfile, struct localedef_t *result,
 	      break;							      \
 	    }								      \
 									      \
-	  arg = lr_token (ldfile, charmap, NULL, verbose);		      \
+	  arg = lr_token (ldfile, charmap, result, NULL, verbose);	      \
 	  if (arg->tok != tok_number)					      \
 	    goto err_label;						      \
 	  else if (address->cat != 0)					      \
@@ -571,7 +571,7 @@ address_read (struct linereader *ldfile, struct localedef_t *result,
 
 	case tok_end:
 	  /* Next we assume `LC_ADDRESS'.  */
-	  arg = lr_token (ldfile, charmap, NULL, verbose);
+	  arg = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (arg->tok == tok_eof)
 	    break;
 	  if (arg->tok == tok_eol)
@@ -589,7 +589,7 @@ address_read (struct linereader *ldfile, struct localedef_t *result,
 	}
 
       /* Prepare for the next round.  */
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
 
diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
index 6d238a658e..4f587c113c 100644
--- a/locale/programs/ld-collate.c
+++ b/locale/programs/ld-collate.c
@@ -384,8 +384,9 @@ new_symbol (struct locale_collate_t *collate, const char *name, size_t len)
 /* Test whether this name is already defined somewhere.  */
 static int
 check_duplicate (struct linereader *ldfile, struct locale_collate_t *collate,
-		 struct charmap_t *charmap, struct repertoire_t *repertoire,
-		 const char *symbol, size_t symbol_len)
+		 const struct charmap_t *charmap,
+		 struct repertoire_t *repertoire, const char *symbol,
+		 size_t symbol_len)
 {
   void *ignore = NULL;
 
@@ -426,13 +427,14 @@ check_duplicate (struct linereader *ldfile, struct locale_collate_t *collate,
 /* Read the direction specification.  */
 static void
 read_directions (struct linereader *ldfile, struct token *arg,
-		 struct charmap_t *charmap, struct repertoire_t *repertoire,
-		 struct locale_collate_t *collate)
+		 const struct charmap_t *charmap,
+		 struct repertoire_t *repertoire, struct localedef_t *result)
 {
   int cnt = 0;
   int max = nrules ?: 10;
   enum coll_sort_rule *rules = calloc (max, sizeof (*rules));
   int warned = 0;
+  struct locale_collate_t *collate = result->categories[LC_COLLATE].collate;
 
   while (1)
     {
@@ -508,7 +510,7 @@ read_directions (struct linereader *ldfile, struct token *arg,
 	}
 
       if (valid)
-	arg = lr_token (ldfile, charmap, repertoire, verbose);
+	arg = lr_token (ldfile, charmap, result, repertoire, verbose);
 
       if (arg->tok == tok_eof || arg->tok == tok_eol || arg->tok == tok_comma
 	  || arg->tok == tok_semicolon)
@@ -572,7 +574,7 @@ read_directions (struct linereader *ldfile, struct token *arg,
 	    }
 	}
 
-      arg = lr_token (ldfile, charmap, repertoire, verbose);
+      arg = lr_token (ldfile, charmap, result, repertoire, verbose);
     }
 
   if (nrules == 0)
@@ -660,11 +662,13 @@ unlink_element (struct locale_collate_t *collate)
 
 static void
 insert_weights (struct linereader *ldfile, struct element_t *elem,
-		struct charmap_t *charmap, struct repertoire_t *repertoire,
-		struct locale_collate_t *collate, enum token_t ellipsis)
+		const struct charmap_t *charmap,
+		struct repertoire_t *repertoire, struct localedef_t *result,
+		enum token_t ellipsis)
 {
   int weight_cnt;
   struct token *arg;
+  struct locale_collate_t *collate = result->categories[LC_COLLATE].collate;
 
   /* Initialize all the fields.  */
   elem->file = ldfile->fname;
@@ -697,7 +701,7 @@ insert_weights (struct linereader *ldfile, struct element_t *elem,
 
   weight_cnt = 0;
 
-  arg = lr_token (ldfile, charmap, repertoire, verbose);
+  arg = lr_token (ldfile, charmap, result, repertoire, verbose);
   do
     {
       if (arg->tok == tok_eof || arg->tok == tok_eol)
@@ -867,11 +871,11 @@ insert_weights (struct linereader *ldfile, struct element_t *elem,
 	  break;
 	}
 
-      arg = lr_token (ldfile, charmap, repertoire, verbose);
+      arg = lr_token (ldfile, charmap, result, repertoire, verbose);
       /* This better should be the end of the line or a semicolon.  */
       if (arg->tok == tok_semicolon)
 	/* OK, ignore this and read the next token.  */
-	arg = lr_token (ldfile, charmap, repertoire, verbose);
+	arg = lr_token (ldfile, charmap, result, repertoire, verbose);
       else if (arg->tok != tok_eof && arg->tok != tok_eol)
 	{
 	  /* It's a syntax error.  */
@@ -914,13 +918,14 @@ insert_weights (struct linereader *ldfile, struct element_t *elem,
 
 static int
 insert_value (struct linereader *ldfile, const char *symstr, size_t symlen,
-	      struct charmap_t *charmap, struct repertoire_t *repertoire,
-	      struct locale_collate_t *collate)
+	      const struct charmap_t *charmap, struct repertoire_t *repertoire,
+	      struct localedef_t *result)
 {
   /* First find out what kind of symbol this is.  */
   struct charseq *seq;
   uint32_t wc;
   struct element_t *elem = NULL;
+  struct locale_collate_t *collate = result->categories[LC_COLLATE].collate;
 
   /* Try to find the character in the charmap.  */
   seq = charmap_find_value (charmap, symstr, symlen);
@@ -1021,7 +1026,7 @@ insert_value (struct linereader *ldfile, const char *symstr, size_t symlen,
       return 1;
     }
 
-  insert_weights (ldfile, elem, charmap, repertoire, collate, tok_none);
+  insert_weights (ldfile, elem, charmap, repertoire, result, tok_none);
 
   return 0;
 }
@@ -1029,12 +1034,13 @@ insert_value (struct linereader *ldfile, const char *symstr, size_t symlen,
 
 static void
 handle_ellipsis (struct linereader *ldfile, const char *symstr, size_t symlen,
-		 enum token_t ellipsis, struct charmap_t *charmap,
+		 enum token_t ellipsis, const struct charmap_t *charmap,
 		 struct repertoire_t *repertoire,
-		 struct locale_collate_t *collate)
+		 struct localedef_t *result)
 {
   struct element_t *startp;
   struct element_t *endp;
+  struct locale_collate_t *collate = result->categories[LC_COLLATE].collate;
 
   /* Unlink the entry added for the ellipsis.  */
   unlink_element (collate);
@@ -1042,7 +1048,7 @@ handle_ellipsis (struct linereader *ldfile, const char *symstr, size_t symlen,
 
   /* Process and add the end-entry.  */
   if (symstr != NULL
-      && insert_value (ldfile, symstr, symlen, charmap, repertoire, collate))
+      && insert_value (ldfile, symstr, symlen, charmap, repertoire, result))
     /* Something went wrong with inserting the to-value.  This means
        we cannot process the ellipsis.  */
     return;
@@ -1469,7 +1475,7 @@ collate_startup (struct linereader *ldfile, struct localedef_t *locale,
 
 
 void
-collate_finish (struct localedef_t *locale, struct charmap_t *charmap)
+collate_finish (struct localedef_t *locale, const struct charmap_t *charmap)
 {
   /* Now is the time when we can assign the individual collation
      values for all the symbols.  We have possibly different values
@@ -1897,7 +1903,7 @@ output_weightwc (struct obstack *pool, struct locale_collate_t *collate,
 
 
 void
-collate_output (struct localedef_t *locale, struct charmap_t *charmap,
+collate_output (struct localedef_t *locale, const struct charmap_t *charmap,
 		const char *output_path)
 {
   struct locale_collate_t *collate = locale->categories[LC_COLLATE].collate;
@@ -2555,7 +2561,7 @@ collate_output (struct localedef_t *locale, struct charmap_t *charmap,
 
 void
 collate_read (struct linereader *ldfile, struct localedef_t *result,
-	      struct charmap_t *charmap, const char *repertoire_name,
+	      const struct charmap_t *charmap, const char *repertoire_name,
 	      int ignore_content)
 {
   struct repertoire_t *repertoire = NULL;
@@ -2585,7 +2591,7 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
 
   do
     {
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
   while (nowtok == tok_eol);
@@ -2593,18 +2599,18 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
   if (nowtok == tok_copy)
     {
       state = 2;
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       if (now->tok != tok_string)
 	{
 	  SYNTAX_ERROR (_("%s: syntax error"), "LC_COLLATE");
 
 	skip_category:
 	  do
-	    now = lr_token (ldfile, charmap, NULL, verbose);
+	    now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  while (now->tok != tok_eof && now->tok != tok_end);
 
 	  if (now->tok != tok_eof
-	      || (now = lr_token (ldfile, charmap, NULL, verbose),
+	      || (now = lr_token (ldfile, charmap, result, NULL, verbose),
 		  now->tok == tok_eof))
 	    lr_error (ldfile, _("%s: premature end of file"), "LC_COLLATE");
 	  else if (now->tok != tok_lc_collate)
@@ -2634,7 +2640,7 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
 
       lr_ignore_rest (ldfile, 1);
 
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
 
@@ -2655,7 +2661,7 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
       /* Ingore empty lines.  */
       if (nowtok == tok_eol)
 	{
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  nowtok = now->tok;
 	  continue;
 	}
@@ -2664,7 +2670,7 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
 	{
 	case tok_copy:
 	  /* Allow copying other locales.  */
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (now->tok != tok_string)
 	    goto err_label;
 
@@ -2687,7 +2693,7 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
 	  if (state != 0)
 	    goto err_label;
 
-	  arg = lr_token (ldfile, charmap, NULL, verbose);
+	  arg = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (arg->tok != tok_number)
 	    goto err_label;
 	  if (collate->col_weight_max != -1)
@@ -2710,7 +2716,7 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
 	  if (state != 0)
 	    goto err_label;
 
-	  arg = lr_token (ldfile, charmap, repertoire, verbose);
+	  arg = lr_token (ldfile, charmap, result, repertoire, verbose);
 	  if (arg->tok != tok_bsymbol)
 	    goto err_label;
 	  else if (!ignore_content)
@@ -2757,7 +2763,7 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
 	  if (state != 0 && state != 2)
 	    goto err_label;
 
-	  arg = lr_token (ldfile, charmap, repertoire, verbose);
+	  arg = lr_token (ldfile, charmap, result, repertoire, verbose);
 	  if (arg->tok != tok_bsymbol)
 	    goto err_label;
 	  else
@@ -2766,7 +2772,7 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
 	      size_t symbol_len = arg->val.str.lenmb;
 
 	      /* Next the `from' keyword.  */
-	      arg = lr_token (ldfile, charmap, repertoire, verbose);
+	      arg = lr_token (ldfile, charmap, result, repertoire, verbose);
 	      if (arg->tok != tok_from)
 		{
 		  free ((char *) symbol);
@@ -2777,7 +2783,7 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
 	      ldfile->translate_strings = 1;
 
 	      /* Finally the string with the replacement.  */
-	      arg = lr_token (ldfile, charmap, repertoire, verbose);
+	      arg = lr_token (ldfile, charmap, result, repertoire, verbose);
 
 	      ldfile->return_widestr = 0;
 	      ldfile->translate_strings = 0;
@@ -2826,7 +2832,7 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
 	  if (state != 0 && state != 2)
 	    goto err_label;
 
-	  arg = lr_token (ldfile, charmap, repertoire, verbose);
+	  arg = lr_token (ldfile, charmap, result, repertoire, verbose);
 	  if (arg->tok != tok_bsymbol)
 	    goto err_label;
 	  else
@@ -2837,12 +2843,13 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
 	      size_t endsymbol_len = 0;
 	      enum token_t ellipsis = tok_none;
 
-	      arg = lr_token (ldfile, charmap, repertoire, verbose);
+	      arg = lr_token (ldfile, charmap, result, repertoire, verbose);
 	      if (arg->tok == tok_ellipsis2 || arg->tok == tok_ellipsis4)
 		{
 		  ellipsis = arg->tok;
 
-		  arg = lr_token (ldfile, charmap, repertoire, verbose);
+		  arg = lr_token (ldfile, charmap, result, repertoire,
+				  verbose);
 		  if (arg->tok != tok_bsymbol)
 		    {
 		      free (symbol);
@@ -2973,7 +2980,7 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
 	  if (state != 0)
 	    goto err_label;
 
-	  arg = lr_token (ldfile, charmap, repertoire, verbose);
+	  arg = lr_token (ldfile, charmap, result, repertoire, verbose);
 	  if (arg->tok != tok_bsymbol)
 	    goto err_label;
 	  else
@@ -2984,7 +2991,7 @@ collate_read (struct linereader *ldfile, struct localedef_t *result,
 	      size_t symname_len;
 	      struct symbol_t *symval;
 
-	      arg = lr_token (ldfile, charmap, repertoire, verbose);
+	      arg = lr_token (ldfile, charmap, result, repertoire, verbose);
 	      if (arg->tok != tok_bsymbol)
 		{
 		  if (newname != NULL)
@@ -3041,7 +3048,7 @@ error while adding equivalent collating symbol"));
 
 	case tok_script:
 	  /* We get told about the scripts we know.  */
-	  arg = lr_token (ldfile, charmap, repertoire, verbose);
+	  arg = lr_token (ldfile, charmap, result, repertoire, verbose);
 	  if (arg->tok != tok_bsymbol)
 	    goto err_label;
 	  else
@@ -3093,7 +3100,7 @@ error while adding equivalent collating symbol"));
 	  /* 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, verbose);
+	  arg = lr_token (ldfile, charmap, result, repertoire, verbose);
 	  if (arg->tok == tok_bsymbol)
 	    {
 	      /* This better should be a section name.  */
@@ -3152,7 +3159,8 @@ error while adding equivalent collating symbol"));
 		    }
 
 		  /* Next should come the end of the line or a semicolon.  */
-		  arg = lr_token (ldfile, charmap, repertoire, verbose);
+		  arg = lr_token (ldfile, charmap, result, repertoire,
+				  verbose);
 		  if (arg->tok == tok_eol)
 		    {
 		      uint32_t cnt;
@@ -3175,7 +3183,8 @@ error while adding equivalent collating symbol"));
 		    }
 
 		  /* Get the next token.  */
-		  arg = lr_token (ldfile, charmap, repertoire, verbose);
+		  arg = lr_token (ldfile, charmap, result, repertoire,
+				  verbose);
 		}
 	    }
 	  else
@@ -3198,7 +3207,7 @@ error while adding equivalent collating symbol"));
 	    }
 
 	  /* Now read the direction names.  */
-	  read_directions (ldfile, arg, charmap, repertoire, collate);
+	  read_directions (ldfile, arg, charmap, repertoire, result);
 
 	  /* From now we need the strings untranslated.  */
 	  ldfile->translate_strings = 0;
@@ -3220,7 +3229,7 @@ error while adding equivalent collating symbol"));
 	  if (was_ellipsis != tok_none)
 	    {
 	      handle_ellipsis (ldfile, NULL, 0, was_ellipsis, charmap,
-			       repertoire, collate);
+			       repertoire, result);
 	      was_ellipsis = tok_none;
 	    }
 
@@ -3248,7 +3257,7 @@ error while adding equivalent collating symbol"));
 		{
 		  handle_ellipsis (ldfile, arg->val.str.startmb,
 				   arg->val.str.lenmb, was_ellipsis, charmap,
-				   repertoire, collate);
+				   repertoire, result);
 		  was_ellipsis = tok_none;
 		}
 	    }
@@ -3256,7 +3265,7 @@ error while adding equivalent collating symbol"));
 	    goto err_label;
 	  state = 3;
 
-	  arg = lr_token (ldfile, charmap, repertoire, verbose);
+	  arg = lr_token (ldfile, charmap, result, repertoire, verbose);
 	  if (arg->tok == tok_bsymbol || arg->tok == tok_ucs4)
 	    {
 	      /* Find this symbol in the sequence table.  */
@@ -3370,7 +3379,7 @@ error while adding equivalent collating symbol"));
 	      if (was_ellipsis != tok_none)
 		{
 		  handle_ellipsis (ldfile, NULL, 0, was_ellipsis, charmap,
-				   repertoire, collate);
+				   repertoire, result);
 		  was_ellipsis = tok_none;
 		}
 	    }
@@ -3385,7 +3394,7 @@ error while adding equivalent collating symbol"));
 	  state = 5;
 
 	  /* Get the name of the sections we are adding after.  */
-	  arg = lr_token (ldfile, charmap, repertoire, verbose);
+	  arg = lr_token (ldfile, charmap, result, repertoire, verbose);
 	  if (arg->tok == tok_bsymbol)
 	    {
 	      /* Now find a section with this name.  */
@@ -3418,7 +3427,7 @@ error while adding equivalent collating symbol"));
 		    {
 		      lr_ignore_rest (ldfile, 0);
 
-		      now = lr_token (ldfile, charmap, NULL, verbose);
+		      now = lr_token (ldfile, charmap, result, NULL, verbose);
 		    }
 		  while (now->tok == tok_reorder_sections_after
 			 || now->tok == tok_reorder_sections_end
@@ -3512,7 +3521,7 @@ error while adding equivalent collating symbol"));
 		{
 
 		  handle_ellipsis (ldfile, symstr, symlen, was_ellipsis,
-				   charmap, repertoire, collate);
+				   charmap, repertoire, result);
 
 		  /* Remember that we processed the ellipsis.  */
 		  was_ellipsis = tok_none;
@@ -3572,7 +3581,7 @@ error while adding equivalent collating symbol"));
 		    seqp->section->last = seqp->last;
 
 		  /* Now insert it in the new place.  */
-		  insert_weights (ldfile, seqp, charmap, repertoire, collate,
+		  insert_weights (ldfile, seqp, charmap, repertoire, result,
 				  tok_none);
 		  break;
 		}
@@ -3617,10 +3626,11 @@ error while adding equivalent collating symbol"));
 
 		  /* Process the rest of the line which might change
                      the collation rules.  */
-		  arg = lr_token (ldfile, charmap, repertoire, verbose);
+		  arg = lr_token (ldfile, charmap, result, repertoire,
+				  verbose);
 		  if (arg->tok != tok_eof && arg->tok != tok_eol)
 		    read_directions (ldfile, arg, charmap, repertoire,
-				     collate);
+				     result);
 		}
 	      break;
 	    }
@@ -3632,7 +3642,7 @@ error while adding equivalent collating symbol"));
 	      assert (state == 1);
 
 	      handle_ellipsis (ldfile, symstr, symlen, was_ellipsis, charmap,
-			       repertoire, collate);
+			       repertoire, result);
 
 	      /* Remember that we processed the ellipsis.  */
 	      was_ellipsis = tok_none;
@@ -3642,7 +3652,7 @@ error while adding equivalent collating symbol"));
 	    }
 
 	  /* Now insert in the new place.  */
-	  insert_value (ldfile, symstr, symlen, charmap, repertoire, collate);
+	  insert_value (ldfile, symstr, symlen, charmap, repertoire, result);
 	  break;
 
 	case tok_undefined:
@@ -3681,7 +3691,7 @@ error while adding equivalent collating symbol"));
 	  else
 	    /* Parse the weights.  */
 	     insert_weights (ldfile, &collate->undefined, charmap,
-			     repertoire, collate, tok_none);
+			     repertoire, result, tok_none);
 	  break;
 
 	case tok_ellipsis2: /* symbolic hexadecimal ellipsis */
@@ -3698,7 +3708,7 @@ error while adding equivalent collating symbol"));
 	  was_ellipsis = nowtok;
 
 	  insert_weights (ldfile, &collate->ellipsis_weight, charmap,
-			  repertoire, collate, nowtok);
+			  repertoire, result, nowtok);
 	  break;
 
 	case tok_end:
@@ -3720,7 +3730,7 @@ error while adding equivalent collating symbol"));
 		  if (was_ellipsis != tok_none)
 		    {
 		      handle_ellipsis (ldfile, NULL, 0, was_ellipsis, charmap,
-				       repertoire, collate);
+				       repertoire, result);
 		      was_ellipsis = tok_none;
 		    }
 		}
@@ -3731,7 +3741,7 @@ error while adding equivalent collating symbol"));
 		error (0, 0, _("%s: missing `reorder-sections-end' keyword"),
 		       "LC_COLLATE");
 	    }
-	  arg = lr_token (ldfile, charmap, NULL, verbose);
+	  arg = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (arg->tok == tok_eof)
 	    break;
 	  if (arg->tok == tok_eol)
@@ -3748,7 +3758,7 @@ error while adding equivalent collating symbol"));
 	}
 
       /* Prepare for the next round.  */
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
 
diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c
index fbcf388cb7..c1a92d861d 100644
--- a/locale/programs/ld-ctype.c
+++ b/locale/programs/ld-ctype.c
@@ -205,6 +205,7 @@ struct locale_ctype_t
   struct obstack mempool;
 };
 
+
 /* Marker for an empty slot.  This has the value 0xFFFFFFFF, regardless
    whether 'int' is 16 bit, 32 bit, or 64 bit.  */
 #define EMPTY ((uint32_t) ~0)
@@ -216,21 +217,21 @@ struct locale_ctype_t
 
 /* Prototypes for local functions.  */
 static void ctype_startup (struct linereader *lr, struct localedef_t *locale,
-			   struct charmap_t *charmap,
+			   const struct charmap_t *charmap,
 			   struct localedef_t *copy_locale,
 			   int ignore_content);
 static void ctype_class_new (struct linereader *lr,
 			     struct locale_ctype_t *ctype, const char *name);
 static void ctype_map_new (struct linereader *lr,
 			   struct locale_ctype_t *ctype,
-			   const char *name, struct charmap_t *charmap);
+			   const char *name, const struct charmap_t *charmap);
 static uint32_t *find_idx (struct locale_ctype_t *ctype, uint32_t **table,
 			   size_t *max, size_t *act, unsigned int idx);
 static void set_class_defaults (struct locale_ctype_t *ctype,
-				struct charmap_t *charmap,
+				const struct charmap_t *charmap,
 				struct repertoire_t *repertoire);
 static void allocate_arrays (struct locale_ctype_t *ctype,
-			     struct charmap_t *charmap,
+			     const struct charmap_t *charmap,
 			     struct repertoire_t *repertoire);
 
 
@@ -249,8 +250,8 @@ static const unsigned char digits[] = "0123456789";
 
 static void
 ctype_startup (struct linereader *lr, struct localedef_t *locale,
-	       struct charmap_t *charmap, struct localedef_t *copy_locale,
-	       int ignore_content)
+	       const struct charmap_t *charmap,
+	       struct localedef_t *copy_locale, int ignore_content)
 {
   unsigned int cnt;
   struct locale_ctype_t *ctype;
@@ -347,7 +348,7 @@ ctype_startup (struct linereader *lr, struct localedef_t *locale,
 
 
 void
-ctype_finish (struct localedef_t *locale, struct charmap_t *charmap)
+ctype_finish (struct localedef_t *locale, const struct charmap_t *charmap)
 {
   /* See POSIX.2, table 2-6 for the meaning of the following table.  */
 #define NCLASS 12
@@ -727,7 +728,7 @@ character '%s' in class `%s' must not be in class `%s'"),
     {
       if (ctype->mbdigits_max == 0)
 	{
-	  ctype->mbdigits = obstack_alloc (&charmap->mem_pool,
+	  ctype->mbdigits = obstack_alloc (&((struct charmap_t *) charmap)->mem_pool,
 					   10 * sizeof (struct charseq *));
 	  ctype->mbdigits_max = 10;
 	}
@@ -747,7 +748,7 @@ character '%s' in class `%s' must not be in class `%s'"),
 		  error (0, 0, _("\
 no input digits defined and none of the standard names in the charmap"));
 
-		  ctype->mbdigits[cnt] = obstack_alloc (&charmap->mem_pool,
+		  ctype->mbdigits[cnt] = obstack_alloc (&((struct charmap_t *) charmap)->mem_pool,
 							sizeof (struct charseq) + 1);
 
 		  /* This is better than nothing.  */
@@ -789,7 +790,7 @@ no input digits defined and none of the standard names in the charmap"));
     {
       if (ctype->wcdigits_max == 0)
 	{
-	  ctype->wcdigits = obstack_alloc (&charmap->mem_pool,
+	  ctype->wcdigits = obstack_alloc (&((struct charmap_t *) charmap)->mem_pool,
 					   10 * sizeof (uint32_t));
 	  ctype->wcdigits_max = 10;
 	}
@@ -864,7 +865,7 @@ not all characters used in `outdigit' are available in the repertoire"));
 
 
 void
-ctype_output (struct localedef_t *locale, struct charmap_t *charmap,
+ctype_output (struct localedef_t *locale, const struct charmap_t *charmap,
 	      const char *output_path)
 {
   static const char nulbytes[4] = { 0, 0, 0, 0 };
@@ -1236,7 +1237,7 @@ implementation limit: no more than %Zd character classes allowed"),
 
 static void
 ctype_map_new (struct linereader *lr, struct locale_ctype_t *ctype,
-	       const char *name, struct charmap_t *charmap)
+	       const char *name, const struct charmap_t *charmap)
 {
   size_t max_chars = 0;
   size_t cnt;
@@ -1346,7 +1347,7 @@ find_idx (struct locale_ctype_t *ctype, uint32_t **table, size_t *max,
 
 
 static int
-get_character (struct token *now, struct charmap_t *charmap,
+get_character (struct token *now, const struct charmap_t *charmap,
 	       struct repertoire_t *repertoire,
 	       struct charseq **seqp, uint32_t *wchp)
 {
@@ -1430,7 +1431,7 @@ get_character (struct token *now, struct charmap_t *charmap,
 static void
 charclass_symbolic_ellipsis (struct linereader *ldfile,
 			     struct locale_ctype_t *ctype,
-			     struct charmap_t *charmap,
+			     const struct charmap_t *charmap,
 			     struct repertoire_t *repertoire,
 			     struct token *now,
 			     const char *last_str,
@@ -1542,7 +1543,7 @@ charclass_symbolic_ellipsis (struct linereader *ldfile,
 static void
 charclass_ucs4_ellipsis (struct linereader *ldfile,
 			 struct locale_ctype_t *ctype,
-			 struct charmap_t *charmap,
+			 const struct charmap_t *charmap,
 			 struct repertoire_t *repertoire,
 			 struct token *now, uint32_t last_wch,
 			 unsigned long int class256_bit,
@@ -1667,7 +1668,7 @@ to-value <U%0*X> of range is smaller than from-value <U%0*X>"),
 static void
 charclass_charcode_ellipsis (struct linereader *ldfile,
 			     struct locale_ctype_t *ctype,
-			     struct charmap_t *charmap,
+			     const struct charmap_t *charmap,
 			     struct repertoire_t *repertoire,
 			     struct token *now, char *last_charcode,
 			     uint32_t last_charcode_len,
@@ -1775,10 +1776,104 @@ to-value character sequence is smaller than from-value sequence"));
 }
 
 
+static uint32_t *
+find_translit2 (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
+		uint32_t wch)
+{
+  struct translit_t *trunp = ctype->translit;
+  struct translit_ignore_t *tirunp = ctype->translit_ignore;
+
+  while (trunp != NULL)
+    {
+      /* XXX We simplify things here.  The transliterations we look
+	 for are only allowed to have one character.  */
+      if (trunp->from[0] == wch && trunp->from[1] == 0)
+	{
+	  /* Found it.  Now look for a transliteration which can be
+	     represented with the character set.  */
+	  struct translit_to_t *torunp = trunp->to;
+
+	  while (torunp != NULL)
+	    {
+	      int i;
+
+	      for (i = 0; torunp->str[i] != 0; ++i)
+		{
+		  char utmp[10];
+
+		  snprintf (utmp, sizeof (utmp), "U%08X", torunp->str[i]);
+		  if (charmap_find_value (charmap, utmp, 9) == NULL)
+		    /* This character cannot be represented.  */
+		    break;
+		}
+
+	      if (torunp->str[i] == 0)
+		return torunp->str;
+
+	      torunp = torunp->next;
+	    }
+
+	  break;
+	}
+
+      trunp = trunp->next;
+    }
+
+  /* Check for ignored chars.  */
+  while (tirunp != NULL)
+    {
+      if (tirunp->from <= wch && tirunp->to >= wch)
+	{
+	  uint32_t wi;
+
+	  for (wi = tirunp->from; wi <= wch; wi += tirunp->step)
+	    if (wi == wch)
+	      return (uint32_t []) { 0 };
+	}
+    }
+
+  /* Nothing found.  */
+  return NULL;
+}
+
+
+uint32_t *
+find_translit (struct localedef_t *locale, const struct charmap_t *charmap,
+	       uint32_t wch)
+{
+  struct locale_ctype_t *ctype;
+  uint32_t *result = NULL;
+
+  assert (locale != NULL);
+  ctype = locale->categories[LC_CTYPE].ctype;
+
+  if (ctype->translit != NULL)
+    result = find_translit2 (ctype, charmap, wch);
+
+  if (result == NULL)
+    {
+      struct translit_include_t *irunp = ctype->translit_include;
+
+      while (irunp != NULL && result == NULL)
+	{
+	  result = find_translit (find_locale (CTYPE_LOCALE,
+					       irunp->copy_locale,
+					       irunp->copy_repertoire,
+					       charmap),
+				  charmap, wch);
+	  irunp = irunp->next;
+	}
+    }
+
+  return result;
+}
+
+
 /* Read one transliteration entry.  */
 static uint32_t *
 read_widestring (struct linereader *ldfile, struct token *now,
-		 struct charmap_t *charmap, struct repertoire_t *repertoire)
+		 const struct charmap_t *charmap,
+		 struct repertoire_t *repertoire)
 {
   uint32_t *wstr;
 
@@ -1848,7 +1943,7 @@ read_widestring (struct linereader *ldfile, struct token *now,
 
 static void
 read_translit_entry (struct linereader *ldfile, struct locale_ctype_t *ctype,
-		     struct token *now, struct charmap_t *charmap,
+		     struct token *now, const struct charmap_t *charmap,
 		     struct repertoire_t *repertoire)
 {
   uint32_t *from_wstr = read_widestring (ldfile, now, charmap, repertoire);
@@ -1879,7 +1974,7 @@ read_translit_entry (struct linereader *ldfile, struct locale_ctype_t *ctype,
 
       /* Next we have one or more transliterations.  They are
 	 separated by semicolons.  */
-      now = lr_token (ldfile, charmap, repertoire, verbose);
+      now = lr_token (ldfile, charmap, NULL, repertoire, verbose);
 
       if (!first && (now->tok == tok_semicolon || now->tok == tok_eol))
 	{
@@ -1932,7 +2027,7 @@ read_translit_entry (struct linereader *ldfile, struct locale_ctype_t *ctype,
 static void
 read_translit_ignore_entry (struct linereader *ldfile,
 			    struct locale_ctype_t *ctype,
-			    struct charmap_t *charmap,
+			    const struct charmap_t *charmap,
 			    struct repertoire_t *repertoire)
 {
   /* We expect a semicolon-separated list of characters we ignore.  We are
@@ -1940,7 +2035,8 @@ read_translit_ignore_entry (struct linereader *ldfile,
      single characters, possibly defining a range when an ellipsis is used.  */
   while (1)
     {
-      struct token *now = lr_token (ldfile, charmap, repertoire, verbose);
+      struct token *now = lr_token (ldfile, charmap, NULL, repertoire,
+				    verbose);
       struct translit_ignore_t *newp;
       uint32_t from;
 
@@ -1984,7 +2080,7 @@ read_translit_ignore_entry (struct linereader *ldfile,
 
       /* Now we expect either a semicolon, an ellipsis, or the end of the
 	 line.  */
-      now = lr_token (ldfile, charmap, repertoire, verbose);
+      now = lr_token (ldfile, charmap, NULL, repertoire, verbose);
 
       if (now->tok == tok_ellipsis2 || now->tok == tok_ellipsis2_2)
 	{
@@ -1993,7 +2089,7 @@ read_translit_ignore_entry (struct linereader *ldfile,
 	  uint32_t to;
 	  int step = now->tok == tok_ellipsis2_2 ? 2 : 1;
 
-	  now = lr_token (ldfile, charmap, repertoire, verbose);
+	  now = lr_token (ldfile, charmap, NULL, repertoire, verbose);
 
 	  if (now->tok == tok_eol || now->tok == tok_eof)
 	    {
@@ -2034,7 +2130,7 @@ to-value <U%0*X> of range is smaller than from-value <U%0*X>"),
 	    }
 
 	  /* And the next token.  */
-	  now = lr_token (ldfile, charmap, repertoire, verbose);
+	  now = lr_token (ldfile, charmap, NULL, repertoire, verbose);
 	}
 
       if (now->tok == tok_eol || now->tok == tok_eof)
@@ -2056,7 +2152,7 @@ to-value <U%0*X> of range is smaller than from-value <U%0*X>"),
 /* The parser for the LC_CTYPE section of the locale definition.  */
 void
 ctype_read (struct linereader *ldfile, struct localedef_t *result,
-	    struct charmap_t *charmap, const char *repertoire_name,
+	    const struct charmap_t *charmap, const char *repertoire_name,
 	    int ignore_content)
 {
   struct repertoire_t *repertoire = NULL;
@@ -2085,7 +2181,7 @@ ctype_read (struct linereader *ldfile, struct localedef_t *result,
 
   do
     {
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, NULL, NULL, verbose);
       nowtok = now->tok;
     }
   while (nowtok == tok_eol);
@@ -2093,18 +2189,18 @@ ctype_read (struct linereader *ldfile, struct localedef_t *result,
   /* If we see `copy' now we are almost done.  */
   if (nowtok == tok_copy)
     {
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, NULL, NULL, verbose);
       if (now->tok != tok_string)
 	{
 	  SYNTAX_ERROR (_("%s: syntax error"), "LC_CTYPE");
 
 	skip_category:
 	  do
-	    now = lr_token (ldfile, charmap, NULL, verbose);
+	    now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	  while (now->tok != tok_eof && now->tok != tok_end);
 
 	  if (now->tok != tok_eof
-	      || (now = lr_token (ldfile, charmap, NULL, verbose),
+	      || (now = lr_token (ldfile, charmap, NULL, NULL, verbose),
 		  now->tok == tok_eof))
 	    lr_error (ldfile, _("%s: premature end of file"), "LC_CTYPE");
 	  else if (now->tok != tok_lc_ctype)
@@ -2134,7 +2230,7 @@ ctype_read (struct linereader *ldfile, struct localedef_t *result,
 
       lr_ignore_rest (ldfile, 1);
 
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, NULL, NULL, verbose);
       nowtok = now->tok;
     }
 
@@ -2159,7 +2255,7 @@ ctype_read (struct linereader *ldfile, struct localedef_t *result,
       /* Ingore empty lines.  */
       if (nowtok == tok_eol)
 	{
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	  nowtok = now->tok;
 	  continue;
 	}
@@ -2167,14 +2263,14 @@ ctype_read (struct linereader *ldfile, struct localedef_t *result,
       switch (nowtok)
 	{
 	case tok_charclass:
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	  while (now->tok == tok_ident || now->tok == tok_string)
 	    {
 	      ctype_class_new (ldfile, ctype, now->val.str.startmb);
-	      now = lr_token (ldfile, charmap, NULL, verbose);
+	      now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	      if (now->tok != tok_semicolon)
 		break;
-	      now = lr_token (ldfile, charmap, NULL, verbose);
+	      now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	    }
 	  if (now->tok != tok_eol)
 	    SYNTAX_ERROR (_("\
@@ -2182,14 +2278,14 @@ ctype_read (struct linereader *ldfile, struct localedef_t *result,
 	  break;
 
 	case tok_charconv:
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	  while (now->tok == tok_ident || now->tok == tok_string)
 	    {
 	      ctype_map_new (ldfile, ctype, now->val.str.startmb, charmap);
-	      now = lr_token (ldfile, charmap, NULL, verbose);
+	      now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	      if (now->tok != tok_semicolon)
 		break;
-	      now = lr_token (ldfile, charmap, NULL, verbose);
+	      now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	    }
 	  if (now->tok != tok_eol)
 	    SYNTAX_ERROR (_("\
@@ -2207,7 +2303,7 @@ ctype_read (struct linereader *ldfile, struct localedef_t *result,
 
 	  /* We simply forget the `class' keyword and use the following
 	     operand to determine the bit.  */
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	  if (now->tok == tok_ident || now->tok == tok_string)
 	    {
 	      /* Must can be one of the predefined class names.  */
@@ -2253,7 +2349,7 @@ ctype_read (struct linereader *ldfile, struct localedef_t *result,
 	    }
 
 	  /* The next character must be a semicolon.  */
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	  if (now->tok != tok_semicolon)
 	    goto err_label;
 	  goto read_charclass;
@@ -2285,7 +2381,7 @@ ctype_read (struct linereader *ldfile, struct localedef_t *result,
 	  last_token = tok_none;
 	  ellipsis_token = tok_none;
 	  step = 1;
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	  while (now->tok != tok_eol && now->tok != tok_eof)
 	    {
 	      uint32_t wch;
@@ -2422,7 +2518,7 @@ with character code range values one must use the absolute ellipsis `...'"));
 		}
 
 	      /* Next we expect a semicolon or the end of the line.  */
-	      now = lr_token (ldfile, charmap, NULL, verbose);
+	      now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	      if (now->tok == tok_eol || now->tok == tok_eof)
 		break;
 
@@ -2442,7 +2538,7 @@ with character code range values one must use the absolute ellipsis `...'"));
 
 		  ellipsis_token = now->tok;
 
-		  now = lr_token (ldfile, charmap, NULL, verbose);
+		  now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 		  continue;
 		}
 
@@ -2450,7 +2546,7 @@ with character code range values one must use the absolute ellipsis `...'"));
 		goto err_label;
 
 	      /* And get the next character.  */
-	      now = lr_token (ldfile, charmap, NULL, verbose);
+	      now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 
 	      ellipsis_token = tok_none;
 	      step = 1;
@@ -2525,7 +2621,7 @@ with character code range values one must use the absolute ellipsis `...'"));
 
 	  /* We simply forget the `map' keyword and use the following
 	     operand to determine the mapping.  */
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	  if (now->tok == tok_ident || now->tok == tok_string)
 	    {
 	      size_t cnt;
@@ -2547,7 +2643,7 @@ with character code range values one must use the absolute ellipsis `...'"));
 	  else
 	    mapidx = now->tok - tok_toupper;
 
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	  /* This better should be a semicolon.  */
 	  if (now->tok != tok_semicolon)
 	    goto err_label;
@@ -2563,7 +2659,7 @@ with character code range values one must use the absolute ellipsis `...'"));
 	    }
 	  ctype->tomap_done[mapidx] = 1;
 
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	  while (now->tok != tok_eol && now->tok != tok_eof)
 	    {
 	      struct charseq *from_seq;
@@ -2576,24 +2672,24 @@ with character code range values one must use the absolute ellipsis `...'"));
 		goto err_label;
 
 	      /* Next comes the from-value.  */
-	      now = lr_token (ldfile, charmap, NULL, verbose);
+	      now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	      if (get_character (now, charmap, repertoire, &from_seq,
 				 &from_wch) != 0)
 		goto err_label;
 
 	      /* The next is a comma.  */
-	      now = lr_token (ldfile, charmap, NULL, verbose);
+	      now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	      if (now->tok != tok_comma)
 		goto err_label;
 
 	      /* And the other value.  */
-	      now = lr_token (ldfile, charmap, NULL, verbose);
+	      now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	      if (get_character (now, charmap, repertoire, &to_seq,
 				 &to_wch) != 0)
 		goto err_label;
 
 	      /* And the last thing is the closing brace.  */
-	      now = lr_token (ldfile, charmap, NULL, verbose);
+	      now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	      if (now->tok != tok_close_brace)
 		goto err_label;
 
@@ -2615,9 +2711,9 @@ with character code range values one must use the absolute ellipsis `...'"));
 		}
 
 	      /* Now comes a semicolon or the end of the line/file.  */
-	      now = lr_token (ldfile, charmap, NULL, verbose);
+	      now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	      if (now->tok == tok_semicolon)
-		now = lr_token (ldfile, charmap, NULL, verbose);
+		now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	    }
 	  break;
 
@@ -2629,7 +2725,7 @@ with character code range values one must use the absolute ellipsis `...'"));
 	      do
 		{
 		  lr_ignore_rest (ldfile, 0);
-		  now = lr_token (ldfile, charmap, NULL, verbose);
+		  now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 		}
 	      while (now->tok != tok_translit_end && now->tok != tok_eof);
 
@@ -2652,7 +2748,7 @@ with character code range values one must use the absolute ellipsis `...'"));
 	  ldfile->return_widestr = 1;
 
 	  /* We proceed until we see the `translit_end' token.  */
-	  while (now = lr_token (ldfile, charmap, repertoire, verbose),
+	  while (now = lr_token (ldfile, charmap, NULL, repertoire, verbose),
 		 now->tok != tok_translit_end && now->tok != tok_eof)
 	    {
 	      if (now->tok == tok_eol)
@@ -2666,7 +2762,7 @@ with character code range values one must use the absolute ellipsis `...'"));
 		  const char *repertoire_name;
 		  struct translit_include_t *include_stmt, **include_ptr;
 
-		  now = lr_token (ldfile, charmap, NULL, verbose);
+		  now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 		  /* This should be a string or an identifier.  In any
 		     case something to name a locale.  */
 		  if (now->tok != tok_string && now->tok != tok_ident)
@@ -2679,12 +2775,12 @@ with character code range values one must use the absolute ellipsis `...'"));
 		  locale_name = now->val.str.startmb;
 
 		  /* Next should be a semicolon.  */
-		  now = lr_token (ldfile, charmap, NULL, verbose);
+		  now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 		  if (now->tok != tok_semicolon)
 		    goto translit_syntax;
 
 		  /* Now the repertoire name.  */
-		  now = lr_token (ldfile, charmap, NULL, verbose);
+		  now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 		  if ((now->tok != tok_string && now->tok != tok_ident)
 		      || now->val.str.startmb == NULL)
 		    goto translit_syntax;
@@ -2718,7 +2814,7 @@ with character code range values one must use the absolute ellipsis `...'"));
 		    {
 		      /* We expect a single character or string as the
 			 argument.  */
-		      now = lr_token (ldfile, charmap, NULL, verbose);
+		      now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 		      wstr = read_widestring (ldfile, now, charmap,
 					      repertoire);
 
@@ -2748,7 +2844,7 @@ previous definition was here"));
 			break;
 
 		      /* Maybe there is another replacement we can use.  */
-		      now = lr_token (ldfile, charmap, NULL, verbose);
+		      now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 		      if (now->tok == tok_eol || now->tok == tok_eof)
 			{
 			  /* Nothing found.  We tell the user.  */
@@ -2839,7 +2935,7 @@ previous definition was here"));
 
 	case tok_end:
 	  /* Next we assume `LC_CTYPE'.  */
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, NULL, NULL, verbose);
 	  if (now->tok == tok_eof)
 	    break;
 	  if (now->tok == tok_eol)
@@ -2858,7 +2954,7 @@ previous definition was here"));
 	}
 
       /* Prepare for the next round.  */
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, NULL, NULL, verbose);
       nowtok = now->tok;
     }
 
@@ -2868,7 +2964,8 @@ previous definition was here"));
 
 
 static void
-set_class_defaults (struct locale_ctype_t *ctype, struct charmap_t *charmap,
+set_class_defaults (struct locale_ctype_t *ctype,
+		    const struct charmap_t *charmap,
 		    struct repertoire_t *repertoire)
 {
   size_t cnt;
@@ -3351,7 +3448,7 @@ character `%s' not defined while needed as default value"),
 	      error (0, 0, _("\
 no output digits defined and none of the standard names in the charmap"));
 
-	      ctype->mboutdigits[cnt] = obstack_alloc (&charmap->mem_pool,
+	      ctype->mboutdigits[cnt] = obstack_alloc (&((struct charmap_t *) charmap)->mem_pool,
 						       sizeof (struct charseq)
 						       + 1);
 
@@ -3621,7 +3718,8 @@ wctrans_table_add (struct wctrans_table *t, uint32_t wc, uint32_t mapped_wc)
 /* Flattens the included transliterations into a translit list.
    Inserts them in the list at `cursor', and returns the new cursor.  */
 static struct translit_t **
-translit_flatten (struct locale_ctype_t *ctype, struct charmap_t *charmap,
+translit_flatten (struct locale_ctype_t *ctype,
+		  const struct charmap_t *charmap,
 		  struct translit_t **cursor)
 {
   while (ctype->translit_include != NULL)
@@ -3675,7 +3773,7 @@ translit_flatten (struct locale_ctype_t *ctype, struct charmap_t *charmap,
 }
 
 static void
-allocate_arrays (struct locale_ctype_t *ctype, struct charmap_t *charmap,
+allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
 		 struct repertoire_t *repertoire)
 {
   size_t idx, nr;
diff --git a/locale/programs/ld-identification.c b/locale/programs/ld-identification.c
index a64fe63d1b..74420fcde2 100644
--- a/locale/programs/ld-identification.c
+++ b/locale/programs/ld-identification.c
@@ -95,7 +95,8 @@ identification_startup (struct linereader *lr, struct localedef_t *locale,
 
 
 void
-identification_finish (struct localedef_t *locale, struct charmap_t *charmap)
+identification_finish (struct localedef_t *locale,
+		       const struct charmap_t *charmap)
 {
   struct locale_identification_t *identification
     = locale->categories[LC_IDENTIFICATION].identification;
@@ -174,7 +175,8 @@ identification_finish (struct localedef_t *locale, struct charmap_t *charmap)
 
 
 void
-identification_output (struct localedef_t *locale, struct charmap_t *charmap,
+identification_output (struct localedef_t *locale,
+		       const struct charmap_t *charmap,
 		       const char *output_path)
 {
   struct locale_identification_t *identification
@@ -294,7 +296,7 @@ identification_output (struct localedef_t *locale, struct charmap_t *charmap,
 /* The parser for the LC_IDENTIFICATION section of the locale definition.  */
 void
 identification_read (struct linereader *ldfile, struct localedef_t *result,
-	       struct charmap_t *charmap, const char *repertoire_name,
+	       const struct charmap_t *charmap, const char *repertoire_name,
 	       int ignore_content)
 {
   struct locale_identification_t *identification;
@@ -309,7 +311,7 @@ identification_read (struct linereader *ldfile, struct localedef_t *result,
 
   do
     {
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
   while (nowtok == tok_eol);
@@ -336,7 +338,7 @@ identification_read (struct linereader *ldfile, struct localedef_t *result,
       /* Ignore empty lines.  */
       if (nowtok == tok_eol)
 	{
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  nowtok = now->tok;
 	  continue;
 	}
@@ -353,7 +355,7 @@ identification_read (struct linereader *ldfile, struct localedef_t *result,
 	      break;							      \
 	    }								      \
 									      \
-	  arg = lr_token (ldfile, charmap, NULL, verbose);		      \
+	  arg = lr_token (ldfile, charmap, result, NULL, verbose);	      \
 	  if (arg->tok != tok_string)					      \
 	    goto err_label;						      \
 	  if (identification->cat != NULL)				      \
@@ -394,15 +396,15 @@ identification_read (struct linereader *ldfile, struct localedef_t *result,
 	    }
 
 	  /* We expect two operands.  */
-	  arg = lr_token (ldfile, charmap, NULL, verbose);
+	  arg = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (arg->tok != tok_string && arg->tok != tok_ident)
 	    goto err_label;
 	  /* Next is a semicolon.  */
-	  cattok = lr_token (ldfile, charmap, NULL, verbose);
+	  cattok = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (cattok->tok != tok_semicolon)
 	    goto err_label;
 	  /* Now a LC_xxx identifier.  */
-	  cattok = lr_token (ldfile, charmap, NULL, verbose);
+	  cattok = lr_token (ldfile, charmap, result, NULL, verbose);
 	  switch (cattok->tok)
 	    {
 #define CATEGORY(lname, uname) \
@@ -438,7 +440,7 @@ identification_read (struct linereader *ldfile, struct localedef_t *result,
 
 	case tok_end:
 	  /* Next we assume `LC_IDENTIFICATION'.  */
-	  arg = lr_token (ldfile, charmap, NULL, verbose);
+	  arg = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (arg->tok == tok_eof)
 	    break;
 	  if (arg->tok == tok_eol)
@@ -456,7 +458,7 @@ identification_read (struct linereader *ldfile, struct localedef_t *result,
 	}
 
       /* Prepare for the next round.  */
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
 
diff --git a/locale/programs/ld-measurement.c b/locale/programs/ld-measurement.c
index 90187420b4..f0b960d63d 100644
--- a/locale/programs/ld-measurement.c
+++ b/locale/programs/ld-measurement.c
@@ -57,7 +57,8 @@ measurement_startup (struct linereader *lr, struct localedef_t *locale,
 
 
 void
-measurement_finish (struct localedef_t *locale, struct charmap_t *charmap)
+measurement_finish (struct localedef_t *locale,
+		    const struct charmap_t *charmap)
 {
   struct locale_measurement_t *measurement =
     locale->categories[LC_MEASUREMENT].measurement;
@@ -116,8 +117,8 @@ measurement_finish (struct localedef_t *locale, struct charmap_t *charmap)
 
 
 void
-measurement_output (struct localedef_t *locale, struct charmap_t *charmap,
-		    const char *output_path)
+measurement_output (struct localedef_t *locale,
+		    const struct charmap_t *charmap, const char *output_path)
 {
   struct locale_measurement_t *measurement =
     locale->categories[LC_MEASUREMENT].measurement;
@@ -156,7 +157,7 @@ measurement_output (struct localedef_t *locale, struct charmap_t *charmap,
 /* The parser for the LC_MEASUREMENT section of the locale definition.  */
 void
 measurement_read (struct linereader *ldfile, struct localedef_t *result,
-		  struct charmap_t *charmap, const char *repertoire_name,
+		  const struct charmap_t *charmap, const char *repertoire_name,
 		  int ignore_content)
 {
   struct locale_measurement_t *measurement;
@@ -169,7 +170,7 @@ measurement_read (struct linereader *ldfile, struct localedef_t *result,
 
   do
     {
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
   while (nowtok == tok_eol);
@@ -196,7 +197,7 @@ measurement_read (struct linereader *ldfile, struct localedef_t *result,
       /* Ingore empty lines.  */
       if (nowtok == tok_eol)
 	{
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  nowtok = now->tok;
 	  continue;
 	}
@@ -213,7 +214,7 @@ measurement_read (struct linereader *ldfile, struct localedef_t *result,
 	      break;							      \
 	    }								      \
 									      \
-	  arg = lr_token (ldfile, charmap, NULL, verbose);		      \
+	  arg = lr_token (ldfile, charmap, result, NULL, verbose);	      \
 	  if (arg->tok != tok_number)					      \
 	    goto err_label;						      \
 	  else if (measurement->cat != 0)				      \
@@ -227,7 +228,7 @@ measurement_read (struct linereader *ldfile, struct localedef_t *result,
 
 	case tok_end:
 	  /* Next we assume `LC_MEASUREMENT'.  */
-	  arg = lr_token (ldfile, charmap, NULL, verbose);
+	  arg = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (arg->tok == tok_eof)
 	    break;
 	  if (arg->tok == tok_eol)
@@ -245,7 +246,7 @@ measurement_read (struct linereader *ldfile, struct localedef_t *result,
 	}
 
       /* Prepare for the next round.  */
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
 
diff --git a/locale/programs/ld-messages.c b/locale/programs/ld-messages.c
index 48c63e2a61..b005cb5da2 100644
--- a/locale/programs/ld-messages.c
+++ b/locale/programs/ld-messages.c
@@ -63,7 +63,7 @@ messages_startup (struct linereader *lr, struct localedef_t *locale,
 
 
 void
-messages_finish (struct localedef_t *locale, struct charmap_t *charmap)
+messages_finish (struct localedef_t *locale, const struct charmap_t *charmap)
 {
   struct locale_messages_t *messages
     = locale->categories[LC_MESSAGES].messages;
@@ -178,7 +178,7 @@ messages_finish (struct localedef_t *locale, struct charmap_t *charmap)
 
 
 void
-messages_output (struct localedef_t *locale, struct charmap_t *charmap,
+messages_output (struct localedef_t *locale, const struct charmap_t *charmap,
 		 const char *output_path)
 {
   struct locale_messages_t *messages
@@ -232,7 +232,7 @@ messages_output (struct localedef_t *locale, struct charmap_t *charmap,
 /* The parser for the LC_MESSAGES section of the locale definition.  */
 void
 messages_read (struct linereader *ldfile, struct localedef_t *result,
-	       struct charmap_t *charmap, const char *repertoire_name,
+	       const struct charmap_t *charmap, const char *repertoire_name,
 	       int ignore_content)
 {
   struct repertoire_t *repertoire = NULL;
@@ -250,7 +250,7 @@ messages_read (struct linereader *ldfile, struct localedef_t *result,
 
   do
     {
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
   while (nowtok == tok_eol);
@@ -278,7 +278,7 @@ messages_read (struct linereader *ldfile, struct localedef_t *result,
       /* Ignore empty lines.  */
       if (nowtok == tok_eol)
 	{
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  nowtok = now->tok;
 	  continue;
 	}
@@ -302,7 +302,7 @@ messages_read (struct linereader *ldfile, struct localedef_t *result,
 	      lr_ignore_rest (ldfile, 0);				      \
 	      break;							      \
 	    }								      \
-	  now = lr_token (ldfile, charmap, repertoire, verbose);	      \
+	  now = lr_token (ldfile, charmap, result, repertoire, verbose);      \
 	  if (now->tok != tok_string)					      \
 	    goto syntax_error;						      \
 	  else if (!ignore_content && now->val.str.startmb == NULL)	      \
@@ -322,7 +322,7 @@ messages_read (struct linereader *ldfile, struct localedef_t *result,
 
 	case tok_end:
 	  /* Next we assume `LC_MESSAGES'.  */
-	  arg = lr_token (ldfile, charmap, NULL, verbose);
+	  arg = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (arg->tok == tok_eof)
 	    break;
 	  if (arg->tok == tok_eol)
@@ -339,7 +339,7 @@ messages_read (struct linereader *ldfile, struct localedef_t *result,
 	}
 
       /* Prepare for the next round.  */
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
 
diff --git a/locale/programs/ld-monetary.c b/locale/programs/ld-monetary.c
index 08a10fdcc1..0cd9579f50 100644
--- a/locale/programs/ld-monetary.c
+++ b/locale/programs/ld-monetary.c
@@ -159,7 +159,7 @@ monetary_startup (struct linereader *lr, struct localedef_t *locale,
 
 
 void
-monetary_finish (struct localedef_t *locale, struct charmap_t *charmap)
+monetary_finish (struct localedef_t *locale, const struct charmap_t *charmap)
 {
   struct locale_monetary_t *monetary
     = locale->categories[LC_MONETARY].monetary;
@@ -353,7 +353,7 @@ not correspond to a valid name in ISO 4217"),
 
 
 void
-monetary_output (struct localedef_t *locale, struct charmap_t *charmap,
+monetary_output (struct localedef_t *locale, const struct charmap_t *charmap,
 		 const char *output_path)
 {
   struct locale_monetary_t *monetary
@@ -627,7 +627,7 @@ curr_strcmp (const char *s1, const char **s2)
 /* The parser for the LC_MONETARY section of the locale definition.  */
 void
 monetary_read (struct linereader *ldfile, struct localedef_t *result,
-	       struct charmap_t *charmap, const char *repertoire_name,
+	       const struct charmap_t *charmap, const char *repertoire_name,
 	       int ignore_content)
 {
   struct repertoire_t *repertoire = NULL;
@@ -644,7 +644,7 @@ monetary_read (struct linereader *ldfile, struct localedef_t *result,
 
   do
     {
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
   while (nowtok == tok_eol);
@@ -670,7 +670,7 @@ monetary_read (struct linereader *ldfile, struct localedef_t *result,
       /* Ignore empty lines.  */
       if (nowtok == tok_eol)
 	{
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  nowtok = now->tok;
 	  continue;
 	}
@@ -687,7 +687,7 @@ monetary_read (struct linereader *ldfile, struct localedef_t *result,
 	      break;							      \
 	    }								      \
 									      \
-	  now = lr_token (ldfile, charmap, NULL, verbose);		      \
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);	      \
 	  if (now->tok != tok_string)					      \
 	    goto err_label;						      \
 	  else if (monetary->cat != NULL)				      \
@@ -722,7 +722,7 @@ monetary_read (struct linereader *ldfile, struct localedef_t *result,
 	    }								      \
 									      \
 	  ldfile->return_widestr = 1;					      \
-	  now = lr_token (ldfile, charmap, repertoire, verbose);	      \
+	  now = lr_token (ldfile, charmap, result, repertoire, verbose);      \
 	  if (now->tok != tok_string)					      \
 	    goto err_label;						      \
 	  if (monetary->cat != NULL)					      \
@@ -763,7 +763,7 @@ monetary_read (struct linereader *ldfile, struct localedef_t *result,
 	      break;							      \
 	    }								      \
 									      \
-	  now = lr_token (ldfile, charmap, NULL, verbose);		      \
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);	      \
 	  if (now->tok != tok_minus1 && now->tok != tok_number)		      \
 	    goto err_label;						      \
 	  else if (monetary->cat != -2)					      \
@@ -815,7 +815,7 @@ monetary_read (struct linereader *ldfile, struct localedef_t *result,
 	      break;
 	    }
 
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (now->tok != tok_minus1 && now->tok != tok_number)
 	    goto err_label;
 	  else
@@ -863,11 +863,11 @@ monetary_read (struct linereader *ldfile, struct localedef_t *result,
 		    grouping[act++] = now->val.num;
 
 		  /* Next must be semicolon.  */
-		  now = lr_token (ldfile, charmap, NULL, verbose);
+		  now = lr_token (ldfile, charmap, result, NULL, verbose);
 		  if (now->tok != tok_semicolon)
 		    break;
 
-		  now = lr_token (ldfile, charmap, NULL, verbose);
+		  now = lr_token (ldfile, charmap, result, NULL, verbose);
 		}
 	      while (now->tok == tok_minus1 || now->tok == tok_number);
 
@@ -893,7 +893,7 @@ monetary_read (struct linereader *ldfile, struct localedef_t *result,
 	      break;
 	    }
 
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (now->tok != tok_number)
 	    goto err_label;
 	  if (now->val.num == 0)
@@ -910,11 +910,11 @@ monetary_read (struct linereader *ldfile, struct localedef_t *result,
 	  if (!ignore_content)
 	    monetary->conversion_rate[0] = now->val.num;
 	  /* Next must be a semicolon.  */
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (now->tok != tok_semicolon)
 	    goto err_label;
 	  /* And another number.  */
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (now->tok != tok_number)
 	    goto err_label;
 	  if (now->val.num == 0)
@@ -927,7 +927,7 @@ monetary_read (struct linereader *ldfile, struct localedef_t *result,
 
 	case tok_end:
 	  /* Next we assume `LC_MONETARY'.  */
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (now->tok == tok_eof)
 	    break;
 	  if (now->tok == tok_eol)
@@ -944,7 +944,7 @@ monetary_read (struct linereader *ldfile, struct localedef_t *result,
 	}
 
       /* Prepare for the next round.  */
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
 
diff --git a/locale/programs/ld-name.c b/locale/programs/ld-name.c
index 423f1707c2..a838b6e114 100644
--- a/locale/programs/ld-name.c
+++ b/locale/programs/ld-name.c
@@ -60,7 +60,7 @@ name_startup (struct linereader *lr, struct localedef_t *locale,
 
 
 void
-name_finish (struct localedef_t *locale, struct charmap_t *charmap)
+name_finish (struct localedef_t *locale, const struct charmap_t *charmap)
 {
   struct locale_name_t *name = locale->categories[LC_NAME].name;
   int nothing = 0;
@@ -151,7 +151,7 @@ name_finish (struct localedef_t *locale, struct charmap_t *charmap)
 
 
 void
-name_output (struct localedef_t *locale, struct charmap_t *charmap,
+name_output (struct localedef_t *locale, const struct charmap_t *charmap,
 	     const char *output_path)
 {
   struct locale_name_t *name = locale->categories[LC_NAME].name;
@@ -215,7 +215,7 @@ name_output (struct localedef_t *locale, struct charmap_t *charmap,
 /* The parser for the LC_NAME section of the locale definition.  */
 void
 name_read (struct linereader *ldfile, struct localedef_t *result,
-	   struct charmap_t *charmap, const char *repertoire_name,
+	   const struct charmap_t *charmap, const char *repertoire_name,
 	   int ignore_content)
 {
   struct locale_name_t *name;
@@ -228,7 +228,7 @@ name_read (struct linereader *ldfile, struct localedef_t *result,
 
   do
     {
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
   while (nowtok == tok_eol);
@@ -254,7 +254,7 @@ name_read (struct linereader *ldfile, struct localedef_t *result,
       /* Ignore empty lines.  */
       if (nowtok == tok_eol)
 	{
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  nowtok = now->tok;
 	  continue;
 	}
@@ -271,7 +271,7 @@ name_read (struct linereader *ldfile, struct localedef_t *result,
 	      break;							      \
 	    }								      \
 									      \
-	  arg = lr_token (ldfile, charmap, NULL, verbose);		      \
+	  arg = lr_token (ldfile, charmap, result, NULL, verbose);	      \
 	  if (arg->tok != tok_string)					      \
 	    goto err_label;						      \
 	  if (name->cat != NULL)					      \
@@ -296,7 +296,7 @@ name_read (struct linereader *ldfile, struct localedef_t *result,
 
 	case tok_end:
 	  /* Next we assume `LC_NAME'.  */
-	  arg = lr_token (ldfile, charmap, NULL, verbose);
+	  arg = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (arg->tok == tok_eof)
 	    break;
 	  if (arg->tok == tok_eol)
@@ -313,7 +313,7 @@ name_read (struct linereader *ldfile, struct localedef_t *result,
 	}
 
       /* Prepare for the next round.  */
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
 
diff --git a/locale/programs/ld-numeric.c b/locale/programs/ld-numeric.c
index 886dd9d27f..c0be827133 100644
--- a/locale/programs/ld-numeric.c
+++ b/locale/programs/ld-numeric.c
@@ -65,7 +65,7 @@ numeric_startup (struct linereader *lr, struct localedef_t *locale,
 
 
 void
-numeric_finish (struct localedef_t *locale, struct charmap_t *charmap)
+numeric_finish (struct localedef_t *locale, const struct charmap_t *charmap)
 {
   struct locale_numeric_t *numeric = locale->categories[LC_NUMERIC].numeric;
   int nothing = 0;
@@ -129,7 +129,7 @@ numeric_finish (struct localedef_t *locale, struct charmap_t *charmap)
 
 
 void
-numeric_output (struct localedef_t *locale, struct charmap_t *charmap,
+numeric_output (struct localedef_t *locale, const struct charmap_t *charmap,
 		const char *output_path)
 {
   struct locale_numeric_t *numeric = locale->categories[LC_NUMERIC].numeric;
@@ -194,7 +194,7 @@ numeric_output (struct localedef_t *locale, struct charmap_t *charmap,
 /* The parser for the LC_NUMERIC section of the locale definition.  */
 void
 numeric_read (struct linereader *ldfile, struct localedef_t *result,
-	      struct charmap_t *charmap, const char *repertoire_name,
+	      const struct charmap_t *charmap, const char *repertoire_name,
 	      int ignore_content)
 {
   struct repertoire_t *repertoire = NULL;
@@ -212,7 +212,7 @@ numeric_read (struct linereader *ldfile, struct localedef_t *result,
 
   do
     {
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
   while (nowtok == tok_eol);
@@ -238,7 +238,7 @@ numeric_read (struct linereader *ldfile, struct localedef_t *result,
       /* Ingore empty lines.  */
       if (nowtok == tok_eol)
 	{
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  nowtok = now->tok;
 	  continue;
 	}
@@ -256,7 +256,7 @@ numeric_read (struct linereader *ldfile, struct localedef_t *result,
 	    }								      \
 									      \
 	  ldfile->return_widestr = 1;					      \
-	  now = lr_token (ldfile, charmap, repertoire, verbose);	      \
+	  now = lr_token (ldfile, charmap, result, repertoire, verbose);	      \
 	  if (now->tok != tok_string)					      \
 	    goto err_label;						      \
 	  if (numeric->cat != NULL)					      \
@@ -296,7 +296,7 @@ numeric_read (struct linereader *ldfile, struct localedef_t *result,
 	      break;
 	    }
 
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (now->tok != tok_minus1 && now->tok != tok_number)
 	    goto err_label;
 	  else
@@ -343,11 +343,11 @@ numeric_read (struct linereader *ldfile, struct localedef_t *result,
 		    grouping[act++] = now->val.num;
 
 		  /* Next must be semicolon.  */
-		  now = lr_token (ldfile, charmap, NULL, verbose);
+		  now = lr_token (ldfile, charmap, result, NULL, verbose);
 		  if (now->tok != tok_semicolon)
 		    break;
 
-		  now = lr_token (ldfile, charmap, NULL, verbose);
+		  now = lr_token (ldfile, charmap, result, NULL, verbose);
 		}
 	      while (now->tok == tok_minus1 || now->tok == tok_number);
 
@@ -366,7 +366,7 @@ numeric_read (struct linereader *ldfile, struct localedef_t *result,
 
 	case tok_end:
 	  /* Next we assume `LC_NUMERIC'.  */
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (now->tok == tok_eof)
 	    break;
 	  if (now->tok == tok_eol)
@@ -383,7 +383,7 @@ numeric_read (struct linereader *ldfile, struct localedef_t *result,
 	}
 
       /* Prepare for the next round.  */
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
 
diff --git a/locale/programs/ld-paper.c b/locale/programs/ld-paper.c
index 2fc78202a2..334d405ca8 100644
--- a/locale/programs/ld-paper.c
+++ b/locale/programs/ld-paper.c
@@ -57,7 +57,7 @@ paper_startup (struct linereader *lr, struct localedef_t *locale,
 
 
 void
-paper_finish (struct localedef_t *locale, struct charmap_t *charmap)
+paper_finish (struct localedef_t *locale, const struct charmap_t *charmap)
 {
   struct locale_paper_t *paper = locale->categories[LC_PAPER].paper;
   int nothing = 0;
@@ -114,7 +114,7 @@ paper_finish (struct localedef_t *locale, struct charmap_t *charmap)
 
 
 void
-paper_output (struct localedef_t *locale, struct charmap_t *charmap,
+paper_output (struct localedef_t *locale, const struct charmap_t *charmap,
 	      const char *output_path)
 {
   struct locale_paper_t *paper = locale->categories[LC_PAPER].paper;
@@ -158,7 +158,7 @@ paper_output (struct localedef_t *locale, struct charmap_t *charmap,
 /* The parser for the LC_PAPER section of the locale definition.  */
 void
 paper_read (struct linereader *ldfile, struct localedef_t *result,
-	    struct charmap_t *charmap, const char *repertoire_name,
+	    const struct charmap_t *charmap, const char *repertoire_name,
 	    int ignore_content)
 {
   struct locale_paper_t *paper;
@@ -171,7 +171,7 @@ paper_read (struct linereader *ldfile, struct localedef_t *result,
 
   do
     {
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
   while (nowtok == tok_eol);
@@ -197,7 +197,7 @@ paper_read (struct linereader *ldfile, struct localedef_t *result,
       /* Ingore empty lines.  */
       if (nowtok == tok_eol)
 	{
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  nowtok = now->tok;
 	  continue;
 	}
@@ -214,7 +214,7 @@ paper_read (struct linereader *ldfile, struct localedef_t *result,
 	      break;							      \
 	    }								      \
 									      \
-	  arg = lr_token (ldfile, charmap, NULL, verbose);		      \
+	  arg = lr_token (ldfile, charmap, result, NULL, verbose);	      \
 	  if (arg->tok != tok_number)					      \
 	    goto err_label;						      \
 	  else if (paper->cat != 0)					      \
@@ -229,7 +229,7 @@ paper_read (struct linereader *ldfile, struct localedef_t *result,
 
 	case tok_end:
 	  /* Next we assume `LC_PAPER'.  */
-	  arg = lr_token (ldfile, charmap, NULL, verbose);
+	  arg = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (arg->tok == tok_eof)
 	    break;
 	  if (arg->tok == tok_eol)
@@ -246,7 +246,7 @@ paper_read (struct linereader *ldfile, struct localedef_t *result,
 	}
 
       /* Prepare for the next round.  */
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
 
diff --git a/locale/programs/ld-telephone.c b/locale/programs/ld-telephone.c
index 31cfd25041..a66b48d436 100644
--- a/locale/programs/ld-telephone.c
+++ b/locale/programs/ld-telephone.c
@@ -59,7 +59,7 @@ telephone_startup (struct linereader *lr, struct localedef_t *locale,
 
 
 void
-telephone_finish (struct localedef_t *locale, struct charmap_t *charmap)
+telephone_finish (struct localedef_t *locale, const struct charmap_t *charmap)
 {
   struct locale_telephone_t *telephone =
     locale->categories[LC_TELEPHONE].telephone;
@@ -170,7 +170,7 @@ telephone_finish (struct localedef_t *locale, struct charmap_t *charmap)
 
 
 void
-telephone_output (struct localedef_t *locale, struct charmap_t *charmap,
+telephone_output (struct localedef_t *locale, const struct charmap_t *charmap,
 		  const char *output_path)
 {
   struct locale_telephone_t *telephone =
@@ -225,7 +225,7 @@ telephone_output (struct localedef_t *locale, struct charmap_t *charmap,
 /* The parser for the LC_TELEPHONE section of the locale definition.  */
 void
 telephone_read (struct linereader *ldfile, struct localedef_t *result,
-		struct charmap_t *charmap, const char *repertoire_name,
+		const struct charmap_t *charmap, const char *repertoire_name,
 		int ignore_content)
 {
   struct locale_telephone_t *telephone;
@@ -238,7 +238,7 @@ telephone_read (struct linereader *ldfile, struct localedef_t *result,
 
   do
     {
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
   while (nowtok == tok_eol);
@@ -264,7 +264,7 @@ telephone_read (struct linereader *ldfile, struct localedef_t *result,
       /* Ingore empty lines.  */
       if (nowtok == tok_eol)
 	{
-	  now = lr_token (ldfile, charmap, NULL, verbose);
+	  now = lr_token (ldfile, charmap, result, NULL, verbose);
 	  nowtok = now->tok;
 	  continue;
 	}
@@ -281,7 +281,7 @@ telephone_read (struct linereader *ldfile, struct localedef_t *result,
 	      break;							      \
 	    }								      \
 									      \
-	  arg = lr_token (ldfile, charmap, NULL, verbose);		      \
+	  arg = lr_token (ldfile, charmap, result, NULL, verbose);	      \
 	  if (arg->tok != tok_string)					      \
 	    goto err_label;						      \
 	  if (telephone->cat != NULL)					      \
@@ -304,7 +304,7 @@ telephone_read (struct linereader *ldfile, struct localedef_t *result,
 
 	case tok_end:
 	  /* Next we assume `LC_TELEPHONE'.  */
-	  arg = lr_token (ldfile, charmap, NULL, verbose);
+	  arg = lr_token (ldfile, charmap, result, NULL, verbose);
 	  if (arg->tok == tok_eof)
 	    break;
 	  if (arg->tok == tok_eol)
@@ -321,7 +321,7 @@ telephone_read (struct linereader *ldfile, struct localedef_t *result,
 	}
 
       /* Prepare for the next round.  */
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
       nowtok = now->tok;
     }
 
diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c
index 6245b0f05e..5883d4c31c 100644
--- a/locale/programs/ld-time.c
+++ b/locale/programs/ld-time.c
@@ -126,7 +126,7 @@ time_startup (struct linereader *lr, struct localedef_t *locale,
 
 
 void
-time_finish (struct localedef_t *locale, struct charmap_t *charmap)
+time_finish (struct localedef_t *locale, const struct charmap_t *charmap)
 {
   struct locale_time_t *time = locale->categories[LC_TIME].time;
   int nothing = 0;
@@ -523,7 +523,7 @@ time_finish (struct localedef_t *locale, struct charmap_t *charmap)
 
 
 void
-time_output (struct localedef_t *locale, struct charmap_t *charmap,
+time_output (struct localedef_t *locale, const struct charmap_t *charmap,
 	     const char *output_path)
 {
   struct locale_time_t *time = locale->categories[LC_TIME].time;
@@ -912,7 +912,7 @@ time_output (struct localedef_t *locale, struct charmap_t *charmap,
 /* The parser for the LC_TIME section of the locale definition.  */
 void
 time_read (struct linereader *ldfile, struct localedef_t *result,
-	   struct charmap_t *charmap, const char *repertoire_name,
+	   const struct charmap_t *charmap, const char *repertoire_name,
 	   int ignore_content)
 {
   struct repertoire_t *repertoire = NULL;
@@ -931,7 +931,7 @@ time_read (struct linereader *ldfile, struct localedef_t *result,
 
   do
     {
-      now = lr_token (ldfile, charmap, repertoire, verbose);
+      now = lr_token (ldfile, charmap, result, repertoire, verbose);
       nowtok = now->tok;
     }
   while (nowtok == tok_eol);
@@ -957,7 +957,7 @@ time_read (struct linereader *ldfile, struct localedef_t *result,
       /* Ingore empty lines.  */
       if (nowtok == tok_eol)
 	{
-	  now = lr_token (ldfile, charmap, repertoire, verbose);
+	  now = lr_token (ldfile, charmap, result, repertoire, verbose);
 	  nowtok = now->tok;
 	  continue;
 	}
@@ -976,7 +976,7 @@ time_read (struct linereader *ldfile, struct localedef_t *result,
 									      \
 	  for (cnt = 0; cnt < max; ++cnt)				      \
 	    {								      \
-	      now = lr_token (ldfile, charmap, repertoire, verbose);	      \
+	      now = lr_token (ldfile, charmap, result, repertoire, verbose);  \
 	      if (now->tok == tok_eol)					      \
 		{							      \
 		  if (cnt < min)					      \
@@ -1008,7 +1008,7 @@ time_read (struct linereader *ldfile, struct localedef_t *result,
 		}							      \
 									      \
 	      /* Match the semicolon.  */				      \
-	      now = lr_token (ldfile, charmap, repertoire, verbose);	      \
+	      now = lr_token (ldfile, charmap, result, repertoire, verbose);  \
 	      if (now->tok != tok_semicolon && now->tok != tok_eol)	      \
 		break;							      \
 	    }								      \
@@ -1022,7 +1022,8 @@ time_read (struct linereader *ldfile, struct localedef_t *result,
 	      								      \
 	      if (now->tok == tok_semicolon)				      \
 		{							      \
-		  now = lr_token (ldfile, charmap, repertoire, verbose);      \
+		  now = lr_token (ldfile, charmap, result, repertoire,	      \
+				  verbose);				      \
 		  if (now->tok == tok_eol)				      \
 		    lr_error (ldfile, _("extra trailing semicolon"));	      \
 		  else if (now->tok == tok_string)			      \
@@ -1058,7 +1059,7 @@ time_read (struct linereader *ldfile, struct localedef_t *result,
 	    }
 	  do
 	    {
-	      now = lr_token (ldfile, charmap, repertoire, verbose);
+	      now = lr_token (ldfile, charmap, result, repertoire, verbose);
 	      if (now->tok != tok_string)
 		goto err_label;
 	      if (!ignore_content && (now->val.str.startmb == NULL
@@ -1080,7 +1081,7 @@ time_read (struct linereader *ldfile, struct localedef_t *result,
 					 * sizeof (char *));
 		  time->wera[time->num_era++] = now->val.str.startwc;
 		}
-	      now = lr_token (ldfile, charmap, repertoire, verbose);
+	      now = lr_token (ldfile, charmap, result, repertoire, verbose);
 	      if (now->tok != tok_eol && now->tok != tok_semicolon)
 		goto err_label;
 	    }
@@ -1097,7 +1098,7 @@ time_read (struct linereader *ldfile, struct localedef_t *result,
 	      break;							      \
 	    }								      \
 									      \
-	  now = lr_token (ldfile, charmap, repertoire, verbose);	      \
+	  now = lr_token (ldfile, charmap, result, repertoire, verbose);      \
 	  if (now->tok != tok_string)					      \
 	    goto err_label;						      \
 	  else if (time->cat != NULL)					      \
@@ -1139,7 +1140,7 @@ time_read (struct linereader *ldfile, struct localedef_t *result,
 	      break;							      \
 	    }								      \
 									      \
-	  now = lr_token (ldfile, charmap, repertoire, verbose);	      \
+	  now = lr_token (ldfile, charmap, result, repertoire, verbose);      \
 	  if (now->tok != tok_number)					      \
 	    goto err_label;						      \
 	  else if (time->cat != 0)					      \
@@ -1162,25 +1163,25 @@ time_read (struct linereader *ldfile, struct localedef_t *result,
 	      break;
 	    }
 
-	  now = lr_token (ldfile, charmap, repertoire, verbose);
+	  now = lr_token (ldfile, charmap, result, repertoire, verbose);
 	  if (now->tok != tok_number)
 	    goto err_label;
 	  time->week_ndays = now->val.num;
 
-	  now = lr_token (ldfile, charmap, repertoire, verbose);
+	  now = lr_token (ldfile, charmap, result, repertoire, verbose);
 	  if (now->tok != tok_semicolon)
 	    goto err_label;
 
-	  now = lr_token (ldfile, charmap, repertoire, verbose);
+	  now = lr_token (ldfile, charmap, result, repertoire, verbose);
 	  if (now->tok != tok_number)
 	    goto err_label;
 	  time->week_1stday = now->val.num;
 
-	  now = lr_token (ldfile, charmap, repertoire, verbose);
+	  now = lr_token (ldfile, charmap, result, repertoire, verbose);
 	  if (now->tok != tok_semicolon)
 	    goto err_label;
 
-	  now = lr_token (ldfile, charmap, repertoire, verbose);
+	  now = lr_token (ldfile, charmap, result, repertoire, verbose);
 	  if (now->tok != tok_number)
 	    goto err_label;
 	  time->week_1stweek = now->val.num;
@@ -1190,7 +1191,7 @@ time_read (struct linereader *ldfile, struct localedef_t *result,
 
 	case tok_end:
 	  /* Next we assume `LC_TIME'.  */
-	  now = lr_token (ldfile, charmap, repertoire, verbose);
+	  now = lr_token (ldfile, charmap, result, repertoire, verbose);
 	  if (now->tok == tok_eof)
 	    break;
 	  if (now->tok == tok_eol)
@@ -1207,7 +1208,7 @@ time_read (struct linereader *ldfile, struct localedef_t *result,
 	}
 
       /* Prepare for the next round.  */
-      now = lr_token (ldfile, charmap, repertoire, verbose);
+      now = lr_token (ldfile, charmap, result, repertoire, verbose);
       nowtok = now->tok;
     }
 
diff --git a/locale/programs/linereader.c b/locale/programs/linereader.c
index ac843bcd2f..9f5191226b 100644
--- a/locale/programs/linereader.c
+++ b/locale/programs/linereader.c
@@ -21,6 +21,7 @@
 # include <config.h>
 #endif
 
+#include <assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <libintl.h>
@@ -31,6 +32,8 @@
 #include "charmap.h"
 #include "error.h"
 #include "linereader.h"
+#include "localedef.h"
+#include "locfile.h"
 
 /* Prototypes for a few program-wide used functions.  */
 extern void *xmalloc (size_t __n);
@@ -44,6 +47,7 @@ static struct token *get_symname (struct linereader *lr);
 static struct token *get_ident (struct linereader *lr);
 static struct token *get_string (struct linereader *lr,
 				 const struct charmap_t *charmap,
+				 struct localedef_t *locale,
 				 const struct repertoire_t *repertoire,
 				 int verbose);
 
@@ -163,7 +167,8 @@ extern char *program_name;
 
 struct token *
 lr_token (struct linereader *lr, const struct charmap_t *charmap,
-	  const struct repertoire_t *repertoire, int verbose)
+	  struct localedef_t *locale, const struct repertoire_t *repertoire,
+	  int verbose)
 {
   int ch;
 
@@ -295,7 +300,7 @@ lr_token (struct linereader *lr, const struct charmap_t *charmap,
       return &lr->token;
 
     case '"':
-      return get_string (lr, charmap, repertoire, verbose);
+      return get_string (lr, charmap, locale, repertoire, verbose);
 
     case '-':
       ch = lr_getc (lr);
@@ -568,7 +573,8 @@ get_ident (struct linereader *lr)
 
 static struct token *
 get_string (struct linereader *lr, const struct charmap_t *charmap,
-	    const struct repertoire_t *repertoire, int verbose)
+	    struct localedef_t *locale, const struct repertoire_t *repertoire,
+	    int verbose)
 {
   int return_widestr = lr->return_widestr;
   char *buf;
@@ -690,7 +696,6 @@ non-symbolic character value should not be used"));
 	      if (cp == &buf[bufact])
 		{
 		  char utmp[10];
-		  const char *symbol = NULL;
 
 		  /* Yes, it is.  */
 		  ADDC ('\0');
@@ -712,21 +717,65 @@ non-symbolic character value should not be used"));
 			the repertoire the name of the character and
 			find it in the charmap.  */
 		      if (repertoire != NULL)
-			symbol = repertoire_find_symbol (repertoire, wch);
-
-		      if (symbol == NULL)
-			/* We cannot generate a string since we
-			   cannot map from the Unicode number to the
-			   character symbol.  */
-			illegal_string = 1;
-		      else
 			{
-			  seq = charmap_find_value (charmap, symbol,
-						    strlen (symbol));
+			  const char *symbol;
 
-			  if (seq == NULL)
-			    /* Not a known name.  */
-			    illegal_string = 1;
+			  symbol = repertoire_find_symbol (repertoire, wch);
+
+			  if (symbol != NULL)
+			    seq = charmap_find_value (charmap, symbol,
+						      strlen (symbol));
+			}
+
+		      if (seq == NULL)
+			{
+#ifndef NO_TRANSLITERATION
+			  /* Transliterate if possible.  */
+			  if (locale != NULL)
+			    {
+			      uint32_t *translit;
+
+			      if ((locale->avail & CTYPE_LOCALE) == 0)
+				{
+				  /* Load the CTYPE data now.  */
+				  int old_needed = locale->needed;
+
+				  locale->needed = 0;
+				  locale = load_locale (CTYPE_LOCALE,
+							locale->name,
+							locale->repertoire_name,
+							charmap, locale);
+				  locale->needed = old_needed;
+				}
+
+			      if ((locale->avail & CTYPE_LOCALE) != 0
+				  && ((translit = find_translit (locale,
+								 charmap, wch))
+				      != NULL))
+				/* The CTYPE data contains a matching
+				   transliteration.  */
+				{
+				  int i;
+
+				  for (i = 0; translit[i] != 0; ++i)
+				    {
+				      char utmp[10];
+
+				      snprintf (utmp, sizeof (utmp), "U%08X",
+						translit[i]);
+				      seq = charmap_find_value (charmap, utmp,
+								9);
+				      assert (seq != NULL);
+				      ADDS (seq->bytes, seq->nbytes);
+				    }
+
+				  continue;
+				}
+			    }
+#endif	/* NO_TRANSLITERATION */
+
+			  /* Not a known name.  */
+			  illegal_string = 1;
 			}
 		    }
 
diff --git a/locale/programs/linereader.h b/locale/programs/linereader.h
index 69053cb02e..868c50264e 100644
--- a/locale/programs/linereader.h
+++ b/locale/programs/linereader.h
@@ -33,7 +33,7 @@
 
 typedef const struct keyword_t *(*kw_hash_fct_t) (const char *, unsigned int);
 struct charset_t;
-
+struct localedef_t;
 
 struct token
 {
@@ -85,12 +85,14 @@ struct linereader
 
 /* Functions defined in linereader.c.  */
 extern struct linereader *lr_open (const char *fname, kw_hash_fct_t hf);
-extern struct linereader *lr_create (FILE *fp, const char *fname, kw_hash_fct_t hf);
+extern struct linereader *lr_create (FILE *fp, const char *fname,
+				     kw_hash_fct_t hf);
 extern int lr_eof (struct linereader *lr);
 extern void lr_close (struct linereader *lr);
 extern int lr_next (struct linereader *lr);
 extern struct token *lr_token (struct linereader *lr,
 			       const struct charmap_t *charmap,
+			       struct localedef_t *locale,
 			       const struct repertoire_t *repertoire,
 			       int verbose);
 
diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c
index 62dbc1aafc..97034c0999 100644
--- a/locale/programs/localedef.c
+++ b/locale/programs/localedef.c
@@ -505,7 +505,7 @@ add_to_readlist (int locale, const char *name, const char *repertoire_name,
 
 struct localedef_t *
 find_locale (int locale, const char *name, const char *repertoire_name,
-	     struct charmap_t *charmap)
+	     const struct charmap_t *charmap)
 {
   struct localedef_t *result;
 
@@ -525,7 +525,7 @@ find_locale (int locale, const char *name, const char *repertoire_name,
 
 struct localedef_t *
 load_locale (int locale, const char *name, const char *repertoire_name,
-	     struct charmap_t *charmap, struct localedef_t *copy_locale)
+	     const struct charmap_t *charmap, struct localedef_t *copy_locale)
 {
   struct localedef_t *result;
 
diff --git a/locale/programs/localedef.h b/locale/programs/localedef.h
index dc631e96ac..cdb08d8293 100644
--- a/locale/programs/localedef.h
+++ b/locale/programs/localedef.h
@@ -1,5 +1,5 @@
 /* General definitions for localedef(1).
-   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -131,12 +131,12 @@ extern struct localedef_t *add_to_readlist (int locale, const char *name,
 /* Find the information for the locale NAME.  */
 extern struct localedef_t *find_locale (int locale, const char *name,
 					const char *repertoire_name,
-					struct charmap_t *charmap);
+					const struct charmap_t *charmap);
 
 /* Load (if necessary) the information for the locale NAME.  */
 extern struct localedef_t *load_locale (int locale, const char *name,
 					const char *repertoire_name,
-					struct charmap_t *charmap,
+					const struct charmap_t *charmap,
 					struct localedef_t *copy_locale);
 
 #endif /* localedef.h */
diff --git a/locale/programs/locfile.c b/locale/programs/locfile.c
index 3d774ef43d..d2e9ba1382 100644
--- a/locale/programs/locfile.c
+++ b/locale/programs/locfile.c
@@ -37,7 +37,7 @@
 
 
 int
-locfile_read (struct localedef_t *result, struct charmap_t *charmap)
+locfile_read (struct localedef_t *result, const struct charmap_t *charmap)
 {
   const char *filename = result->name;
   const char *repertoire_name = result->repertoire_name;
@@ -97,7 +97,7 @@ locfile_read (struct localedef_t *result, struct charmap_t *charmap)
     /* Parse locale definition file and store result in RESULT.  */
   while (1)
     {
-      struct token *now = lr_token (ldfile, charmap, NULL, verbose);
+      struct token *now = lr_token (ldfile, charmap, NULL, NULL, verbose);
       enum token_t nowtok = now->tok;
       struct token *arg;
 
@@ -113,7 +113,7 @@ locfile_read (struct localedef_t *result, struct charmap_t *charmap)
 	case tok_escape_char:
 	case tok_comment_char:
 	  /* We need an argument.  */
-	  arg = lr_token (ldfile, charmap, NULL, verbose);
+	  arg = lr_token (ldfile, charmap, NULL, NULL, verbose);
 
 	  if (arg->tok != tok_ident)
 	    {
@@ -140,7 +140,7 @@ argument to `%s' must be a single character"),
 
 	case tok_repertoiremap:
 	  /* We need an argument.  */
-	  arg = lr_token (ldfile, charmap, NULL, verbose);
+	  arg = lr_token (ldfile, charmap, NULL, NULL, verbose);
 
 	  if (arg->tok != tok_ident)
 	    {
@@ -265,7 +265,7 @@ syntax error: not inside a locale definition section"));
 /* Semantic checking of locale specifications.  */
 
 static void (*const check_funcs[]) (struct localedef_t *,
-				    struct charmap_t *) =
+				    const struct charmap_t *) =
 {
   [LC_CTYPE] = ctype_finish,
   [LC_COLLATE] = collate_finish,
@@ -283,7 +283,7 @@ static void (*const check_funcs[]) (struct localedef_t *,
 
 void
 check_all_categories (struct localedef_t *definitions,
-		      struct charmap_t *charmap)
+		      const struct charmap_t *charmap)
 {
   int cnt;
 
@@ -295,8 +295,8 @@ check_all_categories (struct localedef_t *definitions,
 
 /* Writing the locale data files.  All files use the same output_path.  */
 
-static void (*const write_funcs[]) (struct localedef_t *, struct charmap_t *,
-				    const char *) =
+static void (*const write_funcs[]) (struct localedef_t *,
+				    const struct charmap_t *, const char *) =
 {
   [LC_CTYPE] = ctype_output,
   [LC_COLLATE] = collate_output,
@@ -314,7 +314,7 @@ static void (*const write_funcs[]) (struct localedef_t *, struct charmap_t *,
 
 void
 write_all_categories (struct localedef_t *definitions,
-		      struct charmap_t *charmap,
+		      const struct charmap_t *charmap,
 		      const char *output_path)
 {
   int cnt;
diff --git a/locale/programs/locfile.h b/locale/programs/locfile.h
index 2693187f9b..4f6c8fee3e 100644
--- a/locale/programs/locfile.h
+++ b/locale/programs/locfile.h
@@ -46,7 +46,7 @@ struct locale_file
 
 /* General handling of `copy'.  */
 static inline void
-handle_copy (struct linereader *ldfile, struct charmap_t *charmap,
+handle_copy (struct linereader *ldfile, const struct charmap_t *charmap,
 	     const char *repertoire_name, struct localedef_t *result,
 	     enum token_t token, int locale, const char *locale_name,
 	     int ignore_content)
@@ -54,7 +54,7 @@ handle_copy (struct linereader *ldfile, struct charmap_t *charmap,
   struct token *now;
   int warned = 0;
 
-  now = lr_token (ldfile, charmap, NULL, verbose);
+  now = lr_token (ldfile, charmap, result, NULL, verbose);
   if (now->tok != tok_string)
     lr_error (ldfile, _("expect string argument for `copy'"));
   else if (!ignore_content)
@@ -74,8 +74,8 @@ locale name should consist only of portable characters"));
 
   /* The rest of the line must be empty and the next keyword must be
      `END xxx'.  */
-  while ((now = lr_token (ldfile, charmap, NULL, verbose))->tok != tok_end
-	 && now->tok != tok_eof)
+  while ((now = lr_token (ldfile, charmap, result, NULL, verbose))->tok
+	 != tok_end && now->tok != tok_eof)
     {
       if (warned == 0)
 	{
@@ -90,7 +90,7 @@ no other keyword shall be specified when `copy' is used"));
   if (now->tok != tok_eof)
     {
       /* Handle `END xxx'.  */
-      now = lr_token (ldfile, charmap, NULL, verbose);
+      now = lr_token (ldfile, charmap, result, NULL, verbose);
 
       if (now->tok != token)
 	lr_error (ldfile, _("\
@@ -106,15 +106,15 @@ no other keyword shall be specified when `copy' is used"));
 
 /* Found in locfile.c.  */
 extern int locfile_read (struct localedef_t *result,
-			 struct charmap_t *charmap);
+			 const struct charmap_t *charmap);
 
 /* Check validity of all the locale data.  */
 extern void check_all_categories (struct localedef_t *definitions,
-				  struct charmap_t *charmap);
+				  const struct charmap_t *charmap);
 
 /* Write out all locale categories.  */
 extern void write_all_categories (struct localedef_t *definitions,
-				  struct charmap_t *charmap,
+				  const struct charmap_t *charmap,
 				  const char *output_path);
 
 /* Write out the data.  */
@@ -127,145 +127,147 @@ extern void write_locale_data (const char *output_path, const char *category,
 /* Handle LC_CTYPE category.  */
 extern void ctype_read (struct linereader *ldfile,
 			struct localedef_t *result,
-			struct charmap_t *charmap,
+			const struct charmap_t *charmap,
 			const char *repertoire_name,
 			int ignore_content);
 extern void ctype_finish (struct localedef_t *locale,
-			  struct charmap_t *charmap);
+			  const struct charmap_t *charmap);
 extern void ctype_output (struct localedef_t *locale,
-			  struct charmap_t *charmap,
+			  const struct charmap_t *charmap,
 			  const char *output_path);
+extern uint32_t *find_translit (struct localedef_t *locale,
+				const struct charmap_t *charmap, uint32_t wch);
 
 /* Handle LC_COLLATE category.  */
 extern void collate_read (struct linereader *ldfile,
 			  struct localedef_t *result,
-			  struct charmap_t *charmap,
+			  const struct charmap_t *charmap,
 			  const char *repertoire_name,
 			  int ignore_content);
 extern void collate_finish (struct localedef_t *locale,
-			    struct charmap_t *charmap);
+			    const struct charmap_t *charmap);
 extern void collate_output (struct localedef_t *locale,
-			    struct charmap_t *charmap,
+			    const struct charmap_t *charmap,
 			    const char *output_path);
 
 /* Handle LC_MONETARY category.  */
 extern void monetary_read (struct linereader *ldfile,
 			   struct localedef_t *result,
-			   struct charmap_t *charmap,
+			   const struct charmap_t *charmap,
 			   const char *repertoire_name,
 			   int ignore_content);
 extern void monetary_finish (struct localedef_t *locale,
-			     struct charmap_t *charmap);
+			     const struct charmap_t *charmap);
 extern void monetary_output (struct localedef_t *locale,
-			     struct charmap_t *charmap,
+			     const struct charmap_t *charmap,
 			     const char *output_path);
 
 /* Handle LC_NUMERIC category.  */
 extern void numeric_read (struct linereader *ldfile,
 			  struct localedef_t *result,
-			  struct charmap_t *charmap,
+			  const struct charmap_t *charmap,
 			  const char *repertoire_name,
 			  int ignore_content);
 extern void numeric_finish (struct localedef_t *locale,
-			    struct charmap_t *charmap);
+			    const struct charmap_t *charmap);
 extern void numeric_output (struct localedef_t *locale,
-			    struct charmap_t *charmap,
+			    const struct charmap_t *charmap,
 			    const char *output_path);
 
 /* Handle LC_MESSAGES category.  */
 extern void messages_read (struct linereader *ldfile,
 			   struct localedef_t *result,
-			   struct charmap_t *charmap,
+			   const struct charmap_t *charmap,
 			   const char *repertoire_name,
 			   int ignore_content);
 extern void messages_finish (struct localedef_t *locale,
-			     struct charmap_t *charmap);
+			     const struct charmap_t *charmap);
 extern void messages_output (struct localedef_t *locale,
-			     struct charmap_t *charmap,
+			     const struct charmap_t *charmap,
 			     const char *output_path);
 
 /* Handle LC_TIME category.  */
 extern void time_read (struct linereader *ldfile,
 		       struct localedef_t *result,
-		       struct charmap_t *charmap,
+		       const struct charmap_t *charmap,
 		       const char *repertoire_name,
 		       int ignore_content);
 extern void time_finish (struct localedef_t *locale,
-			 struct charmap_t *charmap);
+			 const struct charmap_t *charmap);
 extern void time_output (struct localedef_t *locale,
-			 struct charmap_t *charmap,
+			 const struct charmap_t *charmap,
 			 const char *output_path);
 
 /* Handle LC_PAPER category.  */
 extern void paper_read (struct linereader *ldfile,
 			struct localedef_t *result,
-			struct charmap_t *charmap,
+			const struct charmap_t *charmap,
 			const char *repertoire_name,
 			int ignore_content);
 extern void paper_finish (struct localedef_t *locale,
-			  struct charmap_t *charmap);
+			  const struct charmap_t *charmap);
 extern void paper_output (struct localedef_t *locale,
-			  struct charmap_t *charmap,
+			  const struct charmap_t *charmap,
 			  const char *output_path);
 
 /* Handle LC_NAME category.  */
 extern void name_read (struct linereader *ldfile,
 		       struct localedef_t *result,
-		       struct charmap_t *charmap,
+		       const struct charmap_t *charmap,
 		       const char *repertoire_name,
 		       int ignore_content);
 extern void name_finish (struct localedef_t *locale,
-			 struct charmap_t *charmap);
+			 const struct charmap_t *charmap);
 extern void name_output (struct localedef_t *locale,
-			 struct charmap_t *charmap,
+			 const struct charmap_t *charmap,
 			 const char *output_path);
 
 /* Handle LC_ADDRESS category.  */
 extern void address_read (struct linereader *ldfile,
 			  struct localedef_t *result,
-			  struct charmap_t *charmap,
+			  const struct charmap_t *charmap,
 			  const char *repertoire_name,
 			  int ignore_content);
 extern void address_finish (struct localedef_t *locale,
-			    struct charmap_t *charmap);
+			    const struct charmap_t *charmap);
 extern void address_output (struct localedef_t *locale,
-			    struct charmap_t *charmap,
+			    const struct charmap_t *charmap,
 			    const char *output_path);
 
 /* Handle LC_TELEPHONE category.  */
 extern void telephone_read (struct linereader *ldfile,
 			    struct localedef_t *result,
-			    struct charmap_t *charmap,
+			    const struct charmap_t *charmap,
 			    const char *repertoire_name,
 			    int ignore_content);
 extern void telephone_finish (struct localedef_t *locale,
-			      struct charmap_t *charmap);
+			      const struct charmap_t *charmap);
 extern void telephone_output (struct localedef_t *locale,
-			      struct charmap_t *charmap,
+			      const struct charmap_t *charmap,
 			      const char *output_path);
 
 /* Handle LC_MEASUREMENT category.  */
 extern void measurement_read (struct linereader *ldfile,
 			      struct localedef_t *result,
-			      struct charmap_t *charmap,
+			      const struct charmap_t *charmap,
 			      const char *repertoire_name,
 			      int ignore_content);
 extern void measurement_finish (struct localedef_t *locale,
-				struct charmap_t *charmap);
+				const struct charmap_t *charmap);
 extern void measurement_output (struct localedef_t *locale,
-				struct charmap_t *charmap,
+				const struct charmap_t *charmap,
 				const char *output_path);
 
 /* Handle LC_IDENTIFICATION category.  */
 extern void identification_read (struct linereader *ldfile,
 				 struct localedef_t *result,
-				 struct charmap_t *charmap,
+				 const struct charmap_t *charmap,
 				 const char *repertoire_name,
 				 int ignore_content);
 extern void identification_finish (struct localedef_t *locale,
-				   struct charmap_t *charmap);
+				   const struct charmap_t *charmap);
 extern void identification_output (struct localedef_t *locale,
-				   struct charmap_t *charmap,
+				   const struct charmap_t *charmap,
 				   const char *output_path);
 
 #endif /* locfile.h */
diff --git a/locale/programs/repertoire.c b/locale/programs/repertoire.c
index e66b24fe58..903b620216 100644
--- a/locale/programs/repertoire.c
+++ b/locale/programs/repertoire.c
@@ -149,7 +149,7 @@ repertoire_read (const char *filename)
   while (1)
     {
       /* What's on?  */
-      struct token *now = lr_token (repfile, NULL, NULL, verbose);
+      struct token *now = lr_token (repfile, NULL, NULL, NULL, verbose);
       enum token_t nowtok = now->tok;
       struct token *arg;
 
@@ -168,7 +168,7 @@ repertoire_read (const char *filename)
 	  if (nowtok == tok_escape_char || nowtok == tok_comment_char)
 	    {
 	      /* We know that we need an argument.  */
-	      arg = lr_token (repfile, NULL, NULL, verbose);
+	      arg = lr_token (repfile, NULL, NULL, NULL, verbose);
 
 	      if (arg->tok != tok_ident)
 		{
diff --git a/localedata/ChangeLog b/localedata/ChangeLog
index 18f9b412de..8ebfeb0d21 100644
--- a/localedata/ChangeLog
+++ b/localedata/ChangeLog
@@ -1,3 +1,7 @@
+2001-12-09  Ulrich Drepper  <drepper@redhat.com>
+
+	* charmaps/TCVN5712-1: Add combined characters.
+
 2001-12-05  Ulrich Drepper  <drepper@redhat.com>
 
 	* locales/bg_BG: Rewrite.
diff --git a/localedata/charmaps/TCVN5712-1 b/localedata/charmaps/TCVN5712-1
index 824a76408c..be7fa14a7b 100644
--- a/localedata/charmaps/TCVN5712-1
+++ b/localedata/charmaps/TCVN5712-1
@@ -1,6 +1,8 @@
 <code_set_name> TCVN5712-1
 <comment_char> %
 <escape_char> /
+<mb_cur_min> 1
+<mb_cur_max> 2
 
 % alias TCVN
 % alias TCVN-5712
@@ -262,4 +264,60 @@ CHARMAP
 <U00FD>     /xfd         LATIN SMALL LETTER Y WITH ACUTE
 <U1EF5>     /xfe         LATIN SMALL LETTER Y WITH DOT BELOW
 <U1ED0>     /xff         LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE
+<U0106>     /x43/xb3     LATIN CAPITAL LETTER C WITH ACUTE
+<U0107>     /x63/xb3     LATIN SMALL LETTER C WITH ACUTE
+<U00D1>     /x4e/xb2     LATIN CAPITAL LETTER N WITH TILDE
+<U00F1>     /x6e/xb2     LATIN SMALL LETTER N WITH TILDE
+<U0139>     /x4c/xb3     LATIN CAPITAL LETTER L WITH ACUTE
+<U013A>     /x6c/xb3     LATIN SMALL LETTER L WITH ACUTE
+<U0143>     /x4e/xb3     LATIN CAPITAL LETTER N WITH ACUTE
+<U0144>     /x6e/xb3     LATIN SMALL LETTER N WITH ACUTE
+<U0154>     /x52/xb3     LATIN CAPITAL LETTER R WITH ACUTE
+<U0155>     /x72/xb3     LATIN SMALL LETTER R WITH ACUTE
+<U015A>     /x53/xb3     LATIN CAPITAL LETTER S WITH ACUTE
+<U015B>     /x73/xb3     LATIN SMALL LETTER S WITH ACUTE
+<U0179>     /x5a/xb3     LATIN CAPITAL LETTER Z WITH ACUTE
+<U017A>     /x7a/xb3     LATIN SMALL LETTER Z WITH ACUTE
+<U01F4>     /x47/xb3     LATIN CAPITAL LETTER G WITH ACUTE
+<U01F5>     /x67/xb3     LATIN SMALL LETTER G WITH ACUTE
+<U01F8>     /x4e/xb0     LATIN CAPITAL LETTER N WITH GRAVE
+<U01F9>     /x6e/xb0     LATIN SMALL LETTER N WITH GRAVE
+<U1E04>     /x42/xb4     LATIN CAPITAL LETTER B WITH DOT BELOW
+<U1E05>     /x62/xb4     LATIN SMALL LETTER B WITH DOT BELOW
+<U1E0C>     /x44/xb4     LATIN CAPITAL LETTER D WITH DOT BELOW
+<U1E0D>     /x64/xb4     LATIN SMALL LETTER D WITH DOT BELOW
+<U1E24>     /x48/xb4     LATIN CAPITAL LETTER H WITH DOT BELOW
+<U1E25>     /x68/xb4     LATIN SMALL LETTER H WITH DOT BELOW
+<U1E30>     /x4b/xb3     LATIN CAPITAL LETTER K WITH ACUTE
+<U1E31>     /x6b/xb3     LATIN SMALL LETTER K WITH ACUTE
+<U1E32>     /x4b/xb4     LATIN CAPITAL LETTER K WITH DOT BELOW
+<U1E33>     /x6b/xb4     LATIN SMALL LETTER K WITH DOT BELOW
+<U1E36>     /x4c/xb4     LATIN CAPITAL LETTER L WITH DOT BELOW
+<U1E37>     /x6c/xb4     LATIN SMALL LETTER L WITH DOT BELOW
+<U1E3E>     /x4d/xb3     LATIN CAPITAL LETTER M WITH ACUTE
+<U1E3F>     /x6d/xb3     LATIN SMALL LETTER M WITH ACUTE
+<U1E42>     /x4d/xb4     LATIN CAPITAL LETTER M WITH DOT BELOW
+<U1E43>     /x6d/xb4     LATIN SMALL LETTER M WITH DOT BELOW
+<U1E46>     /x4e/xb4     LATIN CAPITAL LETTER N WITH DOT BELOW
+<U1E47>     /x6e/xb4     LATIN SMALL LETTER N WITH DOT BELOW
+<U1E54>     /x50/xb3     LATIN CAPITAL LETTER P WITH ACUTE
+<U1E55>     /x70/xb3     LATIN SMALL LETTER P WITH ACUTE
+<U1E5A>     /x52/xb4     LATIN CAPITAL LETTER R WITH DOT BELOW
+<U1E5B>     /x72/xb4     LATIN SMALL LETTER R WITH DOT BELOW
+<U1E62>     /x53/xb4     LATIN CAPITAL LETTER S WITH DOT BELOW
+<U1E63>     /x73/xb4     LATIN SMALL LETTER S WITH DOT BELOW
+<U1E6C>     /x54/xb4     LATIN CAPITAL LETTER T WITH DOT BELOW
+<U1E6D>     /x74/xb4     LATIN SMALL LETTER T WITH DOT BELOW
+<U1E7C>     /x56/xb2     LATIN CAPITAL LETTER V WITH TILDE
+<U1E7D>     /x76/xb2     LATIN SMALL LETTER V WITH TILDE
+<U1E7E>     /x56/xb4     LATIN CAPITAL LETTER V WITH DOT BELOW
+<U1E7F>     /x76/xb4     LATIN SMALL LETTER V WITH DOT BELOW
+<U1E80>     /x57/xb0     LATIN CAPITAL LETTER W WITH GRAVE
+<U1E81>     /x77/xb0     LATIN SMALL LETTER W WITH GRAVE
+<U1E82>     /x57/xb3     LATIN CAPITAL LETTER W WITH ACUTE
+<U1E83>     /x77/xb3     LATIN SMALL LETTER W WITH ACUTE
+<U1E88>     /x57/xb4     LATIN CAPITAL LETTER W WITH DOT BELOW
+<U1E89>     /x77/xb4     LATIN SMALL LETTER W WITH DOT BELOW
+<U1E92>     /x5a/xb4     LATIN CAPITAL LETTER Z WITH DOT BELOW
+<U1E93>     /x7a/xb4     LATIN SMALL LETTER Z WITH DOT BELOW
 END CHARMAP