github.com/afumu/libc@v0.0.6/freebsd/xlocale_private.h (about)

     1  /*-
     2   * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
     3   *
     4   * Copyright (c) 2011 The FreeBSD Foundation
     5   * All rights reserved.
     6   *
     7   * This software was developed by David Chisnall under sponsorship from
     8   * the FreeBSD Foundation.
     9   *
    10   * Redistribution and use in source and binary forms, with or without
    11   * modification, are permitted provided that the following conditions
    12   * are met:
    13   * 1. Redistributions of source code must retain the above copyright
    14   *    notice, this list of conditions and the following disclaimer.
    15   * 2. Redistributions in binary form must reproduce the above copyright
    16   *    notice, this list of conditions and the following disclaimer in the
    17   *    documentation and/or other materials provided with the distribution.
    18   *
    19   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
    20   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    21   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    22   * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
    23   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    24   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    25   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    26   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    27   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    28   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    29   * SUCH DAMAGE.
    30   *
    31   * $FreeBSD$
    32   */
    33  
    34  #ifndef _XLOCALE_PRIVATE__H_
    35  #define _XLOCALE_PRIVATE__H_
    36  
    37  #include <xlocale.h>
    38  #include <locale.h>
    39  #include <stdlib.h>
    40  #include <stdint.h>
    41  #include <sys/types.h>
    42  #include <machine/atomic.h>
    43  #include "setlocale.h"
    44  
    45  /**
    46   * The XLC_ values are indexes into the components array.  They are defined in
    47   * the same order as the LC_ values in locale.h, but without the LC_ALL zero
    48   * value.  Translating from LC_X to XLC_X is done by subtracting one.
    49   *
    50   * Any reordering of this enum should ensure that these invariants are not
    51   * violated.
    52   */
    53  enum {
    54  	XLC_COLLATE = 0,
    55  	XLC_CTYPE,
    56  	XLC_MONETARY,
    57  	XLC_NUMERIC,
    58  	XLC_TIME,
    59  	XLC_MESSAGES,
    60  	XLC_LAST
    61  };
    62  
    63  _Static_assert(XLC_LAST - XLC_COLLATE == 6, "XLC values should be contiguous");
    64  _Static_assert(XLC_COLLATE == LC_COLLATE - 1,
    65                 "XLC_COLLATE doesn't match the LC_COLLATE value.");
    66  _Static_assert(XLC_CTYPE == LC_CTYPE - 1,
    67                 "XLC_CTYPE doesn't match the LC_CTYPE value.");
    68  _Static_assert(XLC_MONETARY == LC_MONETARY - 1,
    69                 "XLC_MONETARY doesn't match the LC_MONETARY value.");
    70  _Static_assert(XLC_NUMERIC == LC_NUMERIC - 1,
    71                 "XLC_NUMERIC doesn't match the LC_NUMERIC value.");
    72  _Static_assert(XLC_TIME == LC_TIME - 1,
    73                 "XLC_TIME doesn't match the LC_TIME value.");
    74  _Static_assert(XLC_MESSAGES == LC_MESSAGES - 1,
    75                 "XLC_MESSAGES doesn't match the LC_MESSAGES value.");
    76  
    77  /**
    78   * Header used for objects that are reference counted.  Objects may optionally
    79   * have a destructor associated, which is responsible for destroying the
    80   * structure.  Global / static versions of the structure should have no
    81   * destructor set - they can then have their reference counts manipulated as
    82   * normal, but will not do anything with them.
    83   *
    84   * The header stores a retain count - objects are assumed to have a reference
    85   * count of 1 when they are created, but the retain count is 0.  When the
    86   * retain count is less than 0, they are freed.
    87   */
    88  struct xlocale_refcounted {
    89  	/** Number of references to this component.  */
    90  	long retain_count;
    91  	/** Function used to destroy this component, if one is required*/
    92  	void(*destructor)(void*);
    93  };
    94  
    95  #define XLOCALE_DEF_VERSION_LEN 12
    96  
    97  /**
    98   * Header for a locale component.  All locale components must begin with this
    99   * header.
   100   */
   101  struct xlocale_component {
   102  	struct xlocale_refcounted header;
   103  	/** Name of the locale used for this component. */
   104  	char locale[ENCODING_LEN+1];
   105  	/** Version of the definition for this component. */
   106  	char version[XLOCALE_DEF_VERSION_LEN];
   107  };
   108  
   109  /**
   110   * xlocale structure, stores per-thread locale information.  
   111   */
   112  struct _xlocale {
   113  	struct xlocale_refcounted header;
   114  	/** Components for the locale.  */
   115  	struct xlocale_component *components[XLC_LAST];
   116  	/** Flag indicating if components[XLC_MONETARY] has changed since the
   117  	 * last call to localeconv_l() with this locale. */
   118  	int monetary_locale_changed;
   119  	/** Flag indicating whether this locale is actually using a locale for
   120  	 * LC_MONETARY (1), or if it should use the C default instead (0). */
   121  	int using_monetary_locale;
   122  	/** Flag indicating if components[XLC_NUMERIC] has changed since the
   123  	 * last call to localeconv_l() with this locale. */
   124  	int numeric_locale_changed;
   125  	/** Flag indicating whether this locale is actually using a locale for
   126  	 * LC_NUMERIC (1), or if it should use the C default instead (0). */
   127  	int using_numeric_locale;
   128  	/** Flag indicating whether this locale is actually using a locale for
   129  	 * LC_TIME (1), or if it should use the C default instead (0). */
   130  	int using_time_locale;
   131  	/** Flag indicating whether this locale is actually using a locale for
   132  	 * LC_MESSAGES (1), or if it should use the C default instead (0). */
   133  	int using_messages_locale;
   134  	/** The structure to be returned from localeconv_l() for this locale. */
   135  	struct lconv lconv;
   136  	/** Buffer used by nl_langinfo_l() */
   137  	char *csym;
   138  };
   139  
   140  /**
   141   * Increments the reference count of a reference-counted structure.
   142   */
   143  __attribute__((unused)) static void*
   144  xlocale_retain(void *val)
   145  {
   146  	struct xlocale_refcounted *obj = val;
   147  	atomic_add_long(&(obj->retain_count), 1);
   148  	return (val);
   149  }
   150  /**
   151   * Decrements the reference count of a reference-counted structure, freeing it
   152   * if this is the last reference, calling its destructor if it has one.
   153   */
   154  __attribute__((unused)) static void
   155  xlocale_release(void *val)
   156  {
   157  	struct xlocale_refcounted *obj = val;
   158  	long count;
   159  
   160  	count = atomic_fetchadd_long(&(obj->retain_count), -1) - 1;
   161  	if (count < 0 && obj->destructor != NULL)
   162  		obj->destructor(obj);
   163  }
   164  
   165  /**
   166   * Load functions.  Each takes the name of a locale and a pointer to the data
   167   * to be initialised as arguments.  Two special values are allowed for the 
   168   */
   169  extern void* __collate_load(const char*, locale_t);
   170  extern void* __ctype_load(const char*, locale_t);
   171  extern void* __messages_load(const char*, locale_t);
   172  extern void* __monetary_load(const char*, locale_t);
   173  extern void* __numeric_load(const char*, locale_t);
   174  extern void* __time_load(const char*, locale_t);
   175  
   176  extern struct _xlocale __xlocale_global_locale;
   177  extern struct _xlocale __xlocale_C_locale;
   178  
   179  /**
   180   * Caches the rune table in TLS for fast access.
   181   */
   182  void __set_thread_rune_locale(locale_t loc);
   183  /**
   184   * Flag indicating whether a per-thread locale has been set.  If no per-thread
   185   * locale has ever been set, then we always use the global locale.
   186   */
   187  extern int __has_thread_locale;
   188  
   189  /**
   190   * The per-thread locale.  Avoids the need to use pthread lookup functions when
   191   * getting the per-thread locale.
   192   */
   193  extern _Thread_local locale_t __thread_locale;
   194  
   195  /**
   196   * Returns the current locale for this thread, or the global locale if none is
   197   * set.  The caller does not have to free the locale.  The return value from
   198   * this call is not guaranteed to remain valid after the locale changes.  As
   199   * such, this should only be called within libc functions.
   200   */
   201  static inline locale_t __get_locale(void)
   202  {
   203  
   204  	if (!__has_thread_locale) {
   205  		return (&__xlocale_global_locale);
   206  	}
   207  	return (__thread_locale ? __thread_locale : &__xlocale_global_locale);
   208  }
   209  
   210  /**
   211   * Two magic values are allowed for locale_t objects.  NULL and -1.  This
   212   * function maps those to the real locales that they represent.
   213   */
   214  static inline locale_t get_real_locale(locale_t locale)
   215  {
   216  	switch ((intptr_t)locale) {
   217  		case 0: return (&__xlocale_C_locale);
   218  		case -1: return (&__xlocale_global_locale);
   219  		default: return (locale);
   220  	}
   221  }
   222  
   223  /**
   224   * Replace a placeholder locale with the real global or thread-local locale_t.
   225   */
   226  #define FIX_LOCALE(l) (l = get_real_locale(l))
   227  
   228  #endif