1From 33e9867758e830e19d181d5a0aa7f2f3cc4a08b3 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 18 Mar 2015 01:33:49 +0000
4Subject: [PATCH] eglibc: Forward port cross locale generation support
5
6Upstream-Status: Pending
7
8Signed-off-by: Khem Raj <raj.khem@gmail.com>
9---
10 locale/Makefile               |  1 +
11 locale/catnames.c             | 46 +++++++++++++++++++++++++++
12 locale/localeinfo.h           |  2 +-
13 locale/programs/charmap-dir.c |  6 ++++
14 locale/programs/ld-collate.c  | 17 +++++-----
15 locale/programs/ld-ctype.c    | 27 ++++++++--------
16 locale/programs/ld-time.c     | 31 ++++++++++++------
17 locale/programs/linereader.c  |  2 +-
18 locale/programs/localedef.c   |  8 +++++
19 locale/programs/locfile.c     |  5 ++-
20 locale/programs/locfile.h     | 59 +++++++++++++++++++++++++++++++++--
21 locale/setlocale.c            | 29 -----------------
22 12 files changed, 166 insertions(+), 67 deletions(-)
23 create mode 100644 locale/catnames.c
24
25diff --git a/locale/Makefile b/locale/Makefile
26index 2810f28605..05f847f9a6 100644
27--- a/locale/Makefile
28+++ b/locale/Makefile
29@@ -30,6 +30,7 @@ headers = \
30   locale.h \
31   # headers
32 routines = \
33+	catnames \
34   duplocale \
35   findlocale \
36   freelocale \
37diff --git a/locale/catnames.c b/locale/catnames.c
38new file mode 100644
39index 0000000000..538f3f5edb
40--- /dev/null
41+++ b/locale/catnames.c
42@@ -0,0 +1,46 @@
43+/* Copyright (C) 2006  Free Software Foundation, Inc.
44+   This file is part of the GNU C Library.
45+
46+   The GNU C Library is free software; you can redistribute it and/or
47+   modify it under the terms of the GNU Lesser General Public
48+   License as published by the Free Software Foundation; either
49+   version 2.1 of the License, or (at your option) any later version.
50+
51+   The GNU C Library is distributed in the hope that it will be useful,
52+   but WITHOUT ANY WARRANTY; without even the implied warranty of
53+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
54+   Lesser General Public License for more details.
55+
56+   You should have received a copy of the GNU Lesser General Public
57+   License along with the GNU C Library; if not, write to the Free
58+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
59+   02111-1307 USA.  */
60+
61+#include "localeinfo.h"
62+
63+/* Define an array of category names (also the environment variable names).  */
64+const struct catnamestr_t _nl_category_names attribute_hidden =
65+  {
66+#define DEFINE_CATEGORY(category, category_name, items, a) \
67+    category_name,
68+#include "categories.def"
69+#undef DEFINE_CATEGORY
70+  };
71+
72+const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden =
73+  {
74+#define DEFINE_CATEGORY(category, category_name, items, a) \
75+    [category] = offsetof (struct catnamestr_t, CATNAMEMF (__LINE__)),
76+#include "categories.def"
77+#undef DEFINE_CATEGORY
78+  };
79+
80+/* An array of their lengths, for convenience.  */
81+const uint8_t _nl_category_name_sizes[] attribute_hidden =
82+  {
83+#define DEFINE_CATEGORY(category, category_name, items, a) \
84+    [category] = sizeof (category_name) - 1,
85+#include "categories.def"
86+#undef	DEFINE_CATEGORY
87+    [LC_ALL] = sizeof ("LC_ALL") - 1
88+  };
89diff --git a/locale/localeinfo.h b/locale/localeinfo.h
90index f7efc288a5..6ef082eb25 100644
91--- a/locale/localeinfo.h
92+++ b/locale/localeinfo.h
93@@ -246,7 +246,7 @@ __libc_tsd_define (extern, locale_t, LOCALE)
94    unused.  We can manage this playing some tricks with weak references.
95    But with thread-local locale settings, it becomes quite ungainly unless
96    we can use __thread variables.  So only in that case do we attempt this.  */
97-#ifndef SHARED
98+#if !defined SHARED && !defined IN_GLIBC_LOCALEDEF
99 # include <tls.h>
100 # define NL_CURRENT_INDIRECT	1
101 #endif
102diff --git a/locale/programs/charmap-dir.c b/locale/programs/charmap-dir.c
103index 36504f238d..56ee97e61b 100644
104--- a/locale/programs/charmap-dir.c
105+++ b/locale/programs/charmap-dir.c
106@@ -18,7 +18,9 @@
107 #include <errno.h>
108 #include <fcntl.h>
109 #include <libintl.h>
110+#ifndef NO_UNCOMPRESS
111 #include <spawn.h>
112+#endif
113 #include <stdio.h>
114 #include <stdlib.h>
115 #include <string.h>
116@@ -154,6 +156,7 @@ charmap_closedir (CHARMAP_DIR *cdir)
117   return closedir (dir);
118 }
119
120+#ifndef NO_UNCOMPRESS
121 /* Creates a subprocess decompressing the given pathname, and returns
122    a stream reading its output (the decompressed data).  */
123 static
124@@ -202,6 +205,7 @@ fopen_uncompressed (const char *pathname, const char *compressor)
125     }
126   return NULL;
127 }
128+#endif
129
130 /* Opens a charmap for reading, given its name (not an alias name).  */
131 FILE *
132@@ -224,6 +228,7 @@ charmap_open (const char *directory, const char *name)
133   if (stream != NULL)
134     return stream;
135
136+#ifndef NO_UNCOMPRESS
137   memcpy (p, ".gz", 4);
138   stream = fopen_uncompressed (pathname, "gzip");
139   if (stream != NULL)
140@@ -233,6 +238,7 @@ charmap_open (const char *directory, const char *name)
141   stream = fopen_uncompressed (pathname, "bzip2");
142   if (stream != NULL)
143     return stream;
144+#endif
145
146   return NULL;
147 }
148diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c
149index 5048adbd9f..4232834ead 100644
150--- a/locale/programs/ld-collate.c
151+++ b/locale/programs/ld-collate.c
152@@ -352,7 +352,7 @@ new_element (struct locale_collate_t *collate, const char *mbs, size_t mbslen,
153     }
154   if (wcs != NULL)
155     {
156-      size_t nwcs = wcslen ((wchar_t *) wcs);
157+      size_t nwcs = wcslen_uint32 (wcs);
158       uint32_t zero = 0;
159       /* Handle <U0000> as a single character.  */
160       if (nwcs == 0)
161@@ -1776,8 +1776,7 @@ symbol `%s' has the same encoding as"), (*eptr)->name);
162
163 	      if ((*eptr)->nwcs == runp->nwcs)
164 		{
165-		  int c = wmemcmp ((wchar_t *) (*eptr)->wcs,
166-				   (wchar_t *) runp->wcs, runp->nwcs);
167+		  int c = wmemcmp_uint32 ((*eptr)->wcs, runp->wcs, runp->nwcs);
168
169 		  if (c == 0)
170 		    {
171@@ -2004,9 +2003,9 @@ add_to_tablewc (uint32_t ch, struct element_t *runp)
172 	     one consecutive entry.  */
173 	  if (runp->wcnext != NULL
174 	      && runp->nwcs == runp->wcnext->nwcs
175-	      && wmemcmp ((wchar_t *) runp->wcs,
176-			  (wchar_t *)runp->wcnext->wcs,
177-			  runp->nwcs - 1) == 0
178+	      && wmemcmp_uint32 (runp->wcs,
179+				 runp->wcnext->wcs,
180+				 runp->nwcs - 1) == 0
181 	      && (runp->wcs[runp->nwcs - 1]
182 		  == runp->wcnext->wcs[runp->nwcs - 1] + 1))
183 	    {
184@@ -2030,9 +2029,9 @@ add_to_tablewc (uint32_t ch, struct element_t *runp)
185 		runp = runp->wcnext;
186 	      while (runp->wcnext != NULL
187 		     && runp->nwcs == runp->wcnext->nwcs
188-		     && wmemcmp ((wchar_t *) runp->wcs,
189-				 (wchar_t *)runp->wcnext->wcs,
190-				 runp->nwcs - 1) == 0
191+		     && wmemcmp_uint32 (runp->wcs,
192+					runp->wcnext->wcs,
193+					runp->nwcs - 1) == 0
194 		     && (runp->wcs[runp->nwcs - 1]
195 			 == runp->wcnext->wcs[runp->nwcs - 1] + 1));
196
197diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c
198index eb6e7e145c..14736d1cac 100644
199--- a/locale/programs/ld-ctype.c
200+++ b/locale/programs/ld-ctype.c
201@@ -914,7 +914,7 @@ ctype_output (struct localedef_t *locale, const struct charmap_t *charmap,
202   allocate_arrays (ctype, charmap, ctype->repertoire);
203
204   default_missing_len = (ctype->default_missing
205-			 ? wcslen ((wchar_t *) ctype->default_missing)
206+			 ? wcslen_uint32 (ctype->default_missing)
207 			 : 0);
208
209   init_locale_data (&file, nelems);
210@@ -1926,7 +1926,7 @@ read_translit_entry (struct linereader *ldfile, struct locale_ctype_t *ctype,
211 	    ignore = 1;
212 	  else
213 	    /* This value is usable.  */
214-	    obstack_grow (ob, to_wstr, wcslen ((wchar_t *) to_wstr) * 4);
215+	    obstack_grow (ob, to_wstr, wcslen_uint32 (to_wstr) * 4);
216
217 	  first = 0;
218 	}
219@@ -2460,8 +2460,8 @@ with character code range values one must use the absolute ellipsis `...'"));
220 	    }
221
222 	handle_tok_digit:
223-	  class_bit = _ISwdigit;
224-	  class256_bit = _ISdigit;
225+	  class_bit = BITw (tok_digit);
226+	  class256_bit = BIT (tok_digit);
227 	  handle_digits = 1;
228 	  goto read_charclass;
229
230@@ -3876,8 +3876,7 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
231
232 	  while (idx < number)
233 	    {
234-	      int res = wcscmp ((const wchar_t *) sorted[idx]->from,
235-				(const wchar_t *) runp->from);
236+	      int res = wcscmp_uint32 (sorted[idx]->from, runp->from);
237 	      if (res == 0)
238 		{
239 		  replace = 1;
240@@ -3914,11 +3913,11 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
241       for (size_t cnt = 0; cnt < number; ++cnt)
242 	{
243 	  struct translit_to_t *srunp;
244-	  from_len += wcslen ((const wchar_t *) sorted[cnt]->from) + 1;
245+	  from_len += wcslen_uint32 (sorted[cnt]->from) + 1;
246 	  srunp = sorted[cnt]->to;
247 	  while (srunp != NULL)
248 	    {
249-	      to_len += wcslen ((const wchar_t *) srunp->str) + 1;
250+	      to_len += wcslen_uint32 (srunp->str) + 1;
251 	      srunp = srunp->next;
252 	    }
253 	  /* Plus one for the extra NUL character marking the end of
254@@ -3942,18 +3941,18 @@ allocate_arrays (struct locale_ctype_t *ctype, const struct charmap_t *charmap,
255 	  ctype->translit_from_idx[cnt] = from_len;
256 	  ctype->translit_to_idx[cnt] = to_len;
257
258-	  len = wcslen ((const wchar_t *) sorted[cnt]->from) + 1;
259-	  wmemcpy ((wchar_t *) &ctype->translit_from_tbl[from_len],
260-		   (const wchar_t *) sorted[cnt]->from, len);
261+	  len = wcslen_uint32 (sorted[cnt]->from) + 1;
262+	  wmemcpy_uint32 (&ctype->translit_from_tbl[from_len],
263+			  sorted[cnt]->from, len);
264 	  from_len += len;
265
266 	  ctype->translit_to_idx[cnt] = to_len;
267 	  srunp = sorted[cnt]->to;
268 	  while (srunp != NULL)
269 	    {
270-	      len = wcslen ((const wchar_t *) srunp->str) + 1;
271-	      wmemcpy ((wchar_t *) &ctype->translit_to_tbl[to_len],
272-		       (const wchar_t *) srunp->str, len);
273+	      len = wcslen_uint32 (srunp->str) + 1;
274+	      wmemcpy_uint32 (&ctype->translit_to_tbl[to_len],
275+			      srunp->str, len);
276 	      to_len += len;
277 	      srunp = srunp->next;
278 	    }
279diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c
280index 1abff3cf53..8a2f2b820a 100644
281--- a/locale/programs/ld-time.c
282+++ b/locale/programs/ld-time.c
283@@ -219,8 +219,10 @@ No definition for %s category found"), "LC_TIME");
284 	}
285       else
286 	{
287+	  static const uint32_t wt_fmt_ampm[]
288+	    = { '%','I',':','%','M',':','%','S',' ','%','p',0 };
289 	  time->t_fmt_ampm = "%I:%M:%S %p";
290-	  time->wt_fmt_ampm = (const uint32_t *) L"%I:%M:%S %p";
291+	  time->wt_fmt_ampm = wt_fmt_ampm;
292 	}
293     }
294
295@@ -230,7 +232,7 @@ No definition for %s category found"), "LC_TIME");
296       const int days_per_month[12] = { 31, 29, 31, 30, 31, 30,
297 				       31, 31, 30, 31 ,30, 31 };
298       size_t idx;
299-      wchar_t *wstr;
300+      uint32_t *wstr;
301
302       time->era_entries =
303 	(struct era_data *) xmalloc (time->num_era
304@@ -456,18 +458,18 @@ No definition for %s category found"), "LC_TIME");
305 	    }
306
307 	  /* Now generate the wide character name and format.  */
308-	  wstr = wcschr ((wchar_t *) time->wera[idx], L':');/* end direction */
309-	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end offset */
310-	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end start */
311-	  wstr = wstr ? wcschr (wstr + 1, L':') : NULL;	/* end end */
312+	  wstr = wcschr_uint32 (time->wera[idx], L':'); /* end direction */
313+	  wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end offset */
314+	  wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end start */
315+	  wstr = wstr ? wcschr_uint32 (wstr + 1, L':') : NULL; /* end end */
316 	  if (wstr != NULL)
317 	    {
318-	      time->era_entries[idx].wname = (uint32_t *) wstr + 1;
319-	      wstr = wcschr (wstr + 1, L':');	/* end name */
320+	      time->era_entries[idx].wname = wstr + 1;
321+	      wstr = wcschr_uint32 (wstr + 1, L':'); /* end name */
322 	      if (wstr != NULL)
323 		{
324 		  *wstr = L'\0';
325-		  time->era_entries[idx].wformat = (uint32_t *) wstr + 1;
326+		  time->era_entries[idx].wformat = wstr + 1;
327 		}
328 	      else
329 		time->era_entries[idx].wname =
330@@ -526,7 +528,16 @@ No definition for %s category found"), "LC_TIME");
331   if (time->date_fmt == NULL)
332     time->date_fmt = "%a %b %e %H:%M:%S %Z %Y";
333   if (time->wdate_fmt == NULL)
334-    time->wdate_fmt = (const uint32_t *) L"%a %b %e %H:%M:%S %Z %Y";
335+    {
336+      static const uint32_t wdate_fmt[] =
337+	{ '%','a',' ',
338+	  '%','b',' ',
339+	  '%','e',' ',
340+	  '%','H',':','%','M',':','%','S',' ',
341+	  '%','Z',' ',
342+	  '%','Y',0 };
343+      time->wdate_fmt = wdate_fmt;
344+    }
345 }
346
347
348diff --git a/locale/programs/linereader.c b/locale/programs/linereader.c
349index 61373d2657..7ec5726377 100644
350--- a/locale/programs/linereader.c
351+++ b/locale/programs/linereader.c
352@@ -776,7 +776,7 @@ get_string (struct linereader *lr, const struct charmap_t *charmap,
353 {
354   int return_widestr = lr->return_widestr;
355   struct lr_buffer lrb;
356-  wchar_t *buf2 = NULL;
357+  uint32_t *buf2 = NULL;
358
359   lr_buffer_init (&lrb);
360
361diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c
362index 907bb5fb25..3106529043 100644
363--- a/locale/programs/localedef.c
364+++ b/locale/programs/localedef.c
365@@ -108,6 +108,7 @@ void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
366 #define OPT_NO_WARN 402
367 #define OPT_WARN 403
368 #define OPT_NO_HARD_LINKS 404
369+#define OPT_UINT32_ALIGN 405
370
371 /* Definitions of arguments for argp functions.  */
372 static const struct argp_option options[] =
373@@ -152,6 +153,8 @@ static const struct argp_option options[] =
374     N_("Generate little-endian output") },
375   { "big-endian", OPT_BIG_ENDIAN, NULL, 0,
376     N_("Generate big-endian output") },
377+  { "uint32-align", OPT_UINT32_ALIGN, "ALIGNMENT", 0,
378+    N_("Set the target's uint32_t alignment in bytes (default 4)") },
379   { NULL, 0, NULL, 0, NULL }
380 };
381
382@@ -242,12 +245,14 @@ main (int argc, char *argv[])
383      ctype locale.  (P1003.2 4.35.5.2)  */
384   setlocale (LC_CTYPE, "POSIX");
385
386+#ifndef NO_SYSCONF
387   /* Look whether the system really allows locale definitions.  POSIX
388      defines error code 3 for this situation so I think it must be
389      a fatal error (see P1003.2 4.35.8).  */
390   if (sysconf (_SC_2_LOCALEDEF) < 0)
391     record_error (3, 0, _("\
392 FATAL: system does not define `_POSIX2_LOCALEDEF'"));
393+#endif
394
395   /* Process charmap file.  */
396   charmap = charmap_read (charmap_file, verbose, 1, be_quiet, 1);
397@@ -399,6 +404,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
398       /* Do not hard link to other locales.  */
399       hard_links = false;
400       break;
401+    case OPT_UINT32_ALIGN:
402+      uint32_align_mask = strtol (arg, NULL, 0) - 1;
403+      break;
404     case 'c':
405       force_output = 1;
406       break;
407diff --git a/locale/programs/locfile.c b/locale/programs/locfile.c
408index 6c6ebf2dd6..cc02ab82bf 100644
409--- a/locale/programs/locfile.c
410+++ b/locale/programs/locfile.c
411@@ -543,6 +543,9 @@ compare_files (const char *filename1, const char *filename2, size_t size,
412    machine running localedef.  */
413 bool swap_endianness_p;
414
415+/* The target's value of __align__(uint32_t) - 1.  */
416+unsigned int uint32_align_mask = 3;
417+
418 /* When called outside a start_locale_structure/end_locale_structure
419    or start_locale_prelude/end_locale_prelude block, record that the
420    next byte in FILE's obstack will be the first byte of a new element.
421@@ -620,7 +623,7 @@ add_locale_string (struct locale_file *file, const char *string)
422 void
423 add_locale_wstring (struct locale_file *file, const uint32_t *string)
424 {
425-  add_locale_uint32_array (file, string, wcslen ((const wchar_t *) string) + 1);
426+  add_locale_uint32_array (file, string, wcslen_uint32 (string) + 1);
427 }
428
429 /* Record that FILE's next element is the 32-bit integer VALUE.  */
430diff --git a/locale/programs/locfile.h b/locale/programs/locfile.h
431index 3afb0a8d29..46785374e8 100644
432--- a/locale/programs/locfile.h
433+++ b/locale/programs/locfile.h
434@@ -70,6 +70,8 @@ extern void write_all_categories (struct localedef_t *definitions,
435
436 extern bool swap_endianness_p;
437
438+extern unsigned int uint32_align_mask;
439+
440 /* Change the output to be big-endian if BIG_ENDIAN is true and
441    little-endian otherwise.  */
442 static inline void
443@@ -88,7 +90,8 @@ maybe_swap_uint32 (uint32_t value)
444 }
445
446 /* Likewise, but munge an array of N uint32_ts starting at ARRAY.  */
447-static inline void
448+static void
449+__attribute__ ((unused))
450 maybe_swap_uint32_array (uint32_t *array, size_t n)
451 {
452   if (swap_endianness_p)
453@@ -98,7 +101,8 @@ maybe_swap_uint32_array (uint32_t *array, size_t n)
454
455 /* Like maybe_swap_uint32_array, but the array of N elements is at
456    the end of OBSTACK's current object.  */
457-static inline void
458+static void
459+__attribute__ ((unused))
460 maybe_swap_uint32_obstack (struct obstack *obstack, size_t n)
461 {
462   maybe_swap_uint32_array ((uint32_t *) obstack_next_free (obstack) - n, n);
463@@ -275,4 +279,55 @@ extern void identification_output (struct localedef_t *locale,
464 				   const struct charmap_t *charmap,
465 				   const char *output_path);
466
467+static size_t wcslen_uint32 (const uint32_t *str) __attribute__ ((unused));
468+static uint32_t * wmemcpy_uint32 (uint32_t *s1, const uint32_t *s2, size_t n) __attribute__ ((unused));
469+static uint32_t * wcschr_uint32 (const uint32_t *s, uint32_t ch) __attribute__ ((unused));
470+static int wcscmp_uint32 (const uint32_t *s1, const uint32_t *s2) __attribute__ ((unused));
471+static int wmemcmp_uint32 (const uint32_t *s1, const uint32_t *s2, size_t n) __attribute__ ((unused));
472+
473+static size_t
474+wcslen_uint32 (const uint32_t *str)
475+{
476+  size_t len = 0;
477+  while (str[len] != 0)
478+    len++;
479+  return len;
480+}
481+
482+static  int
483+wmemcmp_uint32 (const uint32_t *s1, const uint32_t *s2, size_t n)
484+{
485+  while (n-- != 0)
486+    {
487+      int diff = *s1++ - *s2++;
488+      if (diff != 0)
489+	return diff;
490+    }
491+  return 0;
492+}
493+
494+static int
495+wcscmp_uint32 (const uint32_t *s1, const uint32_t *s2)
496+{
497+  while (*s1 != 0 && *s1 == *s2)
498+    s1++, s2++;
499+  return *s1 - *s2;
500+}
501+
502+static uint32_t *
503+wmemcpy_uint32 (uint32_t *s1, const uint32_t *s2, size_t n)
504+{
505+  return memcpy (s1, s2, n * sizeof (uint32_t));
506+}
507+
508+static uint32_t *
509+wcschr_uint32 (const uint32_t *s, uint32_t ch)
510+{
511+  do
512+    if (*s == ch)
513+      return (uint32_t *) s;
514+  while (*s++ != 0);
515+  return 0;
516+}
517+
518 #endif /* locfile.h */
519diff --git a/locale/setlocale.c b/locale/setlocale.c
520index 7bd27e5398..2f194bad7c 100644
521--- a/locale/setlocale.c
522+++ b/locale/setlocale.c
523@@ -63,35 +63,6 @@ static char *const _nl_current_used[] =
524
525 #endif
526
527-
528-/* Define an array of category names (also the environment variable names).  */
529-const struct catnamestr_t _nl_category_names attribute_hidden =
530-  {
531-#define DEFINE_CATEGORY(category, category_name, items, a) \
532-    category_name,
533-#include "categories.def"
534-#undef DEFINE_CATEGORY
535-  };
536-
537-const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden =
538-  {
539-#define DEFINE_CATEGORY(category, category_name, items, a) \
540-    [category] = offsetof (struct catnamestr_t, CATNAMEMF (__LINE__)),
541-#include "categories.def"
542-#undef DEFINE_CATEGORY
543-  };
544-
545-/* An array of their lengths, for convenience.  */
546-const uint8_t _nl_category_name_sizes[] attribute_hidden =
547-  {
548-#define DEFINE_CATEGORY(category, category_name, items, a) \
549-    [category] = sizeof (category_name) - 1,
550-#include "categories.def"
551-#undef	DEFINE_CATEGORY
552-    [LC_ALL] = sizeof ("LC_ALL") - 1
553-  };
554-
555-
556 #ifdef NL_CURRENT_INDIRECT
557 # define WEAK_POSTLOAD(postload) weak_extern (postload)
558 #else
559