[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commits] r23939 - in /fsf/trunk/libc: ./ benchtests/ inet/netinet/ locale/programs/ localedata/ localedata/locales/ sysdeps/unix/sysv...



Author: eglibc
Date: Fri Sep  6 17:39:04 2013
New Revision: 23939

Log:
Import glibc-mainline for 2013-09-06

Added:
    fsf/trunk/libc/benchtests/bench-memrchr-ifunc.c
    fsf/trunk/libc/benchtests/bench-memrchr.c
Modified:
    fsf/trunk/libc/ChangeLog
    fsf/trunk/libc/benchtests/Makefile
    fsf/trunk/libc/benchtests/bench-memchr.c
    fsf/trunk/libc/inet/netinet/in.h
    fsf/trunk/libc/locale/programs/3level.h
    fsf/trunk/libc/locale/programs/ld-address.c
    fsf/trunk/libc/locale/programs/ld-collate.c
    fsf/trunk/libc/locale/programs/ld-ctype.c
    fsf/trunk/libc/locale/programs/ld-identification.c
    fsf/trunk/libc/locale/programs/ld-measurement.c
    fsf/trunk/libc/locale/programs/ld-messages.c
    fsf/trunk/libc/locale/programs/ld-monetary.c
    fsf/trunk/libc/locale/programs/ld-name.c
    fsf/trunk/libc/locale/programs/ld-numeric.c
    fsf/trunk/libc/locale/programs/ld-paper.c
    fsf/trunk/libc/locale/programs/ld-telephone.c
    fsf/trunk/libc/locale/programs/ld-time.c
    fsf/trunk/libc/locale/programs/locfile.c
    fsf/trunk/libc/locale/programs/locfile.h
    fsf/trunk/libc/localedata/ChangeLog
    fsf/trunk/libc/localedata/locales/nr_ZA
    fsf/trunk/libc/localedata/locales/nso_ZA
    fsf/trunk/libc/localedata/locales/ss_ZA
    fsf/trunk/libc/localedata/locales/tk_TM
    fsf/trunk/libc/localedata/locales/tn_ZA
    fsf/trunk/libc/localedata/locales/ve_ZA
    fsf/trunk/libc/sysdeps/unix/sysv/linux/bits/in.h

Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Fri Sep  6 17:39:04 2013
@@ -1,3 +1,107 @@
+2013-09-06  Richard Sandiford  <richard@xxxxxxxxxxxxxxxx>
+	    Joseph Myers  <joseph@xxxxxxxxxxxxxxxx>
+
+	* locale/programs/locfile.c: Include <assert.h>, <wchar.h> and
+	"localeinfo.h".
+	(obstack_chunk_alloc): New macro.
+	(obstack_chunk_free): Likewise.
+	(record_offset): New function.
+	(init_locale_data): Likewise.
+	(align_locale_data): Likewise.
+	(add_locale_empty): Likewise.
+	(add_locale_raw_data): Likewise.
+	(add_locale_raw_obstack): Likewise.
+	(add_locale_string): Likewise.
+	(add_locale_wstring): Likewise.
+	(add_locale_uint32): Likewise.
+	(add_locale_uint32_array): Likewise.
+	(add_locale_char): Likewise.
+	(start_locale_structure): Likewise.
+	(end_locale_structure): Likewise.
+	(start_locale_prelude): Likewise.
+	(end_locale_prelude): Likewise.
+	(write_locale_data): Take locale_file structure rather than an
+	iovec.
+	* locale/programs/locfile.h: Include "obstack.h".
+	(struct locale_file): Change to store locale file contents instead
+	of header.
+	(init_locale_data): New prototype.
+	(align_locale_data): Likewise.
+	(add_locale_empty): Likewise.
+	(add_locale_raw_data): Likewise.
+	(add_locale_raw_obstack): Likewise.
+	(add_locale_string): Likewise.
+	(add_locale_wstring): Likewise.
+	(add_locale_uint32): Likewise.
+	(add_locale_uint32_array): Likewise.
+	(add_locale_char): Likewise.
+	(start_locale_structure): Likewise.
+	(end_locale_structure): Likewise.
+	(start_locale_prelude): Likewise.
+	(end_locale_prelude): Likewise.
+	(write_locale_data): Update prototype.
+	* locale/programs/3level.h (struct TABLE): Remove result field.
+	(CONCAT(TABLE,_finalize)): Change to CONCAT(add_locale_,TABLE).
+	Use new locale_file interface.
+	[!NO_FINALIZE]: Change condition to [!NO_ADD_LOCALE].
+	(NO_FINALIZE): Change #undef to #undef of NO_ADD_LOCALE.
+	* locale/programs/ld-address.c (address_output): Use new
+	locale_file interface.
+	* locale/programs/ld-collate.c (NO_FINALIZE): Change to
+	NO_ADD_LOCALE.
+	(collate_finish): Don't call collseq_table_finalize.
+	(collate_output): Use new locale_file interface.
+	* locale/programs/ld-ctype.c: Move includes of "3level.h" earlier
+	in file.
+	(NO_FINALIZE): Change to NO_ADD_LOCALE.
+	(TABLE): Move defines earlier in file.
+	(ELEMENT): Likewise.
+	(DEFAULT): Likewise.
+	(wctrans_table_add): Move macro and inline function earlier in
+	file.
+	(struct wctype_table): Move type earlier in file.
+	(add_locale_wctype_table): New static prototype.
+	(struct locale_ctype_t): Use logical types instead of struct iovec
+	pointers for members.
+	(ctype_output): Use new locale_file interface.
+	(wctype_table_finalize): Change to add_locale_wctype_table.  Use
+	new locale_file interface.
+	(allocate_arrays): Update for use of new locale_file interface.
+	* locale/programs/ld-identification.c (identification_output): Use
+	new locale_file interface.
+	* locale/programs/ld-measurement.c (measurement_output): Likewise.
+	* locale/programs/ld-messages.c (messages_output): Likewise.
+	* locale/programs/ld-monetary.c (monetary_output): Likewise.
+	* locale/programs/ld-name.c (name_output): Likewise.
+	* locale/programs/ld-numeric.c (numeric_output): Likewise.
+	* locale/programs/ld-paper.c (paper_output): Likewise.
+	* locale/programs/ld-telephone.c (telephone_output): Likewise.
+	* locale/programs/ld-time.c (time_output): Likewise.
+
+2013-09-06  Adhemerval Zanella  <azanella@xxxxxxxxxxxxxxxxxx>
+
+	* benchtests/Makefile: Add memrchr benchmark.
+	* benchtests/bench-memchr.c (USE_AS_MEMRCHR): Add define to use
+	benchmark as memrchr.
+	* benchtests/bench-memrchr-ifunc.c: New file.
+	* benchtests/bench-memrchr.c: New file.
+
+2013-09-06   Will Newton  <will.newton@xxxxxxxxxx>
+
+	* benchtests/Makefile (string-bench): Add memcpy.
+
+2013-09-05  Carlos O'Donell  <carlos@xxxxxxxxxx>
+	    Cong Wang  <amwang@xxxxxxxxxx>
+
+	* sysdeps/unix/sysv/linux/bits/in.h
+	[_UAPI_LINUX_IN6_H]: Define __USE_KERNEL_IPV6_DEFS.
+	* inet/netinet/in.h: Move in_addr definition and bits/in.h inclusion
+	before __USE_KERNEL_IPV6_DEFS uses.
+	* inet/netinet/in.h [!__USE_KERNEL_IPV6_DEFS]: Define IPPROTO_MH, and
+	IPPROTO_BEETPH.
+	[__USE_KERNEL_IPV6_DEFS]: Don't define any of IPPROTO_*, in6_addr,
+	sockaddr_in6, or ipv6_mreq.
+
 2013-09-05  Adhemerval Zanella  <azanella@xxxxxxxxxxxxxxxxxx>
 
 	* sysdeps/powerpc/powerpc32/power7/memrchr.S (__memrchr): Fix invalid

Modified: fsf/trunk/libc/benchtests/Makefile
==============================================================================
--- fsf/trunk/libc/benchtests/Makefile (original)
+++ fsf/trunk/libc/benchtests/Makefile Fri Sep  6 17:39:04 2013
@@ -24,11 +24,11 @@
 	 sinh tan tanh
 
 # String function benchmarks.
-string-bench := bcopy bzero memccpy memchr memcmp memmem memmove mempcpy \
-		memset rawmemchr stpcpy stpncpy strcasecmp strcasestr strcat \
-		strchr strchrnul strcmp strcpy strcspn strlen strncasecmp \
-		strncat strncmp strncpy strnlen strpbrk strrchr strspn strstr \
-		strcpy_chk stpcpy_chk
+string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \
+		mempcpy memset rawmemchr stpcpy stpncpy strcasecmp strcasestr \
+		strcat strchr strchrnul strcmp strcpy strcspn strlen \
+		strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \
+		strspn strstr strcpy_chk stpcpy_chk memrchr
 string-bench-ifunc := $(addsuffix -ifunc, $(string-bench))
 string-bench-all := $(string-bench) $(string-bench-ifunc)
 

Modified: fsf/trunk/libc/benchtests/bench-memchr.c
==============================================================================
--- fsf/trunk/libc/benchtests/bench-memchr.c (original)
+++ fsf/trunk/libc/benchtests/bench-memchr.c Fri Sep  6 17:39:04 2013
@@ -16,9 +16,10 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define TEST_MAIN
-#define TEST_NAME "memchr"
-#include "bench-string.h"
+#ifndef USE_AS_MEMRCHR
+# define TEST_MAIN
+# define TEST_NAME "memchr"
+# include "bench-string.h"
 
 typedef char *(*proto_t) (const char *, int, size_t);
 char *simple_memchr (const char *, int, size_t);
@@ -34,6 +35,7 @@
       return (char *) s - 1;
   return NULL;
 }
+#endif
 
 static void
 do_one_test (impl_t *impl, const char *s, int c, size_t n, char *exp_res)

Added: fsf/trunk/libc/benchtests/bench-memrchr-ifunc.c
==============================================================================
--- fsf/trunk/libc/benchtests/bench-memrchr-ifunc.c (added)
+++ fsf/trunk/libc/benchtests/bench-memrchr-ifunc.c Fri Sep  6 17:39:04 2013
@@ -1,0 +1,20 @@
+/* Measure IFUNC implementations of memrchr function.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_IFUNC 1
+#include "bench-memrchr.c"

Added: fsf/trunk/libc/benchtests/bench-memrchr.c
==============================================================================
--- fsf/trunk/libc/benchtests/bench-memrchr.c (added)
+++ fsf/trunk/libc/benchtests/bench-memrchr.c Fri Sep  6 17:39:04 2013
@@ -1,0 +1,40 @@
+/* Measure memrchr functions.
+   Copyright (C) 2013 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#define TEST_MAIN
+#define TEST_NAME "memrchr"
+#include "bench-string.h"
+
+typedef char *(*proto_t) (const char *, int, size_t);
+char *simple_memrchr (const char *, int, size_t);
+
+IMPL (simple_memrchr, 0)
+IMPL (memrchr, 1)
+
+char *
+simple_memrchr (const char *s, int c, size_t n)
+{
+  s = s + n;
+  while (n--)
+    if (*--s == (char) c)
+      return (char *) s;
+  return NULL;
+}
+
+#define USE_AS_MEMRCHR
+#include "bench-memchr.c"

Modified: fsf/trunk/libc/inet/netinet/in.h
==============================================================================
--- fsf/trunk/libc/inet/netinet/in.h (original)
+++ fsf/trunk/libc/inet/netinet/in.h Fri Sep  6 17:39:04 2013
@@ -26,13 +26,21 @@
 
 __BEGIN_DECLS
 
+/* Internet address.  */
+typedef uint32_t in_addr_t;
+struct in_addr
+  {
+    in_addr_t s_addr;
+  };
+
+/* Get system-specific definitions.  */
+#include <bits/in.h>
+
 /* Standard well-defined IP protocols.  */
 enum
   {
     IPPROTO_IP = 0,	   /* Dummy protocol for TCP.  */
 #define IPPROTO_IP		IPPROTO_IP
-    IPPROTO_HOPOPTS = 0,   /* IPv6 Hop-by-Hop options.  */
-#define IPPROTO_HOPOPTS		IPPROTO_HOPOPTS
     IPPROTO_ICMP = 1,	   /* Internet Control Message Protocol.  */
 #define IPPROTO_ICMP		IPPROTO_ICMP
     IPPROTO_IGMP = 2,	   /* Internet Group Management Protocol. */
@@ -55,10 +63,6 @@
 #define IPPROTO_DCCP		IPPROTO_DCCP
     IPPROTO_IPV6 = 41,     /* IPv6 header.  */
 #define IPPROTO_IPV6		IPPROTO_IPV6
-    IPPROTO_ROUTING = 43,  /* IPv6 routing header.  */
-#define IPPROTO_ROUTING		IPPROTO_ROUTING
-    IPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header.  */
-#define IPPROTO_FRAGMENT	IPPROTO_FRAGMENT
     IPPROTO_RSVP = 46,	   /* Reservation Protocol.  */
 #define IPPROTO_RSVP		IPPROTO_RSVP
     IPPROTO_GRE = 47,	   /* General Routing Encapsulation.  */
@@ -67,14 +71,10 @@
 #define IPPROTO_ESP		IPPROTO_ESP
     IPPROTO_AH = 51,       /* authentication header.  */
 #define IPPROTO_AH		IPPROTO_AH
-    IPPROTO_ICMPV6 = 58,   /* ICMPv6.  */
-#define IPPROTO_ICMPV6		IPPROTO_ICMPV6
-    IPPROTO_NONE = 59,     /* IPv6 no next header.  */
-#define IPPROTO_NONE		IPPROTO_NONE
-    IPPROTO_DSTOPTS = 60,  /* IPv6 destination options.  */
-#define IPPROTO_DSTOPTS		IPPROTO_DSTOPTS
     IPPROTO_MTP = 92,	   /* Multicast Transport Protocol.  */
 #define IPPROTO_MTP		IPPROTO_MTP
+    IPPROTO_BEETPH = 94,   /* IP option pseudo header for BEET.  */
+#define IPPROTO_BEETPH		IPPROTO_BEETPH
     IPPROTO_ENCAP = 98,	   /* Encapsulation Header.  */
 #define IPPROTO_ENCAP		IPPROTO_ENCAP
     IPPROTO_PIM = 103,	   /* Protocol Independent Multicast.  */
@@ -90,6 +90,28 @@
     IPPROTO_MAX
   };
 
