2002-11-20 Roland McGrath <roland@redhat.com>
[kopensolaris-gnu/glibc.git] / locale / localeinfo.h
1 /* Declarations for internal libc locale interfaces
2    Copyright (C) 1995-2001, 2002 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, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #ifndef _LOCALEINFO_H
21 #define _LOCALEINFO_H 1
22
23 #include <stddef.h>
24 #include <langinfo.h>
25 #include <limits.h>
26 #include <locale.h>
27 #include <time.h>
28 #include <stdint.h>
29 #include <sys/types.h>
30
31 #include <intl/loadinfo.h>      /* For loaded_l10nfile definition.  */
32
33 /* Magic number at the beginning of a locale data file for CATEGORY.  */
34 #define LIMAGIC(category)       ((unsigned int) (0x20000828 ^ (category)))
35
36 /* Two special weight constants for the collation data.  */
37 #define IGNORE_CHAR     2
38
39 /* We use a special value for the usage counter in `locale_data' to
40    signal that this data must never be removed anymore.  */
41 #define MAX_USAGE_COUNT (UINT_MAX - 1)
42 #define UNDELETABLE     UINT_MAX
43
44 /* Structure describing locale data in core for a category.  */
45 struct locale_data
46 {
47   const char *name;
48   const char *filedata;         /* Region mapping the file data.  */
49   off_t filesize;               /* Size of the file (and the region).  */
50   enum                          /* Flavor of storage used for those.  */
51   {
52     ld_malloced,                /* Both are malloc'd.  */
53     ld_mapped,                  /* name is malloc'd, filedata mmap'd */
54     ld_archive                  /* Both point into mmap'd archive regions.  */
55   } alloc;
56
57   /* This provides a slot for category-specific code to cache data computed
58      about this locale.  That code can set a cleanup function to deallocate
59      the data.  */
60   struct
61   {
62     void (*cleanup) (struct locale_data *) internal_function;
63     union
64     {
65       void *data;
66       struct lc_time_data *time;
67       const struct gconv_fcts *ctype;
68     };
69   } private;
70
71   unsigned int usage_count;     /* Counter for users.  */
72
73   int use_translit;             /* Nonzero if the mb*towv*() and wc*tomb()
74                                    functions should use transliteration.  */
75
76   unsigned int nstrings;        /* Number of strings below.  */
77   union locale_data_value
78   {
79     const uint32_t *wstr;
80     const char *string;
81     /* The values we store here are always uint32_t in fact.  But it's
82        safer for the union to use a type that matches pointers so that
83        casting one of the pointer values to uint32_t produces the right
84        value for big-endian 64-bit platforms.  */
85     uintptr_t word;
86   }
87   values __flexarr;     /* Items, usually pointers into `filedata'.  */
88 };
89
90 /* We know three kinds of collation sorting rules.  */
91 enum coll_sort_rule
92 {
93   illegal_0__,
94   sort_forward,
95   sort_backward,
96   illegal_3__,
97   sort_position,
98   sort_forward_position,
99   sort_backward_position,
100   sort_mask
101 };
102
103 /* We can map the types of the entries into a few categories.  */
104 enum value_type
105 {
106   none,
107   string,
108   stringarray,
109   byte,
110   bytearray,
111   word,
112   stringlist,
113   wordarray,
114   wstring,
115   wstringarray,
116   wstringlist
117 };
118
119
120 /* Definitions for `era' information from LC_TIME.  */
121 #define ERA_NAME_FORMAT_MEMBERS 4
122 #define ERA_M_NAME   0
123 #define ERA_M_FORMAT 1
124 #define ERA_W_NAME   2
125 #define ERA_W_FORMAT 3
126
127
128 /* Structure to access `era' information from LC_TIME.  */
129 struct era_entry
130 {
131   uint32_t direction;           /* Contains '+' or '-'.  */
132   int32_t offset;
133   int32_t start_date[3];
134   int32_t stop_date[3];
135   const char *era_name;
136   const char *era_format;
137   const wchar_t *era_wname;
138   const wchar_t *era_wformat;
139   int absolute_direction;
140   /* absolute direction:
141      +1 indicates that year number is higher in the future. (like A.D.)
142      -1 indicates that year number is higher in the past. (like B.C.)  */
143 };
144
145 /* Structure caching computed data about information from LC_TIME.
146    The `private.time' member of `struct locale_data' points to this.  */
147 struct lc_time_data
148 {
149   struct era_entry *eras;
150   size_t num_eras;
151   int era_initialized;
152
153   const char **alt_digits;
154   const wchar_t **walt_digits;
155   int alt_digits_initialized;
156   int walt_digits_initialized;
157 };
158
159
160 /* LC_CTYPE specific:
161    Hardwired indices for standard wide character translation mappings.  */
162 enum
163 {
164   __TOW_toupper = 0,
165   __TOW_tolower = 1
166 };
167
168
169 /* LC_CTYPE specific:
170    Access a wide character class with a single character index.
171    _ISCTYPE (c, desc) = iswctype (btowc (c), desc).
172    c must be an `unsigned char'.  desc must be a nonzero wctype_t.  */
173 #define _ISCTYPE(c, desc) \
174   (((((const uint32_t *) (desc)) - 8)[(c) >> 5] >> ((c) & 0x1f)) & 1)
175
176 extern const char *const _nl_category_names[__LC_LAST] attribute_hidden;
177 extern const size_t _nl_category_name_sizes[__LC_LAST] attribute_hidden;
178
179 /* Name of the standard locales.  */
180 extern const char _nl_C_name[] attribute_hidden;
181 extern const char _nl_POSIX_name[] attribute_hidden;
182
183 /* The standard codeset.  */
184 extern const char _nl_C_codeset[] attribute_hidden;
185
186 /* This is the internal locale_t object that holds the global locale
187    controlled by calls to setlocale.  A thread's TSD locale pointer
188    points to this when `uselocale (LC_GLOBAL_LOCALE)' is in effect.  */
189 extern struct __locale_struct _nl_global_locale attribute_hidden;
190
191 /* This fetches the thread-local locale_t pointer, either one set with
192    uselocale or &_nl_global_locale.  */
193 #define _NL_CURRENT_LOCALE      ((__locale_t) __libc_tsd_get (LOCALE))
194 #include <bits/libc-tsd.h>
195 __libc_tsd_define (extern, LOCALE)
196
197
198 /* For static linking it is desireable to avoid always linking in the code
199    and data for every category when we can tell at link time that they are
200    unused.  We can manage this playing some tricks with weak references.
201    But with thread-local locale settings, it becomes quite ungainly unless
202    we can use __thread variables.  So only in that case do we attempt this.  */
203 #if !defined SHARED && defined HAVE___THREAD && defined HAVE_WEAK_SYMBOLS
204 # include <tls.h>
205 # if USE_TLS
206 #  define NL_CURRENT_INDIRECT   1
207 # endif
208 #endif
209
210 #ifdef NL_CURRENT_INDIRECT
211
212 /* For each category declare the thread-local variable for the current
213    locale data.  This has an extra indirection so it points at the
214    __locales[CATEGORY] element in either _nl_global_locale or the current
215    locale object set by uselocale, which points at the actual data.  The
216    reason for having these variables is so that references to particular
217    categories will link in the lc-CATEGORY.c module to define this symbol,
218    and we arrange that linking that module is what brings in all the code
219    associated with this category.  */
220 #define DEFINE_CATEGORY(category, category_name, items, a) \
221 extern __thread struct locale_data *const *_nl_current_##category \
222   attribute_hidden;
223 #include "categories.def"
224 #undef  DEFINE_CATEGORY
225
226 /* Return a pointer to the current `struct locale_data' for CATEGORY.  */
227 #define _NL_CURRENT_DATA(category)      (*_nl_current_##category)
228
229 /* Extract the current CATEGORY locale's string for ITEM.  */
230 #define _NL_CURRENT(category, item) \
231   ((*_nl_current_##category)->values[_NL_ITEM_INDEX (item)].string)
232
233 /* Extract the current CATEGORY locale's string for ITEM.  */
234 #define _NL_CURRENT_WSTR(category, item) \
235   ((wchar_t *) (*_nl_current_##category)->values[_NL_ITEM_INDEX (item)].wstr)
236
237 /* Extract the current CATEGORY locale's word for ITEM.  */
238 #define _NL_CURRENT_WORD(category, item) \
239   ((uint32_t) (*_nl_current_##category)->values[_NL_ITEM_INDEX (item)].word)
240
241 /* This is used in lc-CATEGORY.c to define _nl_current_CATEGORY.  */
242 #define _NL_CURRENT_DEFINE(category) \
243   __thread struct locale_data *const *_nl_current_##category \
244     attribute_hidden = &_nl_global_locale.__locales[category]; \
245   asm (_NL_CURRENT_DEFINE_STRINGIFY (ASM_GLOBAL_DIRECTIVE) \
246        " " __SYMBOL_PREFIX "_nl_current_" #category "_used\n" \
247        _NL_CURRENT_DEFINE_ABS (_nl_current_##category##_used, 1));
248 #define _NL_CURRENT_DEFINE_STRINGIFY(x) _NL_CURRENT_DEFINE_STRINGIFY_1 (x)
249 #define _NL_CURRENT_DEFINE_STRINGIFY_1(x) #x
250 #ifdef HAVE_ASM_SET_DIRECTIVE
251 # define _NL_CURRENT_DEFINE_ABS(sym, val) ".set " #sym ", " #val
252 #else
253 # define _NL_CURRENT_DEFINE_ABS(sym, val) #sym " = " #val
254 #endif
255
256 #else
257
258 /* All categories are always loaded in the shared library, so there is no
259    point in having lots of separate symbols for linking.  */
260
261 /* Return a pointer to the current `struct locale_data' for CATEGORY.  */
262 # define _NL_CURRENT_DATA(category) \
263   (_NL_CURRENT_LOCALE->__locales[category])
264
265 /* Extract the current CATEGORY locale's string for ITEM.  */
266 # define _NL_CURRENT(category, item) \
267   (_NL_CURRENT_DATA (category)->values[_NL_ITEM_INDEX (item)].string)
268
269 /* Extract the current CATEGORY locale's string for ITEM.  */
270 # define _NL_CURRENT_WSTR(category, item) \
271   ((wchar_t *) _NL_CURRENT_DATA (category)->values[_NL_ITEM_INDEX (item)].wstr)
272
273 /* Extract the current CATEGORY locale's word for ITEM.  */
274 # define _NL_CURRENT_WORD(category, item) \
275   ((uint32_t) _NL_CURRENT_DATA (category)->values[_NL_ITEM_INDEX (item)].word)
276
277 /* This is used in lc-CATEGORY.c to define _nl_current_CATEGORY.  */
278 # define _NL_CURRENT_DEFINE(category) \
279   /* No per-category variable here. */
280
281 #endif
282
283
284 /* Default search path if no LOCPATH environment variable.  */
285 extern const char _nl_default_locale_path[] attribute_hidden;
286
287 /* Load the locale data for CATEGORY from the file specified by *NAME.
288    If *NAME is "", use environment variables as specified by POSIX, and
289    fill in *NAME with the actual name used.  If LOCALE_PATH is not null,
290    those directories are searched for the locale files.  If it's null,
291    the locale archive is checked first and then _nl_default_locale_path
292    is searched for locale files.  */
293 extern struct locale_data *_nl_find_locale (const char *locale_path,
294                                             size_t locale_path_len,
295                                             int category, const char **name)
296      internal_function attribute_hidden;
297
298 /* Try to load the file described by FILE.  */
299 extern void _nl_load_locale (struct loaded_l10nfile *file, int category)
300      internal_function attribute_hidden;
301
302 /* Free all resource.  */
303 extern void _nl_unload_locale (struct locale_data *locale)
304      internal_function attribute_hidden;
305
306 /* Free the locale and give back all memory if the usage count is one.  */
307 extern void _nl_remove_locale (int locale, struct locale_data *data)
308      internal_function attribute_hidden;
309
310 /* Find the locale *NAMEP in the locale archive, and return the
311    internalized data structure for its CATEGORY data.  If this locale has
312    already been loaded from the archive, just returns the existing data
313    structure.  If successful, sets *NAMEP to point directly into the mapped
314    archive string table; that way, the next call can short-circuit strcmp.  */
315 extern struct locale_data *_nl_load_locale_from_archive (int category,
316                                                          const char **namep)
317      internal_function attribute_hidden;
318
319 /* Subroutine of setlocale's __libc_subfreeres hook.  */
320 extern void _nl_archive_subfreeres (void) attribute_hidden;
321
322 /* Validate the contents of a locale file and set up the in-core
323    data structure to point into the data.  This leaves the `alloc'
324    and `name' fields uninitialized, for the caller to fill in.
325    If any bogons are detected in the data, this will refuse to
326    intern it, and return a null pointer instead.  */
327 extern struct locale_data *_nl_intern_locale_data (int category,
328                                                    const void *data,
329                                                    size_t datasize)
330      internal_function attribute_hidden;
331
332
333 /* Return `era' entry which corresponds to TP.  Used in strftime.  */
334 extern struct era_entry *_nl_get_era_entry (const struct tm *tp,
335                                             struct locale_data *lc_time)
336      internal_function attribute_hidden;
337
338 /* Return `era' cnt'th entry .  Used in strptime.  */
339 extern struct era_entry *_nl_select_era_entry (int cnt,
340                                                struct locale_data *lc_time)
341           internal_function attribute_hidden;
342
343 /* Return `alt_digit' which corresponds to NUMBER.  Used in strftime.  */
344 extern const char *_nl_get_alt_digit (unsigned int number,
345                                       struct locale_data *lc_time)
346           internal_function attribute_hidden;
347
348 /* Similar, but now for wide characters.  */
349 extern const wchar_t *_nl_get_walt_digit (unsigned int number,
350                                           struct locale_data *lc_time)
351      internal_function attribute_hidden;
352
353 /* Parse string as alternative digit and return numeric value.  */
354 extern int _nl_parse_alt_digit (const char **strp,
355                                 struct locale_data *lc_time)
356      internal_function attribute_hidden;
357
358 /* Postload processing.  */
359 extern void _nl_postload_ctype (void);
360
361 /* Functions used for the `private.cleanup' hook.  */
362 extern void _nl_cleanup_time (struct locale_data *)
363      internal_function attribute_hidden;
364
365
366 #endif  /* localeinfo.h */