]>
Commit | Line | Data |
---|---|---|
4b10dd6c | 1 | /* Declarations for internal libc locale interfaces |
bfff8b1b | 2 | Copyright (C) 1995-2017 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 PE |
16 | License along with the GNU C Library; if not, see |
17 | <http://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 | ||
9446614c UD |
186 | /* Category name handling variables. */ |
187 | #define CATNAMEMF(line) CATNAMEMF1 (line) | |
188 | #define CATNAMEMF1(line) str##line | |
189 | extern const union catnamestr_t | |
190 | { | |
191 | struct | |
192 | { | |
193 | #define DEFINE_CATEGORY(category, category_name, items, a) \ | |
194 | char CATNAMEMF (__LINE__)[sizeof (category_name)]; | |
195 | #include "categories.def" | |
196 | #undef DEFINE_CATEGORY | |
197 | }; | |
198 | char str[0]; | |
199 | } _nl_category_names attribute_hidden; | |
715d43fe | 200 | extern const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden; |
9446614c | 201 | extern const uint8_t _nl_category_name_sizes[__LC_LAST] attribute_hidden; |
933e73fa | 202 | |
a2b08ee5 | 203 | /* Name of the standard locales. */ |
418f1701 UD |
204 | extern const char _nl_C_name[] attribute_hidden; |
205 | extern const char _nl_POSIX_name[] attribute_hidden; | |
7a12c6bb | 206 | |
e7f21fa6 | 207 | /* The standard codeset. */ |
418f1701 | 208 | extern const char _nl_C_codeset[] attribute_hidden; |
e7f21fa6 | 209 | |
1a0d874e RM |
210 | /* This is the internal locale_t object that holds the global locale |
211 | controlled by calls to setlocale. A thread's TSD locale pointer | |
212 | points to this when `uselocale (LC_GLOBAL_LOCALE)' is in effect. */ | |
213 | extern struct __locale_struct _nl_global_locale attribute_hidden; | |
214 | ||
215 | /* This fetches the thread-local locale_t pointer, either one set with | |
216 | uselocale or &_nl_global_locale. */ | |
af85385f | 217 | #define _NL_CURRENT_LOCALE (__libc_tsd_get (locale_t, LOCALE)) |
02d55fe0 | 218 | #include <libc-tsd.h> |
af85385f | 219 | __libc_tsd_define (extern, locale_t, LOCALE) |
cb09a2cd | 220 | |
30c14c31 | 221 | |
1a0d874e RM |
222 | /* For static linking it is desireable to avoid always linking in the code |
223 | and data for every category when we can tell at link time that they are | |
224 | unused. We can manage this playing some tricks with weak references. | |
225 | But with thread-local locale settings, it becomes quite ungainly unless | |
226 | we can use __thread variables. So only in that case do we attempt this. */ | |
a0da5fe1 | 227 | #ifndef SHARED |
1a0d874e | 228 | # include <tls.h> |
11bf311e | 229 | # define NL_CURRENT_INDIRECT 1 |
1a0d874e RM |
230 | #endif |
231 | ||
232 | #ifdef NL_CURRENT_INDIRECT | |
233 | ||
234 | /* For each category declare the thread-local variable for the current | |
235 | locale data. This has an extra indirection so it points at the | |
236 | __locales[CATEGORY] element in either _nl_global_locale or the current | |
237 | locale object set by uselocale, which points at the actual data. The | |
238 | reason for having these variables is so that references to particular | |
239 | categories will link in the lc-CATEGORY.c module to define this symbol, | |
240 | and we arrange that linking that module is what brings in all the code | |
241 | associated with this category. */ | |
30c14c31 | 242 | #define DEFINE_CATEGORY(category, category_name, items, a) \ |
f095bb72 | 243 | extern __thread struct __locale_data *const *_nl_current_##category \ |
556a97c1 | 244 | attribute_hidden attribute_tls_model_ie; |
30c14c31 RM |
245 | #include "categories.def" |
246 | #undef DEFINE_CATEGORY | |
30c14c31 | 247 | |
f095bb72 | 248 | /* Return a pointer to the current `struct __locale_data' for CATEGORY. */ |
1a0d874e | 249 | #define _NL_CURRENT_DATA(category) (*_nl_current_##category) |
174d73a3 | 250 | |
933e73fa RM |
251 | /* Extract the current CATEGORY locale's string for ITEM. */ |
252 | #define _NL_CURRENT(category, item) \ | |
1a0d874e | 253 | ((*_nl_current_##category)->values[_NL_ITEM_INDEX (item)].string) |
4b10dd6c UD |
254 | |
255 | /* Extract the current CATEGORY locale's string for ITEM. */ | |
256 | #define _NL_CURRENT_WSTR(category, item) \ | |
1a0d874e | 257 | ((wchar_t *) (*_nl_current_##category)->values[_NL_ITEM_INDEX (item)].wstr) |
19bc17a9 RM |
258 | |
259 | /* Extract the current CATEGORY locale's word for ITEM. */ | |
260 | #define _NL_CURRENT_WORD(category, item) \ | |
5d0bbaaf | 261 | ((uint32_t) (*_nl_current_##category)->values[_NL_ITEM_INDEX (item)].word) |
933e73fa | 262 | |
5fa26823 SL |
263 | /* This is used in lc-CATEGORY.c to define _nl_current_CATEGORY. The symbol |
264 | _nl_current_CATEGORY_used is set to a value unequal to zero to mark this | |
265 | category as used. On S390 the used relocation to load the symbol address | |
266 | can only handle even addresses. */ | |
933e73fa | 267 | #define _NL_CURRENT_DEFINE(category) \ |
f095bb72 | 268 | __thread struct __locale_data *const *_nl_current_##category \ |
1a0d874e | 269 | attribute_hidden = &_nl_global_locale.__locales[category]; \ |
7b8e0d49 | 270 | asm (".globl " __SYMBOL_PREFIX "_nl_current_" #category "_used\n" \ |
5fa26823 | 271 | _NL_CURRENT_DEFINE_ABS (_nl_current_##category##_used, 2)); |
1a0d874e RM |
272 | #ifdef HAVE_ASM_SET_DIRECTIVE |
273 | # define _NL_CURRENT_DEFINE_ABS(sym, val) ".set " #sym ", " #val | |
274 | #else | |
275 | # define _NL_CURRENT_DEFINE_ABS(sym, val) #sym " = " #val | |
276 | #endif | |
933e73fa | 277 | |
30c14c31 RM |
278 | #else |
279 | ||
280 | /* All categories are always loaded in the shared library, so there is no | |
281 | point in having lots of separate symbols for linking. */ | |
282 | ||
f095bb72 | 283 | /* Return a pointer to the current `struct __locale_data' for CATEGORY. */ |
30c14c31 RM |
284 | # define _NL_CURRENT_DATA(category) \ |
285 | (_NL_CURRENT_LOCALE->__locales[category]) | |
286 | ||
287 | /* Extract the current CATEGORY locale's string for ITEM. */ | |
288 | # define _NL_CURRENT(category, item) \ | |
289 | (_NL_CURRENT_DATA (category)->values[_NL_ITEM_INDEX (item)].string) | |
290 | ||
291 | /* Extract the current CATEGORY locale's string for ITEM. */ | |
292 | # define _NL_CURRENT_WSTR(category, item) \ | |
293 | ((wchar_t *) _NL_CURRENT_DATA (category)->values[_NL_ITEM_INDEX (item)].wstr) | |
294 | ||
295 | /* Extract the current CATEGORY locale's word for ITEM. */ | |
296 | # define _NL_CURRENT_WORD(category, item) \ | |
5d0bbaaf | 297 | ((uint32_t) _NL_CURRENT_DATA (category)->values[_NL_ITEM_INDEX (item)].word) |
30c14c31 RM |
298 | |
299 | /* This is used in lc-CATEGORY.c to define _nl_current_CATEGORY. */ | |
300 | # define _NL_CURRENT_DEFINE(category) \ | |
301 | /* No per-category variable here. */ | |
302 | ||
303 | #endif | |
304 | ||
985fc132 FW |
305 | /* Extract CATEGORY locale's string for ITEM. */ |
306 | static inline const char * | |
307 | _nl_lookup (locale_t l, int category, int item) | |
308 | { | |
309 | return l->__locales[category]->values[_NL_ITEM_INDEX (item)].string; | |
310 | } | |
311 | ||
312 | /* Extract CATEGORY locale's wide string for ITEM. */ | |
313 | static inline const wchar_t * | |
314 | _nl_lookup_wstr (locale_t l, int category, int item) | |
315 | { | |
316 | return (wchar_t *) l->__locales[category] | |
317 | ->values[_NL_ITEM_INDEX (item)].wstr; | |
318 | } | |
319 | ||
320 | /* Extract the CATEGORY locale's word for ITEM. */ | |
321 | static inline uint32_t | |
322 | _nl_lookup_word (locale_t l, int category, int item) | |
323 | { | |
324 | return l->__locales[category]->values[_NL_ITEM_INDEX (item)].word; | |
325 | } | |
30c14c31 | 326 | |
cb09a2cd RM |
327 | /* Default search path if no LOCPATH environment variable. */ |
328 | extern const char _nl_default_locale_path[] attribute_hidden; | |
329 | ||
933e73fa | 330 | /* Load the locale data for CATEGORY from the file specified by *NAME. |
cb09a2cd RM |
331 | If *NAME is "", use environment variables as specified by POSIX, and |
332 | fill in *NAME with the actual name used. If LOCALE_PATH is not null, | |
333 | those directories are searched for the locale files. If it's null, | |
334 | the locale archive is checked first and then _nl_default_locale_path | |
335 | is searched for locale files. */ | |
f095bb72 UD |
336 | extern struct __locale_data *_nl_find_locale (const char *locale_path, |
337 | size_t locale_path_len, | |
338 | int category, const char **name) | |
d7ccc6c9 | 339 | attribute_hidden; |
933e73fa | 340 | |
7a12c6bb | 341 | /* Try to load the file described by FILE. */ |
cb09a2cd | 342 | extern void _nl_load_locale (struct loaded_l10nfile *file, int category) |
d7ccc6c9 | 343 | attribute_hidden; |
28f540f4 | 344 | |
a5a0310d | 345 | /* Free all resource. */ |
d7ccc6c9 | 346 | extern void _nl_unload_locale (struct __locale_data *locale) attribute_hidden; |
a5a0310d | 347 | |
c84142e8 | 348 | /* Free the locale and give back all memory if the usage count is one. */ |
f095bb72 | 349 | extern void _nl_remove_locale (int locale, struct __locale_data *data) |
d7ccc6c9 | 350 | attribute_hidden; |
cb09a2cd RM |
351 | |
352 | /* Find the locale *NAMEP in the locale archive, and return the | |
353 | internalized data structure for its CATEGORY data. If this locale has | |
354 | already been loaded from the archive, just returns the existing data | |
355 | structure. If successful, sets *NAMEP to point directly into the mapped | |
356 | archive string table; that way, the next call can short-circuit strcmp. */ | |
f095bb72 UD |
357 | extern struct __locale_data *_nl_load_locale_from_archive (int category, |
358 | const char **namep) | |
d7ccc6c9 | 359 | attribute_hidden; |
cb09a2cd | 360 | |
a89a3dab | 361 | /* Subroutine of setlocale's __libc_subfreeres hook. */ |
f4c16cee | 362 | extern void _nl_archive_subfreeres (void) attribute_hidden; |
a89a3dab | 363 | |
7c11c4a1 UD |
364 | /* Subroutine of gconv-db's __libc_subfreeres hook. */ |
365 | extern void _nl_locale_subfreeres (void) attribute_hidden; | |
366 | ||
cb09a2cd RM |
367 | /* Validate the contents of a locale file and set up the in-core |
368 | data structure to point into the data. This leaves the `alloc' | |
369 | and `name' fields uninitialized, for the caller to fill in. | |
370 | If any bogons are detected in the data, this will refuse to | |
371 | intern it, and return a null pointer instead. */ | |
f095bb72 UD |
372 | extern struct __locale_data *_nl_intern_locale_data (int category, |
373 | const void *data, | |
374 | size_t datasize) | |
d7ccc6c9 | 375 | attribute_hidden; |
c84142e8 | 376 | |
19bc17a9 | 377 | |
c4029823 | 378 | /* Return `era' entry which corresponds to TP. Used in strftime. */ |
df9f41c9 | 379 | extern struct era_entry *_nl_get_era_entry (const struct tm *tp, |
f095bb72 | 380 | struct __locale_data *lc_time) |
d7ccc6c9 | 381 | attribute_hidden; |
c4029823 | 382 | |
958d6807 | 383 | /* Return `era' cnt'th entry . Used in strptime. */ |
df9f41c9 | 384 | extern struct era_entry *_nl_select_era_entry (int cnt, |
f095bb72 | 385 | struct __locale_data *lc_time) |
d7ccc6c9 | 386 | attribute_hidden; |
9bae8b00 | 387 | |
c4029823 | 388 | /* Return `alt_digit' which corresponds to NUMBER. Used in strftime. */ |
df9f41c9 | 389 | extern const char *_nl_get_alt_digit (unsigned int number, |
f095bb72 | 390 | struct __locale_data *lc_time) |
d7ccc6c9 | 391 | attribute_hidden; |
c4029823 | 392 | |
4b10dd6c | 393 | /* Similar, but now for wide characters. */ |
df9f41c9 | 394 | extern const wchar_t *_nl_get_walt_digit (unsigned int number, |
f095bb72 | 395 | struct __locale_data *lc_time) |
d7ccc6c9 | 396 | attribute_hidden; |
4b10dd6c | 397 | |
2b15132f | 398 | /* Parse string as alternative digit and return numeric value. */ |
df9f41c9 | 399 | extern int _nl_parse_alt_digit (const char **strp, |
f095bb72 | 400 | struct __locale_data *lc_time) |
d7ccc6c9 | 401 | attribute_hidden; |
2b15132f | 402 | |
72f70279 AJ |
403 | /* Postload processing. */ |
404 | extern void _nl_postload_ctype (void); | |
df9f41c9 RM |
405 | |
406 | /* Functions used for the `private.cleanup' hook. */ | |
d7ccc6c9 | 407 | extern void _nl_cleanup_time (struct __locale_data *) attribute_hidden; |
72f70279 AJ |
408 | |
409 | ||
933e73fa | 410 | #endif /* localeinfo.h */ |