190423eceSAlexey Zelkin /* 274f2b975SAlexey Zelkin * Copyright (c) 2000, 2001 Alexey Zelkin <phantom@FreeBSD.org> 390423eceSAlexey Zelkin * All rights reserved. 490423eceSAlexey Zelkin * 5*3c87aa1dSDavid Chisnall * Copyright (c) 2011 The FreeBSD Foundation 6*3c87aa1dSDavid Chisnall * All rights reserved. 7*3c87aa1dSDavid Chisnall * Portions of this software were developed by David Chisnall 8*3c87aa1dSDavid Chisnall * under sponsorship from the FreeBSD Foundation. 9*3c87aa1dSDavid Chisnall * 1090423eceSAlexey Zelkin * Redistribution and use in source and binary forms, with or without 1190423eceSAlexey Zelkin * modification, are permitted provided that the following conditions 1290423eceSAlexey Zelkin * are met: 1390423eceSAlexey Zelkin * 1. Redistributions of source code must retain the above copyright 1490423eceSAlexey Zelkin * notice, this list of conditions and the following disclaimer. 1590423eceSAlexey Zelkin * 2. Redistributions in binary form must reproduce the above copyright 1690423eceSAlexey Zelkin * notice, this list of conditions and the following disclaimer in the 1790423eceSAlexey Zelkin * documentation and/or other materials provided with the distribution. 1890423eceSAlexey Zelkin * 1990423eceSAlexey Zelkin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2090423eceSAlexey Zelkin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2190423eceSAlexey Zelkin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2290423eceSAlexey Zelkin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2390423eceSAlexey Zelkin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2490423eceSAlexey Zelkin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2590423eceSAlexey Zelkin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2690423eceSAlexey Zelkin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2790423eceSAlexey Zelkin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2890423eceSAlexey Zelkin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2990423eceSAlexey Zelkin * SUCH DAMAGE. 3090423eceSAlexey Zelkin */ 3190423eceSAlexey Zelkin 32333fc21eSDavid E. O'Brien #include <sys/cdefs.h> 33333fc21eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 34333fc21eSDavid E. O'Brien 351bd7723dSAlexey Zelkin #include <limits.h> 36f4da1a75STim J. Robbins #include <stddef.h> 37831e8f61SAndrey A. Chernov #include <stdlib.h> 38683fe113SAlexey Zelkin 3990423eceSAlexey Zelkin #include "ldpart.h" 40683fe113SAlexey Zelkin #include "lmonetary.h" 4190423eceSAlexey Zelkin 421bd7723dSAlexey Zelkin extern const char * __fix_locale_grouping_str(const char *); 4390423eceSAlexey Zelkin 448a093dadSAndrey A. Chernov #define LCMONETARY_SIZE_FULL (sizeof(struct lc_monetary_T) / sizeof(char *)) 458a093dadSAndrey A. Chernov #define LCMONETARY_SIZE_MIN \ 468a093dadSAndrey A. Chernov (offsetof(struct lc_monetary_T, int_p_cs_precedes) / \ 478a093dadSAndrey A. Chernov sizeof(char *)) 4890423eceSAlexey Zelkin 4990423eceSAlexey Zelkin static char empty[] = ""; 501bd7723dSAlexey Zelkin static char numempty[] = { CHAR_MAX, '\0'}; 5190423eceSAlexey Zelkin 5290423eceSAlexey Zelkin static const struct lc_monetary_T _C_monetary_locale = { 5390423eceSAlexey Zelkin empty, /* int_curr_symbol */ 5490423eceSAlexey Zelkin empty, /* currency_symbol */ 5554e3bc25SAndrey A. Chernov empty, /* mon_decimal_point */ 5690423eceSAlexey Zelkin empty, /* mon_thousands_sep */ 5790423eceSAlexey Zelkin numempty, /* mon_grouping */ 5890423eceSAlexey Zelkin empty, /* positive_sign */ 5990423eceSAlexey Zelkin empty, /* negative_sign */ 6090423eceSAlexey Zelkin numempty, /* int_frac_digits */ 6190423eceSAlexey Zelkin numempty, /* frac_digits */ 6290423eceSAlexey Zelkin numempty, /* p_cs_precedes */ 6390423eceSAlexey Zelkin numempty, /* p_sep_by_space */ 6490423eceSAlexey Zelkin numempty, /* n_cs_precedes */ 6590423eceSAlexey Zelkin numempty, /* n_sep_by_space */ 6690423eceSAlexey Zelkin numempty, /* p_sign_posn */ 67f4da1a75STim J. Robbins numempty, /* n_sign_posn */ 68f4da1a75STim J. Robbins numempty, /* int_p_cs_precedes */ 69f4da1a75STim J. Robbins numempty, /* int_n_cs_precedes */ 70f4da1a75STim J. Robbins numempty, /* int_p_sep_by_space */ 71f4da1a75STim J. Robbins numempty, /* int_n_sep_by_space */ 72f4da1a75STim J. Robbins numempty, /* int_p_sign_posn */ 73f4da1a75STim J. Robbins numempty /* int_n_sign_posn */ 7490423eceSAlexey Zelkin }; 7590423eceSAlexey Zelkin 76*3c87aa1dSDavid Chisnall struct xlocale_monetary __xlocale_global_monetary; 7790423eceSAlexey Zelkin 78831e8f61SAndrey A. Chernov static char 79ecc4c620SAndrey A. Chernov cnv(const char *str) 80ecc4c620SAndrey A. Chernov { 81831e8f61SAndrey A. Chernov int i = strtol(str, NULL, 10); 82ecc4c620SAndrey A. Chernov 83831e8f61SAndrey A. Chernov if (i == -1) 84831e8f61SAndrey A. Chernov i = CHAR_MAX; 85ecc4c620SAndrey A. Chernov return ((char)i); 86831e8f61SAndrey A. Chernov } 87831e8f61SAndrey A. Chernov 88*3c87aa1dSDavid Chisnall static void 89*3c87aa1dSDavid Chisnall destruct_monetary(void *v) 90*3c87aa1dSDavid Chisnall { 91*3c87aa1dSDavid Chisnall struct xlocale_monetary *l = v; 92*3c87aa1dSDavid Chisnall if (l->buffer) 93*3c87aa1dSDavid Chisnall free(l->buffer); 94*3c87aa1dSDavid Chisnall free(l); 95*3c87aa1dSDavid Chisnall } 96*3c87aa1dSDavid Chisnall 97*3c87aa1dSDavid Chisnall static int 98*3c87aa1dSDavid Chisnall monetary_load_locale_l(struct xlocale_monetary *loc, int *using_locale, 99*3c87aa1dSDavid Chisnall int *changed, const char *name) 100ecc4c620SAndrey A. Chernov { 10190423eceSAlexey Zelkin int ret; 102*3c87aa1dSDavid Chisnall struct lc_monetary_T *l = &loc->locale; 103ecc4c620SAndrey A. Chernov 104*3c87aa1dSDavid Chisnall ret = __part_load_locale(name, using_locale, 105*3c87aa1dSDavid Chisnall &loc->buffer, "LC_MONETARY", 1068a093dadSAndrey A. Chernov LCMONETARY_SIZE_FULL, LCMONETARY_SIZE_MIN, 107*3c87aa1dSDavid Chisnall (const char **)l); 10876692b80SAndrey A. Chernov if (ret != _LDP_ERROR) 109*3c87aa1dSDavid Chisnall *changed = 1; 11076692b80SAndrey A. Chernov if (ret == _LDP_LOADED) { 111*3c87aa1dSDavid Chisnall l->mon_grouping = 112*3c87aa1dSDavid Chisnall __fix_locale_grouping_str(l->mon_grouping); 113831e8f61SAndrey A. Chernov 114*3c87aa1dSDavid Chisnall #define M_ASSIGN_CHAR(NAME) (((char *)l->NAME)[0] = \ 115*3c87aa1dSDavid Chisnall cnv(l->NAME)) 116831e8f61SAndrey A. Chernov 117831e8f61SAndrey A. Chernov M_ASSIGN_CHAR(int_frac_digits); 118831e8f61SAndrey A. Chernov M_ASSIGN_CHAR(frac_digits); 119831e8f61SAndrey A. Chernov M_ASSIGN_CHAR(p_cs_precedes); 120831e8f61SAndrey A. Chernov M_ASSIGN_CHAR(p_sep_by_space); 121831e8f61SAndrey A. Chernov M_ASSIGN_CHAR(n_cs_precedes); 122831e8f61SAndrey A. Chernov M_ASSIGN_CHAR(n_sep_by_space); 123831e8f61SAndrey A. Chernov M_ASSIGN_CHAR(p_sign_posn); 124831e8f61SAndrey A. Chernov M_ASSIGN_CHAR(n_sign_posn); 125f4da1a75STim J. Robbins 126f4da1a75STim J. Robbins /* 127f4da1a75STim J. Robbins * The six additional C99 international monetary formatting 128f4da1a75STim J. Robbins * parameters default to the national parameters when 129683fe113SAlexey Zelkin * reading FreeBSD LC_MONETARY data files. 130f4da1a75STim J. Robbins */ 131f4da1a75STim J. Robbins #define M_ASSIGN_ICHAR(NAME) \ 132f4da1a75STim J. Robbins do { \ 133*3c87aa1dSDavid Chisnall if (l->int_##NAME == NULL) \ 134*3c87aa1dSDavid Chisnall l->int_##NAME = \ 135*3c87aa1dSDavid Chisnall l->NAME; \ 136f4da1a75STim J. Robbins else \ 137f4da1a75STim J. Robbins M_ASSIGN_CHAR(int_##NAME); \ 138f4da1a75STim J. Robbins } while (0) 139f4da1a75STim J. Robbins 140f4da1a75STim J. Robbins M_ASSIGN_ICHAR(p_cs_precedes); 141f4da1a75STim J. Robbins M_ASSIGN_ICHAR(n_cs_precedes); 142f4da1a75STim J. Robbins M_ASSIGN_ICHAR(p_sep_by_space); 143f4da1a75STim J. Robbins M_ASSIGN_ICHAR(n_sep_by_space); 144f4da1a75STim J. Robbins M_ASSIGN_ICHAR(p_sign_posn); 145f4da1a75STim J. Robbins M_ASSIGN_ICHAR(n_sign_posn); 146831e8f61SAndrey A. Chernov } 147ecc4c620SAndrey A. Chernov return (ret); 14890423eceSAlexey Zelkin } 149*3c87aa1dSDavid Chisnall int 150*3c87aa1dSDavid Chisnall __monetary_load_locale(const char *name) 151*3c87aa1dSDavid Chisnall { 152*3c87aa1dSDavid Chisnall return monetary_load_locale_l(&__xlocale_global_monetary, 153*3c87aa1dSDavid Chisnall &__xlocale_global_locale.using_monetary_locale, 154*3c87aa1dSDavid Chisnall &__xlocale_global_locale.monetary_locale_changed, name); 155*3c87aa1dSDavid Chisnall } 156*3c87aa1dSDavid Chisnall void* __monetary_load(const char *name, locale_t l) 157*3c87aa1dSDavid Chisnall { 158*3c87aa1dSDavid Chisnall struct xlocale_monetary *new = calloc(sizeof(struct xlocale_monetary), 1); 159*3c87aa1dSDavid Chisnall new->header.header.destructor = destruct_monetary; 160*3c87aa1dSDavid Chisnall if (monetary_load_locale_l(new, &l->using_monetary_locale, 161*3c87aa1dSDavid Chisnall &l->monetary_locale_changed, name) == _LDP_ERROR) 162*3c87aa1dSDavid Chisnall { 163*3c87aa1dSDavid Chisnall xlocale_release(new); 164*3c87aa1dSDavid Chisnall return NULL; 165*3c87aa1dSDavid Chisnall } 166*3c87aa1dSDavid Chisnall return new; 167*3c87aa1dSDavid Chisnall } 168*3c87aa1dSDavid Chisnall 16990423eceSAlexey Zelkin 17090423eceSAlexey Zelkin struct lc_monetary_T * 171*3c87aa1dSDavid Chisnall __get_current_monetary_locale(locale_t loc) 172ecc4c620SAndrey A. Chernov { 173*3c87aa1dSDavid Chisnall return (loc->using_monetary_locale 174*3c87aa1dSDavid Chisnall ? &((struct xlocale_monetary*)loc->components[XLC_MONETARY])->locale 17590423eceSAlexey Zelkin : (struct lc_monetary_T *)&_C_monetary_locale); 17690423eceSAlexey Zelkin } 17790423eceSAlexey Zelkin 17890423eceSAlexey Zelkin #ifdef LOCALE_DEBUG 17990423eceSAlexey Zelkin void 18090423eceSAlexey Zelkin monetdebug() { 18190423eceSAlexey Zelkin printf( "int_curr_symbol = %s\n" 18290423eceSAlexey Zelkin "currency_symbol = %s\n" 18390423eceSAlexey Zelkin "mon_decimal_point = %s\n" 18490423eceSAlexey Zelkin "mon_thousands_sep = %s\n" 18590423eceSAlexey Zelkin "mon_grouping = %s\n" 18690423eceSAlexey Zelkin "positive_sign = %s\n" 18790423eceSAlexey Zelkin "negative_sign = %s\n" 188831e8f61SAndrey A. Chernov "int_frac_digits = %d\n" 189831e8f61SAndrey A. Chernov "frac_digits = %d\n" 190831e8f61SAndrey A. Chernov "p_cs_precedes = %d\n" 191831e8f61SAndrey A. Chernov "p_sep_by_space = %d\n" 192831e8f61SAndrey A. Chernov "n_cs_precedes = %d\n" 193831e8f61SAndrey A. Chernov "n_sep_by_space = %d\n" 194831e8f61SAndrey A. Chernov "p_sign_posn = %d\n" 195831e8f61SAndrey A. Chernov "n_sign_posn = %d\n", 196683fe113SAlexey Zelkin "int_p_cs_precedes = %d\n" 197683fe113SAlexey Zelkin "int_p_sep_by_space = %d\n" 198683fe113SAlexey Zelkin "int_n_cs_precedes = %d\n" 199683fe113SAlexey Zelkin "int_n_sep_by_space = %d\n" 200683fe113SAlexey Zelkin "int_p_sign_posn = %d\n" 201683fe113SAlexey Zelkin "int_n_sign_posn = %d\n", 20290423eceSAlexey Zelkin _monetary_locale.int_curr_symbol, 20390423eceSAlexey Zelkin _monetary_locale.currency_symbol, 20490423eceSAlexey Zelkin _monetary_locale.mon_decimal_point, 20590423eceSAlexey Zelkin _monetary_locale.mon_thousands_sep, 20690423eceSAlexey Zelkin _monetary_locale.mon_grouping, 20790423eceSAlexey Zelkin _monetary_locale.positive_sign, 20890423eceSAlexey Zelkin _monetary_locale.negative_sign, 209831e8f61SAndrey A. Chernov _monetary_locale.int_frac_digits[0], 210831e8f61SAndrey A. Chernov _monetary_locale.frac_digits[0], 211831e8f61SAndrey A. Chernov _monetary_locale.p_cs_precedes[0], 212831e8f61SAndrey A. Chernov _monetary_locale.p_sep_by_space[0], 213831e8f61SAndrey A. Chernov _monetary_locale.n_cs_precedes[0], 214831e8f61SAndrey A. Chernov _monetary_locale.n_sep_by_space[0], 215831e8f61SAndrey A. Chernov _monetary_locale.p_sign_posn[0], 216683fe113SAlexey Zelkin _monetary_locale.n_sign_posn[0], 217683fe113SAlexey Zelkin _monetary_locale.int_p_cs_precedes[0], 218683fe113SAlexey Zelkin _monetary_locale.int_p_sep_by_space[0], 219683fe113SAlexey Zelkin _monetary_locale.int_n_cs_precedes[0], 220683fe113SAlexey Zelkin _monetary_locale.int_n_sep_by_space[0], 221683fe113SAlexey Zelkin _monetary_locale.int_p_sign_posn[0], 222683fe113SAlexey Zelkin _monetary_locale.int_n_sign_posn[0] 22390423eceSAlexey Zelkin ); 22490423eceSAlexey Zelkin } 22590423eceSAlexey Zelkin #endif /* LOCALE_DEBUG */ 226