+/* If __USER_KERNEL_IPV6_DEFS is defined then the user has included the kernel
+   network headers first and we should use those ABI-identical definitions
+   instead of our own.  */
+#ifndef __USE_KERNEL_IPV6_DEFS
+enum
+  {
+    IPPROTO_HOPOPTS = 0,   /* IPv6 Hop-by-Hop options.  */
+#define IPPROTO_HOPOPTS		IPPROTO_HOPOPTS
+    IPPROTO_ROUTING = 43,  /* IPv6 routing header.  */
+#define IPPROTO_ROUTING		IPPROTO_ROUTING
+    IPPROTO_FRAGMENT = 44, /* IPv6 fragmentation header.  */
+#define IPPROTO_FRAGMENT	IPPROTO_FRAGMENT
+    IPPROTO_ICMPV6 = 58,   /* ICMPv6.  */
+#define IPPROTO_ICMPV6		IPPROTO_ICMPV6
+    IPPROTO_NONE = 59,     /* IPv6 no next header.  */
+#define IPPROTO_NONE		IPPROTO_NONE
+    IPPROTO_DSTOPTS = 60,  /* IPv6 destination options.  */
+#define IPPROTO_DSTOPTS		IPPROTO_DSTOPTS
+    IPPROTO_MH = 135,      /* IPv6 mobility header.  */
+#define IPPROTO_MH		IPPROTO_MH
+  };
+#endif /* !__USE_KERNEL_IPV6_DEFS */
 
 /* Type to represent a port.  */
 typedef uint16_t in_port_t;
@@ -134,15 +156,6 @@
     IPPORT_USERRESERVED = 5000
   };
 
-
-/* Internet address.  */
-typedef uint32_t in_addr_t;
-struct in_addr
-  {
-    in_addr_t s_addr;
-  };
-
-
 /* Definitions of the bits in an Internet address integer.
 
    On subnets, host and network parts are found according to
@@ -191,7 +204,7 @@
 #define INADDR_ALLRTRS_GROUP    ((in_addr_t) 0xe0000002) /* 224.0.0.2 */
 #define INADDR_MAX_LOCAL_GROUP  ((in_addr_t) 0xe00000ff) /* 224.0.0.255 */
 
-
+#ifndef __USE_KERNEL_IPV6_DEFS
 /* IPv6 address */
 struct in6_addr
   {
@@ -209,6 +222,7 @@
 # define s6_addr32		__in6_u.__u6_addr32
 #endif
   };
+#endif /* !__USE_KERNEL_IPV6_DEFS */
 
 extern const struct in6_addr in6addr_any;        /* :: */
 extern const struct in6_addr in6addr_loopback;   /* ::1 */
@@ -233,6 +247,7 @@
 			   sizeof (struct in_addr)];
   };
 
+#ifndef __USE_KERNEL_IPV6_DEFS
 /* Ditto, for IPv6.  */
 struct sockaddr_in6
   {
@@ -242,7 +257,7 @@
     struct in6_addr sin6_addr;	/* IPv6 address */
     uint32_t sin6_scope_id;	/* IPv6 scope-id */
   };
-
+#endif /* !__USE_KERNEL_IPV6_DEFS */
 
 #if defined __USE_MISC || defined __USE_GNU
 /* IPv4 multicast request.  */
@@ -268,7 +283,7 @@
   };
 #endif
 
-
+#ifndef __USE_KERNEL_IPV6_DEFS
 /* Likewise, for IPv6.  */
 struct ipv6_mreq
   {
@@ -278,7 +293,7 @@
     /* local interface */
     unsigned int ipv6mr_interface;
   };
-
+#endif /* !__USE_KERNEL_IPV6_DEFS */
 
 #if defined __USE_MISC || defined __USE_GNU
 /* Multicast group request.  */
@@ -348,10 +363,6 @@
 				   + ((numsrc)				      \
 				      * sizeof (struct sockaddr_storage)))
 #endif
-
-
-/* Get system-specific definitions.  */
-#include <bits/in.h>
 
 /* Functions to convert between host and network byte order.
 

Modified: fsf/trunk/libc/locale/programs/3level.h
==============================================================================
--- fsf/trunk/libc/locale/programs/3level.h (original)
+++ fsf/trunk/libc/locale/programs/3level.h Fri Sep  6 17:39:04 2013
@@ -26,7 +26,8 @@
      ELEMENT      to the type of every entry
      DEFAULT      to the default value for empty entries
      ITERATE      if you want the TABLE_iterate function to be defined
-     NO_FINALIZE  if you don't want the TABLE_finalize function to be defined
+     NO_ADD_LOCALE  if you don't want the add_locale_TABLE function
+		    to be defined
 
    This will define
 
@@ -36,7 +37,7 @@
      void TABLE_add (struct TABLE *t, uint32_t wc, ELEMENT value);
      void TABLE_iterate (struct TABLE *t,
 			 void (*fn) (uint32_t wc, ELEMENT value));
-     void TABLE_finalize (struct TABLE *t);
+     void add_locale_TABLE (struct locale_file *file, struct TABLE *t);
 */
 
 #define CONCAT(a,b) CONCAT1(a,b)
@@ -57,9 +58,8 @@
   size_t level3_alloc;
   size_t level3_size;
   ELEMENT *level3;
-  /* Compressed representation.  */
+  /* Size of compressed representation.  */
   size_t result_size;
-  char *result;
 };
 
 /* Initialize.  Assumes t->p and t->q have already been set.  */
@@ -206,15 +206,15 @@
 }
 #endif
 
-#ifndef NO_FINALIZE
+#ifndef NO_ADD_LOCALE
 /* Finalize and shrink.  */
 static void
-CONCAT(TABLE,_finalize) (struct TABLE *t)
+CONCAT(add_locale_,TABLE) (struct locale_file *file, struct TABLE *t)
 {
   size_t i, j, k;
   uint32_t reorder3[t->level3_size];
   uint32_t reorder2[t->level2_size];
-  uint32_t level1_offset, level2_offset, level3_offset, last_offset;
+  uint32_t level2_offset, level3_offset, last_offset;
 
   /* Uniquify level3 blocks.  */
   k = 0;
@@ -271,10 +271,7 @@
     + (t->level2_size << t->q) * sizeof (uint32_t)
     + (t->level3_size << t->p) * sizeof (ELEMENT);
   t->result_size = (last_offset + 3) & ~3ul;
-  t->result = (char *) xmalloc (t->result_size);
-
-  level1_offset =
-    5 * sizeof (uint32_t);
+
   level2_offset =
     5 * sizeof (uint32_t)
     + t->level1_size * sizeof (uint32_t);
@@ -283,29 +280,36 @@
     + t->level1_size * sizeof (uint32_t)
     + (t->level2_size << t->q) * sizeof (uint32_t);
 
-  ((uint32_t *) t->result)[0] = t->q + t->p;
-  ((uint32_t *) t->result)[1] = t->level1_size;
-  ((uint32_t *) t->result)[2] = t->p;
-  ((uint32_t *) t->result)[3] = (1 << t->q) - 1;
-  ((uint32_t *) t->result)[4] = (1 << t->p) - 1;
+  start_locale_structure (file);
+  add_locale_uint32 (file, t->q + t->p);
+  add_locale_uint32 (file, t->level1_size);
+  add_locale_uint32 (file, t->p);
+  add_locale_uint32 (file, (1 << t->q) - 1);
+  add_locale_uint32 (file, (1 << t->p) - 1);
 
   for (i = 0; i < t->level1_size; i++)
-    ((uint32_t *) (t->result + level1_offset))[i] =
-      (t->level1[i] == EMPTY
+    add_locale_uint32
+      (file,
+       t->level1[i] == EMPTY
        ? 0
        : (t->level1[i] << t->q) * sizeof (uint32_t) + level2_offset);
 
   for (i = 0; i < (t->level2_size << t->q); i++)
-    ((uint32_t *) (t->result + level2_offset))[i] =
-      (t->level2[i] == EMPTY
+    add_locale_uint32
+      (file,
+       t->level2[i] == EMPTY
        ? 0
        : (t->level2[i] << t->p) * sizeof (ELEMENT) + level3_offset);
 
-  for (i = 0; i < (t->level3_size << t->p); i++)
-    ((ELEMENT *) (t->result + level3_offset))[i] = t->level3[i];
-
-  if (last_offset < t->result_size)
-    memset (t->result + last_offset, 0, t->result_size - last_offset);
+  if (sizeof (ELEMENT) == 1)
+    add_locale_raw_data (file, t->level3, t->level3_size << t->p);
+  else if (sizeof (ELEMENT) == sizeof (uint32_t))
+    add_locale_uint32_array (file, (uint32_t *) t->level3,
+			     t->level3_size << t->p);
+  else
+    abort ();
+  align_locale_data (file, 4);
+  end_locale_structure (file);
 
   if (t->level1_alloc > 0)
     free (t->level1);
@@ -321,4 +325,4 @@
 #undef ELEMENT
 #undef DEFAULT
 #undef ITERATE
-#undef NO_FINALIZE
+#undef NO_ADD_LOCALE

Modified: fsf/trunk/libc/locale/programs/ld-address.c
==============================================================================
--- fsf/trunk/libc/locale/programs/ld-address.c (original)
+++ fsf/trunk/libc/locale/programs/ld-address.c Fri Sep  6 17:39:04 2013
@@ -349,97 +349,23 @@
 		const char *output_path)
 {
   struct locale_address_t *address = locale->categories[LC_ADDRESS].address;
-  struct iovec iov[3 + _NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS)];
-  struct locale_file data;
-  uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS)];
-  size_t cnt = 0;
-
-  data.magic = LIMAGIC (LC_ADDRESS);
-  data.n = _NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS);
-  iov[cnt].iov_base = (void *) &data;
-  iov[cnt].iov_len = sizeof (data);
-  ++cnt;
-
-  iov[cnt].iov_base = (void *) idx;
-  iov[cnt].iov_len = sizeof (idx);
-  ++cnt;
-
-  idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len;
-  iov[cnt].iov_base = (void *) address->postal_fmt;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) address->country_name;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) address->country_post;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) address->country_ab2;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) address->country_ab3;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) address->country_car;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-
-  /* Align following data */
-  iov[cnt].iov_base = (void *) "\0\0";
-  iov[cnt].iov_len = ((idx[cnt - 2] + 3) & ~3) - idx[cnt - 2];
-  idx[cnt - 2] = (idx[cnt - 2] + 3) & ~3;
-  ++cnt;
-
-  iov[cnt].iov_base = (void *) &address->country_num;
-  iov[cnt].iov_len = sizeof (uint32_t);
-  ++cnt;
-
-  idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) address->country_isbn;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) address->lang_name;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) address->lang_ab;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) address->lang_term;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) address->lang_lib;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) charmap->code_set_name;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  assert (cnt == 3 + _NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS));
-
-  write_locale_data (output_path, LC_ADDRESS, "LC_ADDRESS",
-		     3 + _NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS), iov);
+  struct locale_file file;
+
+  init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_ADDRESS));
+  add_locale_string (&file, address->postal_fmt);
+  add_locale_string (&file, address->country_name);
+  add_locale_string (&file, address->country_post);
+  add_locale_string (&file, address->country_ab2);
+  add_locale_string (&file, address->country_ab3);
+  add_locale_string (&file, address->country_car);
+  add_locale_uint32 (&file, address->country_num);
+  add_locale_string (&file, address->country_isbn);
+  add_locale_string (&file, address->lang_name);
+  add_locale_string (&file, address->lang_ab);
+  add_locale_string (&file, address->lang_term);
+  add_locale_string (&file, address->lang_lib);
+  add_locale_string (&file, charmap->code_set_name);
+  write_locale_data (output_path, LC_ADDRESS, "LC_ADDRESS", &file);
 }
 
 

