add opendir alias
[minix.git] / lib / libc / locale / nb_lc_template.h
blob73870c63940d8042123c59093655545751ca99e9
1 /* $NetBSD: nb_lc_template.h,v 1.4 2012/03/04 21:14:56 tnozaki Exp $ */
3 /*-
4 * Copyright (c)1999, 2008 Citrus Project,
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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
26 * SUCH DAMAGE.
29 /*-
30 * Copyright (c) 1998 The NetBSD Foundation, Inc.
31 * All rights reserved.
33 * This code is derived from software contributed to The NetBSD Foundation
34 * by Paul Kranenburg.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
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.
58 /*-
59 * Copyright (c) 1993
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
67 * are met:
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
87 * SUCH DAMAGE.
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_default_c _PREFIX(default_c)
96 #define _nb_default_posix _PREFIX(default_posix)
97 #define _nb_mutex _PREFIX(mutex)
99 typedef struct _nb_part_t {
100 char name[_LOCALENAME_LEN_MAX];
101 _CATEGORY_TYPE *impl;
102 SIMPLEQ_ENTRY(_nb_part_t) entry;
103 } _nb_part_t;
105 static SIMPLEQ_HEAD(, _nb_part_t) _nb_part_cache =
106 SIMPLEQ_HEAD_INITIALIZER(_nb_part_cache);
108 static const _nb_part_t _nb_default_c = {
109 _C_LOCALE,
110 __UNCONST(&_CATEGORY_DEFAULT),
111 { NULL },
114 static const _nb_part_t _nb_default_posix = {
115 _POSIX_LOCALE,
116 __UNCONST(&_CATEGORY_DEFAULT),
117 { NULL },
120 #ifdef _REENTRANT
121 static mutex_t _nb_mutex = MUTEX_INITIALIZER;
122 #endif
124 static int
125 _PREFIX(load_sub)(const char * __restrict name, const char * __restrict real,
126 _nb_part_t ** __restrict part, int force)
128 _nb_part_t *p, *q;
129 int ret;
131 _DIAGASSERT(name != NULL);
132 _DIAGASSERT(part != NULL);
134 if (!strcmp(_C_LOCALE, name)) {
135 p = __UNCONST(&_nb_default_c);
136 } else if (!strcmp(_POSIX_LOCALE, name)) {
137 p = __UNCONST(&_nb_default_posix);
138 } else {
139 SIMPLEQ_FOREACH(p, &_nb_part_cache, entry) {
140 if (!strcmp((const char *)&p->name[0], name))
141 goto found;
143 p = malloc(sizeof(*p));
144 if (p == NULL)
145 return ENOMEM;
146 if (force) {
147 p->impl = __UNCONST(&_CATEGORY_DEFAULT);
148 } else {
149 _DIAGASSERT(_PathLocale != NULL);
150 ret = _PREFIX(create_impl)((const char *)_PathLocale,
151 name, &p->impl);
152 if (ret) {
153 free(p);
154 return ret;
157 strlcpy(&p->name[0], name, sizeof(p->name));
158 SIMPLEQ_INSERT_TAIL(&_nb_part_cache, p, entry);
160 found:
161 if (real != NULL) {
162 q = malloc(sizeof(*q));
163 if (q == NULL)
164 return ENOMEM;
165 strlcpy(&q->name[0], real, sizeof(p->name));
166 q->impl = p->impl;
167 SIMPLEQ_INSERT_TAIL(&_nb_part_cache, q, entry);
168 p = q;
170 *part = p;
171 return 0;
174 static __inline int
175 _PREFIX(load)(const char * __restrict name,
176 _nb_part_t ** __restrict part)
178 int ret, force;
179 char path[PATH_MAX + 1], loccat[PATH_MAX + 1], buf[PATH_MAX + 1];
180 const char *aliaspath, *alias;
182 #define _LOAD_SUB_ALIAS(key) \
183 do { \
184 alias = __unaliasname(aliaspath, key, &buf[0], sizeof(buf)); \
185 if (alias != NULL) { \
186 ret = (force = !__isforcemapping(alias)) \
187 ? _PREFIX(load_sub)(name, NULL, part, force) \
188 : _PREFIX(load_sub)(alias, name, part, force); \
189 _DIAGASSERT(!ret || !force); \
190 goto done; \
192 } while (/*CONSTCOND*/0)
194 /* (1) non-aliased file */
195 mutex_lock(&_nb_mutex);
196 ret = _PREFIX(load_sub)(name, NULL, part, 0);
197 if (ret != ENOENT)
198 goto done;
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);
212 done:
213 mutex_unlock(&_nb_mutex);
214 return ret;
217 const char *
218 _PREFIX(setlocale)(const char * __restrict name,
219 struct _locale_impl_t * __restrict locale)
221 _nb_part_t *part;
223 /* name may be NULL */
224 _DIAGASSERT(locale != NULL);
226 if (name != NULL) {
227 if (*name == '\0')
228 name = _get_locale_env(_CATEGORY_NAME);
229 _DIAGASSERT(name != NULL);
230 _DIAGASSERT(locale->part_name[(size_t)_CATEGORY_ID] != NULL);
231 if (strcmp(name, locale->part_name[(size_t)_CATEGORY_ID])) {
232 if (_PREFIX(load)(name, &part))
233 return NULL;
234 locale->part_name[(size_t)_CATEGORY_ID]
235 = &part->name[0];
236 locale->part_impl[(size_t)_CATEGORY_ID]
237 = part->impl;
238 _PREFIX(build_cache)(locale->cache, part->impl);
239 if (locale == &_global_locale)
240 _PREFIX(fixup)(part->impl);
243 return locale->part_name[(size_t)_CATEGORY_ID];
246 #endif /*_NB_LC_TEMPLATE_H_*/