xref: /freebsd/usr.bin/localedef/monetary.c (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
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 #include <stdio.h>
36 #include <stdlib.h>
37 #include <errno.h>
38 #include <sys/types.h>
39 #include <string.h>
40 #include <unistd.h>
41 #include "localedef.h"
42 #include "parser.h"
43 #include "lmonetary.h"
44 
45 static struct lc_monetary_T mon;
46 
47 void
48 init_monetary(void)
49 {
50 	(void) memset(&mon, 0, sizeof (mon));
51 }
52 
53 void
54 add_monetary_str(wchar_t *wcs)
55 {
56 	char *str;
57 
58 	if ((str = to_mb_string(wcs)) == NULL) {
59 		INTERR;
60 		return;
61 	}
62 	free(wcs);
63 	switch (last_kw) {
64 	case T_INT_CURR_SYMBOL:
65 		mon.int_curr_symbol = str;
66 		break;
67 	case T_CURRENCY_SYMBOL:
68 		mon.currency_symbol = str;
69 		break;
70 	case T_MON_DECIMAL_POINT:
71 		mon.mon_decimal_point = str;
72 		break;
73 	case T_MON_THOUSANDS_SEP:
74 		mon.mon_thousands_sep = str;
75 		break;
76 	case T_POSITIVE_SIGN:
77 		mon.positive_sign = str;
78 		break;
79 	case T_NEGATIVE_SIGN:
80 		mon.negative_sign = str;
81 		break;
82 	default:
83 		free(str);
84 		INTERR;
85 		break;
86 	}
87 }
88 
89 void
90 add_monetary_num(int n)
91 {
92 	char *str = NULL;
93 
94 	(void) asprintf(&str, "%d", n);
95 	if (str == NULL) {
96 		fprintf(stderr, "out of memory\n");
97 		return;
98 	}
99 
100 	switch (last_kw) {
101 	case T_INT_FRAC_DIGITS:
102 		mon.int_frac_digits = str;
103 		break;
104 	case T_FRAC_DIGITS:
105 		mon.frac_digits = str;
106 		break;
107 	case T_P_CS_PRECEDES:
108 		mon.p_cs_precedes = str;
109 		break;
110 	case T_P_SEP_BY_SPACE:
111 		mon.p_sep_by_space = str;
112 		break;
113 	case T_N_CS_PRECEDES:
114 		mon.n_cs_precedes = str;
115 		break;
116 	case T_N_SEP_BY_SPACE:
117 		mon.n_sep_by_space = str;
118 		break;
119 	case T_P_SIGN_POSN:
120 		mon.p_sign_posn = str;
121 		break;
122 	case T_N_SIGN_POSN:
123 		mon.n_sign_posn = str;
124 		break;
125 	case T_INT_P_CS_PRECEDES:
126 		mon.int_p_cs_precedes = str;
127 		break;
128 	case T_INT_N_CS_PRECEDES:
129 		mon.int_n_cs_precedes = str;
130 		break;
131 	case T_INT_P_SEP_BY_SPACE:
132 		mon.int_p_sep_by_space = str;
133 		break;
134 	case T_INT_N_SEP_BY_SPACE:
135 		mon.int_n_sep_by_space = str;
136 		break;
137 	case T_INT_P_SIGN_POSN:
138 		mon.int_p_sign_posn = str;
139 		break;
140 	case T_INT_N_SIGN_POSN:
141 		mon.int_n_sign_posn = str;
142 		break;
143 	case T_MON_GROUPING:
144 		mon.mon_grouping = str;
145 		break;
146 	default:
147 		INTERR;
148 		break;
149 	}
150 }
151 
152 void
153 reset_monetary_group(void)
154 {
155 	free((char *)mon.mon_grouping);
156 	mon.mon_grouping = NULL;
157 }
158 
159 void
160 add_monetary_group(int n)
161 {
162 	char *s = NULL;
163 
164 	if (mon.mon_grouping == NULL) {
165 		(void) asprintf(&s, "%d", n);
166 	} else {
167 		(void) asprintf(&s, "%s;%d", mon.mon_grouping, n);
168 	}
169 	if (s == NULL)
170 		fprintf(stderr, "out of memory\n");
171 
172 	free((char *)mon.mon_grouping);
173 	mon.mon_grouping = s;
174 }
175 
176 void
177 dump_monetary(void)
178 {
179 	FILE *f;
180 
181 	if ((f = open_category()) == NULL) {
182 		return;
183 	}
184 
185 	if ((putl_category(mon.int_curr_symbol, f) == EOF) ||
186 	    (putl_category(mon.currency_symbol, f) == EOF) ||
187 	    (putl_category(mon.mon_decimal_point, f) == EOF) ||
188 	    (putl_category(mon.mon_thousands_sep, f) == EOF) ||
189 	    (putl_category(mon.mon_grouping, f) == EOF) ||
190 	    (putl_category(mon.positive_sign, f) == EOF) ||
191 	    (putl_category(mon.negative_sign, f) == EOF) ||
192 	    (putl_category(mon.int_frac_digits, f) == EOF) ||
193 	    (putl_category(mon.frac_digits, f) == EOF) ||
194 	    (putl_category(mon.p_cs_precedes, f) == EOF) ||
195 	    (putl_category(mon.p_sep_by_space, f) == EOF) ||
196 	    (putl_category(mon.n_cs_precedes, f) == EOF) ||
197 	    (putl_category(mon.n_sep_by_space, f) == EOF) ||
198 	    (putl_category(mon.p_sign_posn, f) == EOF) ||
199 	    (putl_category(mon.n_sign_posn, f) == EOF) ||
200 	    (putl_category(mon.int_p_cs_precedes, f) == EOF) ||
201 	    (putl_category(mon.int_n_cs_precedes, f) == EOF) ||
202 	    (putl_category(mon.int_p_sep_by_space, f) == EOF) ||
203 	    (putl_category(mon.int_n_sep_by_space, f) == EOF) ||
204 	    (putl_category(mon.int_p_sign_posn, f) == EOF) ||
205 	    (putl_category(mon.int_n_sign_posn, f) == EOF)) {
206 		return;
207 	}
208 	close_category(f);
209 }
210