1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2013 Garrett D'Amore <garrett@damore.org> 14 * Copyright 2010 Nexenta Systems, Inc. All rights reserved. 15 */ 16 17 /* 18 * LC_MONETARY database generation routines for localedef. 19 */ 20 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include <errno.h> 24 #include <sys/types.h> 25 #include <string.h> 26 #include <unistd.h> 27 #include "localedef.h" 28 #include "parser.tab.h" 29 #include "lmonetary.h" 30 31 static struct lc_monetary mon; 32 33 void 34 init_monetary(void) 35 { 36 (void) memset(&mon, 0, sizeof (mon)); 37 } 38 39 void 40 add_monetary_str(wchar_t *wcs) 41 { 42 char *str; 43 44 if ((str = to_mb_string(wcs)) == NULL) { 45 INTERR; 46 return; 47 } 48 free(wcs); 49 switch (last_kw) { 50 case T_INT_CURR_SYMBOL: 51 mon.int_curr_symbol = str; 52 break; 53 case T_CURRENCY_SYMBOL: 54 mon.currency_symbol = str; 55 break; 56 case T_MON_DECIMAL_POINT: 57 mon.mon_decimal_point = str; 58 break; 59 case T_MON_THOUSANDS_SEP: 60 mon.mon_thousands_sep = str; 61 break; 62 case T_POSITIVE_SIGN: 63 mon.positive_sign = str; 64 break; 65 case T_NEGATIVE_SIGN: 66 mon.negative_sign = str; 67 break; 68 default: 69 free(str); 70 INTERR; 71 break; 72 } 73 } 74 75 void 76 add_monetary_num(int n) 77 { 78 char *str = NULL; 79 80 (void) asprintf(&str, "%d", n); 81 if (str == NULL) { 82 errf(_("out of memory")); 83 return; 84 } 85 86 switch (last_kw) { 87 case T_INT_FRAC_DIGITS: 88 mon.int_frac_digits = str; 89 break; 90 case T_FRAC_DIGITS: 91 mon.frac_digits = str; 92 break; 93 case T_P_CS_PRECEDES: 94 mon.p_cs_precedes = str; 95 break; 96 case T_P_SEP_BY_SPACE: 97 mon.p_sep_by_space = str; 98 break; 99 case T_N_CS_PRECEDES: 100 mon.n_cs_precedes = str; 101 break; 102 case T_N_SEP_BY_SPACE: 103 mon.n_sep_by_space = str; 104 break; 105 case T_P_SIGN_POSN: 106 mon.p_sign_posn = str; 107 break; 108 case T_N_SIGN_POSN: 109 mon.n_sign_posn = str; 110 break; 111 case T_INT_P_CS_PRECEDES: 112 mon.int_p_cs_precedes = str; 113 break; 114 case T_INT_N_CS_PRECEDES: 115 mon.int_n_cs_precedes = str; 116 break; 117 case T_INT_P_SEP_BY_SPACE: 118 mon.int_p_sep_by_space = str; 119 break; 120 case T_INT_N_SEP_BY_SPACE: 121 mon.int_n_sep_by_space = str; 122 break; 123 case T_INT_P_SIGN_POSN: 124 mon.int_p_sign_posn = str; 125 break; 126 case T_INT_N_SIGN_POSN: 127 mon.int_n_sign_posn = str; 128 break; 129 case T_MON_GROUPING: 130 mon.mon_grouping = str; 131 break; 132 default: 133 INTERR; 134 break; 135 } 136 } 137 138 void 139 reset_monetary_group(void) 140 { 141 free((char *)mon.mon_grouping); 142 mon.mon_grouping = NULL; 143 } 144 145 void 146 add_monetary_group(int n) 147 { 148 char *s = NULL; 149 150 if (mon.mon_grouping == NULL) { 151 (void) asprintf(&s, "%d", n); 152 } else { 153 (void) asprintf(&s, "%s;%d", mon.mon_grouping, n); 154 } 155 if (s == NULL) 156 errf(_("out of memory")); 157 158 free((char *)mon.mon_grouping); 159 mon.mon_grouping = s; 160 } 161 162 void 163 dump_monetary(void) 164 { 165 FILE *f; 166 167 if ((f = open_category()) == NULL) { 168 return; 169 } 170 171 if ((putl_category(mon.int_curr_symbol, f) == EOF) || 172 (putl_category(mon.currency_symbol, f) == EOF) || 173 (putl_category(mon.mon_decimal_point, f) == EOF) || 174 (putl_category(mon.mon_thousands_sep, f) == EOF) || 175 (putl_category(mon.mon_grouping, f) == EOF) || 176 (putl_category(mon.positive_sign, f) == EOF) || 177 (putl_category(mon.negative_sign, f) == EOF) || 178 (putl_category(mon.int_frac_digits, f) == EOF) || 179 (putl_category(mon.frac_digits, f) == EOF) || 180 (putl_category(mon.p_cs_precedes, f) == EOF) || 181 (putl_category(mon.p_sep_by_space, f) == EOF) || 182 (putl_category(mon.n_cs_precedes, f) == EOF) || 183 (putl_category(mon.n_sep_by_space, f) == EOF) || 184 (putl_category(mon.p_sign_posn, f) == EOF) || 185 (putl_category(mon.n_sign_posn, f) == EOF) || 186 (putl_category(mon.int_p_cs_precedes, f) == EOF) || 187 (putl_category(mon.int_n_cs_precedes, f) == EOF) || 188 (putl_category(mon.int_p_sep_by_space, f) == EOF) || 189 (putl_category(mon.int_n_sep_by_space, f) == EOF) || 190 (putl_category(mon.int_p_sign_posn, f) == EOF) || 191 (putl_category(mon.int_n_sign_posn, f) == EOF)) { 192 return; 193 } 194 close_category(f); 195 }