Home | History | Annotate | Line # | Download | only in mklocale
mklocaledb.c revision 1.2.16.1
      1  1.2.16.1      tls /* $NetBSD: mklocaledb.c,v 1.2.16.1 2014/08/20 00:05:01 tls Exp $ */
      2       1.1  tnozaki 
      3       1.1  tnozaki /*-
      4       1.1  tnozaki  * Copyright (c)2008 Citrus Project,
      5       1.1  tnozaki  * All rights reserved.
      6       1.1  tnozaki  *
      7       1.1  tnozaki  * Redistribution and use in source and binary forms, with or without
      8       1.1  tnozaki  * modification, are permitted provided that the following conditions
      9       1.1  tnozaki  * are met:
     10       1.1  tnozaki  * 1. Redistributions of source code must retain the above copyright
     11       1.1  tnozaki  *    notice, this list of conditions and the following disclaimer.
     12       1.1  tnozaki  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.1  tnozaki  *    notice, this list of conditions and the following disclaimer in the
     14       1.1  tnozaki  *    documentation and/or other materials provided with the distribution.
     15       1.1  tnozaki  *
     16       1.1  tnozaki  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     17       1.1  tnozaki  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18       1.1  tnozaki  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19       1.1  tnozaki  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     20       1.1  tnozaki  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21       1.1  tnozaki  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22       1.1  tnozaki  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23       1.1  tnozaki  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24       1.1  tnozaki  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25       1.1  tnozaki  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26       1.1  tnozaki  * SUCH DAMAGE.
     27       1.1  tnozaki  */
     28       1.1  tnozaki 
     29       1.1  tnozaki /*
     30       1.1  tnozaki  * XXX TEMPORARY IMPLEMENTATION.
     31       1.1  tnozaki  * don't waste your time, all we need is localedef(1).
     32       1.1  tnozaki  */
     33       1.1  tnozaki 
     34       1.2   dogcow #if HAVE_NBTOOL_CONFIG_H
     35       1.2   dogcow #include "nbtool_config.h"
     36       1.2   dogcow #endif
     37       1.2   dogcow 
     38       1.1  tnozaki #include <sys/cdefs.h>
     39       1.1  tnozaki #if !defined(lint)
     40  1.2.16.1      tls __RCSID("$NetBSD: mklocaledb.c,v 1.2.16.1 2014/08/20 00:05:01 tls Exp $");
     41       1.1  tnozaki #endif /* not lint */
     42       1.1  tnozaki 
     43       1.1  tnozaki #include <assert.h>
     44       1.1  tnozaki #include <err.h>
     45       1.1  tnozaki #include <errno.h>
     46       1.1  tnozaki #include <limits.h>
     47       1.1  tnozaki #include <stdint.h>
     48       1.1  tnozaki #include <stdio.h>
     49       1.1  tnozaki #include <stdlib.h>
     50       1.1  tnozaki #include <string.h>
     51       1.1  tnozaki #include <unistd.h>
     52       1.1  tnozaki 
     53       1.1  tnozaki #include "fix_grouping.h"
     54       1.1  tnozaki 
     55       1.1  tnozaki #include "citrus_namespace.h"
     56       1.1  tnozaki #include "citrus_bcs.h"
     57       1.1  tnozaki #include "citrus_types.h"
     58       1.1  tnozaki #include "citrus_region.h"
     59       1.1  tnozaki #include "citrus_db_factory.h"
     60       1.1  tnozaki #include "citrus_db_hash.h"
     61       1.1  tnozaki #include "citrus_db.h"
     62       1.1  tnozaki 
     63       1.1  tnozaki #include "citrus_lc_monetary.h"
     64       1.1  tnozaki #include "citrus_lc_numeric.h"
     65       1.1  tnozaki #include "citrus_lc_time.h"
     66       1.1  tnozaki #include "citrus_lc_messages.h"
     67       1.1  tnozaki 
     68       1.1  tnozaki void mklocaledb(const char *, FILE *, FILE *);
     69       1.1  tnozaki 
     70       1.1  tnozaki /*
     71       1.1  tnozaki  * TODO: -d debug options's output.
     72       1.1  tnozaki  */
     73       1.1  tnozaki extern int debug;
     74       1.1  tnozaki extern void usage(void);
     75       1.1  tnozaki 
     76       1.1  tnozaki static int
     77       1.1  tnozaki save_as_string(struct _db_factory *df,
     78       1.1  tnozaki     const char *key, const char *value)
     79       1.1  tnozaki {
     80       1.1  tnozaki 	return _db_factory_addstr_by_s(df, key, value);
     81       1.1  tnozaki }
     82       1.1  tnozaki 
     83       1.1  tnozaki static int
     84       1.1  tnozaki save_as_grouping(struct _db_factory *df,
     85       1.1  tnozaki     const char *key, const char *value)
     86       1.1  tnozaki {
     87       1.1  tnozaki 	value = __fix_locale_grouping_str(value);
     88       1.1  tnozaki 	return _db_factory_addstr_by_s(df, key, value);
     89       1.1  tnozaki }
     90       1.1  tnozaki 
     91       1.1  tnozaki static int
     92       1.1  tnozaki save_as_uint8(struct _db_factory *df,
     93       1.1  tnozaki     const char *key, const char *head)
     94       1.1  tnozaki {
     95       1.1  tnozaki 	char *tail;
     96       1.1  tnozaki 	unsigned long int value;
     97       1.1  tnozaki 	uint8_t u8;
     98       1.1  tnozaki 
     99       1.1  tnozaki 	value = _bcs_strtoul(head, &tail, 0);
    100       1.1  tnozaki 	if (head == tail || value > 0xFF)
    101       1.1  tnozaki 		return 1;
    102       1.1  tnozaki 	u8 = (uint8_t)(value & 0xFF);
    103       1.1  tnozaki 	return _db_factory_add8_by_s(df, key, u8);
    104       1.1  tnozaki }
    105       1.1  tnozaki 
    106       1.1  tnozaki typedef struct {
    107       1.1  tnozaki 	const char *key;
    108       1.1  tnozaki 	int (*save)(struct _db_factory *,
    109       1.1  tnozaki 	    const char *, const char *);
    110       1.1  tnozaki } token_t;
    111       1.1  tnozaki 
    112       1.1  tnozaki typedef struct {
    113       1.1  tnozaki 	const char *magic, * vers_sym;
    114       1.1  tnozaki 	uint32_t version;
    115       1.1  tnozaki 	const token_t tokens[];
    116       1.1  tnozaki } category_t;
    117       1.1  tnozaki 
    118       1.1  tnozaki static const category_t lc_monetary = {
    119       1.1  tnozaki     _CITRUS_LC_MONETARY_MAGIC_1,
    120       1.1  tnozaki     _CITRUS_LC_MONETARY_SYM_VERSION,
    121       1.1  tnozaki     _CITRUS_LC_MONETARY_VERSION,
    122       1.1  tnozaki     {
    123       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_INT_CURR_SYMBOL,    &save_as_string   },
    124       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_CURRENCY_SYMBOL,    &save_as_string   },
    125       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_MON_DECIMAL_POINT,  &save_as_string   },
    126       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_MON_THOUSANDS_SEP,  &save_as_string   },
    127       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_MON_GROUPING,       &save_as_grouping },
    128       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_POSITIVE_SIGN,      &save_as_string   },
    129       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_NEGATIVE_SIGN,      &save_as_string   },
    130       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_INT_FRAC_DIGITS,    &save_as_uint8    },
    131       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_FRAC_DIGITS,        &save_as_uint8    },
    132       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_P_CS_PRECEDES,      &save_as_uint8    },
    133       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_P_SEP_BY_SPACE,     &save_as_uint8    },
    134       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_N_CS_PRECEDES,      &save_as_uint8    },
    135       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_N_SEP_BY_SPACE,     &save_as_uint8    },
    136       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_P_SIGN_POSN,        &save_as_uint8    },
    137       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_N_SIGN_POSN,        &save_as_uint8    },
    138       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_INT_P_CS_PRECEDES,  &save_as_uint8    },
    139       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_INT_P_SEP_BY_SPACE, &save_as_uint8    },
    140  1.2.16.1      tls 	{ _CITRUS_LC_MONETARY_SYM_INT_N_CS_PRECEDES,  &save_as_uint8    },
    141       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_INT_N_SEP_BY_SPACE, &save_as_uint8    },
    142       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_INT_P_SIGN_POSN,    &save_as_uint8    },
    143       1.1  tnozaki 	{ _CITRUS_LC_MONETARY_SYM_INT_N_SIGN_POSN,    &save_as_uint8    },
    144       1.1  tnozaki 	{ NULL },
    145       1.1  tnozaki     },
    146       1.1  tnozaki };
    147       1.1  tnozaki 
    148       1.1  tnozaki static const category_t lc_numeric = {
    149       1.1  tnozaki     _CITRUS_LC_NUMERIC_MAGIC_1,
    150       1.1  tnozaki     _CITRUS_LC_NUMERIC_SYM_VERSION,
    151       1.1  tnozaki     _CITRUS_LC_NUMERIC_VERSION,
    152       1.1  tnozaki     {
    153       1.1  tnozaki 	{ _CITRUS_LC_NUMERIC_SYM_DECIMAL_POINT, &save_as_string   },
    154       1.1  tnozaki 	{ _CITRUS_LC_NUMERIC_SYM_THOUSANDS_SEP, &save_as_string   },
    155       1.1  tnozaki 	{ _CITRUS_LC_NUMERIC_SYM_GROUPING,      &save_as_grouping },
    156       1.1  tnozaki 	{ NULL },
    157       1.1  tnozaki     },
    158       1.1  tnozaki };
    159       1.1  tnozaki 
    160       1.1  tnozaki static const category_t lc_time = {
    161       1.1  tnozaki     _CITRUS_LC_TIME_MAGIC_1,
    162       1.1  tnozaki     _CITRUS_LC_TIME_SYM_VERSION,
    163       1.1  tnozaki     _CITRUS_LC_TIME_VERSION,
    164       1.1  tnozaki     {
    165       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABDAY_1,     &save_as_string },
    166       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABDAY_2,     &save_as_string },
    167       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABDAY_3,     &save_as_string },
    168       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABDAY_4,     &save_as_string },
    169       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABDAY_5,     &save_as_string },
    170       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABDAY_6,     &save_as_string },
    171       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABDAY_7,     &save_as_string },
    172       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_DAY_1,       &save_as_string },
    173       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_DAY_2,       &save_as_string },
    174       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_DAY_3,       &save_as_string },
    175       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_DAY_4,       &save_as_string },
    176       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_DAY_5,       &save_as_string },
    177       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_DAY_6,       &save_as_string },
    178       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_DAY_7,       &save_as_string },
    179       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABMON_1,     &save_as_string },
    180       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABMON_2,     &save_as_string },
    181       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABMON_3,     &save_as_string },
    182       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABMON_4,     &save_as_string },
    183       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABMON_5,     &save_as_string },
    184       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABMON_6,     &save_as_string },
    185       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABMON_7,     &save_as_string },
    186       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABMON_8,     &save_as_string },
    187       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABMON_9,     &save_as_string },
    188       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABMON_10,    &save_as_string },
    189       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABMON_11,    &save_as_string },
    190       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_ABMON_12,    &save_as_string },
    191       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_MON_1,       &save_as_string },
    192       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_MON_2,       &save_as_string },
    193       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_MON_3,       &save_as_string },
    194       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_MON_4,       &save_as_string },
    195       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_MON_5,       &save_as_string },
    196       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_MON_6,       &save_as_string },
    197       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_MON_7,       &save_as_string },
    198       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_MON_8,       &save_as_string },
    199       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_MON_9,       &save_as_string },
    200       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_MON_10,      &save_as_string },
    201       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_MON_11,      &save_as_string },
    202       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_MON_12,      &save_as_string },
    203       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_AM_STR,      &save_as_string },
    204       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_PM_STR,      &save_as_string },
    205       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_D_T_FMT,     &save_as_string },
    206       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_D_FMT,       &save_as_string },
    207       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_T_FMT,       &save_as_string },
    208       1.1  tnozaki 	{ _CITRUS_LC_TIME_SYM_T_FMT_AMPM,  &save_as_string },
    209       1.1  tnozaki 	{ NULL },
    210       1.1  tnozaki     },
    211       1.1  tnozaki };
    212       1.1  tnozaki 
    213       1.1  tnozaki static const category_t lc_messages = {
    214       1.1  tnozaki     _CITRUS_LC_MESSAGES_MAGIC_1,
    215       1.1  tnozaki     _CITRUS_LC_MESSAGES_SYM_VERSION,
    216       1.1  tnozaki     _CITRUS_LC_MESSAGES_VERSION,
    217       1.1  tnozaki     {
    218       1.1  tnozaki 	{ _CITRUS_LC_MESSAGES_SYM_YESEXPR, &save_as_string },
    219       1.1  tnozaki 	{ _CITRUS_LC_MESSAGES_SYM_NOEXPR,  &save_as_string },
    220       1.1  tnozaki 	{ _CITRUS_LC_MESSAGES_SYM_YESSTR,  &save_as_string },
    221       1.1  tnozaki 	{ _CITRUS_LC_MESSAGES_SYM_NOSTR,   &save_as_string },
    222       1.1  tnozaki 	{ NULL },
    223       1.1  tnozaki     },
    224       1.1  tnozaki };
    225       1.1  tnozaki 
    226       1.1  tnozaki void
    227       1.1  tnozaki mklocaledb(const char *type, FILE *reader, FILE *writer)
    228       1.1  tnozaki {
    229       1.1  tnozaki 	static const char delim[3] = { '\0', '\0', '#' };
    230       1.1  tnozaki 	const category_t *category = NULL;
    231       1.1  tnozaki 	struct _db_factory *df;
    232       1.1  tnozaki 	const token_t *token;
    233       1.1  tnozaki 	char *line;
    234       1.1  tnozaki 	size_t size;
    235       1.1  tnozaki 	void *serialized;
    236       1.1  tnozaki 	struct _region r;
    237       1.1  tnozaki 
    238       1.1  tnozaki 	_DIAGASSERT(type != NULL);
    239       1.1  tnozaki 	_DIAGASSERT(reader != NULL);
    240       1.1  tnozaki 	_DIAGASSERT(writer != NULL);
    241       1.1  tnozaki 
    242       1.1  tnozaki 	if (!strcasecmp(type, "MONETARY"))
    243       1.1  tnozaki 		category = &lc_monetary;
    244       1.1  tnozaki 	else if (!strcasecmp(type, "NUMERIC"))
    245       1.1  tnozaki 		category = &lc_numeric;
    246       1.1  tnozaki 	else if (!strcasecmp(type, "TIME"))
    247       1.1  tnozaki 		category = &lc_time;
    248       1.1  tnozaki 	else if (!strcasecmp(type, "MESSAGES"))
    249       1.1  tnozaki 		category = &lc_messages;
    250       1.1  tnozaki 	else {
    251       1.1  tnozaki 		usage();
    252       1.1  tnozaki 		/*NOTREACHED*/
    253       1.1  tnozaki 	}
    254       1.1  tnozaki 	if (_db_factory_create(&df, &_db_hash_std, NULL))
    255       1.1  tnozaki 		errx(1, "can't create db factory.\n");
    256       1.1  tnozaki 	if (_db_factory_add32_by_s(df, category->vers_sym, category->version))
    257       1.1  tnozaki 		errx(1, "can't store db.\n");
    258       1.1  tnozaki 	token = &category->tokens[0];
    259       1.1  tnozaki 	while (token->key != NULL) {
    260       1.1  tnozaki 		line = fparseln(reader, NULL,
    261       1.1  tnozaki 		    NULL, delim, FPARSELN_UNESCALL);
    262       1.1  tnozaki 		if (line == NULL)
    263       1.1  tnozaki 			errx(1, "can't read line.\n");
    264       1.1  tnozaki 		if ((*token->save)(df, token->key, (const char *)line))
    265       1.1  tnozaki 			errx(1, "can't store db.\n");
    266       1.1  tnozaki 		free(line);
    267       1.1  tnozaki 		++token;
    268       1.1  tnozaki 	}
    269       1.1  tnozaki 	size = _db_factory_calc_size(df);
    270       1.1  tnozaki 	_DIAGASSERT(size > 0);
    271       1.1  tnozaki 	serialized = malloc(size);
    272       1.1  tnozaki 	if (serialized == NULL)
    273       1.1  tnozaki 		errx(1, "can't malloc.\n");
    274       1.1  tnozaki 	_DIAGASSERT(serialized != NULL);
    275       1.1  tnozaki 	_region_init(&r, serialized, size);
    276       1.1  tnozaki 	if (_db_factory_serialize(df, category->magic, &r))
    277       1.1  tnozaki 		errx(1, "can't serialize db.\n");
    278       1.1  tnozaki 	fwrite(serialized, size, 1, writer);
    279       1.1  tnozaki 	_db_factory_free(df);
    280       1.1  tnozaki }
    281