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 }