Modified: fsf/trunk/libc/locale/programs/ld-collate.c
==============================================================================
--- fsf/trunk/libc/locale/programs/ld-collate.c (original)
+++ fsf/trunk/libc/locale/programs/ld-collate.c Fri Sep  6 17:39:04 2013
@@ -165,7 +165,7 @@
 #define ELEMENT struct element_t *
 #define DEFAULT NULL
 #define ITERATE
-#define NO_FINALIZE
+#define NO_ADD_LOCALE
 #include "3level.h"
 
 /* Sparse table of int32_t.  */
@@ -1813,8 +1813,6 @@
       runp = runp->next;
     }
 
-  collseq_table_finalize (&collate->wcseqorder);
-
   /* Now determine whether the UNDEFINED entry is needed and if yes,
      whether it was defined.  */
   collate->undefined.used_in_level = need_undefined ? ~0ul : 0;
@@ -2098,10 +2096,7 @@
 {
   struct locale_collate_t *collate = locale->categories[LC_COLLATE].collate;
   const size_t nelems = _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE);
-  struct iovec iov[2 + nelems];
-  struct locale_file data;
-  uint32_t idx[nelems];
-  size_t cnt;
+  struct locale_file file;
   size_t ch;
   int32_t tablemb[256];
   struct obstack weightpool;
@@ -2114,51 +2109,22 @@
   int i;
   struct element_t *runp;
 
-  data.magic = LIMAGIC (LC_COLLATE);
-  data.n = nelems;
-  iov[0].iov_base = (void *) &data;
-  iov[0].iov_len = sizeof (data);
-
-  iov[1].iov_base = (void *) idx;
-  iov[1].iov_len = sizeof (idx);
-
-  idx[0] = iov[0].iov_len + iov[1].iov_len;
-  cnt = 0;
-
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_NRULES));
-  iov[2 + cnt].iov_base = &nrules;
-  iov[2 + cnt].iov_len = sizeof (uint32_t);
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  ++cnt;
+  init_locale_data (&file, nelems);
+  add_locale_uint32 (&file, nrules);
 
   /* If we have no LC_COLLATE data emit only the number of rules as zero.  */
   if (collate == NULL)
     {
-      int32_t dummy = 0;
-
-      while (cnt < _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE))
+      size_t idx;
+      for (idx = 1; idx < nelems; idx++)
 	{
 	  /* The words have to be handled specially.  */
-	  if (cnt == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB))
-	    {
-	      iov[2 + cnt].iov_base = &dummy;
-	      iov[2 + cnt].iov_len = sizeof (int32_t);
-	    }
+	  if (idx == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB))
+	    add_locale_uint32 (&file, 0);
 	  else
-	    {
-	      iov[2 + cnt].iov_base = NULL;
-	      iov[2 + cnt].iov_len = 0;
-	    }
-
-	  if (cnt + 1 < _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE))
-	    idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-	  ++cnt;
-	}
-
-      assert (cnt == _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE));
-
-      write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", 2 + cnt, iov);
-
+	    add_locale_empty (&file);
+	}
+      write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", &file);
       return;
     }
 
@@ -2191,11 +2157,7 @@
       obstack_1grow (&weightpool, '\0');
     while (++i < __alignof__ (int32_t));
 
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_RULESETS));
-  iov[2 + cnt].iov_len = obstack_object_size (&weightpool);
-  iov[2 + cnt].iov_base = obstack_finish (&weightpool);
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  ++cnt;
+  add_locale_raw_obstack (&file, &weightpool);
 
   /* Generate the 8-bit table.  Walk through the lists of sequences
      starting with the same byte and add them one after the other to
@@ -2382,55 +2344,16 @@
     obstack_1grow (&weightpool, 0);
 
   /* Now add the four tables.  */
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_TABLEMB));
-  iov[2 + cnt].iov_base = tablemb;
-  iov[2 + cnt].iov_len = sizeof (tablemb);
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  assert ((iov[2 + cnt].iov_len & (__alignof__ (int32_t) - 1)) == 0);
-  ++cnt;
-
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_WEIGHTMB));
-  iov[2 + cnt].iov_len = obstack_object_size (&weightpool);
-  iov[2 + cnt].iov_base = obstack_finish (&weightpool);
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  ++cnt;
-
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_EXTRAMB));
-  iov[2 + cnt].iov_len = obstack_object_size (&extrapool);
-  iov[2 + cnt].iov_base = obstack_finish (&extrapool);
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  ++cnt;
-
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_INDIRECTMB));
-  iov[2 + cnt].iov_len = obstack_object_size (&indirectpool);
-  iov[2 + cnt].iov_base = obstack_finish (&indirectpool);
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  assert ((iov[2 + cnt].iov_len & (__alignof__ (int32_t) - 1)) == 0);
-  ++cnt;
-
+  add_locale_uint32_array (&file, (const uint32_t *) tablemb, 256);
+  add_locale_raw_obstack (&file, &weightpool);
+  add_locale_raw_obstack (&file, &extrapool);
+  add_locale_raw_obstack (&file, &indirectpool);
 
   /* Now the same for the wide character table.  We need to store some
      more information here.  */
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_GAP1));
-  iov[2 + cnt].iov_base = NULL;
-  iov[2 + cnt].iov_len = 0;
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  assert (idx[cnt] % __alignof__ (int32_t) == 0);
-  ++cnt;
-
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_GAP2));
-  iov[2 + cnt].iov_base = NULL;
-  iov[2 + cnt].iov_len = 0;
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  assert (idx[cnt] % __alignof__ (int32_t) == 0);
-  ++cnt;
-
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_GAP3));
-  iov[2 + cnt].iov_base = NULL;
-  iov[2 + cnt].iov_len = 0;
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  assert (idx[cnt] % __alignof__ (int32_t) == 0);
-  ++cnt;
+  add_locale_empty (&file);
+  add_locale_empty (&file);
+  add_locale_empty (&file);
 
   /* Since we are using the sign of an integer to mark indirection the
      offsets in the arrays we are indirectly referring to must not be
@@ -2462,41 +2385,11 @@
 
   memset (&atwc, 0, sizeof (atwc));
 
-  collidx_table_finalize (&tablewc);
-
   /* Now add the four tables.  */
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_TABLEWC));
-  iov[2 + cnt].iov_base = tablewc.result;
-  iov[2 + cnt].iov_len = tablewc.result_size;
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  assert (iov[2 + cnt].iov_len % sizeof (int32_t) == 0);
-  assert (idx[cnt] % __alignof__ (int32_t) == 0);
-  ++cnt;
-
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_WEIGHTWC));
-  iov[2 + cnt].iov_len = obstack_object_size (&weightpool);
-  iov[2 + cnt].iov_base = obstack_finish (&weightpool);
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  assert (iov[2 + cnt].iov_len % sizeof (int32_t) == 0);
-  assert (idx[cnt] % __alignof__ (int32_t) == 0);
-  ++cnt;
-
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_EXTRAWC));
-  iov[2 + cnt].iov_len = obstack_object_size (&extrapool);
-  iov[2 + cnt].iov_base = obstack_finish (&extrapool);
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  assert (iov[2 + cnt].iov_len % sizeof (int32_t) == 0);
-  assert (idx[cnt] % __alignof__ (int32_t) == 0);
-  ++cnt;
-
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_INDIRECTWC));
-  iov[2 + cnt].iov_len = obstack_object_size (&indirectpool);
-  iov[2 + cnt].iov_base = obstack_finish (&indirectpool);
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  assert (iov[2 + cnt].iov_len % sizeof (int32_t) == 0);
-  assert (idx[cnt] % __alignof__ (int32_t) == 0);
-  ++cnt;
-
+  add_locale_collidx_table (&file, &tablewc);
+  add_locale_raw_obstack (&file, &weightpool);
+  add_locale_raw_obstack (&file, &extrapool);
+  add_locale_raw_obstack (&file, &indirectpool);
 
   /* Finally write the table with collation element names out.  It is
      a hash table with a simple function which gets the name of the
@@ -2594,47 +2487,13 @@
     }
 
   /* Prepare to write out this data.  */
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_HASH_SIZEMB));
-  iov[2 + cnt].iov_base = &elem_size;
-  iov[2 + cnt].iov_len = sizeof (int32_t);
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  assert (idx[cnt] % __alignof__ (int32_t) == 0);
-  ++cnt;
-
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_TABLEMB));
-  iov[2 + cnt].iov_base = elem_table;
-  iov[2 + cnt].iov_len = elem_size * 2 * sizeof (int32_t);
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  assert (idx[cnt] % __alignof__ (int32_t) == 0);
-  ++cnt;
-
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_SYMB_EXTRAMB));
-  iov[2 + cnt].iov_len = obstack_object_size (&extrapool);
-  iov[2 + cnt].iov_base = obstack_finish (&extrapool);
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  ++cnt;
-
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_COLLSEQMB));
-  iov[2 + cnt].iov_base = collate->mbseqorder;
-  iov[2 + cnt].iov_len = 256;
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  ++cnt;
-
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_COLLSEQWC));
-  iov[2 + cnt].iov_base = collate->wcseqorder.result;
-  iov[2 + cnt].iov_len = collate->wcseqorder.result_size;
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  assert (idx[cnt] % __alignof__ (int32_t) == 0);
-  ++cnt;
-
-  assert (cnt == _NL_ITEM_INDEX (_NL_COLLATE_CODESET));
-  iov[2 + cnt].iov_base = (void *) charmap->code_set_name;
-  iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
-  ++cnt;
-
-  assert (cnt == _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE));
-
-  write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", 2 + cnt, iov);
+  add_locale_uint32 (&file, elem_size);
+  add_locale_uint32_array (&file, elem_table, 2 * elem_size);
+  add_locale_raw_obstack (&file, &extrapool);
+  add_locale_raw_data (&file, collate->mbseqorder, 256);
+  add_locale_collseq_table (&file, &collate->wcseqorder);
+  add_locale_string (&file, charmap->code_set_name);
+  write_locale_data (output_path, LC_COLLATE, "LC_COLLATE", &file);
 
   obstack_free (&weightpool, NULL);
   obstack_free (&extrapool, NULL);

Modified: fsf/trunk/libc/locale/programs/ld-ctype.c
==============================================================================
--- fsf/trunk/libc/locale/programs/ld-ctype.c (original)
+++ fsf/trunk/libc/locale/programs/ld-ctype.c Fri Sep  6 17:39:04 2013
@@ -119,9 +119,51 @@
 #define TABLE idx_table
 #define ELEMENT uint32_t
 #define DEFAULT ((uint32_t) ~0)
-#define NO_FINALIZE
+#define NO_ADD_LOCALE
 #include "3level.h"
 
+#define TABLE wcwidth_table
+#define ELEMENT uint8_t
+#define DEFAULT 0xff
+#include "3level.h"
+
+#define TABLE wctrans_table
+#define ELEMENT int32_t
+#define DEFAULT 0
+#define wctrans_table_add wctrans_table_add_internal
+#include "3level.h"
+#undef wctrans_table_add
+/* The wctrans_table must actually store the difference between the
+   desired result and the argument.  */
+static inline void
+wctrans_table_add (struct wctrans_table *t, uint32_t wc, uint32_t mapped_wc)
+{
+  wctrans_table_add_internal (t, wc, mapped_wc - wc);
+}
+
+/* Construction of sparse 3-level tables.
+   See wchar-lookup.h for their structure and the meaning of p and q.  */
+
+struct wctype_table
+{
+  /* Parameters.  */
+  unsigned int p;
+  unsigned int q;
+  /* Working representation.  */
+  size_t level1_alloc;
+  size_t level1_size;
+  uint32_t *level1;
+  size_t level2_alloc;
+  size_t level2_size;
+  uint32_t *level2;
+  size_t level3_alloc;
+  size_t level3_size;
+  uint32_t *level3;
+  size_t result_size;
+};
+
+static void add_locale_wctype_table (struct locale_file *file,
+				     struct wctype_table *t);
 
 /* The real definition of the struct for the LC_CTYPE locale.  */
 struct locale_ctype_t
@@ -189,11 +231,11 @@
   uint32_t **map_b;
   uint32_t **map32_b;
   uint32_t **class_b;
-  struct iovec *class_3level;
-  struct iovec *map_3level;
+  struct wctype_table *class_3level;
+  struct wctrans_table *map_3level;
   uint32_t *class_name_ptr;
   uint32_t *map_name_ptr;
