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
init_monetary(void)34 init_monetary(void)
35 {
36 (void) memset(&mon, 0, sizeof (mon));
37 }
38
39 void
add_monetary_str(wchar_t * wcs)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
add_monetary_num(int n)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
reset_monetary_group(void)139 reset_monetary_group(void)
140 {
141 free((char *)mon.mon_grouping);
142 mon.mon_grouping = NULL;
143 }
144
145 void
add_monetary_group(int n)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
dump_monetary(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 }
196