1 /* $NetBSD: mklocaledb.c,v 1.4 2015/06/16 22:54:10 christos Exp $ */
4 * Copyright (c)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 * XXX TEMPORARY IMPLEMENTATION.
31 * don't waste your time, all we need is localedef(1).
34 #if HAVE_NBTOOL_CONFIG_H
35 #include "nbtool_config.h"
38 #include <sys/cdefs.h>
40 __RCSID("$NetBSD: mklocaledb.c,v 1.4 2015/06/16 22:54:10 christos Exp $");
53 #include "fix_grouping.h"
55 #include "citrus_namespace.h"
56 #include "citrus_bcs.h"
57 #include "citrus_types.h"
58 #include "citrus_region.h"
59 #include "citrus_db_factory.h"
60 #include "citrus_db_hash.h"
61 #include "citrus_db.h"
63 #include "citrus_lc_monetary.h"
64 #include "citrus_lc_numeric.h"
65 #include "citrus_lc_time.h"
66 #include "citrus_lc_messages.h"
68 void mklocaledb(const char *, FILE *, FILE *);
71 * TODO: -d debug options's output.
74 extern void usage(void);
77 save_as_string(struct _db_factory
*df
,
78 const char *key
, const char *value
)
80 return _db_factory_addstr_by_s(df
, key
, value
);
84 save_as_grouping(struct _db_factory
*df
,
85 const char *key
, const char *value
)
87 value
= __fix_locale_grouping_str(value
);
88 return _db_factory_addstr_by_s(df
, key
, value
);
92 save_as_uint8(struct _db_factory
*df
,
93 const char *key
, const char *head
)
96 unsigned long int value
;
99 value
= _bcs_strtoul(head
, &tail
, 0);
100 if (head
== tail
|| value
> 0xFF)
102 u8
= (uint8_t)(value
& 0xFF);
103 return _db_factory_add8_by_s(df
, key
, u8
);
108 int (*save
)(struct _db_factory
*,
109 const char *, const char *);
113 const char *magic
, * vers_sym
;
115 const token_t tokens
[];
118 static const category_t lc_monetary
= {
119 _CITRUS_LC_MONETARY_MAGIC_1
,
120 _CITRUS_LC_MONETARY_SYM_VERSION
,
121 _CITRUS_LC_MONETARY_VERSION
,
123 { _CITRUS_LC_MONETARY_SYM_INT_CURR_SYMBOL
, &save_as_string
},
124 { _CITRUS_LC_MONETARY_SYM_CURRENCY_SYMBOL
, &save_as_string
},
125 { _CITRUS_LC_MONETARY_SYM_MON_DECIMAL_POINT
, &save_as_string
},
126 { _CITRUS_LC_MONETARY_SYM_MON_THOUSANDS_SEP
, &save_as_string
},
127 { _CITRUS_LC_MONETARY_SYM_MON_GROUPING
, &save_as_grouping
},
128 { _CITRUS_LC_MONETARY_SYM_POSITIVE_SIGN
, &save_as_string
},
129 { _CITRUS_LC_MONETARY_SYM_NEGATIVE_SIGN
, &save_as_string
},
130 { _CITRUS_LC_MONETARY_SYM_INT_FRAC_DIGITS
, &save_as_uint8
},
131 { _CITRUS_LC_MONETARY_SYM_FRAC_DIGITS
, &save_as_uint8
},
132 { _CITRUS_LC_MONETARY_SYM_P_CS_PRECEDES
, &save_as_uint8
},
133 { _CITRUS_LC_MONETARY_SYM_P_SEP_BY_SPACE
, &save_as_uint8
},
134 { _CITRUS_LC_MONETARY_SYM_N_CS_PRECEDES
, &save_as_uint8
},
135 { _CITRUS_LC_MONETARY_SYM_N_SEP_BY_SPACE
, &save_as_uint8
},
136 { _CITRUS_LC_MONETARY_SYM_P_SIGN_POSN
, &save_as_uint8
},
137 { _CITRUS_LC_MONETARY_SYM_N_SIGN_POSN
, &save_as_uint8
},
138 { _CITRUS_LC_MONETARY_SYM_INT_P_CS_PRECEDES
, &save_as_uint8
},
139 { _CITRUS_LC_MONETARY_SYM_INT_P_SEP_BY_SPACE
, &save_as_uint8
},
140 { _CITRUS_LC_MONETARY_SYM_INT_N_CS_PRECEDES
, &save_as_uint8
},
141 { _CITRUS_LC_MONETARY_SYM_INT_N_SEP_BY_SPACE
, &save_as_uint8
},
142 { _CITRUS_LC_MONETARY_SYM_INT_P_SIGN_POSN
, &save_as_uint8
},
143 { _CITRUS_LC_MONETARY_SYM_INT_N_SIGN_POSN
, &save_as_uint8
},
148 static const category_t lc_numeric
= {
149 _CITRUS_LC_NUMERIC_MAGIC_1
,
150 _CITRUS_LC_NUMERIC_SYM_VERSION
,
151 _CITRUS_LC_NUMERIC_VERSION
,
153 { _CITRUS_LC_NUMERIC_SYM_DECIMAL_POINT
, &save_as_string
},
154 { _CITRUS_LC_NUMERIC_SYM_THOUSANDS_SEP
, &save_as_string
},
155 { _CITRUS_LC_NUMERIC_SYM_GROUPING
, &save_as_grouping
},
160 static const category_t lc_time
= {
161 _CITRUS_LC_TIME_MAGIC_1
,
162 _CITRUS_LC_TIME_SYM_VERSION
,
163 _CITRUS_LC_TIME_VERSION
,
165 { _CITRUS_LC_TIME_SYM_ABDAY_1
, &save_as_string
},
166 { _CITRUS_LC_TIME_SYM_ABDAY_2
, &save_as_string
},
167 { _CITRUS_LC_TIME_SYM_ABDAY_3
, &save_as_string
},
168 { _CITRUS_LC_TIME_SYM_ABDAY_4
, &save_as_string
},
169 { _CITRUS_LC_TIME_SYM_ABDAY_5
, &save_as_string
},
170 { _CITRUS_LC_TIME_SYM_ABDAY_6
, &save_as_string
},
171 { _CITRUS_LC_TIME_SYM_ABDAY_7
, &save_as_string
},
172 { _CITRUS_LC_TIME_SYM_DAY_1
, &save_as_string
},
173 { _CITRUS_LC_TIME_SYM_DAY_2
, &save_as_string
},
174 { _CITRUS_LC_TIME_SYM_DAY_3
, &save_as_string
},
175 { _CITRUS_LC_TIME_SYM_DAY_4
, &save_as_string
},
176 { _CITRUS_LC_TIME_SYM_DAY_5
, &save_as_string
},
177 { _CITRUS_LC_TIME_SYM_DAY_6
, &save_as_string
},
178 { _CITRUS_LC_TIME_SYM_DAY_7
, &save_as_string
},
179 { _CITRUS_LC_TIME_SYM_ABMON_1
, &save_as_string
},
180 { _CITRUS_LC_TIME_SYM_ABMON_2
, &save_as_string
},
181 { _CITRUS_LC_TIME_SYM_ABMON_3
, &save_as_string
},
182 { _CITRUS_LC_TIME_SYM_ABMON_4
, &save_as_string
},
183 { _CITRUS_LC_TIME_SYM_ABMON_5
, &save_as_string
},
184 { _CITRUS_LC_TIME_SYM_ABMON_6
, &save_as_string
},
185 { _CITRUS_LC_TIME_SYM_ABMON_7
, &save_as_string
},
186 { _CITRUS_LC_TIME_SYM_ABMON_8
, &save_as_string
},
187 { _CITRUS_LC_TIME_SYM_ABMON_9
, &save_as_string
},
188 { _CITRUS_LC_TIME_SYM_ABMON_10
, &save_as_string
},
189 { _CITRUS_LC_TIME_SYM_ABMON_11
, &save_as_string
},
190 { _CITRUS_LC_TIME_SYM_ABMON_12
, &save_as_string
},
191 { _CITRUS_LC_TIME_SYM_MON_1
, &save_as_string
},
192 { _CITRUS_LC_TIME_SYM_MON_2
, &save_as_string
},
193 { _CITRUS_LC_TIME_SYM_MON_3
, &save_as_string
},
194 { _CITRUS_LC_TIME_SYM_MON_4
, &save_as_string
},
195 { _CITRUS_LC_TIME_SYM_MON_5
, &save_as_string
},
196 { _CITRUS_LC_TIME_SYM_MON_6
, &save_as_string
},
197 { _CITRUS_LC_TIME_SYM_MON_7
, &save_as_string
},
198 { _CITRUS_LC_TIME_SYM_MON_8
, &save_as_string
},
199 { _CITRUS_LC_TIME_SYM_MON_9
, &save_as_string
},
200 { _CITRUS_LC_TIME_SYM_MON_10
, &save_as_string
},
201 { _CITRUS_LC_TIME_SYM_MON_11
, &save_as_string
},
202 { _CITRUS_LC_TIME_SYM_MON_12
, &save_as_string
},
203 { _CITRUS_LC_TIME_SYM_AM_STR
, &save_as_string
},
204 { _CITRUS_LC_TIME_SYM_PM_STR
, &save_as_string
},
205 { _CITRUS_LC_TIME_SYM_D_T_FMT
, &save_as_string
},
206 { _CITRUS_LC_TIME_SYM_D_FMT
, &save_as_string
},
207 { _CITRUS_LC_TIME_SYM_T_FMT
, &save_as_string
},
208 { _CITRUS_LC_TIME_SYM_T_FMT_AMPM
, &save_as_string
},
213 static const category_t lc_messages
= {
214 _CITRUS_LC_MESSAGES_MAGIC_1
,
215 _CITRUS_LC_MESSAGES_SYM_VERSION
,
216 _CITRUS_LC_MESSAGES_VERSION
,
218 { _CITRUS_LC_MESSAGES_SYM_YESEXPR
, &save_as_string
},
219 { _CITRUS_LC_MESSAGES_SYM_NOEXPR
, &save_as_string
},
220 { _CITRUS_LC_MESSAGES_SYM_YESSTR
, &save_as_string
},
221 { _CITRUS_LC_MESSAGES_SYM_NOSTR
, &save_as_string
},
227 mklocaledb(const char *type
, FILE *reader
, FILE *writer
)
229 static const char delim
[3] = { '\0', '\0', '#' };
230 const category_t
*category
= NULL
;
231 struct _db_factory
*df
;
232 const token_t
*token
;
238 _DIAGASSERT(type
!= NULL
);
239 _DIAGASSERT(reader
!= NULL
);
240 _DIAGASSERT(writer
!= NULL
);
242 if (!strcasecmp(type
, "MONETARY"))
243 category
= &lc_monetary
;
244 else if (!strcasecmp(type
, "NUMERIC"))
245 category
= &lc_numeric
;
246 else if (!strcasecmp(type
, "TIME"))
248 else if (!strcasecmp(type
, "MESSAGES"))
249 category
= &lc_messages
;
254 if (_db_factory_create(&df
, &_db_hash_std
, NULL
))
255 errx(EXIT_FAILURE
, "can't create db factory");
256 if (_db_factory_add32_by_s(df
, category
->vers_sym
, category
->version
))
257 errx(EXIT_FAILURE
, "can't store db");
258 token
= &category
->tokens
[0];
259 while (token
->key
!= NULL
) {
260 line
= fparseln(reader
, NULL
,
261 NULL
, delim
, FPARSELN_UNESCALL
);
263 errx(EXIT_FAILURE
, "can't read line");
264 if ((*token
->save
)(df
, token
->key
, (const char *)line
))
265 errx(EXIT_FAILURE
, "can't store db");
269 size
= _db_factory_calc_size(df
);
270 _DIAGASSERT(size
> 0);
271 serialized
= malloc(size
);
272 if (serialized
== NULL
)
273 errx(EXIT_FAILURE
, "can't malloc");
274 _DIAGASSERT(serialized
!= NULL
);
275 _region_init(&r
, serialized
, size
);
276 if (_db_factory_serialize(df
, category
->magic
, &r
))
277 errx(EXIT_FAILURE
, "can't serialize db");
278 fwrite(serialized
, size
, 1, writer
);
279 _db_factory_free(df
);