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