|
36 | 36 | import java.nio.charset.Charset; |
37 | 37 | import java.text.DecimalFormat; |
38 | 38 | import java.text.DecimalFormatSymbols; |
| 39 | +import java.text.NumberFormat; |
| 40 | +import java.util.Currency; |
| 41 | +import java.util.Locale; |
39 | 42 |
|
40 | 43 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; |
41 | 44 | import com.oracle.truffle.api.dsl.Specialization; |
@@ -127,10 +130,80 @@ public abstract static class LocaleConv extends RBuiltinNode.Arg0 { |
127 | 130 | @Specialization |
128 | 131 | @TruffleBoundary |
129 | 132 | protected Object localeconv() { |
130 | | - DecimalFormat format = (DecimalFormat) DecimalFormat.getInstance(); |
131 | | - DecimalFormatSymbols symbols = format.getDecimalFormatSymbols(); |
132 | | - char sep = symbols.getDecimalSeparator(); |
133 | | - return RDataFactory.createList(new Object[]{sep}, RDataFactory.createStringVectorFromScalar("decimal_point")); |
| 133 | + RLocale.ContextStateImpl stateRLocale = RContext.getInstance().stateRLocale; |
| 134 | + Locale numericLocale = stateRLocale.getLocale(RLocale.NUMERIC); |
| 135 | + Locale monetaryLocale = stateRLocale.getLocale(RLocale.MONETARY); |
| 136 | + NumberFormat numericFormat = NumberFormat.getNumberInstance(numericLocale); |
| 137 | + NumberFormat monetaryFormat = NumberFormat.getInstance(monetaryLocale); |
| 138 | + DecimalFormatSymbols decimalSymbols = DecimalFormatSymbols.getInstance(numericLocale); |
| 139 | + DecimalFormatSymbols monetarySymbols = DecimalFormatSymbols.getInstance(monetaryLocale); |
| 140 | + Currency currency = monetarySymbols.getCurrency(); |
| 141 | + |
| 142 | + int len = 18; |
| 143 | + int i = 0; |
| 144 | + String[] values = new String[len]; |
| 145 | + String[] names = new String[len]; |
| 146 | + names[i] = "decimal_point"; |
| 147 | + values[i++] = String.valueOf(decimalSymbols.getDecimalSeparator()); |
| 148 | + names[i] = "thousands_sep"; // for non-monetary quantities |
| 149 | + values[i++] = numericFormat.isGroupingUsed() ? String.valueOf(decimalSymbols.getGroupingSeparator()) : ""; |
| 150 | + names[i] = "grouping"; |
| 151 | + StringBuilder grouping = new StringBuilder(2); |
| 152 | + if (numericFormat.isGroupingUsed() && (numericFormat instanceof DecimalFormat)) { |
| 153 | + int groupingSize = ((DecimalFormat) numericFormat).getGroupingSize(); |
| 154 | + for (int j = 2; j > 0; j--) { |
| 155 | + grouping.append((char) groupingSize); |
| 156 | + } |
| 157 | + grouping.setLength(0); |
| 158 | + } |
| 159 | + values[i++] = grouping.toString(); |
| 160 | + names[i] = "int_curr_symbol"; |
| 161 | + values[i++] = monetarySymbols.getInternationalCurrencySymbol() + ' '; // Appears |
| 162 | + // space-terminated |
| 163 | + // in GNU-R |
| 164 | + names[i] = "currency_symbol"; |
| 165 | + values[i++] = monetarySymbols.getCurrencySymbol(); |
| 166 | + names[i] = "mon_decimal_point"; |
| 167 | + values[i++] = String.valueOf(monetarySymbols.getMonetaryDecimalSeparator()); |
| 168 | + names[i] = "mon_thousands_sep"; |
| 169 | + values[i++] = String.valueOf(monetarySymbols.getGroupingSeparator()); |
| 170 | + names[i] = "mon_grouping"; |
| 171 | + if (monetaryFormat.isGroupingUsed() && (monetaryFormat instanceof DecimalFormat)) { |
| 172 | + int groupingSize = ((DecimalFormat) monetaryFormat).getGroupingSize(); |
| 173 | + for (int j = 2; j > 0; j--) { |
| 174 | + grouping.append((char) groupingSize); |
| 175 | + } |
| 176 | + grouping.setLength(0); |
| 177 | + } |
| 178 | + values[i++] = grouping.toString(); |
| 179 | + names[i] = "positive_sign"; |
| 180 | + values[i++] = ""; // TODO not found a corresponding java method yet |
| 181 | + names[i] = "negative_sign"; |
| 182 | + values[i++] = String.valueOf(monetarySymbols.getMinusSign()); |
| 183 | + names[i] = "int_frac_digits"; |
| 184 | + values[i++] = String.valueOf(currency.getDefaultFractionDigits()); |
| 185 | + names[i] = "frac_digits"; |
| 186 | + values[i++] = String.valueOf(currency.getDefaultFractionDigits()); |
| 187 | + names[i] = "p_cs_precedes"; // "1" if currency symbol precedes positive value or "0" |
| 188 | + // otherwise |
| 189 | + values[i++] = "1"; // No corresponding java method found yet - best match found: |
| 190 | + // (DecimalFormat.getPositivePrefix() != null) |
| 191 | + names[i] = "p_sep_by_space"; // "1" if a space separates currency symbol from a positive |
| 192 | + // value or "0" otherwise |
| 193 | + values[i++] = "0"; // No corresponding java method found yet |
| 194 | + names[i] = "n_cs_precedes"; // "1" if currency symbol precedes negative value or "0" |
| 195 | + // otherwise |
| 196 | + values[i++] = "1"; // No corresponding java method found yet |
| 197 | + names[i] = "n_sep_by_space"; // "1" if a space separates currency symbol from a negative |
| 198 | + // value or "0" otherwise |
| 199 | + values[i++] = "0"; // No corresponding java method found yet |
| 200 | + names[i] = "p_sign_posn"; // value indicating the positioning of the positive sign for a |
| 201 | + // non-negative internationally formatted monetary quantity |
| 202 | + values[i++] = "1"; // No corresponding java method found yet |
| 203 | + names[i] = "n_sign_posn"; // value indicating the positioning of the negative sign for a |
| 204 | + // negative internationally formatted monetary quantity |
| 205 | + values[i++] = "1"; // No corresponding java method found yet |
| 206 | + return RDataFactory.createStringVector(values, true, RDataFactory.createStringVector(names, true)); |
134 | 207 | } |
135 | 208 | } |
136 | 209 |
|
|
0 commit comments