-  struct iovec width;
+  struct wcwidth_table width;
   uint32_t mb_cur_max;
   const char *codeset_name;
   uint32_t *translit_from_idx;
@@ -905,33 +947,21 @@
 ctype_output (struct localedef_t *locale, const struct charmap_t *charmap,
 	      const char *output_path)
 {
-  static const char nulbytes[4] = { 0, 0, 0, 0 };
   struct locale_ctype_t *ctype = locale->categories[LC_CTYPE].ctype;
   const size_t nelems = (_NL_ITEM_INDEX (_NL_CTYPE_EXTRA_MAP_1)
 			 + ctype->nr_charclass + ctype->map_collection_nr);
-  struct iovec *iov = alloca (sizeof *iov
-			      * (2 + nelems + 2 * ctype->nr_charclass
-				 + ctype->map_collection_nr + 4));
-  struct locale_file data;
-  uint32_t *idx = alloca (sizeof *idx * (nelems + 1));
+  struct locale_file file;
   uint32_t default_missing_len;
-  size_t elem, cnt, offset, total;
-  char *cp;
+  size_t elem, cnt;
 
   /* Now prepare the output: Find the sizes of the table we can use.  */
   allocate_arrays (ctype, charmap, ctype->repertoire);
 
-  data.magic = LIMAGIC (LC_CTYPE);
-  data.n = nelems;
-  iov[0].iov_base = (void *) &data;
-  iov[0].iov_len = sizeof (data);
-
-  iov[1].iov_base = (void *) idx;
-  iov[1].iov_len = nelems * sizeof (uint32_t);
-
-  idx[0] = iov[0].iov_len + iov[1].iov_len;
-  offset = 0;
-
+  default_missing_len = (ctype->default_missing
+			 ? wcslen ((wchar_t *) ctype->default_missing)
+			 : 0);
+
+  init_locale_data (&file, nelems);
   for (elem = 0; elem < nelems; ++elem)
     {
       if (elem < _NL_ITEM_INDEX (_NL_CTYPE_EXTRA_MAP_1))
@@ -939,9 +969,7 @@
 	  {
 #define CTYPE_EMPTY(name) \
 	  case name:							      \
-	    iov[2 + elem + offset].iov_base = NULL;			      \
-	    iov[2 + elem + offset].iov_len = 0;				      \
-	    idx[elem + 1] = idx[elem];					      \
+	    add_locale_empty (&file);					      \
 	    break
 
 	  CTYPE_EMPTY(_NL_CTYPE_GAP1);
@@ -951,273 +979,156 @@
 	  CTYPE_EMPTY(_NL_CTYPE_GAP5);
 	  CTYPE_EMPTY(_NL_CTYPE_GAP6);
 
-#define CTYPE_DATA(name, base, len)					      \
+#define CTYPE_RAW_DATA(name, base, size)				      \
 	  case _NL_ITEM_INDEX (name):					      \
-	    iov[2 + elem + offset].iov_base = (base);			      \
-	    iov[2 + elem + offset].iov_len = (len);			      \
-	    idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;	      \
+	    add_locale_raw_data (&file, base, size);			      \
 	    break
 
-	  CTYPE_DATA (_NL_CTYPE_CLASS,
-		      ctype->ctype_b,
-		      (256 + 128) * sizeof (char_class_t));
-
-	  CTYPE_DATA (_NL_CTYPE_TOUPPER,
-		      ctype->map_b[0],
-		      (256 + 128) * sizeof (uint32_t));
-	  CTYPE_DATA (_NL_CTYPE_TOLOWER,
-		      ctype->map_b[1],
-		      (256 + 128) * sizeof (uint32_t));
-
-	  CTYPE_DATA (_NL_CTYPE_TOUPPER32,
-		      ctype->map32_b[0],
-		      256 * sizeof (uint32_t));
-	  CTYPE_DATA (_NL_CTYPE_TOLOWER32,
-		      ctype->map32_b[1],
-		      256 * sizeof (uint32_t));
-
-	  CTYPE_DATA (_NL_CTYPE_CLASS32,
-		      ctype->ctype32_b,
-		      256 * sizeof (char_class32_t));
-
-	  CTYPE_DATA (_NL_CTYPE_CLASS_OFFSET,
-		      &ctype->class_offset, sizeof (uint32_t));
-
-	  CTYPE_DATA (_NL_CTYPE_MAP_OFFSET,
-		      &ctype->map_offset, sizeof (uint32_t));
-
-	  CTYPE_DATA (_NL_CTYPE_TRANSLIT_TAB_SIZE,
-		      &ctype->translit_idx_size, sizeof (uint32_t));
-
-	  CTYPE_DATA (_NL_CTYPE_TRANSLIT_FROM_IDX,
-		      ctype->translit_from_idx,
-		      ctype->translit_idx_size * sizeof (uint32_t));
-
-	  CTYPE_DATA (_NL_CTYPE_TRANSLIT_FROM_TBL,
-		      ctype->translit_from_tbl,
-		      ctype->translit_from_tbl_size);
-
-	  CTYPE_DATA (_NL_CTYPE_TRANSLIT_TO_IDX,
-		      ctype->translit_to_idx,
-		      ctype->translit_idx_size * sizeof (uint32_t));
-
-	  CTYPE_DATA (_NL_CTYPE_TRANSLIT_TO_TBL,
-		      ctype->translit_to_tbl, ctype->translit_to_tbl_size);
+	  CTYPE_RAW_DATA (_NL_CTYPE_CLASS,
+			  ctype->ctype_b,
+			  (256 + 128) * sizeof (char_class_t));
+
+#define CTYPE_UINT32_ARRAY(name, base, n_elems)				      \
+	  case _NL_ITEM_INDEX (name):					      \
+	    add_locale_uint32_array (&file, base, n_elems);		      \
+	    break
+
+	  CTYPE_UINT32_ARRAY (_NL_CTYPE_TOUPPER, ctype->map_b[0], 256 + 128);
+	  CTYPE_UINT32_ARRAY (_NL_CTYPE_TOLOWER, ctype->map_b[1], 256 + 128);
+	  CTYPE_UINT32_ARRAY (_NL_CTYPE_TOUPPER32, ctype->map32_b[0], 256);
+	  CTYPE_UINT32_ARRAY (_NL_CTYPE_TOLOWER32, ctype->map32_b[1], 256);
+	  CTYPE_RAW_DATA (_NL_CTYPE_CLASS32,
+			  ctype->ctype32_b,
+			  256 * sizeof (char_class32_t));
+
+#define CTYPE_UINT32(name, value)					      \
+	  case _NL_ITEM_INDEX (name):					      \
+	    add_locale_uint32 (&file, value);				      \
+	    break
+
+	  CTYPE_UINT32 (_NL_CTYPE_CLASS_OFFSET, ctype->class_offset);
+	  CTYPE_UINT32 (_NL_CTYPE_MAP_OFFSET, ctype->map_offset);
+	  CTYPE_UINT32 (_NL_CTYPE_TRANSLIT_TAB_SIZE, ctype->translit_idx_size);
+
+	  CTYPE_UINT32_ARRAY (_NL_CTYPE_TRANSLIT_FROM_IDX,
+			      ctype->translit_from_idx,
+			      ctype->translit_idx_size);
+
+	  CTYPE_UINT32_ARRAY (_NL_CTYPE_TRANSLIT_FROM_TBL,
+			      ctype->translit_from_tbl,
+			      ctype->translit_from_tbl_size
+			      / sizeof (uint32_t));
+
+	  CTYPE_UINT32_ARRAY (_NL_CTYPE_TRANSLIT_TO_IDX,
+			      ctype->translit_to_idx,
+			      ctype->translit_idx_size);
+
+	  CTYPE_UINT32_ARRAY (_NL_CTYPE_TRANSLIT_TO_TBL,
+			      ctype->translit_to_tbl,
+			      ctype->translit_to_tbl_size / sizeof (uint32_t));
 
 	  case _NL_ITEM_INDEX (_NL_CTYPE_CLASS_NAMES):
 	    /* The class name array.  */
-	    total = 0;
-	    for (cnt = 0; cnt < ctype->nr_charclass; ++cnt, ++offset)
-	      {
-		iov[2 + elem + offset].iov_base
-		  = (void *) ctype->classnames[cnt];
-		iov[2 + elem + offset].iov_len
-		  = strlen (ctype->classnames[cnt]) + 1;
-		total += iov[2 + elem + offset].iov_len;
-	      }
-	    iov[2 + elem + offset].iov_base = (void *) nulbytes;
-	    iov[2 + elem + offset].iov_len = 4 - (total % 4);
-	    total += 4 - (total % 4);
-
-	    idx[elem + 1] = idx[elem] + total;
+	    start_locale_structure (&file);
+	    for (cnt = 0; cnt < ctype->nr_charclass; ++cnt)
+	      add_locale_string (&file, ctype->classnames[cnt]);
+	    add_locale_char (&file, 0);
+	    align_locale_data (&file, 4);
+	    end_locale_structure (&file);
 	    break;
 
 	  case _NL_ITEM_INDEX (_NL_CTYPE_MAP_NAMES):
 	    /* The class name array.  */
-	    total = 0;
-	    for (cnt = 0; cnt < ctype->map_collection_nr; ++cnt, ++offset)
-	      {
-		iov[2 + elem + offset].iov_base
-		  = (void *) ctype->mapnames[cnt];
-		iov[2 + elem + offset].iov_len
-		  = strlen (ctype->mapnames[cnt]) + 1;
-		total += iov[2 + elem + offset].iov_len;
-	      }
-	    iov[2 + elem + offset].iov_base = (void *) nulbytes;
-	    iov[2 + elem + offset].iov_len = 4 - (total % 4);
-	    total += 4 - (total % 4);
-
-	    idx[elem + 1] = idx[elem] + total;
+	    start_locale_structure (&file);
+	    for (cnt = 0; cnt < ctype->map_collection_nr; ++cnt)
+	      add_locale_string (&file, ctype->mapnames[cnt]);
+	    add_locale_char (&file, 0);
+	    align_locale_data (&file, 4);
+	    end_locale_structure (&file);
 	    break;
 
-	  CTYPE_DATA (_NL_CTYPE_WIDTH,
-		      ctype->width.iov_base,
-		      ctype->width.iov_len);
-
-	  CTYPE_DATA (_NL_CTYPE_MB_CUR_MAX,
-		      &ctype->mb_cur_max, sizeof (uint32_t));
+	  case _NL_ITEM_INDEX (_NL_CTYPE_WIDTH):
+	    add_locale_wcwidth_table (&file, &ctype->width);
+	    break;
+
+	  CTYPE_UINT32 (_NL_CTYPE_MB_CUR_MAX, ctype->mb_cur_max);
 
 	  case _NL_ITEM_INDEX (_NL_CTYPE_CODESET_NAME):
-	    total = strlen (ctype->codeset_name) + 1;
-	    if (total % 4 == 0)
-	      iov[2 + elem + offset].iov_base = (char *) ctype->codeset_name;
-	    else
-	      {
-		iov[2 + elem + offset].iov_base = alloca ((total + 3) & ~3);
-		memset (mempcpy (iov[2 + elem + offset].iov_base,
-				 ctype->codeset_name, total),
-			'\0', 4 - (total & 3));
-		total = (total + 3) & ~3;
-	      }
-	    iov[2 + elem + offset].iov_len = total;
-	    idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
+	    add_locale_string (&file, ctype->codeset_name);
 	    break;
 
-
-	  CTYPE_DATA (_NL_CTYPE_MAP_TO_NONASCII,
-		      &ctype->to_nonascii, sizeof (uint32_t));
-
-	  CTYPE_DATA (_NL_CTYPE_NONASCII_CASE,
-		      &ctype->nonascii_case, sizeof (uint32_t));
+	  CTYPE_UINT32 (_NL_CTYPE_MAP_TO_NONASCII, ctype->to_nonascii);
+
+	  CTYPE_UINT32 (_NL_CTYPE_NONASCII_CASE, ctype->nonascii_case);
 
 	  case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_MB_LEN):
-	    iov[2 + elem + offset].iov_base = alloca (sizeof (uint32_t));
-	    iov[2 + elem + offset].iov_len = sizeof (uint32_t);
-	    *(uint32_t *) iov[2 + elem + offset].iov_base =
-	      ctype->mbdigits_act / 10;
-	    idx[elem + 1] = idx[elem] + sizeof (uint32_t);
+	    add_locale_uint32 (&file, ctype->mbdigits_act / 10);
 	    break;
 
 	  case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS_WC_LEN):
-	    /* Align entries.  */
-	    iov[2 + elem + offset].iov_base = (void *) nulbytes;
-	    iov[2 + elem + offset].iov_len = (4 - idx[elem] % 4) % 4;
-	    idx[elem] += iov[2 + elem + offset].iov_len;
-	    ++offset;
-
-	    iov[2 + elem + offset].iov_base = alloca (sizeof (uint32_t));
-	    iov[2 + elem + offset].iov_len = sizeof (uint32_t);
-	    *(uint32_t *) iov[2 + elem + offset].iov_base =
-	      ctype->wcdigits_act / 10;
-	    idx[elem + 1] = idx[elem] + sizeof (uint32_t);
+	    add_locale_uint32 (&file, ctype->wcdigits_act / 10);
 	    break;
 
 	  case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_MB) ... _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS9_MB):
