lmonetary.c revision 116274
119370Spst/*
219370Spst * Copyright (c) 2000, 2001 Alexey Zelkin <phantom@FreeBSD.org>
398944Sobrien * All rights reserved.
4130803Smarcel *
598944Sobrien * Redistribution and use in source and binary forms, with or without
619370Spst * modification, are permitted provided that the following conditions
798944Sobrien * are met:
819370Spst * 1. Redistributions of source code must retain the above copyright
998944Sobrien *    notice, this list of conditions and the following disclaimer.
1098944Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1198944Sobrien *    notice, this list of conditions and the following disclaimer in the
1298944Sobrien *    documentation and/or other materials provided with the distribution.
1319370Spst *
1498944Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1598944Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1698944Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1798944Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1819370Spst * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1998944Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2098944Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2198944Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2298944Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2398944Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2419370Spst * SUCH DAMAGE.
2519370Spst */
2619370Spst
2719370Spst#include <sys/cdefs.h>
2819370Spst__FBSDID("$FreeBSD: head/lib/libc/locale/lmonetary.c 116274 2003-06-13 00:14:07Z jkh $");
2919370Spst
3019370Spst#include <limits.h>
3119370Spst#include <stddef.h>
3219370Spst#include <stdlib.h>
3319370Spst#include "lmonetary.h"
3419370Spst#include "ldpart.h"
3519370Spst
3619370Spstextern int __mlocale_changed;
3719370Spstextern const char * __fix_locale_grouping_str(const char *);
3819370Spst
3998944Sobrien#define LCMONETARY_SIZE_FULL (sizeof(struct lc_monetary_T) / sizeof(char *))
4098944Sobrien#define LCMONETARY_SIZE_MIN \
4198944Sobrien		(offsetof(struct lc_monetary_T, int_p_cs_precedes) / \
4298944Sobrien		    sizeof(char *))
43130803Smarcel
44130803Smarcelstatic char	empty[] = "";
45130803Smarcelstatic char	numempty[] = { CHAR_MAX, '\0'};
4619370Spst
47130803Smarcelstatic const struct lc_monetary_T _C_monetary_locale = {
48130803Smarcel	empty,		/* int_curr_symbol */
49130803Smarcel	empty,		/* currency_symbol */
50130803Smarcel	empty,		/* mon_decimal_point */
5119370Spst	empty,		/* mon_thousands_sep */
5219370Spst	numempty,	/* mon_grouping */
5319370Spst	empty,		/* positive_sign */
5419370Spst	empty,		/* negative_sign */
5598944Sobrien	numempty,	/* int_frac_digits */
5698944Sobrien	numempty,	/* frac_digits */
5798944Sobrien	numempty,	/* p_cs_precedes */
5898944Sobrien	numempty,	/* p_sep_by_space */
5998944Sobrien	numempty,	/* n_cs_precedes */
6019370Spst	numempty,	/* n_sep_by_space */
6119370Spst	numempty,	/* p_sign_posn */
6219370Spst	numempty,	/* n_sign_posn */
6319370Spst	numempty,	/* int_p_cs_precedes */
6419370Spst	numempty,	/* int_n_cs_precedes */
6519370Spst	numempty,	/* int_p_sep_by_space */
6619370Spst	numempty,	/* int_n_sep_by_space */
6719370Spst	numempty,	/* int_p_sign_posn */
6819370Spst	numempty	/* int_n_sign_posn */
6919370Spst};
7019370Spst
7119370Spststatic struct lc_monetary_T _monetary_locale;
7219370Spststatic int	_monetary_using_locale;
7346283Sdfrstatic char	*_monetary_locale_buf;
7446283Sdfr
7546283Sdfrstatic char
7646283Sdfrcnv(const char *str)
7719370Spst{
7819370Spst	int i = strtol(str, NULL, 10);
7919370Spst
8019370Spst	if (i == -1)
8119370Spst		i = CHAR_MAX;
8219370Spst	return ((char)i);
8319370Spst}
8498944Sobrien
8519370Spstint
8619370Spst__monetary_load_locale(const char *name)
8719370Spst{
8819370Spst	int ret;
8919370Spst
9019370Spst	ret = __part_load_locale(name, &_monetary_using_locale,
9119370Spst		&_monetary_locale_buf, "LC_MONETARY",
9219370Spst		LCMONETARY_SIZE_FULL, LCMONETARY_SIZE_MIN,
9319370Spst		(const char **)&_monetary_locale);
9419370Spst	if (ret != _LDP_ERROR)
9519370Spst		__mlocale_changed = 1;
9619370Spst	if (ret == _LDP_LOADED) {
9719370Spst		_monetary_locale.mon_grouping =
9819370Spst		     __fix_locale_grouping_str(_monetary_locale.mon_grouping);
9919370Spst
10019370Spst#define M_ASSIGN_CHAR(NAME) (((char *)_monetary_locale.NAME)[0] = \
10119370Spst			     cnv(_monetary_locale.NAME))
10219370Spst
10319370Spst		M_ASSIGN_CHAR(int_frac_digits);
10419370Spst		M_ASSIGN_CHAR(frac_digits);
10519370Spst		M_ASSIGN_CHAR(p_cs_precedes);
10619370Spst		M_ASSIGN_CHAR(p_sep_by_space);
10719370Spst		M_ASSIGN_CHAR(n_cs_precedes);
10819370Spst		M_ASSIGN_CHAR(n_sep_by_space);
10998944Sobrien		M_ASSIGN_CHAR(p_sign_posn);
11098944Sobrien		M_ASSIGN_CHAR(n_sign_posn);
11198944Sobrien
11298944Sobrien		/*
11398944Sobrien		 * The six additional C99 international monetary formatting
11498944Sobrien		 * parameters default to the national parameters when
11598944Sobrien		 * reading FreeBSD 4 LC_MONETARY data files.
11698944Sobrien		 */
11798944Sobrien#define	M_ASSIGN_ICHAR(NAME)						\
11898944Sobrien		do {							\
11998944Sobrien			if (_monetary_locale.int_##NAME == NULL)	\
12098944Sobrien				_monetary_locale.int_##NAME =		\
12198944Sobrien				    _monetary_locale.NAME;		\
12298944Sobrien			else						\
12319370Spst				M_ASSIGN_CHAR(int_##NAME);		\
12419370Spst		} while (0)
12519370Spst
12619370Spst		M_ASSIGN_ICHAR(p_cs_precedes);
12719370Spst		M_ASSIGN_ICHAR(n_cs_precedes);
12819370Spst		M_ASSIGN_ICHAR(p_sep_by_space);
12919370Spst		M_ASSIGN_ICHAR(n_sep_by_space);
13019370Spst		M_ASSIGN_ICHAR(p_sign_posn);
13146283Sdfr		M_ASSIGN_ICHAR(n_sign_posn);
13219370Spst	}
13398944Sobrien	return (ret);
13419370Spst}
13598944Sobrien
13619370Spststruct lc_monetary_T *
13746283Sdfr__get_current_monetary_locale(void)
13846283Sdfr{
13998944Sobrien	return (_monetary_using_locale
14019370Spst		? &_monetary_locale
14198944Sobrien		: (struct lc_monetary_T *)&_C_monetary_locale);
14219370Spst}
14398944Sobrien
14419370Spst#ifdef LOCALE_DEBUG
14598944Sobrienvoid
14619370Spstmonetdebug() {
14798944Sobrienprintf(	"int_curr_symbol = %s\n"
14819370Spst	"currency_symbol = %s\n"
14998944Sobrien	"mon_decimal_point = %s\n"
15019370Spst	"mon_thousands_sep = %s\n"
15198944Sobrien	"mon_grouping = %s\n"
15219370Spst	"positive_sign = %s\n"
15398944Sobrien	"negative_sign = %s\n"
15419370Spst	"int_frac_digits = %d\n"
15598944Sobrien	"frac_digits = %d\n"
15619370Spst	"p_cs_precedes = %d\n"
15798944Sobrien	"p_sep_by_space = %d\n"
15819370Spst	"n_cs_precedes = %d\n"
15998944Sobrien	"n_sep_by_space = %d\n"
16019370Spst	"p_sign_posn = %d\n"
16198944Sobrien	"n_sign_posn = %d\n",
16219370Spst	_monetary_locale.int_curr_symbol,
16398944Sobrien	_monetary_locale.currency_symbol,
16419370Spst	_monetary_locale.mon_decimal_point,
16598944Sobrien	_monetary_locale.mon_thousands_sep,
16619370Spst	_monetary_locale.mon_grouping,
16798944Sobrien	_monetary_locale.positive_sign,
16819370Spst	_monetary_locale.negative_sign,
16998944Sobrien	_monetary_locale.int_frac_digits[0],
17019370Spst	_monetary_locale.frac_digits[0],
17198944Sobrien	_monetary_locale.p_cs_precedes[0],
17219370Spst	_monetary_locale.p_sep_by_space[0],
17398944Sobrien	_monetary_locale.n_cs_precedes[0],
17498944Sobrien	_monetary_locale.n_sep_by_space[0],
17519370Spst	_monetary_locale.p_sign_posn[0],
17698944Sobrien	_monetary_locale.n_sign_posn[0]
17719370Spst);
17898944Sobrien}
17919370Spst#endif /* LOCALE_DEBUG */
18098944Sobrien