172165Sphantom/* 287658Sphantom * Copyright (c) 2000, 2001 Alexey Zelkin <phantom@FreeBSD.org> 372165Sphantom * All rights reserved. 472165Sphantom * 5227753Stheraven * Copyright (c) 2011 The FreeBSD Foundation 6227753Stheraven * All rights reserved. 7227753Stheraven * Portions of this software were developed by David Chisnall 8227753Stheraven * under sponsorship from the FreeBSD Foundation. 9227753Stheraven * 1072165Sphantom * Redistribution and use in source and binary forms, with or without 1172165Sphantom * modification, are permitted provided that the following conditions 1272165Sphantom * are met: 1372165Sphantom * 1. Redistributions of source code must retain the above copyright 1472165Sphantom * notice, this list of conditions and the following disclaimer. 1572165Sphantom * 2. Redistributions in binary form must reproduce the above copyright 1672165Sphantom * notice, this list of conditions and the following disclaimer in the 1772165Sphantom * documentation and/or other materials provided with the distribution. 1872165Sphantom * 1972165Sphantom * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2072165Sphantom * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2172165Sphantom * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2272165Sphantom * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2372165Sphantom * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2472165Sphantom * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2572165Sphantom * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2672165Sphantom * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2772165Sphantom * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2872165Sphantom * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2972165Sphantom * SUCH DAMAGE. 3072165Sphantom */ 3172165Sphantom 3292986Sobrien#include <sys/cdefs.h> 3392986Sobrien__FBSDID("$FreeBSD: releng/10.3/lib/libc/locale/lmonetary.c 227753 2011-11-20 14:45:42Z theraven $"); 3492986Sobrien 3572321Sphantom#include <limits.h> 36104711Stjr#include <stddef.h> 3789907Sache#include <stdlib.h> 38116875Sphantom 39116875Sphantom#include "ldpart.h" 4072165Sphantom#include "lmonetary.h" 4172165Sphantom 4272321Sphantomextern const char * __fix_locale_grouping_str(const char *); 4372165Sphantom 44104982Sache#define LCMONETARY_SIZE_FULL (sizeof(struct lc_monetary_T) / sizeof(char *)) 45104982Sache#define LCMONETARY_SIZE_MIN \ 46104982Sache (offsetof(struct lc_monetary_T, int_p_cs_precedes) / \ 47104982Sache sizeof(char *)) 4872165Sphantom 4972165Sphantomstatic char empty[] = ""; 5087658Sphantomstatic char numempty[] = { CHAR_MAX, '\0'}; 5172165Sphantom 5272165Sphantomstatic const struct lc_monetary_T _C_monetary_locale = { 5387658Sphantom empty, /* int_curr_symbol */ 5487658Sphantom empty, /* currency_symbol */ 5587658Sphantom empty, /* mon_decimal_point */ 5687658Sphantom empty, /* mon_thousands_sep */ 5787658Sphantom numempty, /* mon_grouping */ 5887658Sphantom empty, /* positive_sign */ 5987658Sphantom empty, /* negative_sign */ 6087658Sphantom numempty, /* int_frac_digits */ 6187658Sphantom numempty, /* frac_digits */ 6287658Sphantom numempty, /* p_cs_precedes */ 6387658Sphantom numempty, /* p_sep_by_space */ 6487658Sphantom numempty, /* n_cs_precedes */ 6587658Sphantom numempty, /* n_sep_by_space */ 6687658Sphantom numempty, /* p_sign_posn */ 67104711Stjr numempty, /* n_sign_posn */ 68104711Stjr numempty, /* int_p_cs_precedes */ 69104711Stjr numempty, /* int_n_cs_precedes */ 70104711Stjr numempty, /* int_p_sep_by_space */ 71104711Stjr numempty, /* int_n_sep_by_space */ 72104711Stjr numempty, /* int_p_sign_posn */ 73104711Stjr numempty /* int_n_sign_posn */ 7472165Sphantom}; 7572165Sphantom 76227753Stheravenstruct xlocale_monetary __xlocale_global_monetary; 7772165Sphantom 7889907Sachestatic char 79101498Sachecnv(const char *str) 80101470Sache{ 8189907Sache int i = strtol(str, NULL, 10); 82101470Sache 8389907Sache if (i == -1) 8489907Sache i = CHAR_MAX; 85101470Sache return ((char)i); 8689907Sache} 8789907Sache 88227753Stheravenstatic void 89227753Stheravendestruct_monetary(void *v) 90101470Sache{ 91227753Stheraven struct xlocale_monetary *l = v; 92227753Stheraven if (l->buffer) 93227753Stheraven free(l->buffer); 94227753Stheraven free(l); 95227753Stheraven} 96227753Stheraven 97227753Stheravenstatic int 98227753Stheravenmonetary_load_locale_l(struct xlocale_monetary *loc, int *using_locale, 99227753Stheraven int *changed, const char *name) 100227753Stheraven{ 101101470Sache int ret; 102227753Stheraven struct lc_monetary_T *l = &loc->locale; 10372165Sphantom 104227753Stheraven ret = __part_load_locale(name, using_locale, 105227753Stheraven &loc->buffer, "LC_MONETARY", 106104982Sache LCMONETARY_SIZE_FULL, LCMONETARY_SIZE_MIN, 107227753Stheraven (const char **)l); 108101498Sache if (ret != _LDP_ERROR) 109227753Stheraven *changed = 1; 110101498Sache if (ret == _LDP_LOADED) { 111227753Stheraven l->mon_grouping = 112227753Stheraven __fix_locale_grouping_str(l->mon_grouping); 11389907Sache 114227753Stheraven#define M_ASSIGN_CHAR(NAME) (((char *)l->NAME)[0] = \ 115227753Stheraven cnv(l->NAME)) 11689907Sache 11789907Sache M_ASSIGN_CHAR(int_frac_digits); 11889907Sache M_ASSIGN_CHAR(frac_digits); 11989907Sache M_ASSIGN_CHAR(p_cs_precedes); 12089907Sache M_ASSIGN_CHAR(p_sep_by_space); 12189907Sache M_ASSIGN_CHAR(n_cs_precedes); 12289907Sache M_ASSIGN_CHAR(n_sep_by_space); 12389907Sache M_ASSIGN_CHAR(p_sign_posn); 12489907Sache M_ASSIGN_CHAR(n_sign_posn); 125104711Stjr 126104711Stjr /* 127104711Stjr * The six additional C99 international monetary formatting 128104711Stjr * parameters default to the national parameters when 129116875Sphantom * reading FreeBSD LC_MONETARY data files. 130104711Stjr */ 131104711Stjr#define M_ASSIGN_ICHAR(NAME) \ 132104711Stjr do { \ 133227753Stheraven if (l->int_##NAME == NULL) \ 134227753Stheraven l->int_##NAME = \ 135227753Stheraven l->NAME; \ 136104711Stjr else \ 137104711Stjr M_ASSIGN_CHAR(int_##NAME); \ 138104711Stjr } while (0) 139104711Stjr 140104711Stjr M_ASSIGN_ICHAR(p_cs_precedes); 141104711Stjr M_ASSIGN_ICHAR(n_cs_precedes); 142104711Stjr M_ASSIGN_ICHAR(p_sep_by_space); 143104711Stjr M_ASSIGN_ICHAR(n_sep_by_space); 144104711Stjr M_ASSIGN_ICHAR(p_sign_posn); 145104711Stjr M_ASSIGN_ICHAR(n_sign_posn); 14689907Sache } 147101470Sache return (ret); 14872165Sphantom} 149227753Stheravenint 150227753Stheraven__monetary_load_locale(const char *name) 151227753Stheraven{ 152227753Stheraven return monetary_load_locale_l(&__xlocale_global_monetary, 153227753Stheraven &__xlocale_global_locale.using_monetary_locale, 154227753Stheraven &__xlocale_global_locale.monetary_locale_changed, name); 155227753Stheraven} 156227753Stheravenvoid* __monetary_load(const char *name, locale_t l) 157227753Stheraven{ 158227753Stheraven struct xlocale_monetary *new = calloc(sizeof(struct xlocale_monetary), 1); 159227753Stheraven new->header.header.destructor = destruct_monetary; 160227753Stheraven if (monetary_load_locale_l(new, &l->using_monetary_locale, 161227753Stheraven &l->monetary_locale_changed, name) == _LDP_ERROR) 162227753Stheraven { 163227753Stheraven xlocale_release(new); 164227753Stheraven return NULL; 165227753Stheraven } 166227753Stheraven return new; 167227753Stheraven} 16872165Sphantom 169227753Stheraven 17072165Sphantomstruct lc_monetary_T * 171227753Stheraven__get_current_monetary_locale(locale_t loc) 172101470Sache{ 173227753Stheraven return (loc->using_monetary_locale 174227753Stheraven ? &((struct xlocale_monetary*)loc->components[XLC_MONETARY])->locale 17572165Sphantom : (struct lc_monetary_T *)&_C_monetary_locale); 17672165Sphantom} 17772165Sphantom 17872165Sphantom#ifdef LOCALE_DEBUG 17972165Sphantomvoid 18072165Sphantommonetdebug() { 18172165Sphantomprintf( "int_curr_symbol = %s\n" 18272165Sphantom "currency_symbol = %s\n" 18372165Sphantom "mon_decimal_point = %s\n" 18472165Sphantom "mon_thousands_sep = %s\n" 18572165Sphantom "mon_grouping = %s\n" 18672165Sphantom "positive_sign = %s\n" 18772165Sphantom "negative_sign = %s\n" 18889907Sache "int_frac_digits = %d\n" 18989907Sache "frac_digits = %d\n" 19089907Sache "p_cs_precedes = %d\n" 19189907Sache "p_sep_by_space = %d\n" 19289907Sache "n_cs_precedes = %d\n" 19389907Sache "n_sep_by_space = %d\n" 19489907Sache "p_sign_posn = %d\n" 19589907Sache "n_sign_posn = %d\n", 196116875Sphantom "int_p_cs_precedes = %d\n" 197116875Sphantom "int_p_sep_by_space = %d\n" 198116875Sphantom "int_n_cs_precedes = %d\n" 199116875Sphantom "int_n_sep_by_space = %d\n" 200116875Sphantom "int_p_sign_posn = %d\n" 201116875Sphantom "int_n_sign_posn = %d\n", 20272165Sphantom _monetary_locale.int_curr_symbol, 20372165Sphantom _monetary_locale.currency_symbol, 20472165Sphantom _monetary_locale.mon_decimal_point, 20572165Sphantom _monetary_locale.mon_thousands_sep, 20672165Sphantom _monetary_locale.mon_grouping, 20772165Sphantom _monetary_locale.positive_sign, 20872165Sphantom _monetary_locale.negative_sign, 20989907Sache _monetary_locale.int_frac_digits[0], 21089907Sache _monetary_locale.frac_digits[0], 21189907Sache _monetary_locale.p_cs_precedes[0], 21289907Sache _monetary_locale.p_sep_by_space[0], 21389907Sache _monetary_locale.n_cs_precedes[0], 21489907Sache _monetary_locale.n_sep_by_space[0], 21589907Sache _monetary_locale.p_sign_posn[0], 216116875Sphantom _monetary_locale.n_sign_posn[0], 217116875Sphantom _monetary_locale.int_p_cs_precedes[0], 218116875Sphantom _monetary_locale.int_p_sep_by_space[0], 219116875Sphantom _monetary_locale.int_n_cs_precedes[0], 220116875Sphantom _monetary_locale.int_n_sep_by_space[0], 221116875Sphantom _monetary_locale.int_p_sign_posn[0], 222116875Sphantom _monetary_locale.int_n_sign_posn[0] 22372165Sphantom); 22472165Sphantom} 22572165Sphantom#endif /* LOCALE_DEBUG */ 226