Show locale.cs syntax highlighted
/* **********************************************************************************
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* This source code is subject to terms and conditions of the Shared Source License
* for IronPython. A copy of the license can be found in the License.html file
* at the root of this distribution. If you can not locate the Shared Source License
* for IronPython, please send an email to ironpy@microsoft.com.
* By using this source code in any fashion, you are agreeing to be bound by
* the terms of the Shared Source License for IronPython.
*
* You must not remove this notice, or any other, from this software.
*
* **********************************************************************************/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using IronPython.Runtime;
using IronPython.Runtime.Exceptions;
using IronPython.Runtime.Operations;
[assembly: PythonModule("_locale", typeof(IronPython.Modules.PythonLocale))]
namespace IronPython.Modules {
[PythonType("_locale")]
public static class PythonLocale {
internal static LocaleInfo currentLocale = new LocaleInfo();
public static object CHAR_MAX = 127;
public static object Error = ExceptionConverter.CreatePythonException("Error", "_locale");
public static object LC_ALL = (int)LocaleCategories.All;
public static object LC_COLLATE = (int)LocaleCategories.Collate;
public static object LC_CTYPE = (int)LocaleCategories.CType;
public static object LC_MONETARY = (int)LocaleCategories.Monetary;
public static object LC_NUMERIC = (int)LocaleCategories.Numeric;
public static object LC_TIME = (int)LocaleCategories.Time;
[Documentation("gets the default locale tuple")]
[PythonName("_getdefaultlocale")]
public static object GetDefaultLocale() {
return Tuple.MakeTuple(new object[] { CultureInfo.CurrentCulture.Name, "" });
}
[Documentation(@"gets the locale's convetions table.
The conventions table is a dictionary that contains information on how to use
the locale for numeric and monetary formatting")]
[PythonName("localeconv")]
public static object LocaleConventions() {
return currentLocale.GetConventionsTable();
}
[Documentation(@"Sets the current locale for the given category.
LC_ALL: sets locale for all options below
LC_COLLATE: sets locale for collation (strcoll and strxfrm) only
LC_CTYPE: sets locale for CType [unused]
LC_MONETARY: sets locale for the monetary functions (localeconv())
LC_NUMERIC: sets the locale for numeric functions (slocaleconv())
LC_TIME: sets the locale for time functions [unused]
If locale is None then the current setting is returned.
")]
[PythonName("setlocale")]
public static object SetLocale(object category, [DefaultParameterValue(null)]string locale) {
if (locale == null) {
return currentLocale.GetLocale(category);
}
currentLocale.SetLocale(category, locale);
return null;
}
[Documentation("compares two strings using the current locale")]
[PythonName("strcoll")]
public static int StringCollate(string string1, string string2) {
return String.Compare(string1, string2, false, currentLocale.Collate);
}
[Documentation(@"returns a transformed string that can be compared using the built-in cmp.
Currently returns the string unmodified")]
[PythonName("strxfrm")]
public static object StringTransform(string @string) {
return @string;
}
private enum LocaleCategories {
All = 0,
Collate = 1,
CType = 2,
Monetary = 3,
Numeric = 4,
Time = 5,
}
internal class LocaleInfo {
public LocaleInfo() {
Collate = CultureInfo.CurrentCulture;
CType = CultureInfo.CurrentCulture;
Time = CultureInfo.CurrentCulture;
Monetary = CultureInfo.CurrentCulture;
Numeric = CultureInfo.CurrentCulture;
}
public CultureInfo Collate;
public CultureInfo CType;
public CultureInfo Time;
public CultureInfo Monetary;
public CultureInfo Numeric;
private Dict conv;
public override string ToString() {
return base.ToString();
}
public Dict GetConventionsTable() {
CreateConventionsDict();
return conv;
}
public void SetLocale(object category, string locale) {
switch ((LocaleCategories)(int)category) {
case LocaleCategories.All:
SetLocale(LC_COLLATE, locale);
SetLocale(LC_CTYPE, locale);
SetLocale(LC_MONETARY, locale);
SetLocale(LC_NUMERIC, locale);
SetLocale(LC_TIME, locale);
break;
case LocaleCategories.Collate: Collate = LocaleToCulture(locale); break;
case LocaleCategories.CType: CType = LocaleToCulture(locale); break;
case LocaleCategories.Time: Time = LocaleToCulture(locale); break;
case LocaleCategories.Monetary:
Monetary = LocaleToCulture(locale);
conv = null;
break;
case LocaleCategories.Numeric:
Numeric = LocaleToCulture(locale);
conv = null;
break;
default:
throw ExceptionConverter.CreateThrowable(Error, "unknown locale category");
}
}
public string GetLocale(object category) {
switch ((LocaleCategories)(int)category) {
case LocaleCategories.All:
if (Collate == CType &&
Collate == Time &&
Collate == Monetary &&
Collate == Numeric) {
// they're all the same, return only 1 name
goto case LocaleCategories.Collate;
}
// return them all...
return String.Format("LC_COLLATE={0};LC_CTYPE={1};LC_MONETARY={2};LC_NUMERIC={3};LC_TIME={4}",
GetLocale(LC_COLLATE),
GetLocale(LC_CTYPE),
GetLocale(LC_MONETARY),
GetLocale(LC_NUMERIC),
GetLocale(LC_TIME));
case LocaleCategories.Collate: return CultureToName(Collate);
case LocaleCategories.CType: return CultureToName(CType);
case LocaleCategories.Time: return CultureToName(Time);
case LocaleCategories.Monetary: return CultureToName(Monetary);
case LocaleCategories.Numeric: return CultureToName(Numeric);
default:
throw ExceptionConverter.CreateThrowable(Error, "unknown locale category");
}
}
public string CultureToName(CultureInfo culture) {
return culture.Name.Replace('-', '_');
}
private CultureInfo LocaleToCulture(string locale) {
locale = locale.Replace('_', '-');
try {
return CultureInfo.GetCultureInfo(locale);
} catch (ArgumentException) {
throw ExceptionConverter.CreateThrowable(Error, String.Format("unknown locale: {0}", locale));
}
}
/// <summary>
/// Popupates the given directory w/ the locale information from the given
/// CultureInfo.
/// </summary>
private void CreateConventionsDict() {
conv = new Dict();
conv["decimal_point"] = Numeric.NumberFormat.NumberDecimalSeparator;
conv["grouping"] = GroupsToList(Numeric.NumberFormat.NumberGroupSizes);
conv["thousands_sep"] = Numeric.NumberFormat.NumberGroupSeparator;
conv["mon_decimal_point"] = Monetary.NumberFormat.CurrencyDecimalSeparator;
conv["mon_thousands_sep"] = Monetary.NumberFormat.CurrencyGroupSeparator;
conv["mon_grouping"] = GroupsToList(Monetary.NumberFormat.CurrencyGroupSizes);
conv["int_curr_symbol"] = Monetary.NumberFormat.CurrencySymbol;
conv["currency_symbol"] = Monetary.NumberFormat.CurrencySymbol;
conv["frac_digits"] = Monetary.NumberFormat.CurrencyDecimalDigits;
conv["int_frac_digits"] = Monetary.NumberFormat.CurrencyDecimalDigits;
conv["positive_sign"] = Monetary.NumberFormat.PositiveSign;
conv["negative_sign"] = Monetary.NumberFormat.NegativeSign;
conv["p_sign_posn"] = Monetary.NumberFormat.CurrencyPositivePattern;
conv["n_sign_posn"] = Monetary.NumberFormat.CurrencyNegativePattern;
}
private static List GroupsToList(int[] groups) {
// .NET: values from 0-9, if the last digit is zero, remaining digits
// go ungrouped, otherwise they're grouped based upon the last value.
// locale: ends in CHAR_MAX if no further grouping is performed, ends in
// zero if the last group size is repeatedly used.
List res = new List(groups);
if (groups.Length > 0 && groups[groups.Length - 1] == 0) {
// replace zero w/ CHAR_MAX, no further grouping is performed
res[res.Count - 1] = CHAR_MAX;
} else {
// append 0 to indicate we should repeatedly use the last one
res.AddNoLock(0);
}
return res;
}
}
}
}
See more files for this project here