1 | /* Declarations for internal libc locale interfaces |
2 | Copyright (C) 1995-2016 Free Software Foundation, Inc. |
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 |
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. |
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 |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ |
18 | |
19 | #ifndef _LOCALEINFO_H |
20 | #define _LOCALEINFO_H 1 |
21 | |
22 | #include <stddef.h> |
23 | #include <langinfo.h> |
24 | #include <limits.h> |
25 | #include <locale.h> |
26 | #include <time.h> |
27 | #include <stdint.h> |
28 | #include <sys/types.h> |
29 | |
30 | #include <intl/loadinfo.h> /* For loaded_l10nfile definition. */ |
31 | |
32 | /* Magic number at the beginning of a locale data file for CATEGORY. */ |
33 | #define LIMAGIC(category) \ |
34 | (category == LC_COLLATE \ |
35 | ? ((unsigned int) (0x20051014 ^ (category))) \ |
36 | : category == LC_CTYPE \ |
37 | ? ((unsigned int) (0x20090720 ^ (category))) \ |
38 | : ((unsigned int) (0x20031115 ^ (category)))) |
39 | |
40 | /* Two special weight constants for the collation data. */ |
41 | #define IGNORE_CHAR 2 |
42 | |
43 | /* We use a special value for the usage counter in `__locale_data' to |
44 | signal that this data must never be removed anymore. */ |
45 | #define MAX_USAGE_COUNT (UINT_MAX - 1) |
46 | #define UNDELETABLE UINT_MAX |
47 | |
48 | /* Structure describing locale data in core for a category. */ |
49 | struct __locale_data |
50 | { |
51 | const char *name; |
52 | const char *filedata; /* Region mapping the file data. */ |
53 | off_t filesize; /* Size of the file (and the region). */ |
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; |
60 | |
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 | { |
66 | void (*cleanup) (struct __locale_data *) internal_function; |
67 | union |
68 | { |
69 | void *data; |
70 | struct lc_time_data *time; |
71 | const struct gconv_fcts *ctype; |
72 | }; |
73 | } private; |
74 | |
75 | unsigned int usage_count; /* Counter for users. */ |
76 | |
77 | int use_translit; /* Nonzero if the mb*towv*() and wc*tomb() |
78 | functions should use transliteration. */ |
79 | |
80 | unsigned int nstrings; /* Number of strings below. */ |
81 | union locale_data_value |
82 | { |
83 | const uint32_t *wstr; |
84 | const char *string; |
85 | unsigned int word; /* Note endian issues vs 64-bit pointers. */ |
86 | } |
87 | values __flexarr; /* Items, usually pointers into `filedata'. */ |
88 | }; |
89 | |
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 | |
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 | |
113 | /* We can map the types of the entries into a few categories. */ |
114 | enum value_type |
115 | { |
116 | none, |
117 | string, |
118 | stringarray, |
119 | byte, |
120 | bytearray, |
121 | word, |
122 | stringlist, |
123 | wordarray, |
124 | wstring, |
125 | wstringarray, |
126 | wstringlist |
127 | }; |
128 | |
129 | |
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 | |
138 | /* Structure to access `era' information from LC_TIME. */ |
139 | struct era_entry |
140 | { |
141 | uint32_t direction; /* Contains '+' or '-'. */ |
142 | int32_t offset; |
143 | int32_t start_date[3]; |
144 | int32_t stop_date[3]; |
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.) */ |
153 | }; |
154 | |
155 | /* Structure caching computed data about information from LC_TIME. |
156 | The `private.time' member of `struct __locale_data' points to this. */ |
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; |
165 | int alt_digits_initialized; |
166 | int walt_digits_initialized; |
167 | }; |
168 | |
169 | |
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 | |
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 | |
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; |
200 | extern const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden; |
201 | extern const uint8_t _nl_category_name_sizes[__LC_LAST] attribute_hidden; |
202 | |
203 | /* Name of the standard locales. */ |
204 | extern const char _nl_C_name[] attribute_hidden; |
205 | extern const char _nl_POSIX_name[] attribute_hidden; |
206 | |
207 | /* The standard codeset. */ |
208 | extern const char _nl_C_codeset[] attribute_hidden; |
209 | |
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. */ |
217 | #define _NL_CURRENT_LOCALE (__libc_tsd_get (__locale_t, LOCALE)) |
218 | #include <libc-tsd.h> |
219 | __libc_tsd_define (extern, __locale_t, LOCALE) |
220 | |
221 | |
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. */ |
227 | #ifndef SHARED |
228 | # include <tls.h> |
229 | # define NL_CURRENT_INDIRECT 1 |
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. */ |
242 | #define DEFINE_CATEGORY(category, category_name, items, a) \ |
243 | extern __thread struct __locale_data *const *_nl_current_##category \ |
244 | attribute_hidden attribute_tls_model_ie; |
245 | #include "categories.def" |
246 | #undef DEFINE_CATEGORY |
247 | |
248 | /* Return a pointer to the current `struct __locale_data' for CATEGORY. */ |
249 | #define _NL_CURRENT_DATA(category) (*_nl_current_##category) |
250 | |
251 | /* Extract the current CATEGORY locale's string for ITEM. */ |
252 | #define _NL_CURRENT(category, item) \ |
253 | ((*_nl_current_##category)->values[_NL_ITEM_INDEX (item)].string) |
254 | |
255 | /* Extract the current CATEGORY locale's string for ITEM. */ |
256 | #define _NL_CURRENT_WSTR(category, item) \ |
257 | ((wchar_t *) (*_nl_current_##category)->values[_NL_ITEM_INDEX (item)].wstr) |
258 | |
259 | /* Extract the current CATEGORY locale's word for ITEM. */ |
260 | #define _NL_CURRENT_WORD(category, item) \ |
261 | ((uint32_t) (*_nl_current_##category)->values[_NL_ITEM_INDEX (item)].word) |
262 | |
263 | /* This is used in lc-CATEGORY.c to define _nl_current_CATEGORY. */ |
264 | #define _NL_CURRENT_DEFINE(category) \ |
265 | __thread struct __locale_data *const *_nl_current_##category \ |
266 | attribute_hidden = &_nl_global_locale.__locales[category]; \ |
267 | asm (".globl " __SYMBOL_PREFIX "_nl_current_" #category "_used\n" \ |
268 | _NL_CURRENT_DEFINE_ABS (_nl_current_##category##_used, 1)); |
269 | #ifdef HAVE_ASM_SET_DIRECTIVE |
270 | # define _NL_CURRENT_DEFINE_ABS(sym, val) ".set " #sym ", " #val |
271 | #else |
272 | # define _NL_CURRENT_DEFINE_ABS(sym, val) #sym " = " #val |
273 | #endif |
274 | |
275 | #else |
276 | |
277 | /* All categories are always loaded in the shared library, so there is no |
278 | point in having lots of separate symbols for linking. */ |
279 | |
280 | /* Return a pointer to the current `struct __locale_data' for CATEGORY. */ |
281 | # define _NL_CURRENT_DATA(category) \ |
282 | (_NL_CURRENT_LOCALE->__locales[category]) |
283 | |
284 | /* Extract the current CATEGORY locale's string for ITEM. */ |
285 | # define _NL_CURRENT(category, item) \ |
286 | (_NL_CURRENT_DATA (category)->values[_NL_ITEM_INDEX (item)].string) |
287 | |
288 | /* Extract the current CATEGORY locale's string for ITEM. */ |
289 | # define _NL_CURRENT_WSTR(category, item) \ |
290 | ((wchar_t *) _NL_CURRENT_DATA (category)->values[_NL_ITEM_INDEX (item)].wstr) |
291 | |
292 | /* Extract the current CATEGORY locale's word for ITEM. */ |
293 | # define _NL_CURRENT_WORD(category, item) \ |
294 | ((uint32_t) _NL_CURRENT_DATA (category)->values[_NL_ITEM_INDEX (item)].word) |
295 | |
296 | /* This is used in lc-CATEGORY.c to define _nl_current_CATEGORY. */ |
297 | # define _NL_CURRENT_DEFINE(category) \ |
298 | /* No per-category variable here. */ |
299 | |
300 | #endif |
301 | |
302 | |
303 | /* Default search path if no LOCPATH environment variable. */ |
304 | extern const char _nl_default_locale_path[] attribute_hidden; |
305 | |
306 | /* Load the locale data for CATEGORY from the file specified by *NAME. |
307 | If *NAME is "", use environment variables as specified by POSIX, and |
308 | fill in *NAME with the actual name used. If LOCALE_PATH is not null, |
309 | those directories are searched for the locale files. If it's null, |
310 | the locale archive is checked first and then _nl_default_locale_path |
311 | is searched for locale files. */ |
312 | extern struct __locale_data *_nl_find_locale (const char *locale_path, |
313 | size_t locale_path_len, |
314 | int category, const char **name) |
315 | internal_function attribute_hidden; |
316 | |
317 | /* Try to load the file described by FILE. */ |
318 | extern void _nl_load_locale (struct loaded_l10nfile *file, int category) |
319 | internal_function attribute_hidden; |
320 | |
321 | /* Free all resource. */ |
322 | extern void _nl_unload_locale (struct __locale_data *locale) |
323 | internal_function attribute_hidden; |
324 | |
325 | /* Free the locale and give back all memory if the usage count is one. */ |
326 | extern void _nl_remove_locale (int locale, struct __locale_data *data) |
327 | internal_function attribute_hidden; |
328 | |
329 | /* Find the locale *NAMEP in the locale archive, and return the |
330 | internalized data structure for its CATEGORY data. If this locale has |
331 | already been loaded from the archive, just returns the existing data |
332 | structure. If successful, sets *NAMEP to point directly into the mapped |
333 | archive string table; that way, the next call can short-circuit strcmp. */ |
334 | extern struct __locale_data *_nl_load_locale_from_archive (int category, |
335 | const char **namep) |
336 | internal_function attribute_hidden; |
337 | |
338 | /* Subroutine of setlocale's __libc_subfreeres hook. */ |
339 | extern void _nl_archive_subfreeres (void) attribute_hidden; |
340 | |
341 | /* Subroutine of gconv-db's __libc_subfreeres hook. */ |
342 | extern void _nl_locale_subfreeres (void) attribute_hidden; |
343 | |
344 | /* Validate the contents of a locale file and set up the in-core |
345 | data structure to point into the data. This leaves the `alloc' |
346 | and `name' fields uninitialized, for the caller to fill in. |
347 | If any bogons are detected in the data, this will refuse to |
348 | intern it, and return a null pointer instead. */ |
349 | extern struct __locale_data *_nl_intern_locale_data (int category, |
350 | const void *data, |
351 | size_t datasize) |
352 | internal_function attribute_hidden; |
353 | |
354 | |
355 | /* Return `era' entry which corresponds to TP. Used in strftime. */ |
356 | extern struct era_entry *_nl_get_era_entry (const struct tm *tp, |
357 | struct __locale_data *lc_time) |
358 | internal_function attribute_hidden; |
359 | |
360 | /* Return `era' cnt'th entry . Used in strptime. */ |
361 | extern struct era_entry *_nl_select_era_entry (int cnt, |
362 | struct __locale_data *lc_time) |
363 | internal_function attribute_hidden; |
364 | |
365 | /* Return `alt_digit' which corresponds to NUMBER. Used in strftime. */ |
366 | extern const char *_nl_get_alt_digit (unsigned int number, |
367 | struct __locale_data *lc_time) |
368 | internal_function attribute_hidden; |
369 | |
370 | /* Similar, but now for wide characters. */ |
371 | extern const wchar_t *_nl_get_walt_digit (unsigned int number, |
372 | struct __locale_data *lc_time) |
373 | internal_function attribute_hidden; |
374 | |
375 | /* Parse string as alternative digit and return numeric value. */ |
376 | extern int _nl_parse_alt_digit (const char **strp, |
377 | struct __locale_data *lc_time) |
378 | internal_function attribute_hidden; |
379 | |
380 | /* Postload processing. */ |
381 | extern void _nl_postload_ctype (void); |
382 | |
383 | /* Functions used for the `private.cleanup' hook. */ |
384 | extern void _nl_cleanup_time (struct __locale_data *) |
385 | internal_function attribute_hidden; |
386 | |
387 | |
388 | #endif /* localeinfo.h */ |
389 | |