-	    /* Compute the length of all possible characters.  For INDIGITS
-	       there might be more than one.  We simply concatenate all of
-	       them with a NUL byte following.  The NUL byte wouldn't be
-	       necessary but it makes it easier for the user.  */
-	    total = 0;
-
-	    for (cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_MB);
-		 cnt < ctype->mbdigits_act; cnt += 10)
-	      total += ctype->mbdigits[cnt]->nbytes + 1;
-	    iov[2 + elem + offset].iov_base = (char *) alloca (total);
-	    iov[2 + elem + offset].iov_len = total;
-
-	    cp = iov[2 + elem + offset].iov_base;
+	    start_locale_structure (&file);
 	    for (cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_MB);
 		 cnt < ctype->mbdigits_act; cnt += 10)
 	      {
-		cp = mempcpy (cp, ctype->mbdigits[cnt]->bytes,
-			      ctype->mbdigits[cnt]->nbytes);
-		*cp++ = '\0';
+		add_locale_raw_data (&file, ctype->mbdigits[cnt]->bytes,
+				     ctype->mbdigits[cnt]->nbytes);
+		add_locale_char (&file, 0);
 	      }
-	    idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
+	    end_locale_structure (&file);
 	    break;
 
 	  case _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_MB) ... _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT9_MB):
-	    /* Compute the length of all possible characters.  For INDIGITS
-	       there might be more than one.  We simply concatenate all of
-	       them with a NUL byte following.  The NUL byte wouldn't be
-	       necessary but it makes it easier for the user.  */
+	    start_locale_structure (&file);
 	    cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_MB);
-	    total = ctype->mboutdigits[cnt]->nbytes + 1;
-	    iov[2 + elem + offset].iov_base = (char *) alloca (total);
-	    iov[2 + elem + offset].iov_len = total;
-
-	    *(char *) mempcpy (iov[2 + elem + offset].iov_base,
-			       ctype->mboutdigits[cnt]->bytes,
-			       ctype->mboutdigits[cnt]->nbytes) = '\0';
-	    idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
+	    add_locale_raw_data (&file, ctype->mboutdigits[cnt]->bytes,
+				 ctype->mboutdigits[cnt]->nbytes);
+	    add_locale_char (&file, 0);
+	    end_locale_structure (&file);
 	    break;
 
 	  case _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_WC) ... _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS9_WC):
-	    total = ctype->wcdigits_act / 10;
-
-	    iov[2 + elem + offset].iov_base =
-	      (uint32_t *) alloca (total * sizeof (uint32_t));
-	    iov[2 + elem + offset].iov_len = total * sizeof (uint32_t);
-
+	    start_locale_structure (&file);
 	    for (cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_INDIGITS0_WC);
 		 cnt < ctype->wcdigits_act; cnt += 10)
-	      ((uint32_t *) iov[2 + elem + offset].iov_base)[cnt / 10]
-		= ctype->wcdigits[cnt];
-	    idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
+	      add_locale_uint32 (&file, ctype->wcdigits[cnt]);
+	    end_locale_structure (&file);
 	    break;
 
-	  case _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_WC):
-	    /* Align entries.  */
-	    iov[2 + elem + offset].iov_base = (void *) nulbytes;
-	    iov[2 + elem + offset].iov_len = (4 - idx[elem] % 4) % 4;
-	    idx[elem] += iov[2 + elem + offset].iov_len;
-	    ++offset;
-	    /* FALLTRHOUGH */
-
-	  case _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT1_WC) ... _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT9_WC):
+	  case _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_WC) ... _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT9_WC):
 	    cnt = elem - _NL_ITEM_INDEX (_NL_CTYPE_OUTDIGIT0_WC);
-	    iov[2 + elem + offset].iov_base = &ctype->wcoutdigits[cnt];
-	    iov[2 + elem + offset].iov_len = sizeof (uint32_t);
-	    idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
+	    add_locale_uint32 (&file, ctype->wcoutdigits[cnt]);
 	    break;
 
 	  case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN):
-	    /* Align entries.  */
-	    iov[2 + elem + offset].iov_base = (void *) nulbytes;
-	    iov[2 + elem + offset].iov_len = (4 - idx[elem] % 4) % 4;
-	    idx[elem] += iov[2 + elem + offset].iov_len;
-	    ++offset;
-
-	    default_missing_len = (ctype->default_missing
-				   ? wcslen ((wchar_t *)ctype->default_missing)
-				   : 0);
-	    iov[2 + elem + offset].iov_base = &default_missing_len;
-	    iov[2 + elem + offset].iov_len = sizeof (uint32_t);
-	    idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
+	    add_locale_uint32 (&file, default_missing_len);
 	    break;
 
 	  case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_DEFAULT_MISSING):
-	    iov[2 + elem + offset].iov_base =
-	      ctype->default_missing ?: (uint32_t *) L"";
-	    iov[2 + elem + offset].iov_len =
-	      wcslen (iov[2 + elem + offset].iov_base) * sizeof (uint32_t);
-	    idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
+	    add_locale_uint32_array (&file, ctype->default_missing,
+				     default_missing_len);
 	    break;
 
 	  case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_IGNORE_LEN):
-	    /* Align entries.  */
-	    iov[2 + elem + offset].iov_base = (void *) nulbytes;
-	    iov[2 + elem + offset].iov_len = (4 - idx[elem] % 4) % 4;
-	    idx[elem] += iov[2 + elem + offset].iov_len;
-	    ++offset;
-
-	    iov[2 + elem + offset].iov_base = &ctype->ntranslit_ignore;
-	    iov[2 + elem + offset].iov_len = sizeof (uint32_t);
-	    idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
+	    add_locale_uint32 (&file, ctype->ntranslit_ignore);
 	    break;
 
 	  case _NL_ITEM_INDEX(_NL_CTYPE_TRANSLIT_IGNORE):
-	    {
-	      uint32_t *ranges = (uint32_t *) alloca (ctype->ntranslit_ignore
-						      * 3 * sizeof (uint32_t));
+	    start_locale_structure (&file);
+	    {
 	      struct translit_ignore_t *runp;
-
-	      iov[2 + elem + offset].iov_base = ranges;
-	      iov[2 + elem + offset].iov_len = (ctype->ntranslit_ignore
-						* 3 * sizeof (uint32_t));
-
 	      for (runp = ctype->translit_ignore; runp != NULL;
 		   runp = runp->next)
 		{
-		  *ranges++ = runp->from;
-		  *ranges++ = runp->to;
-		  *ranges++ = runp->step;
+		  add_locale_uint32 (&file, runp->from);
+		  add_locale_uint32 (&file, runp->to);
+		  add_locale_uint32 (&file, runp->step);
 		}
 	    }
-	    /* Remove the following line in case a new entry is added
-	       after _NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN.  */
-	    if (elem < nelems)
-	      idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
+	    end_locale_structure (&file);
 	    break;
 
 	  default:
@@ -1229,28 +1140,21 @@
 	  size_t nr = elem - _NL_ITEM_INDEX (_NL_CTYPE_EXTRA_MAP_1);
 	  if (nr < ctype->nr_charclass)
 	    {
-	      iov[2 + elem + offset].iov_base = ctype->class_b[nr];
-	      iov[2 + elem + offset].iov_len = 256 / 32 * sizeof (uint32_t);
-	      idx[elem] += iov[2 + elem + offset].iov_len;
-	      ++offset;
-
-	      iov[2 + elem + offset] = ctype->class_3level[nr];
+	      start_locale_prelude (&file);
+	      add_locale_uint32_array (&file, ctype->class_b[nr], 256 / 32);
+	      end_locale_prelude (&file);
+	      add_locale_wctype_table (&file, &ctype->class_3level[nr]);
 	    }
 	  else
 	    {
 	      nr -= ctype->nr_charclass;
 	      assert (nr < ctype->map_collection_nr);
-	      iov[2 + elem + offset] = ctype->map_3level[nr];
-	    }
-	  idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
-	}
-    }
-
-  assert (2 + elem + offset == (nelems + 2 * ctype->nr_charclass
-				+ ctype->map_collection_nr + 4 + 2));
-
-  write_locale_data (output_path, LC_CTYPE, "LC_CTYPE", 2 + elem + offset,
-		     iov);
+	      add_locale_wctrans_table (&file, &ctype->map_3level[nr]);
+	    }
+	}
+    }
+
+  write_locale_data (output_path, LC_CTYPE, "LC_CTYPE", &file);
 }
 
 
@@ -3529,29 +3433,6 @@
 }
 
 
-/* Construction of sparse 3-level tables.
-   See wchar-lookup.h for their structure and the meaning of p and q.  */
-
-struct wctype_table
-{
-  /* Parameters.  */
-  unsigned int p;
-  unsigned int q;
-  /* Working representation.  */
-  size_t level1_alloc;
-  size_t level1_size;
-  uint32_t *level1;
-  size_t level2_alloc;
-  size_t level2_size;
-  uint32_t *level2;
-  size_t level3_alloc;
-  size_t level3_size;
-  uint32_t *level3;
-  /* Compressed representation.  */
-  size_t result_size;
-  char *result;
-};
-
 /* Initialize.  Assumes t->p and t->q have already been set.  */
 static inline void
 wctype_table_init (struct wctype_table *t)
@@ -3657,12 +3538,12 @@
 
 /* Finalize and shrink.  */
 static void
-wctype_table_finalize (struct wctype_table *t)
+add_locale_wctype_table (struct locale_file *file, struct wctype_table *t)
 {
   size_t i, j, k;
   uint32_t reorder3[t->level3_size];
   uint32_t reorder2[t->level2_size];
-  uint32_t level1_offset, level2_offset, level3_offset;
+  uint32_t level2_offset, level3_offset;
 
   /* Uniquify level3 blocks.  */
   k = 0;
@@ -3712,16 +3593,12 @@
     if (t->level1[i] != EMPTY)
       t->level1[i] = reorder2[t->level1[i]];
 
-  /* Create and fill the resulting compressed representation.  */
   t->result_size =
     5 * sizeof (uint32_t)
     + t->level1_size * sizeof (uint32_t)
     + (t->level2_size << t->q) * sizeof (uint32_t)
     + (t->level3_size << t->p) * sizeof (uint32_t);
-  t->result = (char *) xmalloc (t->result_size);
-
-  level1_offset =
-    5 * sizeof (uint32_t);
+
   level2_offset =
     5 * sizeof (uint32_t)
     + t->level1_size * sizeof (uint32_t);
@@ -3730,26 +3607,29 @@
     + t->level1_size * sizeof (uint32_t)
     + (t->level2_size << t->q) * sizeof (uint32_t);
 
-  ((uint32_t *) t->result)[0] = t->q + t->p + 5;
-  ((uint32_t *) t->result)[1] = t->level1_size;
-  ((uint32_t *) t->result)[2] = t->p + 5;
-  ((uint32_t *) t->result)[3] = (1 << t->q) - 1;
-  ((uint32_t *) t->result)[4] = (1 << t->p) - 1;
+  start_locale_structure (file);
+  add_locale_uint32 (file, t->q + t->p + 5);
+  add_locale_uint32 (file, t->level1_size);
+  add_locale_uint32 (file, t->p + 5);
+  add_locale_uint32 (file, (1 << t->q) - 1);
+  add_locale_uint32 (file, (1 << t->p) - 1);
 
   for (i = 0; i < t->level1_size; i++)
-    ((uint32_t *) (t->result + level1_offset))[i] =
-      (t->level1[i] == EMPTY
+    add_locale_uint32
+      (file,
+       t->level1[i] == EMPTY
        ? 0
        : (t->level1[i] << t->q) * sizeof (uint32_t) + level2_offset);
 
   for (i = 0; i < (t->level2_size << t->q); i++)
-    ((uint32_t *) (t->result + level2_offset))[i] =
-      (t->level2[i] == EMPTY
+    add_locale_uint32
+      (file,
+       t->level2[i] == EMPTY
        ? 0
        : (t->level2[i] << t->p) * sizeof (uint32_t) + level3_offset);
 
-  for (i = 0; i < (t->level3_size << t->p); i++)
-    ((uint32_t *) (t->result + level3_offset))[i] = t->level3[i];
+  add_locale_uint32_array (file, t->level3, t->level3_size << t->p);
+  end_locale_structure (file);
 
   if (t->level1_alloc > 0)
     free (t->level1);
@@ -3758,26 +3638,6 @@
   if (t->level3_alloc > 0)
     free (t->level3);
 }
-
-#define TABLE wcwidth_table
-#define ELEMENT uint8_t
-#define DEFAULT 0xff
-#include "3level.h"
-
-#define TABLE wctrans_table
-#define ELEMENT int32_t
-#define DEFAULT 0
-#define wctrans_table_add wctrans_table_add_internal
-#include "3level.h"
-#undef wctrans_table_add
-/* The wctrans_table must actually store the difference between the
-   desired result and the argument.  */
-static inline void
-wctrans_table_add (struct wctrans_table *t, uint32_t wc, uint32_t mapped_wc)
-{
-  wctrans_table_add_internal (t, wc, mapped_wc - wc);
-}
-
 
 /* Flattens the included transliterations into a translit list.
    Inserts them in the list at `cursor', and returns the new cursor.  */
@@ -3855,8 +3715,8 @@
   ctype->ctype32_b = (char_class32_t *) xcalloc (256, sizeof (char_class32_t));
   ctype->class_b = (uint32_t **)
     xmalloc (ctype->nr_charclass * sizeof (uint32_t *));
-  ctype->class_3level = (struct iovec *)
-    xmalloc (ctype->nr_charclass * sizeof (struct iovec));
+  ctype->class_3level = (struct wctype_table *)
+    xmalloc (ctype->nr_charclass * sizeof (struct wctype_table));
 
   /* This is the array accessed using the multibyte string elements.  */
   for (idx = 0; idx < 256; ++idx)
@@ -3888,34 +3748,30 @@
 
   for (nr = 0; nr < ctype->nr_charclass; nr++)
     {
-      struct wctype_table t;
-
-      t.p = 4; /* or: 5 */
-      t.q = 7; /* or: 6 */
-      wctype_table_init (&t);
+      struct wctype_table *t;
+
+      t = &ctype->class_3level[nr];
+      t->p = 4; /* or: 5 */
+      t->q = 7; /* or: 6 */
+      wctype_table_init (t);
 
       for (idx = 0; idx < ctype->class_collection_act; ++idx)
 	if (ctype->class_collection[idx] & _ISwbit (nr))
-	  wctype_table_add (&t, ctype->charnames[idx]);
-
-      wctype_table_finalize (&t);
+	  wctype_table_add (t, ctype->charnames[idx]);
 
       if (verbose)
 	WITH_CUR_LOCALE (fprintf (stderr, _("\
 %s: table for class \"%s\": %lu bytes\n"),
 				 "LC_CTYPE", ctype->classnames[nr],
-				 (unsigned long int) t.result_size));
-
-      ctype->class_3level[nr].iov_base = t.result;
-      ctype->class_3level[nr].iov_len = t.result_size;
+				 (unsigned long int) t->result_size));
     }
 
   /* Room for table of mappings.  */
   ctype->map_b = (uint32_t **) xmalloc (2 * sizeof (uint32_t *));
   ctype->map32_b = (uint32_t **) xmalloc (ctype->map_collection_nr
 					  * sizeof (uint32_t *));
