xref: /illumos-gate/usr/src/cmd/localedef/monetary.c (revision bc1f688b4872ace323eaddbb1a6365d054e7bf56)
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 }
196