]>
Commit | Line | Data |
---|---|---|
4b10dd6c | 1 | /* Declarations for internal libc locale interfaces |
2b778ceb | 2 | Copyright (C) 1995-2021 Free Software Foundation, Inc. |
5290baf0 UD |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
5290baf0 UD |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 13 | Lesser General Public License for more details. |
5290baf0 | 14 | |
41bdb6e2 | 15 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 | 16 | License along with the GNU C Library; if not, see |
5a82c748 | 17 | <https://www.gnu.org/licenses/>. */ |
28f540f4 | 18 | |
933e73fa RM |
19 | #ifndef _LOCALEINFO_H |
20 | #define _LOCALEINFO_H 1 | |
28f540f4 | 21 | |
933e73fa RM |
22 | #include <stddef.h> |
23 | #include <langinfo.h> | |
c84142e8 | 24 | #include <limits.h> |
47e8b443 | 25 | #include <locale.h> |
c4029823 | 26 | #include <time.h> |
4b10dd6c | 27 | #include <stdint.h> |
933e73fa | 28 | #include <sys/types.h> |
28f540f4 | 29 | |
4b10dd6c | 30 | #include <intl/loadinfo.h> /* For loaded_l10nfile definition. */ |
7a12c6bb | 31 | |
933e73fa | 32 | /* Magic number at the beginning of a locale data file for CATEGORY. */ |
7d4722e3 UD |
33 | #define LIMAGIC(category) \ |
34 | (category == LC_COLLATE \ | |
35 | ? ((unsigned int) (0x20051014 ^ (category))) \ | |
8a449450 UD |
36 | : category == LC_CTYPE \ |
37 | ? ((unsigned int) (0x20090720 ^ (category))) \ | |
7d4722e3 | 38 | : ((unsigned int) (0x20031115 ^ (category)))) |
19bc17a9 RM |
39 | |
40 | /* Two special weight constants for the collation data. */ | |
575b273b | 41 | #define IGNORE_CHAR 2 |
28f540f4 | 42 | |
f095bb72 | 43 | /* We use a special value for the usage counter in `__locale_data' to |
c84142e8 | 44 | signal that this data must never be removed anymore. */ |
a5a0310d UD |
45 | #define MAX_USAGE_COUNT (UINT_MAX - 1) |
46 | #define UNDELETABLE UINT_MAX | |
c84142e8 | 47 | |
933e73fa | 48 | /* Structure describing locale data in core for a category. */ |
f095bb72 | 49 | struct __locale_data |
19bc17a9 | 50 | { |
7a12c6bb | 51 | const char *name; |
19bc17a9 RM |
52 | const char *filedata; /* Region mapping the file data. */ |
53 | off_t filesize; /* Size of the file (and the region). */ | |
cb09a2cd RM |
54 | enum /* Flavor of storage used for those. */ |
55 | { | |
56 | ld_malloced, /* Both are malloc'd. */ | |
57 | ld_mapped, /* name is malloc'd, filedata mmap'd */ | |
58 | ld_archive /* Both point into mmap'd archive regions. */ | |
59 | } alloc; | |
c84142e8 | 60 | |
df9f41c9 RM |
61 | /* This provides a slot for category-specific code to cache data computed |
62 | about this locale. That code can set a cleanup function to deallocate | |
63 | the data. */ | |
64 | struct | |
65 | { | |
d7ccc6c9 | 66 | void (*cleanup) (struct __locale_data *); |
df9f41c9 RM |
67 | union |
68 | { | |
69 | void *data; | |
70 | struct lc_time_data *time; | |
96310297 | 71 | const struct gconv_fcts *ctype; |
df9f41c9 RM |
72 | }; |
73 | } private; | |
74 | ||
c84142e8 | 75 | unsigned int usage_count; /* Counter for users. */ |
933e73fa | 76 | |
323fb88d UD |
77 | int use_translit; /* Nonzero if the mb*towv*() and wc*tomb() |
78 | functions should use transliteration. */ | |
323fb88d | 79 | |
19bc17a9 RM |
80 | unsigned int nstrings; /* Number of strings below. */ |
81 | union locale_data_value | |
82 | { | |
4b10dd6c | 83 | const uint32_t *wstr; |
19bc17a9 | 84 | const char *string; |
54789f38 | 85 | unsigned int word; /* Note endian issues vs 64-bit pointers. */ |
19bc17a9 | 86 | } |
a7cdbcb8 | 87 | values __flexarr; /* Items, usually pointers into `filedata'. */ |
19bc17a9 RM |
88 | }; |
89 | ||
975569d0 JM |
90 | /* This alignment is used for 32-bit integers in locale files, both |
91 | those that are explicitly int32_t or uint32_t and those that are | |
92 | wchar_t, regardless of the (possibly smaller) alignment required | |
93 | for such integers on a particular host. */ | |
94 | #define LOCFILE_ALIGN sizeof (int32_t) | |
95 | #define LOCFILE_ALIGN_MASK (LOCFILE_ALIGN - 1) | |
96 | #define LOCFILE_ALIGN_UP(x) (((x) + LOCFILE_ALIGN - 1) \ | |
97 | & ~LOCFILE_ALIGN_MASK) | |
98 | #define LOCFILE_ALIGNED_P(x) (((x) & LOCFILE_ALIGN_MASK) == 0) | |
99 | ||
19bc17a9 RM |
100 | /* We know three kinds of collation sorting rules. */ |
101 | enum coll_sort_rule | |
102 | { | |
103 | illegal_0__, | |
104 | sort_forward, | |
105 | sort_backward, | |
106 | illegal_3__, | |
107 | sort_position, | |
108 | sort_forward_position, | |
109 | sort_backward_position, | |
110 | sort_mask | |
111 | }; | |
112 | ||
ec4b0518 | 113 | /* We can map the types of the entries into a few categories. */ |
19bc17a9 RM |
114 | enum value_type |
115 | { | |
116 | none, | |
117 | string, | |
118 | stringarray, | |
119 | byte, | |
120 | bytearray, | |
51702635 | 121 | word, |
4b10dd6c | 122 | stringlist, |
beaaf574 UD |
123 | wordarray, |
124 | wstring, | |
125 | wstringarray, | |
126 | wstringlist | |
19bc17a9 | 127 | }; |
933e73fa RM |
128 | |
129 | ||
9bae8b00 UD |
130 | /* Definitions for `era' information from LC_TIME. */ |
131 | #define ERA_NAME_FORMAT_MEMBERS 4 | |
132 | #define ERA_M_NAME 0 | |
133 | #define ERA_M_FORMAT 1 | |
134 | #define ERA_W_NAME 2 | |
135 | #define ERA_W_FORMAT 3 | |
136 | ||
137 | ||
c4029823 UD |
138 | /* Structure to access `era' information from LC_TIME. */ |
139 | struct era_entry | |
140 | { | |
4b10dd6c | 141 | uint32_t direction; /* Contains '+' or '-'. */ |
c4029823 UD |
142 | int32_t offset; |
143 | int32_t start_date[3]; | |
144 | int32_t stop_date[3]; | |
958d6807 UD |
145 | const char *era_name; |
146 | const char *era_format; | |
147 | const wchar_t *era_wname; | |
148 | const wchar_t *era_wformat; | |
149 | int absolute_direction; | |
150 | /* absolute direction: | |
151 | +1 indicates that year number is higher in the future. (like A.D.) | |
152 | -1 indicates that year number is higher in the past. (like B.C.) */ | |
c4029823 UD |
153 | }; |
154 | ||
df9f41c9 | 155 | /* Structure caching computed data about information from LC_TIME. |
f095bb72 | 156 | The `private.time' member of `struct __locale_data' points to this. */ |
df9f41c9 RM |
157 | struct lc_time_data |
158 | { | |
159 | struct era_entry *eras; | |
160 | size_t num_eras; | |
161 | int era_initialized; | |
162 | ||
163 | const char **alt_digits; | |
164 | const wchar_t **walt_digits; | |
1e05e2a9 UD |
165 | int alt_digits_initialized; |
166 | int walt_digits_initialized; | |
df9f41c9 RM |
167 | }; |
168 | ||
c4029823 | 169 | |
5e463393 UD |
170 | /* LC_CTYPE specific: |
171 | Hardwired indices for standard wide character translation mappings. */ | |
172 | enum | |
173 | { | |
174 | __TOW_toupper = 0, | |
175 | __TOW_tolower = 1 | |
176 | }; | |
177 | ||
178 | ||
8fb81470 UD |
179 | /* LC_CTYPE specific: |
180 | Access a wide character class with a single character index. | |
181 | _ISCTYPE (c, desc) = iswctype (btowc (c), desc). | |
182 | c must be an `unsigned char'. desc must be a nonzero wctype_t. */ | |
183 | #define _ISCTYPE(c, desc) \ | |
184 | (((((const uint32_t *) (desc)) - 8)[(c) >> 5] >> ((c) & 0x1f)) & 1) | |
185 | ||
de18a706 FW |
186 | /* Category name handling variables. Concatenate all the strings in a |
187 | single object to minimize relocations. Individual strings can be | |
188 | accessed using _nl_category_names. */ | |
9446614c UD |
189 | #define CATNAMEMF(line) CATNAMEMF1 (line) |
190 | #define CATNAMEMF1(line) str##line | |
de18a706 | 191 | extern const struct catnamestr_t |
9446614c | 192 | { |
9446614c | 193 | #define DEFINE_CATEGORY(category, category_name, items, a) \ |
de18a706 | 194 | char CATNAMEMF (__LINE__)[sizeof (category_name)]; |
9446614c UD |
195 | #include "categories.def" |
196 | #undef DEFINE_CATEGORY | |
9446614c | 197 | } _nl_category_names attribute_hidden; |
715d43fe | 198 | extern const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden; |
9446614c | 199 | extern const uint8_t _nl_category_name_sizes[__LC_LAST] attribute_hidden; |
933e73fa | 200 | |
de18a706 FW |
201 | /* Return the name of the category INDEX, which must be nonnegative |
202 | and less than _LC_LAST. */ | |
203 | static inline const char * | |
204 | _nl_category_names_get (int index) | |
205 | { | |
206 | return (const char *) &_nl_category_names + _nl_category_name_idxs[index]; | |
207 | } | |
208 | ||
a2b08ee5 | 209 | /* Name of the standard locales. */ |
418f1701 UD |
210 | extern const char _nl_C_name[] attribute_hidden; |
211 | extern const char _nl_POSIX_name[] attribute_hidden; | |
7a12c6bb | 212 | |
e7f21fa6 | 213 | /* The standard codeset. */ |
418f1701 | 214 | extern const char _nl_C_codeset[] attribute_hidden; |
e7f21fa6 | 215 | |
1a0d874e RM |
216 | /* This is the internal locale_t object that holds the global locale |
217 | controlled by calls to setlocale. A thread's TSD locale pointer | |
218 | points to this when `uselocale (LC_GLOBAL_LOCALE)' is in effect. */ | |
219 | extern struct __locale_struct _nl_global_locale attribute_hidden; | |
220 | ||
221 | /* This fetches the thread-local locale_t pointer, either one set with | |
222 | uselocale or &_nl_global_locale. */ | |
af85385f | 223 | #define _NL_CURRENT_LOCALE (__libc_tsd_get (locale_t, LOCALE)) |
02d55fe0 | 224 | #include <libc-tsd.h> |
af85385f | 225 | __libc_tsd_define (extern, locale_t, LOCALE) |
cb09a2cd | 226 | |
30c14c31 | 227 | |
1a0d874e RM |
228 | /* For static linking it is desireable to avoid always linking in the code |
229 | and data for every category when we can tell at link time that they are | |
230 | unused. We can manage this playing some tricks with weak references. | |
231 | But with thread-local locale settings, it becomes quite ungainly unless | |
232 | we can use __thread variables. So only in that case do we attempt this. */ | |
a0da5fe1 | 233 | #ifndef SHARED |
1a0d874e | 234 | # include <tls.h> |
11bf311e | 235 | # define NL_CURRENT_INDIRECT 1 |
1a0d874e RM |
236 | #endif |
237 | ||
238 | #ifdef NL_CURRENT_INDIRECT | |
239 | ||
240 | /* For each category declare the thread-local variable for the current | |
241 | locale data. This has an extra indirection so it points at the | |
242 | __locales[CATEGORY] element in either _nl_global_locale or the current | |
243 | locale object set by uselocale, which points at the actual data. The | |
244 | reason for having these variables is so that references to particular | |
245 | categories will link in the lc-CATEGORY.c module to define this symbol, | |
246 | and we arrange that linking that module is what brings in all the code | |
247 | associated with this category. */ | |
30c14c31 | 248 | #define DEFINE_CATEGORY(category, category_name, items, a) \ |
f095bb72 | 249 | extern __thread struct __locale_data *const *_nl_current_##category \ |
556a97c1 | 250 | attribute_hidden attribute_tls_model_ie; |
30c14c31 RM |
251 | #include "categories.def" |
252 | #undef DEFINE_CATEGORY | |
30c14c31 | 253 | |
f095bb72 | 254 | /* Return a pointer to the current `struct __locale_data' for CATEGORY. */ |
1a0d874e | 255 | #define _NL_CURRENT_DATA(category) (*_nl_current_##category) |
174d73a3 | 256 | |
933e73fa RM |
257 | /* Extract the current CATEGORY locale's string for ITEM. */ |
258 | #define _NL_CURRENT(category, item) \ | |
1a0d874e | 259 | ((*_nl_current_##category)->values[_NL_ITEM_INDEX (item)].string) |
4b10dd6c UD |
260 | |
261 | /* Extract the current CATEGORY locale's string for ITEM. */ | |
262 | #define _NL_CURRENT_WSTR(category, item) \ | |
1a0d874e | 263 | ((wchar_t *) (*_nl_current_##category)->values[_NL_ITEM_INDEX (item)].wstr) |
19bc17a9 RM |
264 | |
265 | /* Extract the current CATEGORY locale's word for ITEM. */ | |
266 | #define _NL_CURRENT_WORD(category, item) \ | |
5d0bbaaf | 267 | ((uint32_t) (*_nl_current_##category)->values[_NL_ITEM_INDEX (item)].word) |
933e73fa | 268 | |
5fa26823 SL |
269 | /* This is used in lc-CATEGORY.c to define _nl_current_CATEGORY. The symbol |
270 | _nl_current_CATEGORY_used is set to a value unequal to zero to mark this | |
271 | category as used. On S390 the used relocation to load the symbol address | |
272 | can only handle even addresses. */ | |
933e73fa | 273 | #define _NL_CURRENT_DEFINE(category) \ |
f095bb72 | 274 | __thread struct __locale_data *const *_nl_current_##category \ |
1a0d874e | 275 | attribute_hidden = &_nl_global_locale.__locales[category]; \ |
7b8e0d49 | 276 | asm (".globl " __SYMBOL_PREFIX "_nl_current_" #category "_used\n" \ |
5fa26823 | 277 | _NL_CURRENT_DEFINE_ABS (_nl_current_##category##_used, 2)); |
1a0d874e RM |
278 | #ifdef HAVE_ASM_SET_DIRECTIVE |
279 | # define _NL_CURRENT_DEFINE_ABS(sym, val) ".set " #sym ", " #val | |
280 | #else | |
281 | # define _NL_CURRENT_DEFINE_ABS(sym, val) #sym " = " #val | |
282 | #endif | |
933e73fa | 283 | |
30c14c31 RM |
284 | #else |
285 | ||
286 | /* All categories are always loaded in the shared library, so there is no | |
287 | point in having lots of separate symbols for linking. */ | |
288 | ||
f095bb72 | 289 | /* Return a pointer to the current `struct __locale_data' for CATEGORY. */ |
30c14c31 RM |
290 | # define _NL_CURRENT_DATA(category) \ |
291 | (_NL_CURRENT_LOCALE->__locales[category]) | |
292 | ||
293 | /* Extract the current CATEGORY locale's string for ITEM. */ | |
294 | # define _NL_CURRENT(category, item) \ | |
295 | (_NL_CURRENT_DATA (category)->values[_NL_ITEM_INDEX (item)].string) | |
296 | ||
297 | /* Extract the current CATEGORY locale's string for ITEM. */ | |
298 | # define _NL_CURRENT_WSTR(category, item) \ | |
299 | ((wchar_t *) _NL_CURRENT_DATA (category)->values[_NL_ITEM_INDEX (item)].wstr) | |
300 | ||
301 | /* Extract the current CATEGORY locale's word for ITEM. */ | |
302 | # define _NL_CURRENT_WORD(category, item) \ | |
5d0bbaaf | 303 | ((uint32_t) _NL_CURRENT_DATA (category)->values[_NL_ITEM_INDEX (item)].word) |
30c14c31 RM |
304 | |
305 | /* This is used in lc-CATEGORY.c to define _nl_current_CATEGORY. */ | |
306 | # define _NL_CURRENT_DEFINE(category) \ | |
307 | /* No per-category variable here. */ | |
308 | ||
309 | #endif | |
310 | ||
985fc132 FW |
311 | /* Extract CATEGORY locale's string for ITEM. */ |
312 | static inline const char * | |
313 | _nl_lookup (locale_t l, int category, int item) | |
314 | { | |
315 | return l->__locales[category]->values[_NL_ITEM_INDEX (item)].string; | |
316 | } | |
317 | ||
318 | /* Extract CATEGORY locale's wide string for ITEM. */ | |
319 | static inline const wchar_t * | |
320 | _nl_lookup_wstr (locale_t l, int category, int item) | |
321 | { | |
322 | return (wchar_t *) l->__locales[category] | |
323 | ->values[_NL_ITEM_INDEX (item)].wstr; | |
324 | } | |
325 | ||
326 | /* Extract the CATEGORY locale's word for ITEM. */ | |
327 | static inline uint32_t | |
328 | _nl_lookup_word (locale_t l, int category, int item) | |
329 | { | |
330 | return l->__locales[category]->values[_NL_ITEM_INDEX (item)].word; | |
331 | } | |
30c14c31 | 332 | |
cb09a2cd RM |
333 | /* Default search path if no LOCPATH environment variable. */ |
334 | extern const char _nl_default_locale_path[] attribute_hidden; | |
335 | ||
933e73fa | 336 | /* Load the locale data for CATEGORY from the file specified by *NAME. |
cb09a2cd RM |
337 | If *NAME is "", use environment variables as specified by POSIX, and |
338 | fill in *NAME with the actual name used. If LOCALE_PATH is not null, | |
339 | those directories are searched for the locale files. If it's null, | |
340 | the locale archive is checked first and then _nl_default_locale_path | |
341 | is searched for locale files. */ | |
f095bb72 UD |
342 | extern struct __locale_data *_nl_find_locale (const char *locale_path, |
343 | size_t locale_path_len, | |
344 | int category, const char **name) | |
d7ccc6c9 | 345 | attribute_hidden; |
933e73fa | 346 | |
7a12c6bb | 347 | /* Try to load the file described by FILE. */ |
cb09a2cd | 348 | extern void _nl_load_locale (struct loaded_l10nfile *file, int category) |
d7ccc6c9 | 349 | attribute_hidden; |
28f540f4 | 350 | |
a5a0310d | 351 | /* Free all resource. */ |
d7ccc6c9 | 352 | extern void _nl_unload_locale (struct __locale_data *locale) attribute_hidden; |
a5a0310d | 353 | |
c84142e8 | 354 | /* Free the locale and give back all memory if the usage count is one. */ |
f095bb72 | 355 | extern void _nl_remove_locale (int locale, struct __locale_data *data) |
d7ccc6c9 | 356 | attribute_hidden; |
cb09a2cd RM |
357 | |
358 | /* Find the locale *NAMEP in the locale archive, and return the | |
359 | internalized data structure for its CATEGORY data. If this locale has | |
360 | already been loaded from the archive, just returns the existing data | |
361 | structure. If successful, sets *NAMEP to point directly into the mapped | |
362 | archive string table; that way, the next call can short-circuit strcmp. */ | |
f095bb72 UD |
363 | extern struct __locale_data *_nl_load_locale_from_archive (int category, |
364 | const char **namep) | |
d7ccc6c9 | 365 | attribute_hidden; |
cb09a2cd | 366 | |
a89a3dab | 367 | /* Subroutine of setlocale's __libc_subfreeres hook. */ |
f4c16cee | 368 | extern void _nl_archive_subfreeres (void) attribute_hidden; |
a89a3dab | 369 | |
7c11c4a1 UD |
370 | /* Subroutine of gconv-db's __libc_subfreeres hook. */ |
371 | extern void _nl_locale_subfreeres (void) attribute_hidden; | |
372 | ||
cb09a2cd RM |
373 | /* Validate the contents of a locale file and set up the in-core |
374 | data structure to point into the data. This leaves the `alloc' | |
375 | and `name' fields uninitialized, for the caller to fill in. | |
376 | If any bogons are detected in the data, this will refuse to | |
377 | intern it, and return a null pointer instead. */ | |
f095bb72 UD |
378 | extern struct __locale_data *_nl_intern_locale_data (int category, |
379 | const void *data, | |
380 | size_t datasize) | |
d7ccc6c9 | 381 | attribute_hidden; |
c84142e8 | 382 | |
19bc17a9 | 383 | |
c4029823 | 384 | /* Return `era' entry which corresponds to TP. Used in strftime. */ |
df9f41c9 | 385 | extern struct era_entry *_nl_get_era_entry (const struct tm *tp, |
f095bb72 | 386 | struct __locale_data *lc_time) |
d7ccc6c9 | 387 | attribute_hidden; |
c4029823 | 388 | |
958d6807 | 389 | /* Return `era' cnt'th entry . Used in strptime. */ |
df9f41c9 | 390 | extern struct era_entry *_nl_select_era_entry (int cnt, |
f095bb72 | 391 | struct __locale_data *lc_time) |
d7ccc6c9 | 392 | attribute_hidden; |
9bae8b00 | 393 | |
c4029823 | 394 | /* Return `alt_digit' which corresponds to NUMBER. Used in strftime. */ |
df9f41c9 | 395 | extern const char *_nl_get_alt_digit (unsigned int number, |
f095bb72 | 396 | struct __locale_data *lc_time) |
d7ccc6c9 | 397 | attribute_hidden; |
c4029823 | 398 | |
4b10dd6c | 399 | /* Similar, but now for wide characters. */ |
df9f41c9 | 400 | extern const wchar_t *_nl_get_walt_digit (unsigned int number, |
f095bb72 | 401 | struct __locale_data *lc_time) |
d7ccc6c9 | 402 | attribute_hidden; |
4b10dd6c | 403 | |
2b15132f | 404 | /* Parse string as alternative digit and return numeric value. */ |
df9f41c9 | 405 | extern int _nl_parse_alt_digit (const char **strp, |
f095bb72 | 406 | struct __locale_data *lc_time) |
d7ccc6c9 | 407 | attribute_hidden; |
2b15132f | 408 | |
72f70279 AJ |
409 | /* Postload processing. */ |
410 | extern void _nl_postload_ctype (void); | |
df9f41c9 RM |
411 | |
412 | /* Functions used for the `private.cleanup' hook. */ | |
d7ccc6c9 | 413 | extern void _nl_cleanup_time (struct __locale_data *) attribute_hidden; |
72f70279 AJ |
414 | |
415 | ||
933e73fa | 416 | #endif /* localeinfo.h */ |