-  ctype->map_3level = (struct iovec *)
-    xmalloc (ctype->map_collection_nr * sizeof (struct iovec));
+  ctype->map_3level = (struct wctrans_table *)
+    xmalloc (ctype->map_collection_nr * sizeof (struct wctrans_table));
 
   /* Fill in all mappings.  */
   for (idx = 0; idx < 2; ++idx)
@@ -3956,27 +3812,23 @@
 
   for (nr = 0; nr < ctype->map_collection_nr; nr++)
     {
-      struct wctrans_table t;
-
-      t.p = 7;
-      t.q = 9;
-      wctrans_table_init (&t);
+      struct wctrans_table *t;
+
+      t = &ctype->map_3level[nr];
+      t->p = 7;
+      t->q = 9;
+      wctrans_table_init (t);
 
       for (idx = 0; idx < ctype->map_collection_act[nr]; ++idx)
 	if (ctype->map_collection[nr][idx] != 0)
-	  wctrans_table_add (&t, ctype->charnames[idx],
+	  wctrans_table_add (t, ctype->charnames[idx],
 			     ctype->map_collection[nr][idx]);
-
-      wctrans_table_finalize (&t);
 
       if (verbose)
 	WITH_CUR_LOCALE (fprintf (stderr, _("\
 %s: table for map \"%s\": %lu bytes\n"),
 				 "LC_CTYPE", ctype->mapnames[nr],
-				 (unsigned long int) t.result_size));
-
-      ctype->map_3level[nr].iov_base = t.result;
-      ctype->map_3level[nr].iov_len = t.result_size;
+				 (unsigned long int) t->result_size));
     }
 
   /* Extra array for class and map names.  */
@@ -3996,11 +3848,12 @@
      saves a run-time check.
      But we put L'\0' in the table.  This again saves a run-time check.  */
   {
-    struct wcwidth_table t;
-
-    t.p = 7;
-    t.q = 9;
-    wcwidth_table_init (&t);
+    struct wcwidth_table *t;
+
+    t = &ctype->width;
+    t->p = 7;
+    t->q = 9;
+    wcwidth_table_init (t);
 
     /* First set all the printable characters of the character set to
        the default width.  */
@@ -4020,7 +3873,7 @@
 			&ctype->class_collection_act, data->ucs4);
 
 	    if (class_bits != NULL && (*class_bits & BITw (tok_print)))
-	      wcwidth_table_add (&t, data->ucs4, charmap->width_default);
+	      wcwidth_table_add (t, data->ucs4, charmap->width_default);
 	  }
       }
 
@@ -4068,7 +3921,7 @@
 				&ctype->class_collection_act, wch);
 
 		    if (class_bits != NULL && (*class_bits & BITw (tok_print)))
-		      wcwidth_table_add (&t, wch,
+		      wcwidth_table_add (t, wch,
 					 charmap->width_rules[cnt].width);
 		  }
 
@@ -4098,16 +3951,11 @@
       }
 
     /* Set the width of L'\0' to 0.  */
-    wcwidth_table_add (&t, 0, 0);
-
-    wcwidth_table_finalize (&t);
+    wcwidth_table_add (t, 0, 0);
 
     if (verbose)
       WITH_CUR_LOCALE (fprintf (stderr, _("%s: table for width: %lu bytes\n"),
-			       "LC_CTYPE", (unsigned long int) t.result_size));
-
-    ctype->width.iov_base = t.result;
-    ctype->width.iov_len = t.result_size;
+			       "LC_CTYPE", (unsigned long int) t->result_size));
   }
 
   /* Set MB_CUR_MAX.  */

Modified: fsf/trunk/libc/locale/programs/ld-identification.c
==============================================================================
--- fsf/trunk/libc/locale/programs/ld-identification.c (original)
+++ fsf/trunk/libc/locale/programs/ld-identification.c Fri Sep  6 17:39:04 2013
@@ -182,116 +182,32 @@
 {
   struct locale_identification_t *identification
     = locale->categories[LC_IDENTIFICATION].identification;
-  struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION)
-		  + (__LC_LAST - 2)];
-  struct locale_file data;
-  uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION)];
-  size_t cnt = 0;
+  struct locale_file file;
   size_t num;
-  size_t last_idx;
-
-  data.magic = LIMAGIC (LC_IDENTIFICATION);
-  data.n = _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION);
-  iov[cnt].iov_base = (void *) &data;
-  iov[cnt].iov_len = sizeof (data);
-  ++cnt;
-
-  iov[cnt].iov_base = (void *) idx;
-  iov[cnt].iov_len = sizeof (idx);
-  ++cnt;
-
-  idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len;
-  iov[cnt].iov_base = (void *) identification->title;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) identification->source;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) identification->address;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) identification->contact;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) identification->email;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) identification->tel;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) identification->fax;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) identification->language;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) identification->territory;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) identification->audience;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) identification->application;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) identification->abbreviation;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) identification->revision;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) identification->date;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  last_idx = cnt - 1;
-  idx[last_idx] = idx[cnt - 2];
+
+  init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION));
+  add_locale_string (&file, identification->title);
+  add_locale_string (&file, identification->source);
+  add_locale_string (&file, identification->address);
+  add_locale_string (&file, identification->contact);
+  add_locale_string (&file, identification->email);
+  add_locale_string (&file, identification->tel);
+  add_locale_string (&file, identification->fax);
+  add_locale_string (&file, identification->language);
+  add_locale_string (&file, identification->territory);
+  add_locale_string (&file, identification->audience);
+  add_locale_string (&file, identification->application);
+  add_locale_string (&file, identification->abbreviation);
+  add_locale_string (&file, identification->revision);
+  add_locale_string (&file, identification->date);
+  start_locale_structure (&file);
   for (num = 0; num < __LC_LAST; ++num)
     if (num != LC_ALL)
-      {
-	iov[cnt].iov_base = (void *) identification->category[num];
-	iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-	idx[last_idx] += iov[cnt].iov_len;
-	++cnt;
-      }
-
-  assert (last_idx == _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION) - 1);
-  iov[cnt].iov_base = (void *) charmap->code_set_name;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  assert (cnt == (2 + _NL_ITEM_INDEX (_NL_NUM_LC_IDENTIFICATION)
-		  + (__LC_LAST - 2)));
-
-  write_locale_data (output_path, LC_IDENTIFICATION, "LC_IDENTIFICATION", cnt,
-		     iov);
+      add_locale_string (&file, identification->category[num]);
+  end_locale_structure (&file);
+  add_locale_string (&file, charmap->code_set_name);
+  write_locale_data (output_path, LC_IDENTIFICATION, "LC_IDENTIFICATION",
+		     &file);
 }
 
 

Modified: fsf/trunk/libc/locale/programs/ld-measurement.c
==============================================================================
--- fsf/trunk/libc/locale/programs/ld-measurement.c (original)
+++ fsf/trunk/libc/locale/programs/ld-measurement.c Fri Sep  6 17:39:04 2013
@@ -122,35 +122,12 @@
 {
   struct locale_measurement_t *measurement =
     locale->categories[LC_MEASUREMENT].measurement;
-  struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT)];
-  struct locale_file data;
-  uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT)];
-  size_t cnt = 0;
-
-  data.magic = LIMAGIC (LC_MEASUREMENT);
-  data.n = _NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT);
-  iov[cnt].iov_base = (void *) &data;
-  iov[cnt].iov_len = sizeof (data);
-  ++cnt;
-
-  iov[cnt].iov_base = (void *) idx;
-  iov[cnt].iov_len = sizeof (idx);
-  ++cnt;
-
-  idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len;
-  iov[cnt].iov_base = &measurement->measurement;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) charmap->code_set_name;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT));
-
-  write_locale_data (output_path, LC_MEASUREMENT, "LC_MEASUREMENT",
-		     2 + _NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT), iov);
+  struct locale_file file;
+
+  init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_MEASUREMENT));
+  add_locale_char (&file, measurement->measurement);
+  add_locale_string (&file, charmap->code_set_name);
+  write_locale_data (output_path, LC_MEASUREMENT, "LC_MEASUREMENT", &file);
 }
 
 

Modified: fsf/trunk/libc/locale/programs/ld-messages.c
==============================================================================
--- fsf/trunk/libc/locale/programs/ld-messages.c (original)
+++ fsf/trunk/libc/locale/programs/ld-messages.c Fri Sep  6 17:39:04 2013
@@ -184,49 +184,15 @@
 {
   struct locale_messages_t *messages
     = locale->categories[LC_MESSAGES].messages;
-  struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)];
-  struct locale_file data;
-  uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)];
-  size_t cnt = 0;
-
-  data.magic = LIMAGIC (LC_MESSAGES);
-  data.n = _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES);
-  iov[cnt].iov_base = (void *) &data;
-  iov[cnt].iov_len = sizeof (data);
-  ++cnt;
-
-  iov[cnt].iov_base = (void *) idx;
-  iov[cnt].iov_len = sizeof (idx);
-  ++cnt;
-
-  idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len;
-  iov[cnt].iov_base = (char *) messages->yesexpr;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (char *) messages->noexpr;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (char *) messages->yesstr;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (char *) messages->nostr;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (char *) charmap->code_set_name;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-
-  assert (cnt + 1 == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES));
-
-  write_locale_data (output_path, LC_MESSAGES, "LC_MESSAGES",
-		     2 + _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES), iov);
+  struct locale_file file;
+
+  init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES));
+  add_locale_string (&file, messages->yesexpr);
+  add_locale_string (&file, messages->noexpr);
+  add_locale_string (&file, messages->yesstr);
+  add_locale_string (&file, messages->nostr);
+  add_locale_string (&file, charmap->code_set_name);
+  write_locale_data (output_path, LC_MESSAGES, "LC_MESSAGES", &file);
 }
 
 

