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