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