Modified: fsf/trunk/libc/locale/programs/ld-monetary.c
==============================================================================
--- fsf/trunk/libc/locale/programs/ld-monetary.c (original)
+++ fsf/trunk/libc/locale/programs/ld-monetary.c Fri Sep  6 17:39:04 2013
@@ -364,262 +364,57 @@
 {
   struct locale_monetary_t *monetary
     = locale->categories[LC_MONETARY].monetary;
-  struct iovec iov[3 + _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY)];
-  struct locale_file data;
-  uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MONETARY)];
-  size_t cnt = 0;
-
-  data.magic = LIMAGIC (LC_MONETARY);
-  data.n = _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY);
-  iov[cnt].iov_base = (void *) &data;
-  iov[cnt].iov_len = sizeof (data);
-  ++cnt;
-
-  iov[cnt].iov_base = (void *) idx;
-  iov[cnt].iov_len = sizeof (idx);
-  ++cnt;
-
-  idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len;
-  iov[cnt].iov_base = (void *) monetary->int_curr_symbol;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) monetary->currency_symbol;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) monetary->mon_decimal_point;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) monetary->mon_thousands_sep;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = monetary->mon_grouping;
-  iov[cnt].iov_len = monetary->mon_grouping_len;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) monetary->positive_sign;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) monetary->negative_sign;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->int_frac_digits;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->frac_digits;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->p_cs_precedes;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->p_sep_by_space;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->n_cs_precedes;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->n_sep_by_space;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->p_sign_posn;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->n_sign_posn;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) monetary->crncystr;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->int_p_cs_precedes;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->int_p_sep_by_space;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->int_n_cs_precedes;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->int_n_sep_by_space;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->int_p_sign_posn;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->int_n_sign_posn;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) monetary->duo_int_curr_symbol;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) monetary->duo_currency_symbol;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->duo_int_frac_digits;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->duo_frac_digits;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->duo_p_cs_precedes;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->duo_p_sep_by_space;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->duo_n_cs_precedes;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->duo_n_sep_by_space;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->duo_int_p_cs_precedes;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->duo_int_p_sep_by_space;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->duo_int_n_cs_precedes;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->duo_int_n_sep_by_space;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->duo_p_sign_posn;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->duo_n_sign_posn;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->duo_int_p_sign_posn;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->duo_int_n_sign_posn;
-  iov[cnt].iov_len = 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-
-  /* Align following data */
-  iov[cnt].iov_base = (void *) "\0\0";
-  iov[cnt].iov_len = ((idx[cnt - 2] + 3) & ~3) - idx[cnt - 2];
-  idx[cnt - 2] = (idx[cnt - 2] + 3) & ~3;
-  ++cnt;
-
-  iov[cnt].iov_base = (void *) &monetary->uno_valid_from;
-  iov[cnt].iov_len = sizeof(uint32_t);
-  ++cnt;
-
-  idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->uno_valid_to;
-  iov[cnt].iov_len = sizeof(uint32_t);
-  ++cnt;
-
-  idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->duo_valid_from;
-  iov[cnt].iov_len = sizeof(uint32_t);
-  ++cnt;
-
-  idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->duo_valid_to;
-  iov[cnt].iov_len = sizeof(uint32_t);
-  ++cnt;
-
-  idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) monetary->conversion_rate;
-  iov[cnt].iov_len = 2 * sizeof(uint32_t);
-  ++cnt;
-
-  idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->mon_decimal_point_wc;
-  iov[cnt].iov_len = sizeof (uint32_t);
-  ++cnt;
-
-  idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &monetary->mon_thousands_sep_wc;
-  iov[cnt].iov_len = sizeof (uint32_t);
-  ++cnt;
-
-  idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) charmap->code_set_name;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  assert (cnt == 3 + _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY));
-
-  write_locale_data (output_path, LC_MONETARY, "LC_MONETARY",
-		     3 + _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY), iov);
+  struct locale_file file;
+
+  init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY));
+  add_locale_string (&file, monetary->int_curr_symbol);
+  add_locale_string (&file, monetary->currency_symbol);
+  add_locale_string (&file, monetary->mon_decimal_point);
+  add_locale_string (&file, monetary->mon_thousands_sep);
+  add_locale_raw_data (&file, monetary->mon_grouping,
+		       monetary->mon_grouping_len);
+  add_locale_string (&file, monetary->positive_sign);
+  add_locale_string (&file, monetary->negative_sign);
+  add_locale_char (&file, monetary->int_frac_digits);
+  add_locale_char (&file, monetary->frac_digits);
+  add_locale_char (&file, monetary->p_cs_precedes);
+  add_locale_char (&file, monetary->p_sep_by_space);
+  add_locale_char (&file, monetary->n_cs_precedes);
+  add_locale_char (&file, monetary->n_sep_by_space);
+  add_locale_char (&file, monetary->p_sign_posn);
+  add_locale_char (&file, monetary->n_sign_posn);
+  add_locale_string (&file, monetary->crncystr);
+  add_locale_char (&file, monetary->int_p_cs_precedes);
+  add_locale_char (&file, monetary->int_p_sep_by_space);
+  add_locale_char (&file, monetary->int_n_cs_precedes);
+  add_locale_char (&file, monetary->int_n_sep_by_space);
+  add_locale_char (&file, monetary->int_p_sign_posn);
+  add_locale_char (&file, monetary->int_n_sign_posn);
+  add_locale_string (&file, monetary->duo_int_curr_symbol);
+  add_locale_string (&file, monetary->duo_currency_symbol);
+  add_locale_char (&file, monetary->duo_int_frac_digits);
+  add_locale_char (&file, monetary->duo_frac_digits);
+  add_locale_char (&file, monetary->duo_p_cs_precedes);
+  add_locale_char (&file, monetary->duo_p_sep_by_space);
+  add_locale_char (&file, monetary->duo_n_cs_precedes);
+  add_locale_char (&file, monetary->duo_n_sep_by_space);
+  add_locale_char (&file, monetary->duo_int_p_cs_precedes);
+  add_locale_char (&file, monetary->duo_int_p_sep_by_space);
+  add_locale_char (&file, monetary->duo_int_n_cs_precedes);
+  add_locale_char (&file, monetary->duo_int_n_sep_by_space);
+  add_locale_char (&file, monetary->duo_p_sign_posn);
+  add_locale_char (&file, monetary->duo_n_sign_posn);
+  add_locale_char (&file, monetary->duo_int_p_sign_posn);
+  add_locale_char (&file, monetary->duo_int_n_sign_posn);
+  add_locale_uint32 (&file, monetary->uno_valid_from);
+  add_locale_uint32 (&file, monetary->uno_valid_to);
+  add_locale_uint32 (&file, monetary->duo_valid_from);
+  add_locale_uint32 (&file, monetary->duo_valid_to);
+  add_locale_uint32_array (&file, monetary->conversion_rate, 2);
+  add_locale_uint32 (&file, monetary->mon_decimal_point_wc);
+  add_locale_uint32 (&file, monetary->mon_thousands_sep_wc);
+  add_locale_string (&file, charmap->code_set_name);
+  write_locale_data (output_path, LC_MONETARY, "LC_MONETARY", &file);
 }
 
 

Modified: fsf/trunk/libc/locale/programs/ld-name.c
==============================================================================
--- fsf/trunk/libc/locale/programs/ld-name.c (original)
+++ fsf/trunk/libc/locale/programs/ld-name.c Fri Sep  6 17:39:04 2013
@@ -157,60 +157,17 @@
 	     const char *output_path)
 {
   struct locale_name_t *name = locale->categories[LC_NAME].name;
-  struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME)];
-  struct locale_file data;
-  uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_NAME)];
-  size_t cnt = 0;
-
-  data.magic = LIMAGIC (LC_NAME);
-  data.n = _NL_ITEM_INDEX (_NL_NUM_LC_NAME);
-  iov[cnt].iov_base = (void *) &data;
-  iov[cnt].iov_len = sizeof (data);
-  ++cnt;
-
-  iov[cnt].iov_base = (void *) idx;
-  iov[cnt].iov_len = sizeof (idx);
-  ++cnt;
-
-  idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len;
-  iov[cnt].iov_base = (void *) name->name_fmt;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) name->name_gen;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) name->name_mr;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) name->name_mrs;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) name->name_miss;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) name->name_ms;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) charmap->code_set_name;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME));
-
-  write_locale_data (output_path, LC_NAME, "LC_NAME",
-		     2 + _NL_ITEM_INDEX (_NL_NUM_LC_NAME), iov);
+  struct locale_file file;
+
+  init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_NAME));
+  add_locale_string (&file, name->name_fmt);
+  add_locale_string (&file, name->name_gen);
+  add_locale_string (&file, name->name_mr);
+  add_locale_string (&file, name->name_mrs);
+  add_locale_string (&file, name->name_miss);
+  add_locale_string (&file, name->name_ms);
+  add_locale_string (&file, charmap->code_set_name);
+  write_locale_data (output_path, LC_NAME, "LC_NAME", &file);
 }
 
 

Modified: fsf/trunk/libc/locale/programs/ld-numeric.c
==============================================================================
--- fsf/trunk/libc/locale/programs/ld-numeric.c (original)
+++ fsf/trunk/libc/locale/programs/ld-numeric.c Fri Sep  6 17:39:04 2013
@@ -133,61 +133,16 @@
 		const char *output_path)
 {
   struct locale_numeric_t *numeric = locale->categories[LC_NUMERIC].numeric;
-  struct iovec iov[3 + _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC)];
-  struct locale_file data;
-  uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC)];
-  size_t cnt = 0;
-
-  data.magic = LIMAGIC (LC_NUMERIC);
-  data.n = _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC);
-  iov[cnt].iov_base = (void *) &data;
-  iov[cnt].iov_len = sizeof (data);
-  ++cnt;
-
-  iov[cnt].iov_base = (void *) idx;
-  iov[cnt].iov_len = sizeof (idx);
-  ++cnt;
-
-  idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len;
-  iov[cnt].iov_base = (void *) (numeric->decimal_point ?: "");
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) (numeric->thousands_sep ?: "");
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = numeric->grouping;
-  iov[cnt].iov_len = numeric->grouping_len;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-
-  /* Align following data */
-  iov[cnt].iov_base = (void *) "\0\0";
-  iov[cnt].iov_len = ((idx[cnt - 2] + 3) & ~3) - idx[cnt - 2];
-  idx[cnt - 2] = (idx[cnt - 2] + 3) & ~3;
-  ++cnt;
-
-  iov[cnt].iov_base = (void *) &numeric->decimal_point_wc;
-  iov[cnt].iov_len = sizeof (uint32_t);
-  ++cnt;
-
-  idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) &numeric->thousands_sep_wc;
-  iov[cnt].iov_len = sizeof (uint32_t);
-  ++cnt;
-
-  idx[cnt - 3] = idx[cnt - 4] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) charmap->code_set_name;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-
-  assert (cnt + 1 == 3 + _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC));
-
-  write_locale_data (output_path, LC_NUMERIC, "LC_NUMERIC",
-		     3 + _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC), iov);
+  struct locale_file file;
+
+  init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC));
+  add_locale_string (&file, numeric->decimal_point ?: "");
+  add_locale_string (&file, numeric->thousands_sep ?: "");
+  add_locale_raw_data (&file, numeric->grouping, numeric->grouping_len);
+  add_locale_uint32 (&file, numeric->decimal_point_wc);
+  add_locale_uint32 (&file, numeric->thousands_sep_wc);
+  add_locale_string (&file, charmap->code_set_name);
+  write_locale_data (output_path, LC_NUMERIC, "LC_NUMERIC", &file);
 }
 
 

Modified: fsf/trunk/libc/locale/programs/ld-paper.c
==============================================================================
--- fsf/trunk/libc/locale/programs/ld-paper.c (original)
+++ fsf/trunk/libc/locale/programs/ld-paper.c Fri Sep  6 17:39:04 2013
@@ -121,40 +121,13 @@
 	      const char *output_path)
 {
   struct locale_paper_t *paper = locale->categories[LC_PAPER].paper;
-  struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_PAPER)];
-  struct locale_file data;
-  uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_PAPER)];
-  size_t cnt = 0;
-
-  data.magic = LIMAGIC (LC_PAPER);
-  data.n = _NL_ITEM_INDEX (_NL_NUM_LC_PAPER);
-  iov[cnt].iov_base = (void *) &data;
-  iov[cnt].iov_len = sizeof (data);
-  ++cnt;
-
-  iov[cnt].iov_base = (void *) idx;
-  iov[cnt].iov_len = sizeof (idx);
-  ++cnt;
-
-  idx[cnt - 2] = iov[cnt - 2].iov_len + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = &paper->height;
-  iov[cnt].iov_len = 4;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = &paper->width;
-  iov[cnt].iov_len = 4;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) charmap->code_set_name;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_PAPER));
-
-  write_locale_data (output_path, LC_PAPER, "LC_PAPER",
-		     2 + _NL_ITEM_INDEX (_NL_NUM_LC_PAPER), iov);
+  struct locale_file file;
+
+  init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_PAPER));
+  add_locale_uint32 (&file, paper->height);
+  add_locale_uint32 (&file, paper->width);
+  add_locale_string (&file, charmap->code_set_name);
+  write_locale_data (output_path, LC_PAPER, "LC_PAPER", &file);
 }
 
 

