12d08521bSGarrett D'Amore /*
22d08521bSGarrett D'Amore  * This file and its contents are supplied under the terms of the
32d08521bSGarrett D'Amore  * Common Development and Distribution License ("CDDL"), version 1.0.
42d08521bSGarrett D'Amore  * You may only use this file in accordance with the terms of version
52d08521bSGarrett D'Amore  * 1.0 of the CDDL.
62d08521bSGarrett D'Amore  *
72d08521bSGarrett D'Amore  * A full copy of the text of the CDDL should have accompanied this
82d08521bSGarrett D'Amore  * source.  A copy of the CDDL is also available via the Internet at
92d08521bSGarrett D'Amore  * http://www.illumos.org/license/CDDL.
102d08521bSGarrett D'Amore  */
112d08521bSGarrett D'Amore 
122d08521bSGarrett D'Amore /*
132d08521bSGarrett D'Amore  * Copyright 2014 Garrett D'Amore <garrett@damore.org>
142d08521bSGarrett D'Amore  */
152d08521bSGarrett D'Amore 
162d08521bSGarrett D'Amore /*
172d08521bSGarrett D'Amore  * This file implements the 2008 newlocale and friends handling. It is
182d08521bSGarrett D'Amore  * private to libc.
192d08521bSGarrett D'Amore  */
202d08521bSGarrett D'Amore #ifndef	_LOCALEIMPL_H_
212d08521bSGarrett D'Amore #define	_LOCALEIMPL_H_
222d08521bSGarrett D'Amore 
232d08521bSGarrett D'Amore #ifndef _LCONV_C99
242d08521bSGarrett D'Amore #define	_LCONV_C99	/* so we get all the extensions */
252d08521bSGarrett D'Amore #endif
262d08521bSGarrett D'Amore 
272d08521bSGarrett D'Amore #include <sys/types.h>
282d08521bSGarrett D'Amore #include <locale.h>
292d08521bSGarrett D'Amore #include <xlocale.h>
302d08521bSGarrett D'Amore #include "setlocale.h"
312d08521bSGarrett D'Amore 
322d08521bSGarrett D'Amore /* private locale structures */
332d08521bSGarrett D'Amore 
342d08521bSGarrett D'Amore /*
352d08521bSGarrett D'Amore  * Because some locale data is rather ahem.. large, we would like to keep
362d08521bSGarrett D'Amore  * reference counts on it.  We create an abstract header (locdata) structure
372d08521bSGarrett D'Amore  * which keeps a point to the opaque per-category data, along with a reference
382d08521bSGarrett D'Amore  * count to it.  To be threadsafe, we will use atomics when holding it or
392d08521bSGarrett D'Amore  * freeing it.  (This only occurs when locale objects are created or destroyed,
402d08521bSGarrett D'Amore  * so there should be no performance impact on hot code paths.  If your code
412d08521bSGarrett D'Amore  * uses locale_t creation/destruction on a hot code path, its broken.  But
422d08521bSGarrett D'Amore  * even so, the atomic and reference counting will probably *greatly* improve
432d08521bSGarrett D'Amore  * your life as bootstrapping locale data from files is quite expensive.
442d08521bSGarrett D'Amore  */
452d08521bSGarrett D'Amore 
462d08521bSGarrett D'Amore #define	NLOCDATA	4
472d08521bSGarrett D'Amore struct locdata {
482d08521bSGarrett D'Amore 	char		l_lname[ENCODING_LEN+1];	/* locale name */
492d08521bSGarrett D'Amore 	void		*l_data[NLOCDATA];		/* storage area */
502d08521bSGarrett D'Amore 	void		*l_map;				/* mapped file */
512d08521bSGarrett D'Amore 	size_t		l_map_len;
522d08521bSGarrett D'Amore 	struct locdata	*l_next;			/* link cached list */
532d08521bSGarrett D'Amore 	int		l_cached;			/* nonzero if cached */
542d08521bSGarrett D'Amore };
552d08521bSGarrett D'Amore 
562d08521bSGarrett D'Amore 
57732efd55SDan McDonald struct _locale {
582d08521bSGarrett D'Amore 	struct locdata	*locdata[LC_ALL];
59732efd55SDan McDonald 	struct _locale	*next;
602d08521bSGarrett D'Amore 	int		on_list;	/* on linked list */
612d08521bSGarrett D'Amore 	char		locname[(ENCODING_LEN+1)*NLOCDATA + 1];
622d08521bSGarrett D'Amore 
632d08521bSGarrett D'Amore 	/*
642d08521bSGarrett D'Amore 	 * Convenience pointers.
652d08521bSGarrett D'Amore 	 */
662d08521bSGarrett D'Amore 	const struct lc_ctype		*ctype;
672d08521bSGarrett D'Amore 	const struct lc_collate		*collate;
682d08521bSGarrett D'Amore 	const struct lc_messages	*messages;
692d08521bSGarrett D'Amore 	const struct lc_monetary	*monetary;
702d08521bSGarrett D'Amore 	const struct lc_numeric		*numeric;
712d08521bSGarrett D'Amore 	const struct lc_time		*time;
72*bc09504fSGordon Ross 	const struct _RuneLocale	*runelocale;
732d08521bSGarrett D'Amore 
742d08521bSGarrett D'Amore 	/*
752d08521bSGarrett D'Amore 	 * The loaded value is used for localeconv.  In paticular, when
762d08521bSGarrett D'Amore 	 * when we change the value of one of the above categories, we will
772d08521bSGarrett D'Amore 	 * also need to update the lconv structure.  The loaded bit indicates
782d08521bSGarrett D'Amore 	 * that the lconv structure is "current" for that category.  It's
792d08521bSGarrett D'Amore 	 * sort of an "inverse dirty" bit.
802d08521bSGarrett D'Amore 	 */
812d08521bSGarrett D'Amore 	int		loaded[LC_ALL];
822d08521bSGarrett D'Amore 	struct lconv	lconv;
832d08521bSGarrett D'Amore };
842d08521bSGarrett D'Amore 
852d08521bSGarrett D'Amore 
862d08521bSGarrett D'Amore struct locdata *__locdata_alloc(const char *, size_t);
872d08521bSGarrett D'Amore void __locdata_free(struct locdata *);
882d08521bSGarrett D'Amore struct locdata *__locdata_get_cache(int, const char *);
892d08521bSGarrett D'Amore void __locdata_set_cache(int, struct locdata *);
902d08521bSGarrett D'Amore 
912d08521bSGarrett D'Amore struct locdata *__lc_numeric_load(const char *name);
922d08521bSGarrett D'Amore struct locdata *__lc_monetary_load(const char *name);
932d08521bSGarrett D'Amore struct locdata *__lc_messages_load(const char *name);
942d08521bSGarrett D'Amore struct locdata *__lc_time_load(const char *name);
952d08521bSGarrett D'Amore struct locdata *__lc_ctype_load(const char *name);
962d08521bSGarrett D'Amore struct locdata *__lc_collate_load(const char *name);
972d08521bSGarrett D'Amore 
982d08521bSGarrett D'Amore extern struct locdata	__posix_numeric_locdata;
992d08521bSGarrett D'Amore extern struct locdata	__posix_monetary_locdata;
1002d08521bSGarrett D'Amore extern struct locdata	__posix_messages_locdata;
1012d08521bSGarrett D'Amore extern struct locdata	__posix_time_locdata;
1022d08521bSGarrett D'Amore extern struct locdata	__posix_ctype_locdata;
1032d08521bSGarrett D'Amore extern struct locdata	__posix_collate_locdata;
1042d08521bSGarrett D'Amore extern locale_t ___global_locale;
1052d08521bSGarrett D'Amore 
1062d08521bSGarrett D'Amore #endif	/* _LOCALEIMPL_H_ */
107