nrelease - fix/improve livecd
[dragonfly.git] / usr.bin / localedef / monetary.c
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
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");
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 #pragma GCC diagnostic push
153 #pragma GCC diagnostic ignored "-Wcast-qual"
154
155 void
156 reset_monetary_group(void)
157 {
158         free((char *)mon.mon_grouping);
159         mon.mon_grouping = NULL;
160 }
161
162 void
163 add_monetary_group(int n)
164 {
165         char *s = NULL;
166
167         if (mon.mon_grouping == NULL) {
168                 (void) asprintf(&s, "%d", n);
169         } else {
170                 (void) asprintf(&s, "%s;%d", mon.mon_grouping, n);
171         }
172         if (s == NULL)
173                 fprintf(stderr, "out of memory");
174
175         free((char *)mon.mon_grouping);
176         mon.mon_grouping = s;
177 }
178
179 #pragma GCC diagnostic pop
180
181 void
182 dump_monetary(void)
183 {
184         FILE *f;
185
186         if ((f = open_category()) == NULL) {
187                 return;
188         }
189
190         if ((putl_category(mon.int_curr_symbol, f) == EOF) ||
191             (putl_category(mon.currency_symbol, f) == EOF) ||
192             (putl_category(mon.mon_decimal_point, f) == EOF) ||
193             (putl_category(mon.mon_thousands_sep, f) == EOF) ||
194             (putl_category(mon.mon_grouping, f) == EOF) ||
195             (putl_category(mon.positive_sign, f) == EOF) ||
196             (putl_category(mon.negative_sign, f) == EOF) ||
197             (putl_category(mon.int_frac_digits, f) == EOF) ||
198             (putl_category(mon.frac_digits, f) == EOF) ||
199             (putl_category(mon.p_cs_precedes, f) == EOF) ||
200             (putl_category(mon.p_sep_by_space, f) == EOF) ||
201             (putl_category(mon.n_cs_precedes, f) == EOF) ||
202             (putl_category(mon.n_sep_by_space, f) == EOF) ||
203             (putl_category(mon.p_sign_posn, f) == EOF) ||
204             (putl_category(mon.n_sign_posn, f) == EOF) ||
205             (putl_category(mon.int_p_cs_precedes, f) == EOF) ||
206             (putl_category(mon.int_n_cs_precedes, f) == EOF) ||
207             (putl_category(mon.int_p_sep_by_space, f) == EOF) ||
208             (putl_category(mon.int_n_sep_by_space, f) == EOF) ||
209             (putl_category(mon.int_p_sign_posn, f) == EOF) ||
210             (putl_category(mon.int_n_sign_posn, f) == EOF)) {
211                 return;
212         }
213         close_category(f);
214 }