1 /* $NetBSD: nl_langinfo.c,v 1.18 2017/01/10 17:50:24 christos Exp $ */
2
3 /*-
4 * Copyright (c)2008 Citrus Project,
5 * All rights reserved.
6 *
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.
15 *
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.
27 */
28
29 #include <sys/cdefs.h>
30 __RCSID("$NetBSD: nl_langinfo.c,v 1.18 2017/01/10 17:50:24 christos Exp $");
31
32 #include "namespace.h"
33 #include <sys/types.h>
34 #include <sys/localedef.h>
35 #include <langinfo.h>
36 #include <stddef.h>
37 #define __SETLOCALE_SOURCE__
38 #include <locale.h>
39 #include <stdlib.h>
40 #include <string.h>
41
42 #include "runetype_local.h"
43 #include "setlocale_local.h"
44
45 static const char langinfo_category[] = {
46 [ D_T_FMT ] = LC_TIME,
47 [ D_FMT ] = LC_TIME,
48 [ T_FMT ] = LC_TIME,
49 [ T_FMT_AMPM ] = LC_TIME,
50 [ AM_STR ] = LC_TIME,
51 [ PM_STR ] = LC_TIME,
52 [ DAY_1 ] = LC_TIME,
53 [ DAY_2 ] = LC_TIME,
54 [ DAY_3 ] = LC_TIME,
55 [ DAY_4 ] = LC_TIME,
56 [ DAY_5 ] = LC_TIME,
57 [ DAY_6 ] = LC_TIME,
58 [ DAY_7 ] = LC_TIME,
59 [ ABDAY_1 ] = LC_TIME,
60 [ ABDAY_2 ] = LC_TIME,
61 [ ABDAY_3 ] = LC_TIME,
62 [ ABDAY_4 ] = LC_TIME,
63 [ ABDAY_5 ] = LC_TIME,
64 [ ABDAY_6 ] = LC_TIME,
65 [ ABDAY_7 ] = LC_TIME,
66 [ MON_1 ] = LC_TIME,
67 [ MON_2 ] = LC_TIME,
68 [ MON_3 ] = LC_TIME,
69 [ MON_4 ] = LC_TIME,
70 [ MON_5 ] = LC_TIME,
71 [ MON_6 ] = LC_TIME,
72 [ MON_7 ] = LC_TIME,
73 [ MON_8 ] = LC_TIME,
74 [ MON_9 ] = LC_TIME,
75 [ MON_10 ] = LC_TIME,
76 [ MON_11 ] = LC_TIME,
77 [ MON_12 ] = LC_TIME,
78 [ ABMON_1 ] = LC_TIME,
79 [ ABMON_2 ] = LC_TIME,
80 [ ABMON_3 ] = LC_TIME,
81 [ ABMON_4 ] = LC_TIME,
82 [ ABMON_5 ] = LC_TIME,
83 [ ABMON_6 ] = LC_TIME,
84 [ ABMON_7 ] = LC_TIME,
85 [ ABMON_8 ] = LC_TIME,
86 [ ABMON_9 ] = LC_TIME,
87 [ ABMON_10 ] = LC_TIME,
88 [ ABMON_11 ] = LC_TIME,
89 [ ABMON_12 ] = LC_TIME,
90 [ RADIXCHAR ] = LC_NUMERIC,
91 [ THOUSEP ] = LC_NUMERIC,
92 [ YESSTR ] = LC_MESSAGES,
93 [ YESEXPR ] = LC_MESSAGES,
94 [ NOSTR ] = LC_MESSAGES,
95 [ NOEXPR ] = LC_MESSAGES,
96 [ CRNCYSTR ] = 0,
97 [ CODESET ] = LC_CTYPE,
98 [ ERA ] = 0,
99 [ ERA_D_FMT ] = 0,
100 [ ERA_D_T_FMT ] = 0,
101 [ ERA_T_FMT ] = 0,
102 [ ALT_DIGITS ] = 0,
103 };
104
105 #define offsetofu16(a, b) ((uint16_t)offsetof(a, b))
106
107 static const uint16_t langinfo_offset[] = {
108 [ D_T_FMT ] = offsetofu16(_TimeLocale, d_t_fmt),
109 [ D_FMT ] = offsetofu16(_TimeLocale, d_fmt),
110 [ T_FMT ] = offsetofu16(_TimeLocale, t_fmt),
111 [ T_FMT_AMPM ] = offsetofu16(_TimeLocale, t_fmt_ampm),
112 [ AM_STR ] = offsetofu16(_TimeLocale, am_pm[0]),
113 [ PM_STR ] = offsetofu16(_TimeLocale, am_pm[1]),
114 [ DAY_1 ] = offsetofu16(_TimeLocale, day[0]),
115 [ DAY_2 ] = offsetofu16(_TimeLocale, day[1]),
116 [ DAY_3 ] = offsetofu16(_TimeLocale, day[2]),
117 [ DAY_4 ] = offsetofu16(_TimeLocale, day[3]),
118 [ DAY_5 ] = offsetofu16(_TimeLocale, day[4]),
119 [ DAY_6 ] = offsetofu16(_TimeLocale, day[5]),
120 [ DAY_7 ] = offsetofu16(_TimeLocale, day[6]),
121 [ ABDAY_1 ] = offsetofu16(_TimeLocale, abday[0]),
122 [ ABDAY_2 ] = offsetofu16(_TimeLocale, abday[1]),
123 [ ABDAY_3 ] = offsetofu16(_TimeLocale, abday[2]),
124 [ ABDAY_4 ] = offsetofu16(_TimeLocale, abday[3]),
125 [ ABDAY_5 ] = offsetofu16(_TimeLocale, abday[4]),
126 [ ABDAY_6 ] = offsetofu16(_TimeLocale, abday[5]),
127 [ ABDAY_7 ] = offsetofu16(_TimeLocale, abday[6]),
128 [ MON_1 ] = offsetofu16(_TimeLocale, mon[0]),
129 [ MON_2 ] = offsetofu16(_TimeLocale, mon[1]),
130 [ MON_3 ] = offsetofu16(_TimeLocale, mon[2]),
131 [ MON_4 ] = offsetofu16(_TimeLocale, mon[3]),
132 [ MON_5 ] = offsetofu16(_TimeLocale, mon[4]),
133 [ MON_6 ] = offsetofu16(_TimeLocale, mon[5]),
134 [ MON_7 ] = offsetofu16(_TimeLocale, mon[6]),
135 [ MON_8 ] = offsetofu16(_TimeLocale, mon[7]),
136 [ MON_9 ] = offsetofu16(_TimeLocale, mon[8]),
137 [ MON_10 ] = offsetofu16(_TimeLocale, mon[9]),
138 [ MON_11 ] = offsetofu16(_TimeLocale, mon[10]),
139 [ MON_12 ] = offsetofu16(_TimeLocale, mon[11]),
140 [ ABMON_1 ] = offsetofu16(_TimeLocale, abmon[0]),
141 [ ABMON_2 ] = offsetofu16(_TimeLocale, abmon[1]),
142 [ ABMON_3 ] = offsetofu16(_TimeLocale, abmon[2]),
143 [ ABMON_4 ] = offsetofu16(_TimeLocale, abmon[3]),
144 [ ABMON_5 ] = offsetofu16(_TimeLocale, abmon[4]),
145 [ ABMON_6 ] = offsetofu16(_TimeLocale, abmon[5]),
146 [ ABMON_7 ] = offsetofu16(_TimeLocale, abmon[6]),
147 [ ABMON_8 ] = offsetofu16(_TimeLocale, abmon[7]),
148 [ ABMON_9 ] = offsetofu16(_TimeLocale, abmon[8]),
149 [ ABMON_10 ] = offsetofu16(_TimeLocale, abmon[9]),
150 [ ABMON_11 ] = offsetofu16(_TimeLocale, abmon[10]),
151 [ ABMON_12 ] = offsetofu16(_TimeLocale, abmon[11]),
152 [ RADIXCHAR ] = offsetofu16(_NumericLocale, decimal_point),
153 [ THOUSEP ] = offsetofu16(_NumericLocale, thousands_sep),
154 [ YESSTR ] = offsetofu16(_MessagesLocale, yesstr),
155 [ YESEXPR ] = offsetofu16(_MessagesLocale, yesexpr),
156 [ NOSTR ] = offsetofu16(_MessagesLocale, nostr),
157 [ NOEXPR ] = offsetofu16(_MessagesLocale, noexpr),
158 [ CRNCYSTR ] = 0,
159 [ CODESET ] = offsetofu16(_RuneLocale, rl_codeset),
160 [ ERA ] = 0,
161 [ ERA_D_FMT ] = 0,
162 [ ERA_D_T_FMT ] = 0,
163 [ ERA_T_FMT ] = 0,
164 [ ALT_DIGITS ] = 0,
165 };
166
__weak_alias(nl_langinfo_l,_nl_langinfo_l)167 __weak_alias(nl_langinfo_l, _nl_langinfo_l)
168
169 char *
170 nl_langinfo(nl_item item)
171 {
172
173 return nl_langinfo_l(item, _current_locale());
174 }
175
176 char *
nl_langinfo_l(nl_item item,locale_t loc)177 nl_langinfo_l(nl_item item, locale_t loc)
178 {
179 char *s;
180 int category;
181 size_t offset;
182
183 if (item < 0 || item >= (long)__arraycount(langinfo_category))
184 return __UNCONST(""); /* Outside the defined range */
185
186 category = langinfo_category[item];
187 if (category == 0)
188 return __UNCONST(""); /* Not in use */
189 offset = langinfo_offset[item];
190
191 memcpy(&s, (char *)loc->part_impl[category] + offset, sizeof(s));
192 if (s == NULL)
193 return __UNCONST("");
194 else
195 return s;
196 }
197