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