blob: bdab9fe74551c54a50b3d9d93517b2617e62ddff [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* Declarations for internal libc locale interfaces
2 Copyright (C) 1995-2015 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. */
49struct __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. */
101enum 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/* Collation encoding type. */
114enum collation_encoding_type
115{
116 __cet_other,
117 __cet_8bit,
118 __cet_utf8
119};
120
121/* We can map the types of the entries into a few categories. */
122enum value_type
123{
124 none,
125 string,
126 stringarray,
127 byte,
128 bytearray,
129 word,
130 stringlist,
131 wordarray,
132 wstring,
133 wstringarray,
134 wstringlist
135};
136
137
138/* Definitions for `era' information from LC_TIME. */
139#define ERA_NAME_FORMAT_MEMBERS 4
140#define ERA_M_NAME 0
141#define ERA_M_FORMAT 1
142#define ERA_W_NAME 2
143#define ERA_W_FORMAT 3
144
145
146/* Structure to access `era' information from LC_TIME. */
147struct era_entry
148{
149 uint32_t direction; /* Contains '+' or '-'. */
150 int32_t offset;
151 int32_t start_date[3];
152 int32_t stop_date[3];
153 const char *era_name;
154 const char *era_format;
155 const wchar_t *era_wname;
156 const wchar_t *era_wformat;
157 int absolute_direction;
158 /* absolute direction:
159 +1 indicates that year number is higher in the future. (like A.D.)
160 -1 indicates that year number is higher in the past. (like B.C.) */
161};
162
163/* Structure caching computed data about information from LC_TIME.
164 The `private.time' member of `struct __locale_data' points to this. */
165struct lc_time_data
166{
167 struct era_entry *eras;
168 size_t num_eras;
169 int era_initialized;
170
171 const char **alt_digits;
172 const wchar_t **walt_digits;
173 int alt_digits_initialized;
174 int walt_digits_initialized;
175};
176
177
178/* LC_CTYPE specific:
179 Hardwired indices for standard wide character translation mappings. */
180enum
181{
182 __TOW_toupper = 0,
183 __TOW_tolower = 1
184};
185
186
187/* LC_CTYPE specific:
188 Access a wide character class with a single character index.
189 _ISCTYPE (c, desc) = iswctype (btowc (c), desc).
190 c must be an `unsigned char'. desc must be a nonzero wctype_t. */
191#define _ISCTYPE(c, desc) \
192 (((((const uint32_t *) (desc)) - 8)[(c) >> 5] >> ((c) & 0x1f)) & 1)
193
194/* Category name handling variables. */
195#define CATNAMEMF(line) CATNAMEMF1 (line)
196#define CATNAMEMF1(line) str##line
197extern const union catnamestr_t
198{
199 struct
200 {
201#define DEFINE_CATEGORY(category, category_name, items, a) \
202 char CATNAMEMF (__LINE__)[sizeof (category_name)];
203#include "categories.def"
204#undef DEFINE_CATEGORY
205 };
206 char str[0];
207} _nl_category_names attribute_hidden;
208extern const uint8_t _nl_category_name_idxs[__LC_LAST] attribute_hidden;
209extern const uint8_t _nl_category_name_sizes[__LC_LAST] attribute_hidden;
210
211/* Name of the standard locales. */
212extern const char _nl_C_name[] attribute_hidden;
213extern const char _nl_POSIX_name[] attribute_hidden;
214
215/* The standard codeset. */
216extern const char _nl_C_codeset[] attribute_hidden;
217
218/* This is the internal locale_t object that holds the global locale
219 controlled by calls to setlocale. A thread's TSD locale pointer
220 points to this when `uselocale (LC_GLOBAL_LOCALE)' is in effect. */
221extern struct __locale_struct _nl_global_locale attribute_hidden;
222
223/* This fetches the thread-local locale_t pointer, either one set with
224 uselocale or &_nl_global_locale. */
225#define _NL_CURRENT_LOCALE (__libc_tsd_get (__locale_t, LOCALE))
226#include <bits/libc-tsd.h>
227__libc_tsd_define (extern, __locale_t, LOCALE)
228
229
230/* For static linking it is desireable to avoid always linking in the code
231 and data for every category when we can tell at link time that they are
232 unused. We can manage this playing some tricks with weak references.
233 But with thread-local locale settings, it becomes quite ungainly unless
234 we can use __thread variables. So only in that case do we attempt this. */
235#ifndef SHARED
236# include <tls.h>
237# define NL_CURRENT_INDIRECT 1
238#endif
239
240#ifdef NL_CURRENT_INDIRECT
241
242/* For each category declare the thread-local variable for the current
243 locale data. This has an extra indirection so it points at the
244 __locales[CATEGORY] element in either _nl_global_locale or the current
245 locale object set by uselocale, which points at the actual data. The
246 reason for having these variables is so that references to particular
247 categories will link in the lc-CATEGORY.c module to define this symbol,
248 and we arrange that linking that module is what brings in all the code
249 associated with this category. */
250#define DEFINE_CATEGORY(category, category_name, items, a) \
251extern __thread struct __locale_data *const *_nl_current_##category \
252 attribute_hidden attribute_tls_model_ie;
253#include "categories.def"
254#undef DEFINE_CATEGORY
255
256/* Return a pointer to the current `struct __locale_data' for CATEGORY. */
257#define _NL_CURRENT_DATA(category) (*_nl_current_##category)
258
259/* Extract the current CATEGORY locale's string for ITEM. */
260#define _NL_CURRENT(category, item) \
261 ((*_nl_current_##category)->values[_NL_ITEM_INDEX (item)].string)
262
263/* Extract the current CATEGORY locale's string for ITEM. */
264#define _NL_CURRENT_WSTR(category, item) \
265 ((wchar_t *) (*_nl_current_##category)->values[_NL_ITEM_INDEX (item)].wstr)
266
267/* Extract the current CATEGORY locale's word for ITEM. */
268#define _NL_CURRENT_WORD(category, item) \
269 ((uint32_t) (*_nl_current_##category)->values[_NL_ITEM_INDEX (item)].word)
270
271/* This is used in lc-CATEGORY.c to define _nl_current_CATEGORY. */
272#define _NL_CURRENT_DEFINE(category) \
273 __thread struct __locale_data *const *_nl_current_##category \
274 attribute_hidden = &_nl_global_locale.__locales[category]; \
275 asm (".globl " __SYMBOL_PREFIX "_nl_current_" #category "_used\n" \
276 _NL_CURRENT_DEFINE_ABS (_nl_current_##category##_used, 1));
277#ifdef HAVE_ASM_SET_DIRECTIVE
278# define _NL_CURRENT_DEFINE_ABS(sym, val) ".set " #sym ", " #val
279#else
280# define _NL_CURRENT_DEFINE_ABS(sym, val) #sym " = " #val
281#endif
282
283#else
284
285/* All categories are always loaded in the shared library, so there is no
286 point in having lots of separate symbols for linking. */
287
288/* Return a pointer to the current `struct __locale_data' for CATEGORY. */
289# define _NL_CURRENT_DATA(category) \
290 (_NL_CURRENT_LOCALE->__locales[category])
291
292/* Extract the current CATEGORY locale's string for ITEM. */
293# define _NL_CURRENT(category, item) \
294 (_NL_CURRENT_DATA (category)->values[_NL_ITEM_INDEX (item)].string)
295
296/* Extract the current CATEGORY locale's string for ITEM. */
297# define _NL_CURRENT_WSTR(category, item) \
298 ((wchar_t *) _NL_CURRENT_DATA (category)->values[_NL_ITEM_INDEX (item)].wstr)
299
300/* Extract the current CATEGORY locale's word for ITEM. */
301# define _NL_CURRENT_WORD(category, item) \
302 ((uint32_t) _NL_CURRENT_DATA (category)->values[_NL_ITEM_INDEX (item)].word)
303
304/* This is used in lc-CATEGORY.c to define _nl_current_CATEGORY. */
305# define _NL_CURRENT_DEFINE(category) \
306 /* No per-category variable here. */
307
308#endif
309
310
311/* Default search path if no LOCPATH environment variable. */
312extern const char _nl_default_locale_path[] attribute_hidden;
313
314/* Load the locale data for CATEGORY from the file specified by *NAME.
315 If *NAME is "", use environment variables as specified by POSIX, and
316 fill in *NAME with the actual name used. If LOCALE_PATH is not null,
317 those directories are searched for the locale files. If it's null,
318 the locale archive is checked first and then _nl_default_locale_path
319 is searched for locale files. */
320extern struct __locale_data *_nl_find_locale (const char *locale_path,
321 size_t locale_path_len,
322 int category, const char **name)
323 internal_function attribute_hidden;
324
325/* Try to load the file described by FILE. */
326extern void _nl_load_locale (struct loaded_l10nfile *file, int category)
327 internal_function attribute_hidden;
328
329/* Free all resource. */
330extern void _nl_unload_locale (struct __locale_data *locale)
331 internal_function attribute_hidden;
332
333/* Free the locale and give back all memory if the usage count is one. */
334extern void _nl_remove_locale (int locale, struct __locale_data *data)
335 internal_function attribute_hidden;
336
337/* Find the locale *NAMEP in the locale archive, and return the
338 internalized data structure for its CATEGORY data. If this locale has
339 already been loaded from the archive, just returns the existing data
340 structure. If successful, sets *NAMEP to point directly into the mapped
341 archive string table; that way, the next call can short-circuit strcmp. */
342extern struct __locale_data *_nl_load_locale_from_archive (int category,
343 const char **namep)
344 internal_function attribute_hidden;
345
346/* Subroutine of setlocale's __libc_subfreeres hook. */
347extern void _nl_archive_subfreeres (void) attribute_hidden;
348
349/* Subroutine of gconv-db's __libc_subfreeres hook. */
350extern void _nl_locale_subfreeres (void) attribute_hidden;
351
352/* Validate the contents of a locale file and set up the in-core
353 data structure to point into the data. This leaves the `alloc'
354 and `name' fields uninitialized, for the caller to fill in.
355 If any bogons are detected in the data, this will refuse to
356 intern it, and return a null pointer instead. */
357extern struct __locale_data *_nl_intern_locale_data (int category,
358 const void *data,
359 size_t datasize)
360 internal_function attribute_hidden;
361
362
363/* Return `era' entry which corresponds to TP. Used in strftime. */
364extern struct era_entry *_nl_get_era_entry (const struct tm *tp,
365 struct __locale_data *lc_time)
366 internal_function attribute_hidden;
367
368/* Return `era' cnt'th entry . Used in strptime. */
369extern struct era_entry *_nl_select_era_entry (int cnt,
370 struct __locale_data *lc_time)
371 internal_function attribute_hidden;
372
373/* Return `alt_digit' which corresponds to NUMBER. Used in strftime. */
374extern const char *_nl_get_alt_digit (unsigned int number,
375 struct __locale_data *lc_time)
376 internal_function attribute_hidden;
377
378/* Similar, but now for wide characters. */
379extern const wchar_t *_nl_get_walt_digit (unsigned int number,
380 struct __locale_data *lc_time)
381 internal_function attribute_hidden;
382
383/* Parse string as alternative digit and return numeric value. */
384extern int _nl_parse_alt_digit (const char **strp,
385 struct __locale_data *lc_time)
386 internal_function attribute_hidden;
387
388/* Postload processing. */
389extern void _nl_postload_ctype (void);
390
391/* Functions used for the `private.cleanup' hook. */
392extern void _nl_cleanup_time (struct __locale_data *)
393 internal_function attribute_hidden;
394
395
396#endif /* localeinfo.h */