xref: /freebsd/usr.bin/localedef/monetary.c (revision 911f0260390e18cf85f3dbf2c719b593efdc1e3c)
1 /*-
2  * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
3  * Copyright 2015 John Marino <draco@marino.st>
4  *
5  * This source code is derived from the illumos localedef command, and
6  * provided under BSD-style license terms by Nexenta Systems, Inc.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 /*
32  * LC_MONETARY database generation routines for localedef.
33  */
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36 
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <errno.h>
40 #include <sys/types.h>
41 #include <string.h>
42 #include <unistd.h>
43 #include "localedef.h"
44 #include "parser.h"
45 #include "lmonetary.h"
46 
47 static struct lc_monetary_T mon;
48 
49 void
50 init_monetary(void)
51 {
52 	(void) memset(&mon, 0, sizeof (mon));
53 }
54 
55 void
56 add_monetary_str(wchar_t *wcs)
57 {
58 	char *str;
59 
60 	if ((str = to_mb_string(wcs)) == NULL) {
61 		INTERR;
62 		return;
63 	}
64 	free(wcs);
65 	switch (last_kw) {
66 	case T_INT_CURR_SYMBOL:
67 		mon.int_curr_symbol = str;
68 		break;
69 	case T_CURRENCY_SYMBOL:
70 		mon.currency_symbol = str;
71 		break;
72 	case T_MON_DECIMAL_POINT:
73 		mon.mon_decimal_point = str;
74 		break;
75 	case T_MON_THOUSANDS_SEP:
76 		mon.mon_thousands_sep = str;
77 		break;
78 	case T_POSITIVE_SIGN:
79 		mon.positive_sign = str;
80 		break;
81 	case T_NEGATIVE_SIGN:
82 		mon.negative_sign = str;
83 		break;
84 	default:
85 		free(str);
86 		INTERR;
87 		break;
88 	}
89 }
90 
91 void
92 add_monetary_num(int n)
93 {
94 	char *str = NULL;
95 
96 	(void) asprintf(&str, "%d", n);
97 	if (str == NULL) {
98 		fprintf(stderr, "out of memory");
99 		return;
100 	}
101 
102 	switch (last_kw) {
103 	case T_INT_FRAC_DIGITS:
104 		mon.int_frac_digits = str;
105 		break;
106 	case T_FRAC_DIGITS:
107 		mon.frac_digits = str;
108 		break;
109 	case T_P_CS_PRECEDES:
110 		mon.p_cs_precedes = str;
111 		break;
112 	case T_P_SEP_BY_SPACE:
113 		mon.p_sep_by_space = str;
114 		break;
115 	case T_N_CS_PRECEDES:
116 		mon.n_cs_precedes = str;
117 		break;
118 	case T_N_SEP_BY_SPACE:
119 		mon.n_sep_by_space = str;
120 		break;
121 	case T_P_SIGN_POSN:
122 		mon.p_sign_posn = str;
123 		break;
124 	case T_N_SIGN_POSN:
125 		mon.n_sign_posn = str;
126 		break;
127 	case T_INT_P_CS_PRECEDES:
128 		mon.int_p_cs_precedes = str;
129 		break;
130 	case T_INT_N_CS_PRECEDES:
131 		mon.int_n_cs_precedes = str;
132 		break;
133 	case T_INT_P_SEP_BY_SPACE:
134 		mon.int_p_sep_by_space = str;
135 		break;
136 	case T_INT_N_SEP_BY_SPACE:
137 		mon.int_n_sep_by_space = str;
138 		break;
139 	case T_INT_P_SIGN_POSN:
140 		mon.int_p_sign_posn = str;
141 		break;
142 	case T_INT_N_SIGN_POSN:
143 		mon.int_n_sign_posn = str;
144 		break;
145 	case T_MON_GROUPING:
146 		mon.mon_grouping = str;
147 		break;
148 	default:
149 		INTERR;
150 		break;
151 	}
152 }
153 
154 void
155 reset_monetary_group(void)
156 {
157 	free((char *)mon.mon_grouping);
158 	mon.mon_grouping = NULL;
159 }
160 
161 void
162 add_monetary_group(int n)
163 {
164 	char *s = NULL;
165 
166 	if (mon.mon_grouping == NULL) {
167 		(void) asprintf(&s, "%d", n);
168 	} else {
169 		(void) asprintf(&s, "%s;%d", mon.mon_grouping, n);
170 	}
171 	if (s == NULL)
172 		fprintf(stderr, "out of memory");
173 
174 	free((char *)mon.mon_grouping);
175 	mon.mon_grouping = s;
176 }
177 
178 void
179 dump_monetary(void)
180 {
181 	FILE *f;
182 
183 	if ((f = open_category()) == NULL) {
184 		return;
185 	}
186 
187 	if ((putl_category(mon.int_curr_symbol, f) == EOF) ||
188 	    (putl_category(mon.currency_symbol, f) == EOF) ||
189 	    (putl_category(mon.mon_decimal_point, f) == EOF) ||
190 	    (putl_category(mon.mon_thousands_sep, f) == EOF) ||
191 	    (putl_category(mon.mon_grouping, f) == EOF) ||
192 	    (putl_category(mon.positive_sign, f) == EOF) ||
193 	    (putl_category(mon.negative_sign, f) == EOF) ||
194 	    (putl_category(mon.int_frac_digits, f) == EOF) ||
195 	    (putl_category(mon.frac_digits, f) == EOF) ||
196 	    (putl_category(mon.p_cs_precedes, f) == EOF) ||
197 	    (putl_category(mon.p_sep_by_space, f) == EOF) ||
198 	    (putl_category(mon.n_cs_precedes, f) == EOF) ||
199 	    (putl_category(mon.n_sep_by_space, f) == EOF) ||
200 	    (putl_category(mon.p_sign_posn, f) == EOF) ||
201 	    (putl_category(mon.n_sign_posn, f) == EOF) ||
202 	    (putl_category(mon.int_p_cs_precedes, f) == EOF) ||
203 	    (putl_category(mon.int_n_cs_precedes, f) == EOF) ||
204 	    (putl_category(mon.int_p_sep_by_space, f) == EOF) ||
205 	    (putl_category(mon.int_n_sep_by_space, f) == EOF) ||
206 	    (putl_category(mon.int_p_sign_posn, f) == EOF) ||
207 	    (putl_category(mon.int_n_sign_posn, f) == EOF)) {
208 		return;
209 	}
210 	close_category(f);
211 }
212