Modified: fsf/trunk/libc/locale/programs/ld-telephone.c
==============================================================================
--- fsf/trunk/libc/locale/programs/ld-telephone.c (original)
+++ fsf/trunk/libc/locale/programs/ld-telephone.c Fri Sep  6 17:39:04 2013
@@ -175,50 +175,15 @@
 {
   struct locale_telephone_t *telephone =
     locale->categories[LC_TELEPHONE].telephone;
-  struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE)];
-  struct locale_file data;
-  uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE)];
-  size_t cnt = 0;
-
-  data.magic = LIMAGIC (LC_TELEPHONE);
-  data.n = _NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE);
-  iov[cnt].iov_base = (void *) &data;
-  iov[cnt].iov_len = sizeof (data);
-  ++cnt;
-
-  iov[cnt].iov_base = (void *) idx;
-  iov[cnt].iov_len = sizeof (idx);
-  ++cnt;
-
-  idx[cnt - 2] = iov[0].iov_len + iov[1].iov_len;
-  iov[cnt].iov_base = (void *) telephone->tel_int_fmt;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) telephone->tel_dom_fmt;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) telephone->int_select;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) telephone->int_prefix;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  idx[cnt - 2] = idx[cnt - 3] + iov[cnt - 1].iov_len;
-  iov[cnt].iov_base = (void *) charmap->code_set_name;;
-  iov[cnt].iov_len = strlen (iov[cnt].iov_base) + 1;
-  ++cnt;
-
-  assert (cnt == 2 + _NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE));
-
-  write_locale_data (output_path, LC_TELEPHONE, "LC_TELEPHONE",
-		     2 + _NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE), iov);
+  struct locale_file file;
+
+  init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_TELEPHONE));
+  add_locale_string (&file, telephone->tel_int_fmt);
+  add_locale_string (&file, telephone->tel_dom_fmt);
+  add_locale_string (&file, telephone->int_select);
+  add_locale_string (&file, telephone->int_prefix);
+  add_locale_string (&file, charmap->code_set_name);
+  write_locale_data (output_path, LC_TELEPHONE, "LC_TELEPHONE", &file);
 }
 
 

Modified: fsf/trunk/libc/locale/programs/ld-time.c
==============================================================================
--- fsf/trunk/libc/locale/programs/ld-time.c (original)
+++ fsf/trunk/libc/locale/programs/ld-time.c Fri Sep  6 17:39:04 2013
@@ -539,394 +539,116 @@
 	     const char *output_path)
 {
   struct locale_time_t *time = locale->categories[LC_TIME].time;
-  struct iovec *iov = alloca (sizeof *iov
-			      * (2 + _NL_ITEM_INDEX (_NL_NUM_LC_TIME)
-				 + time->num_era - 1
-				 + 2 * 99
-				 + 2 + time->num_era * 10));
-  struct locale_file data;
-  uint32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_TIME)];
-  size_t cnt, last_idx, num, n;
-
-  data.magic = LIMAGIC (LC_TIME);
-  data.n = _NL_ITEM_INDEX (_NL_NUM_LC_TIME);
-  iov[0].iov_base = (void *) &data;
-  iov[0].iov_len = sizeof (data);
-
-  iov[1].iov_base = (void *) idx;
-  iov[1].iov_len = sizeof (idx);
-
-  idx[0] = iov[0].iov_len + iov[1].iov_len;
+  struct locale_file file;
+  size_t num, n;
+
+  init_locale_data (&file, _NL_ITEM_INDEX (_NL_NUM_LC_TIME));
 
   /* The ab'days.  */
-  for (cnt = 0; cnt <= _NL_ITEM_INDEX (ABDAY_7); ++cnt)
-    {
-      iov[2 + cnt].iov_base =
-	(void *) (time->abday[cnt - _NL_ITEM_INDEX (ABDAY_1)] ?: "");
-      iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
-      idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-    }
+  for (n = 0; n < 7; ++n)
+    add_locale_string (&file, time->abday[n] ?: "");
 
   /* The days.  */
-  for (; cnt <= _NL_ITEM_INDEX (DAY_7); ++cnt)
-    {
-      iov[2 + cnt].iov_base =
-	(void *) (time->day[cnt - _NL_ITEM_INDEX (DAY_1)] ?: "");
-      iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
-      idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-    }
+  for (n = 0; n < 7; ++n)
+    add_locale_string (&file, time->day[n] ?: "");
 
   /* The ab'mons.  */
-  for (; cnt <= _NL_ITEM_INDEX (ABMON_12); ++cnt)
-    {
-      iov[2 + cnt].iov_base =
-	(void *) (time->abmon[cnt - _NL_ITEM_INDEX (ABMON_1)] ?: "");
-      iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
-      idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-    }
+  for (n = 0; n < 12; ++n)
+    add_locale_string (&file, time->abmon[n] ?: "");
 
   /* The mons.  */
-  for (; cnt <= _NL_ITEM_INDEX (MON_12); ++cnt)
-    {
-      iov[2 + cnt].iov_base =
-	(void *) (time->mon[cnt - _NL_ITEM_INDEX (MON_1)] ?: "");
-      iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
-      idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-    }
+  for (n = 0; n < 12; ++n)
+    add_locale_string (&file, time->mon[n] ?: "");
 
   /* AM/PM.  */
-  for (; cnt <= _NL_ITEM_INDEX (PM_STR); ++cnt)
-    {
-      iov[2 + cnt].iov_base =
-	(void *) (time->am_pm[cnt - _NL_ITEM_INDEX (AM_STR)] ?: "");
-      iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
-      idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-    }
-
-  iov[2 + cnt].iov_base = (void *) (time->d_t_fmt ?: "");
-  iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  ++cnt;
-
-  iov[2 + cnt].iov_base = (void *) (time->d_fmt ?: "");
-  iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  ++cnt;
-
-  iov[2 + cnt].iov_base = (void *) (time->t_fmt ?: "");
-  iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  ++cnt;
-
-  iov[2 + cnt].iov_base = (void *) (time->t_fmt_ampm ?: "");
-  iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
-  idx[1 + cnt] = idx[cnt] + iov[2 + cnt].iov_len;
-  last_idx = ++cnt;
-
-  idx[1 + last_idx] = idx[last_idx];
-  for (num = 0; num < time->num_era; ++num, ++cnt)
-    {
-      iov[2 + cnt].iov_base = (void *) time->era[num];
-      iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
-      idx[1 + last_idx] += iov[2 + cnt].iov_len;
-    }
-  ++last_idx;
-
-  iov[2 + cnt].iov_base = (void *) (time->era_year ?: "");
-  iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
-  idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
-  ++cnt;
-  ++last_idx;
-
-  iov[2 + cnt].iov_base = (void *) (time->era_d_fmt ?: "");
-  iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
-  idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
-  ++cnt;
-  ++last_idx;
-
-  idx[1 + last_idx] = idx[last_idx];
-  for (num = 0; num < 100; ++num, ++cnt)
-    {
-      iov[2 + cnt].iov_base = (void *) (time->alt_digits[num] ?: "");
-      iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
-      idx[1 + last_idx] += iov[2 + cnt].iov_len;
-    }
-  ++last_idx;
-
-  iov[2 + cnt].iov_base = (void *) (time->era_d_t_fmt ?: "");
-  iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
-  idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
-  ++cnt;
-  ++last_idx;
-
-  iov[2 + cnt].iov_base = (void *) (time->era_t_fmt ?: "");
-  iov[2 + cnt].iov_len = strlen (iov[2 + cnt].iov_base) + 1;
-  idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
-  ++cnt;
-  ++last_idx;
-
-
-  /* We must align the following data.  */
-  iov[2 + cnt].iov_base = (void *) "\0\0";
-  iov[2 + cnt].iov_len = ((idx[last_idx] + 3) & ~3) - idx[last_idx];
-  idx[last_idx] = (idx[last_idx] + 3) & ~3;
-  ++cnt;
-
-  /* The `era' data in usable form.  */
-  iov[2 + cnt].iov_base = (void *) &time->num_era;
-  iov[2 + cnt].iov_len = sizeof (uint32_t);
-  idx[1 + last_idx] = idx[last_idx] + iov[2 + cnt].iov_len;
-  ++cnt;
-  ++last_idx;
-
-  idx[1 + last_idx] = idx[last_idx];
+  for (n = 0; n < 2; ++n)
+    add_locale_string (&file, time->am_pm[n]);
+
+  add_locale_string (&file, time->d_t_fmt ?: "");
+  add_locale_string (&file, time->d_fmt ?: "");
+  add_locale_string (&file, time->t_fmt ?: "");
+  add_locale_string (&file, time->t_fmt_ampm ?: "");
+
+  start_locale_structure (&file);
+  for (num = 0; num < time->num_era; ++num)
+    add_locale_string (&file, time->era[num]);
+  end_locale_structure (&file);
+
+  add_locale_string (&file, time->era_year ?: "");
+  add_locale_string (&file, time->era_d_fmt ?: "");
+
+  start_locale_structure (&file);
+  for (num = 0; num < 100; ++num)
+    add_locale_string (&file, time->alt_digits[num] ?: "");
+  end_locale_structure (&file);
+
+  add_locale_string (&file, time->era_d_t_fmt ?: "");
+  add_locale_string (&file, time->era_t_fmt ?: "");
+  add_locale_uint32 (&file, time->num_era);
+
+  start_locale_structure (&file);
   for (num = 0; num < time->num_era; ++num)
     {
-      size_t l, l2;
-
-      iov[2 + cnt].iov_base = (void *) &time->era_entries[num].direction;
-      iov[2 + cnt].iov_len = sizeof (int32_t);
-      ++cnt;
-      iov[2 + cnt].iov_base = (void *) &time->era_entries[num].offset;
-      iov[2 + cnt].iov_len = sizeof (int32_t);
-      ++cnt;
-      iov[2 + cnt].iov_base = (void *) &time->era_entries[num].start_date[0];
-      iov[2 + cnt].iov_len = sizeof (int32_t);
-      ++cnt;
-      iov[2 + cnt].iov_base = (void *) &time->era_entries[num].start_date[1];
-      iov[2 + cnt].iov_len = sizeof (int32_t);
-      ++cnt;
-      iov[2 + cnt].iov_base = (void *) &time->era_entries[num].start_date[2];
-      iov[2 + cnt].iov_len = sizeof (int32_t);
-      ++cnt;
-      iov[2 + cnt].iov_base = (void *) &time->era_entries[num].stop_date[0];
-      iov[2 + cnt].iov_len = sizeof (int32_t);
-      ++cnt;
-      iov[2 + cnt].iov_base = (void *) &time->era_entries[num].stop_date[1];
-      iov[2 + cnt].iov_len = sizeof (int32_t);
-      ++cnt;
-      iov[2 + cnt].iov_base = (void *) &time->era_entries[num].stop_date[2];
-      iov[2 + cnt].iov_len = sizeof (int32_t);
-      ++cnt;
-
-      l = ((char *) rawmemchr (time->era_entries[num].format, '\0')
-	   - time->era_entries[num].name) + 1;
-      l2 = (l + 3) & ~3;
-      iov[2 + cnt].iov_base = alloca (l2);
-      memset (mempcpy (iov[2 + cnt].iov_base, time->era_entries[num].name, l),
-	      '\0', l2 - l);
-      iov[2 + cnt].iov_len = l2;
-      ++cnt;
-
-      idx[1 + last_idx] += 8 * sizeof (int32_t) + l2;
-
-      assert (idx[1 + last_idx] % 4 == 0);
-
-      iov[2 + cnt].iov_base = (void *) time->era_entries[num].wname;
-      iov[2 + cnt].iov_len = ((wcschr ((wchar_t *) time->era_entries[num].wformat, L'\0')
-			       - (wchar_t *) time->era_entries[num].wname + 1)
-			      * sizeof (uint32_t));
-      idx[1 + last_idx] += iov[2 + cnt].iov_len;
-      ++cnt;
+      add_locale_uint32 (&file, time->era_entries[num].direction);
+      add_locale_uint32 (&file, time->era_entries[num].offset);
+      add_locale_uint32 (&file, time->era_entries[num].start_date[0]);
+      add_locale_uint32 (&file, time->era_entries[num].start_date[1]);
+      add_locale_uint32 (&file, time->era_entries[num].start_date[2]);
+      add_locale_uint32 (&file, time->era_entries[num].stop_date[0]);
+      add_locale_uint32 (&file, time->era_entries[num].stop_date[1]);
+      add_locale_uint32 (&file, time->era_entries[num].stop_date[2]);
+      add_locale_string (&file, time->era_entries[num].name);

[... 731 lines stripped ...]
_______________________________________________
Commits mailing list
Commits@xxxxxxxxxx
http://eglibc.org/cgi-bin/mailman/listinfo/commits