about summary refs log tree commit diff
path: root/locale/programs/ld-ctype.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2001-12-10 01:37:56 +0000
committerUlrich Drepper <drepper@redhat.com>2001-12-10 01:37:56 +0000
commit47e8b4439dda245845e85dfbb054693a9b132635 (patch)
treeef27110e00f1a9f726c74c2f8473499ccf3dd0de /locale/programs/ld-ctype.c
parenta352ab4ca56142647227c3d2943adfa455679ada (diff)
downloadglibc-47e8b4439dda245845e85dfbb054693a9b132635.tar.gz
glibc-47e8b4439dda245845e85dfbb054693a9b132635.tar.xz
glibc-47e8b4439dda245845e85dfbb054693a9b132635.zip
Update.
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.
Diffstat (limited to 'locale/programs/ld-ctype.c')
-rw-r--r--locale/programs/ld-ctype.c228
1 files changed, 163 insertions, 65 deletions
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;