1 /* $NetBSD: nb_lc_template.h,v 1.8 2013/09/13 13:13:32 joerg Exp $ */
4 * Copyright (c)1999, 2008 Citrus Project,
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * Copyright (c) 1998 The NetBSD Foundation, Inc.
31 * All rights reserved.
33 * This code is derived from software contributed to The NetBSD Foundation
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
45 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
46 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
47 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
48 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
49 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
50 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
51 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
52 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
53 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
55 * POSSIBILITY OF SUCH DAMAGE.
60 * The Regents of the University of California. All rights reserved.
62 * This code is derived from software contributed to Berkeley by
63 * Paul Borman at Krystal Technologies.
65 * Redistribution and use in source and binary forms, with or without
66 * modification, are permitted provided that the following conditions
68 * 1. Redistributions of source code must retain the above copyright
69 * notice, this list of conditions and the following disclaimer.
70 * 2. Redistributions in binary form must reproduce the above copyright
71 * notice, this list of conditions and the following disclaimer in the
72 * documentation and/or other materials provided with the distribution.
73 * 3. Neither the name of the University nor the names of its contributors
74 * may be used to endorse or promote products derived from this software
75 * without specific prior written permission.
77 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
78 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
79 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
80 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
81 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
82 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
83 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
84 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
85 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
86 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
90 #ifndef _NB_LC_TEMPLATE_H_
91 #define _NB_LC_TEMPLATE_H_
93 #define _nb_part_t _PREFIX(part_t)
94 #define _nb_part_cache _PREFIX(part_cache)
95 #define _nb_mutex _PREFIX(mutex)
97 typedef struct _nb_part_t
{
98 char name
[_LOCALENAME_LEN_MAX
];
100 SIMPLEQ_ENTRY(_nb_part_t
) entry
;
103 static SIMPLEQ_HEAD(, _nb_part_t
) _nb_part_cache
=
104 SIMPLEQ_HEAD_INITIALIZER(_nb_part_cache
);
107 static mutex_t _nb_mutex
= MUTEX_INITIALIZER
;
111 _PREFIX(load_sub
)(const char * __restrict name
, const char * __restrict real
,
112 const char ** __restrict out_name
, _CATEGORY_TYPE
** __restrict out_impl
,
115 const char *cached_name
;
116 _CATEGORY_TYPE
*cached_impl
;
120 _DIAGASSERT(name
!= NULL
);
121 _DIAGASSERT(out_name
!= NULL
);
122 _DIAGASSERT(out_impl
!= NULL
);
124 if (!strcmp(_C_LOCALE
, name
)) {
125 cached_name
= _lc_C_locale
.part_name
[_CATEGORY_ID
];
126 cached_impl
= _lc_C_locale
.part_impl
[_CATEGORY_ID
];
127 } else if (!strcmp(_POSIX_LOCALE
, name
)) {
128 cached_name
= _POSIX_LOCALE
;
129 cached_impl
= _lc_C_locale
.part_impl
[_CATEGORY_ID
];
131 SIMPLEQ_FOREACH(p
, &_nb_part_cache
, entry
) {
132 if (!strcmp((const char *)&p
->name
[0], name
)) {
133 cached_name
= p
->name
;
134 cached_impl
= p
->impl
;
138 p
= malloc(sizeof(*p
));
142 p
->impl
= _lc_C_locale
.part_impl
[_CATEGORY_ID
];
144 _DIAGASSERT(_PathLocale
!= NULL
);
145 ret
= _PREFIX(create_impl
)((const char *)_PathLocale
,
152 strlcpy(&p
->name
[0], name
, sizeof(p
->name
));
153 SIMPLEQ_INSERT_TAIL(&_nb_part_cache
, p
, entry
);
154 cached_name
= p
->name
;
155 cached_impl
= p
->impl
;
159 p
= malloc(sizeof(*p
));
162 strlcpy(&p
->name
[0], real
, sizeof(p
->name
));
163 cached_name
= p
->name
;
164 p
->impl
= cached_impl
;
165 SIMPLEQ_INSERT_TAIL(&_nb_part_cache
, p
, entry
);
167 *out_name
= cached_name
;
168 *out_impl
= cached_impl
;
173 _PREFIX(load
)(const char * __restrict name
,
174 const char ** __restrict out_name
, _CATEGORY_TYPE
** __restrict out_impl
)
177 char path
[PATH_MAX
+ 1], loccat
[PATH_MAX
+ 1], buf
[PATH_MAX
+ 1];
178 const char *aliaspath
, *alias
;
180 #define _LOAD_SUB_ALIAS(key) \
182 alias = __unaliasname(aliaspath, key, &buf[0], sizeof(buf)); \
183 if (alias != NULL) { \
184 ret = (force = !__isforcemapping(alias)) \
185 ? _PREFIX(load_sub)(name, NULL, out_name, out_impl, \
187 : _PREFIX(load_sub)(alias, name, out_name, out_impl, \
189 _DIAGASSERT(!ret || !force); \
192 } while (/*CONSTCOND*/0)
194 /* (1) non-aliased file */
195 mutex_lock(&_nb_mutex
);
196 ret
= _PREFIX(load_sub
)(name
, NULL
, out_name
, out_impl
, 0);
200 /* (2) lookup locname/catname type alias */
201 _DIAGASSERT(_PathLocale
!= NULL
);
202 snprintf(&path
[0], sizeof(path
),
203 "%s/" _LOCALE_ALIAS_NAME
, _PathLocale
);
204 aliaspath
= (const char *)&path
[0];
205 snprintf(&loccat
[0], sizeof(loccat
),
206 "%s/" _CATEGORY_NAME
, name
);
207 _LOAD_SUB_ALIAS((const char *)&loccat
[0]);
209 /* (3) lookup locname type alias */
210 _LOAD_SUB_ALIAS(name
);
213 mutex_unlock(&_nb_mutex
);
218 _PREFIX(setlocale
)(const char * __restrict name
,
219 struct _locale
* __restrict locale
)
221 const char *loaded_name
;
222 _CATEGORY_TYPE
*loaded_impl
;
224 /* name may be NULL */
225 _DIAGASSERT(locale
!= NULL
);
229 name
= _get_locale_env(_CATEGORY_NAME
);
230 _DIAGASSERT(name
!= NULL
);
231 _DIAGASSERT(locale
->part_name
[(size_t)_CATEGORY_ID
] != NULL
);
232 if (strcmp(name
, locale
->part_name
[(size_t)_CATEGORY_ID
])) {
233 if (_PREFIX(load
)(name
, &loaded_name
, &loaded_impl
))
235 locale
->part_name
[(size_t)_CATEGORY_ID
] = loaded_name
;
236 locale
->part_impl
[(size_t)_CATEGORY_ID
] = loaded_impl
;
237 if (locale
== &_lc_global_locale
)
238 _PREFIX(update_global
)(loaded_impl
);
241 return locale
->part_name
[(size_t)_CATEGORY_ID
];
244 #endif /*_NB_LC_TEMPLATE_H_*/