1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2014 Garrett D'Amore <garrett@damore.org>
  14  */
  15 
  16 /*
  17  * This file implements the 2008 newlocale and friends handling. It is
  18  * private to libc.
  19  */
  20 #ifndef _LOCALEIMPL_H_
  21 #define _LOCALEIMPL_H_
  22 
  23 #ifndef _LCONV_C99
  24 #define _LCONV_C99      /* so we get all the extensions */
  25 #endif
  26 
  27 #include <sys/types.h>
  28 #include <locale.h>
  29 #include <xlocale.h>
  30 #include "setlocale.h"
  31 #include "runetype.h"
  32 
  33 /* private locale structures */
  34 
  35 /*
  36  * Because some locale data is rather ahem.. large, we would like to keep
  37  * reference counts on it.  We create an abstract header (locdata) structure
  38  * which keeps a point to the opaque per-category data, along with a reference
  39  * count to it.  To be threadsafe, we will use atomics when holding it or
  40  * freeing it.  (This only occurs when locale objects are created or destroyed,
  41  * so there should be no performance impact on hot code paths.  If your code
  42  * uses locale_t creation/destruction on a hot code path, its broken.  But
  43  * even so, the atomic and reference counting will probably *greatly* improve
  44  * your life as bootstrapping locale data from files is quite expensive.
  45  */
  46 
  47 #define NLOCDATA        4
  48 struct locdata {
  49         char            l_lname[ENCODING_LEN+1];        /* locale name */
  50         void            *l_data[NLOCDATA];              /* storage area */
  51         void            *l_map;                         /* mapped file */
  52         size_t          l_map_len;
  53         struct locdata  *l_next;                        /* link cached list */
  54 };
  55 
  56 
  57 struct locale {
  58         struct locdata  *locdata[LC_ALL];
  59         struct locale   *next;
  60         int             on_list;        /* on linked list */
  61         char            locname[(ENCODING_LEN+1)*NLOCDATA + 1];
  62 
  63         /*
  64          * Convenience pointers.
  65          */
  66         const struct lc_ctype           *ctype;
  67         const struct lc_collate         *collate;
  68         const struct lc_messages        *messages;
  69         const struct lc_monetary        *monetary;
  70         const struct lc_numeric         *numeric;
  71         const struct lc_time            *time;
  72         const _RuneLocale               *runelocale;
  73 
  74         /*
  75          * The loaded value is used for localeconv.  In paticular, when
  76          * when we change the value of one of the above categories, we will
  77          * also need to update the lconv structure.  The loaded bit indicates
  78          * that the lconv structure is "current" for that category.  It's
  79          * sort of an "inverse dirty" bit.
  80          */
  81         int             loaded[LC_ALL];
  82         struct lconv    lconv;
  83 };
  84 
  85 
  86 struct locdata *__locdata_alloc(const char *, size_t);
  87 void __locdata_free(struct locdata *);
  88 struct locdata *__locdata_get_cache(int, const char *);
  89 void __locdata_set_cache(int, struct locdata *);
  90 
  91 struct locdata *__lc_numeric_load(const char *name);
  92 struct locdata *__lc_monetary_load(const char *name);
  93 struct locdata *__lc_messages_load(const char *name);
  94 struct locdata *__lc_time_load(const char *name);
  95 struct locdata *__lc_ctype_load(const char *name);
  96 struct locdata *__lc_collate_load(const char *name);
  97 
  98 extern struct locdata   __posix_numeric_locdata;
  99 extern struct locdata   __posix_monetary_locdata;
 100 extern struct locdata   __posix_messages_locdata;
 101 extern struct locdata   __posix_time_locdata;
 102 extern struct locdata   __posix_ctype_locdata;
 103 extern struct locdata   __posix_collate_locdata;
 104 extern locale_t ___global_locale;
 105 
 106 #endif  /* _LOCALEIMPL_H_ */