Andrew Geissler | d1e8949 | 2021-02-12 15:35:20 -0600 | [diff] [blame] | 1 | From 557ed640b26bd208ce8d4a6fd725b124893668d7 Mon Sep 17 00:00:00 2001 |
Andrew Geissler | 82c905d | 2020-04-13 13:39:40 -0500 | [diff] [blame] | 2 | From: Khem Raj <raj.khem@gmail.com> |
| 3 | Date: Wed, 18 Mar 2015 01:33:49 +0000 |
Andrew Geissler | d1e8949 | 2021-02-12 15:35:20 -0600 | [diff] [blame] | 4 | Subject: [PATCH] eglibc: Forward port cross locale generation support |
Andrew Geissler | 82c905d | 2020-04-13 13:39:40 -0500 | [diff] [blame] | 5 | |
| 6 | Upstream-Status: Pending |
| 7 | |
| 8 | Signed-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 | |
| 25 | diff --git a/locale/Makefile b/locale/Makefile |
Andrew Geissler | d1e8949 | 2021-02-12 15:35:20 -0600 | [diff] [blame] | 26 | index b7c60681fa..07c606cde3 100644 |
Andrew Geissler | 82c905d | 2020-04-13 13:39:40 -0500 | [diff] [blame] | 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 |
Andrew Geissler | 635e0e4 | 2020-08-21 15:58:33 -0500 | [diff] [blame] | 37 | tests-container = tst-localedef-path-norm |
Andrew Geissler | 82c905d | 2020-04-13 13:39:40 -0500 | [diff] [blame] | 38 | categories = ctype messages monetary numeric time paper name \ |
Andrew Geissler | 82c905d | 2020-04-13 13:39:40 -0500 | [diff] [blame] | 39 | diff --git a/locale/catnames.c b/locale/catnames.c |
| 40 | new file mode 100644 |
| 41 | index 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 | + }; |
| 91 | diff --git a/locale/localeinfo.h b/locale/localeinfo.h |
Andrew Geissler | d1e8949 | 2021-02-12 15:35:20 -0600 | [diff] [blame] | 92 | index 22f9dc1140..fa31b3c5ea 100644 |
Andrew Geissler | 82c905d | 2020-04-13 13:39:40 -0500 | [diff] [blame] | 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 |
| 104 | diff --git a/locale/programs/charmap-dir.c b/locale/programs/charmap-dir.c |
Andrew Geissler | d1e8949 | 2021-02-12 15:35:20 -0600 | [diff] [blame] | 105 | index 4841bfd05d..ffcba1fd79 100644 |
Andrew Geissler | 82c905d | 2020-04-13 13:39:40 -0500 | [diff] [blame] | 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 | } |
| 150 | diff --git a/locale/programs/ld-collate.c b/locale/programs/ld-collate.c |
Andrew Geissler | d1e8949 | 2021-02-12 15:35:20 -0600 | [diff] [blame] | 151 | index 0af21e05e2..4980b0c52f 100644 |
Andrew Geissler | 82c905d | 2020-04-13 13:39:40 -0500 | [diff] [blame] | 152 | --- a/locale/programs/ld-collate.c |
| 153 | +++ b/locale/programs/ld-collate.c |
| 154 | @@ -349,7 +349,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 | @@ -1772,8 +1772,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 | @@ -2000,9 +1999,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 | @@ -2026,9 +2025,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 | |
| 199 | diff --git a/locale/programs/ld-ctype.c b/locale/programs/ld-ctype.c |
Andrew Geissler | d1e8949 | 2021-02-12 15:35:20 -0600 | [diff] [blame] | 200 | index 2fb579bbbf..d0be99581c 100644 |
Andrew Geissler | 82c905d | 2020-04-13 13:39:40 -0500 | [diff] [blame] | 201 | --- a/locale/programs/ld-ctype.c |
| 202 | +++ b/locale/programs/ld-ctype.c |
| 203 | @@ -915,7 +915,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 | @@ -1927,7 +1927,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 | @@ -2461,8 +2461,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 | @@ -3904,8 +3904,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 | @@ -3942,11 +3941,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 | @@ -3970,18 +3969,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 | } |
| 281 | diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c |
Andrew Geissler | d1e8949 | 2021-02-12 15:35:20 -0600 | [diff] [blame] | 282 | index dcd2a2386d..6814740325 100644 |
Andrew Geissler | 82c905d | 2020-04-13 13:39:40 -0500 | [diff] [blame] | 283 | --- a/locale/programs/ld-time.c |
| 284 | +++ b/locale/programs/ld-time.c |
| 285 | @@ -220,8 +220,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 | @@ -231,7 +233,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 | @@ -457,18 +459,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 | @@ -527,7 +529,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 | |
| 350 | diff --git a/locale/programs/linereader.c b/locale/programs/linereader.c |
Andrew Geissler | d1e8949 | 2021-02-12 15:35:20 -0600 | [diff] [blame] | 351 | index 96d3ab66db..3af379d2c3 100644 |
Andrew Geissler | 82c905d | 2020-04-13 13:39:40 -0500 | [diff] [blame] | 352 | --- a/locale/programs/linereader.c |
| 353 | +++ b/locale/programs/linereader.c |
| 354 | @@ -595,7 +595,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 | |
| 363 | diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c |
Andrew Geissler | d1e8949 | 2021-02-12 15:35:20 -0600 | [diff] [blame] | 364 | index 832c8fd1fc..fe689b3ae1 100644 |
Andrew Geissler | 82c905d | 2020-04-13 13:39:40 -0500 | [diff] [blame] | 365 | --- a/locale/programs/localedef.c |
| 366 | +++ b/locale/programs/localedef.c |
| 367 | @@ -109,6 +109,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 | @@ -153,6 +154,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 | |
Andrew Geissler | 635e0e4 | 2020-08-21 15:58:33 -0500 | [diff] [blame] | 384 | @@ -243,12 +246,14 @@ main (int argc, char *argv[]) |
Andrew Geissler | 82c905d | 2020-04-13 13:39:40 -0500 | [diff] [blame] | 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); |
Andrew Geissler | 635e0e4 | 2020-08-21 15:58:33 -0500 | [diff] [blame] | 399 | @@ -400,6 +405,9 @@ parse_opt (int key, char *arg, struct argp_state *state) |
Andrew Geissler | 82c905d | 2020-04-13 13:39:40 -0500 | [diff] [blame] | 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; |
| 409 | diff --git a/locale/programs/locfile.c b/locale/programs/locfile.c |
Andrew Geissler | d1e8949 | 2021-02-12 15:35:20 -0600 | [diff] [blame] | 410 | index 0f1affa1d4..7d86fae801 100644 |
Andrew Geissler | 82c905d | 2020-04-13 13:39:40 -0500 | [diff] [blame] | 411 | --- a/locale/programs/locfile.c |
| 412 | +++ b/locale/programs/locfile.c |
| 413 | @@ -544,6 +544,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 | @@ -621,7 +624,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. */ |
| 432 | diff --git a/locale/programs/locfile.h b/locale/programs/locfile.h |
Andrew Geissler | d1e8949 | 2021-02-12 15:35:20 -0600 | [diff] [blame] | 433 | index c986d599ec..222a779176 100644 |
Andrew Geissler | 82c905d | 2020-04-13 13:39:40 -0500 | [diff] [blame] | 434 | --- a/locale/programs/locfile.h |
| 435 | +++ b/locale/programs/locfile.h |
| 436 | @@ -71,6 +71,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 | @@ -89,7 +91,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 | @@ -99,7 +102,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 | @@ -276,4 +280,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 */ |
| 521 | diff --git a/locale/setlocale.c b/locale/setlocale.c |
Andrew Geissler | d1e8949 | 2021-02-12 15:35:20 -0600 | [diff] [blame] | 522 | index 19ed85ae8e..f28ca11446 100644 |
Andrew Geissler | 82c905d | 2020-04-13 13:39:40 -0500 | [diff] [blame] | 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 |