summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarmelo Amoroso <carmelo.amoroso@st.com>2008-05-02 13:57:02 +0000
committerCarmelo Amoroso <carmelo.amoroso@st.com>2008-05-02 13:57:02 +0000
commitfc5abf4933bebea46105b5bb9cd81b77ae670fc9 (patch)
tree034ca6caf7b421f0780ada4fb8c235749f1a8bee
parent2167a906ffd7499685e25af093107db4770a7069 (diff)
Added implementation for 'locale' command.
Signed-off-by: Filippo Arcidiacono <filippo.arcidiacono@st.com>
-rw-r--r--extra/locale/programs/categories.def357
-rw-r--r--extra/locale/programs/locale.c466
-rw-r--r--include/langinfo.h2
-rw-r--r--utils/Makefile.in12
4 files changed, 834 insertions, 3 deletions
diff --git a/extra/locale/programs/categories.def b/extra/locale/programs/categories.def
new file mode 100644
index 000000000..c248ba73e
--- /dev/null
+++ b/extra/locale/programs/categories.def
@@ -0,0 +1,357 @@
+/*
+ *
+ * Copyright (c) 2008 STMicroelectronics Ltd
+ * Filippo Arcidiacono (filippo.arcidiacono@st.com)
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * Taken from glibc 2.6
+ *
+ */
+
+
+/* Definition of all available locale categories and their items. -*- C -*-
+
+ These definitions are used by the 'locale' the program.
+
+ The general format of the descriptions is like this:
+
+ DEFINE_CATEGORY (ID, name, ( items ), setlocale-postload)
+
+ where items itself is an array of entries in the form
+
+ { ID, name, standard, value-type, min, max }
+
+ The usage of the load, check, output functions depends on the individual
+ program code which loads this file.
+
+ The various value types for the items are `string', `stringarray', `byte'
+ `bytearray', and `word'. These cover all possible values in the current
+ locale definitions. `min' and `max' can be individually used again. */
+
+#ifndef NO_POSTLOAD
+#define NO_POSTLOAD NULL
+#endif
+
+#if 0
+DEFINE_CATEGORY
+(
+ LC_COLLATE, "LC_COLLATE",
+ (
+ DEFINE_ELEMENT (_NL_COLLATE_NRULES, "collate-nrules", std, word)
+ DEFINE_ELEMENT (_NL_COLLATE_RULESETS, "collate-rulesets", std, string)
+ DEFINE_ELEMENT (_NL_COLLATE_TABLEMB, "collate-tablemb", std, wstring)
+ DEFINE_ELEMENT (_NL_COLLATE_WEIGHTMB, "collate-weightmb", std, wstring)
+ DEFINE_ELEMENT (_NL_COLLATE_EXTRAMB, "collate-extramb", std, wstring)
+ DEFINE_ELEMENT (_NL_COLLATE_INDIRECTMB, "collate-indirectmb", std, wstring)
+ DEFINE_ELEMENT (_NL_COLLATE_TABLEWC, "collate-tablewc", std, wstring)
+ DEFINE_ELEMENT (_NL_COLLATE_WEIGHTWC, "collate-weightwc", std, wstring)
+ DEFINE_ELEMENT (_NL_COLLATE_EXTRAWC, "collate-extrawc", std, wstring)
+ DEFINE_ELEMENT (_NL_COLLATE_INDIRECTWC, "collate-indirectwc", std, wstring)
+ DEFINE_ELEMENT (_NL_COLLATE_SYMB_HASH_SIZEMB, "collate-symb-hash-sizemb", std, word)
+ DEFINE_ELEMENT (_NL_COLLATE_SYMB_TABLEMB, "collate-symb-tablemb", std, wstring)
+ DEFINE_ELEMENT (_NL_COLLATE_SYMB_EXTRAMB, "collate-symb-extramb", std, wstring)
+ DEFINE_ELEMENT (_NL_COLLATE_COLLSEQMB, "collate-collseqmb", std, wstring)
+ DEFINE_ELEMENT (_NL_COLLATE_COLLSEQWC, "collate-collseqwc", std, wstring)
+ DEFINE_ELEMENT (_NL_COLLATE_CODESET, "collate-codeset", std, string)
+ ), NO_POSTLOAD)
+#endif
+
+
+/* The actual definition of ctype is meaningless here. It is hard coded in
+ the code because it has to be handled very specially. Only the names of
+ the functions and the value types are important. */
+DEFINE_CATEGORY
+(
+ LC_CTYPE, "LC_CTYPE",
+ (
+#if 0
+ DEFINE_ELEMENT (_NL_CTYPE_CLASS, "ctype-class", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_TOUPPER, "ctype-toupper", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_TOLOWER, "ctype-tolower", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_CLASS32, "ctype-class32", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_CLASS_NAMES, "ctype-class-names", std, stringlist, 10, 32)
+ DEFINE_ELEMENT (_NL_CTYPE_MAP_NAMES, "ctype-map-names", std, stringlist, 2, 32)
+ DEFINE_ELEMENT (_NL_CTYPE_WIDTH, "ctype-width", std, bytearray)
+ DEFINE_ELEMENT (_NL_CTYPE_MB_CUR_MAX, "ctype-mb-cur-max", std, word)
+ DEFINE_ELEMENT (_NL_CTYPE_CODESET_NAME, "charmap", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_TOUPPER32, "ctype-toupper32", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_TOLOWER32, "ctype-tolower32", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_CLASS_OFFSET, "ctype-class-offset", std, word)
+ DEFINE_ELEMENT (_NL_CTYPE_MAP_OFFSET, "ctype-map-offset", std, word)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS_MB_LEN, "ctype-indigits_mb-len", std, word)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS0_MB, "ctype-indigits0_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS1_MB, "ctype-indigits1_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS2_MB, "ctype-indigits2_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS3_MB, "ctype-indigits3_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS4_MB, "ctype-indigits4_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS5_MB, "ctype-indigits5_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS6_MB, "ctype-indigits6_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS7_MB, "ctype-indigits7_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS8_MB, "ctype-indigits8_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS9_MB, "ctype-indigits9_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS_WC_LEN, "ctype-indigits_wc-len", std, word)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS0_WC, "ctype-indigits0_wc", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS1_WC, "ctype-indigits1_wc", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS2_WC, "ctype-indigits2_wc", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS3_WC, "ctype-indigits3_wc", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS4_WC, "ctype-indigits4_wc", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS5_WC, "ctype-indigits5_wc", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS6_WC, "ctype-indigits6_wc", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS7_WC, "ctype-indigits7_wc", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS8_WC, "ctype-indigits8_wc", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_INDIGITS9_WC, "ctype-indigits9_wc", std, wstring)
+#endif
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT0_MB, "ctype-outdigit0_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT1_MB, "ctype-outdigit1_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT2_MB, "ctype-outdigit2_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT3_MB, "ctype-outdigit3_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT4_MB, "ctype-outdigit4_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT5_MB, "ctype-outdigit5_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT6_MB, "ctype-outdigit6_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT7_MB, "ctype-outdigit7_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT8_MB, "ctype-outdigit8_mb", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT9_MB, "ctype-outdigit9_mb", std, string)
+#if 0
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT0_WC, "ctype-outdigit0_wc", std, word)
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT1_WC, "ctype-outdigit1_wc", std, word)
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT2_WC, "ctype-outdigit2_wc", std, word)
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT3_WC, "ctype-outdigit3_wc", std, word)
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT4_WC, "ctype-outdigit4_wc", std, word)
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT5_WC, "ctype-outdigit5_wc", std, word)
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT6_WC, "ctype-outdigit6_wc", std, word)
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT7_WC, "ctype-outdigit7_wc", std, word)
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT8_WC, "ctype-outdigit8_wc", std, word)
+ DEFINE_ELEMENT (_NL_CTYPE_OUTDIGIT9_WC, "ctype-outdigit9_wc", std, word)
+ DEFINE_ELEMENT (_NL_CTYPE_TRANSLIT_TAB_SIZE, "ctype-translit-tab-size", std, word)
+ DEFINE_ELEMENT (_NL_CTYPE_TRANSLIT_FROM_IDX, "ctype-translit-from-idx", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_TRANSLIT_FROM_TBL, "ctype-translit-from-tbl", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_TRANSLIT_TO_IDX, "ctype-translit-to-idx", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_TRANSLIT_TO_TBL, "ctype-translit-to-tbl", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_TRANSLIT_DEFAULT_MISSING_LEN, "ctype-translit-default-missing-len", std, word)
+ DEFINE_ELEMENT (_NL_CTYPE_TRANSLIT_DEFAULT_MISSING, "ctype-translit-default-missing", std, wstring)
+ DEFINE_ELEMENT (_NL_CTYPE_TRANSLIT_IGNORE_LEN, "ctype-translit-ignore-len", std, word)
+ DEFINE_ELEMENT (_NL_CTYPE_TRANSLIT_IGNORE, "ctype-translit-ignore", std, string)
+ DEFINE_ELEMENT (_NL_CTYPE_MAP_TO_NONASCII, "map-to-nonascii", std, word)
+#endif
+ ), _nl_postload_ctype)
+
+
+DEFINE_CATEGORY
+(
+ LC_MONETARY, "LC_MONETARY",
+ (
+ DEFINE_ELEMENT (INT_CURR_SYMBOL, "int_curr_symbol", std, string)
+ DEFINE_ELEMENT (CURRENCY_SYMBOL, "currency_symbol", std, string)
+ DEFINE_ELEMENT (MON_DECIMAL_POINT, "mon_decimal_point", std, string)
+ DEFINE_ELEMENT (MON_THOUSANDS_SEP, "mon_thousands_sep", std, string)
+ DEFINE_ELEMENT (MON_GROUPING, "mon_grouping", std, bytearray)
+ DEFINE_ELEMENT (POSITIVE_SIGN, "positive_sign", std, string)
+ DEFINE_ELEMENT (NEGATIVE_SIGN, "negative_sign", std, string)
+ DEFINE_ELEMENT (INT_FRAC_DIGITS, "int_frac_digits", std, byte)
+ DEFINE_ELEMENT (FRAC_DIGITS, "frac_digits", std, byte)
+ DEFINE_ELEMENT (P_CS_PRECEDES, "p_cs_precedes", std, byte, 0, 1)
+ DEFINE_ELEMENT (P_SEP_BY_SPACE, "p_sep_by_space", std, byte, 0, 2)
+ DEFINE_ELEMENT (N_CS_PRECEDES, "n_cs_precedes", std, byte, 0, 1)
+ DEFINE_ELEMENT (N_SEP_BY_SPACE, "n_sep_by_space", std, byte, 0, 2)
+ DEFINE_ELEMENT (P_SIGN_POSN, "p_sign_posn", std, byte, 0, 4)
+ DEFINE_ELEMENT (N_SIGN_POSN, "n_sign_posn", std, byte, 0, 4)
+ DEFINE_ELEMENT (__INT_P_CS_PRECEDES, "int_p_cs_precedes", std, byte, 0, 1)
+ DEFINE_ELEMENT (__INT_P_SEP_BY_SPACE, "int_p_sep_by_space", std, byte, 0, 2)
+ DEFINE_ELEMENT (__INT_N_CS_PRECEDES, "int_n_cs_precedes", std, byte, 0, 1)
+ DEFINE_ELEMENT (__INT_N_SEP_BY_SPACE, "int_n_sep_by_space", std, byte, 0, 2)
+ DEFINE_ELEMENT (__INT_P_SIGN_POSN, "int_p_sign_posn", std, byte, 0, 4)
+ DEFINE_ELEMENT (__INT_N_SIGN_POSN, "int_n_sign_posn", std, byte, 0, 4)
+#if 0
+ DEFINE_ELEMENT (_NL_MONETARY_DUO_INT_CURR_SYMBOL, "duo_int_curr_symbol", std, string)
+ DEFINE_ELEMENT (_NL_MONETARY_DUO_CURRENCY_SYMBOL, "duo_currency_symbol", std, string)
+ DEFINE_ELEMENT (_NL_MONETARY_DUO_INT_FRAC_DIGITS, "duo_int_frac_digits", std, byte)
+ DEFINE_ELEMENT (_NL_MONETARY_DUO_FRAC_DIGITS, "duo_frac_digits", std, byte)
+ DEFINE_ELEMENT (_NL_MONETARY_DUO_P_CS_PRECEDES, "duo_p_cs_precedes", std, byte, 0, 1)
+ DEFINE_ELEMENT (_NL_MONETARY_DUO_P_SEP_BY_SPACE, "duo_p_sep_by_space", std, byte, 0, 2)
+ DEFINE_ELEMENT (_NL_MONETARY_DUO_N_CS_PRECEDES, "duo_n_cs_precedes", std, byte, 0, 1)
+ DEFINE_ELEMENT (_NL_MONETARY_DUO_N_SEP_BY_SPACE, "duo_n_sep_by_space", std, byte, 0, 2)
+ DEFINE_ELEMENT (_NL_MONETARY_DUO_INT_P_CS_PRECEDES, "duo_int_p_cs_precedes", std, byte, 0, 1)
+ DEFINE_ELEMENT (_NL_MONETARY_DUO_INT_P_SEP_BY_SPACE, "duo_int_p_sep_by_space", std, byte, 0, 2)
+ DEFINE_ELEMENT (_NL_MONETARY_DUO_INT_N_CS_PRECEDES, "duo_int_n_cs_precedes", std, byte, 0, 1)
+ DEFINE_ELEMENT (_NL_MONETARY_DUO_INT_N_SEP_BY_SPACE, "duo_int_n_sep_by_space", std, byte, 0, 2)
+ DEFINE_ELEMENT (_NL_MONETARY_DUO_P_SIGN_POSN, "duo_p_sign_posn", std, byte, 0, 4)
+ DEFINE_ELEMENT (_NL_MONETARY_DUO_N_SIGN_POSN, "duo_n_sign_posn", std, byte, 0, 4)
+ DEFINE_ELEMENT (_NL_MONETARY_DUO_INT_P_SIGN_POSN, "duo_int_p_sign_posn", std, byte, 0, 4)
+ DEFINE_ELEMENT (_NL_MONETARY_DUO_INT_N_SIGN_POSN, "duo_int_n_sign_posn", std, byte, 0, 4)
+ DEFINE_ELEMENT (_NL_MONETARY_UNO_VALID_FROM, "uno_valid_from", std, word)
+ DEFINE_ELEMENT (_NL_MONETARY_UNO_VALID_TO, "uno_valid_to", std, word)
+ DEFINE_ELEMENT (_NL_MONETARY_DUO_VALID_FROM, "duo_valid_from", std, word)
+ DEFINE_ELEMENT (_NL_MONETARY_DUO_VALID_TO, "duo_valid_to", std, word)
+ DEFINE_ELEMENT (_NL_MONETARY_CONVERSION_RATE, "conversion_rate", std, wordarray, 2, 2)
+ DEFINE_ELEMENT (_NL_MONETARY_DECIMAL_POINT_WC, "monetary-decimal-point-wc", std, word)
+ DEFINE_ELEMENT (_NL_MONETARY_THOUSANDS_SEP_WC, "monetary-thousands-sep-wc", std, word)
+ DEFINE_ELEMENT (_NL_MONETARY_CODESET, "monetary-codeset", std, string)
+#else
+ DEFINE_ELEMENT (_NL_MONETARY_CRNCYSTR, "monetary-crncystr", std, string)
+#endif
+ ), NO_POSTLOAD)
+
+
+DEFINE_CATEGORY
+(
+ LC_NUMERIC, "LC_NUMERIC",
+ (
+ DEFINE_ELEMENT (DECIMAL_POINT, "decimal_point", std, string)
+ DEFINE_ELEMENT (THOUSANDS_SEP, "thousands_sep", std, string)
+ DEFINE_ELEMENT (GROUPING, "grouping", std, bytearray)
+#if 0
+ DEFINE_ELEMENT (_NL_NUMERIC_DECIMAL_POINT_WC, "numeric-decimal-point-wc", std, word)
+ DEFINE_ELEMENT (_NL_NUMERIC_THOUSANDS_SEP_WC, "numeric-thousands-sep-wc", std, word)
+ DEFINE_ELEMENT (_NL_NUMERIC_CODESET, "numeric-codeset", std, string)
+#endif
+
+ ), NO_POSTLOAD)
+
+
+DEFINE_CATEGORY
+(
+ LC_TIME, "LC_TIME",
+ (
+ DEFINE_ELEMENT (ABDAY_1, "abday", std, stringarray, 7, 7)
+ DEFINE_ELEMENT (DAY_1, "day", std, stringarray, 7, 7)
+ DEFINE_ELEMENT (ABMON_1, "abmon", std, stringarray, 12, 12)
+ DEFINE_ELEMENT (MON_1, "mon", std, stringarray, 12, 12)
+ DEFINE_ELEMENT (AM_STR, "am_pm", std, stringarray, 2, 2)
+ DEFINE_ELEMENT (D_T_FMT, "d_t_fmt", std, string)
+ DEFINE_ELEMENT (D_FMT, "d_fmt", std, string)
+ DEFINE_ELEMENT (T_FMT, "t_fmt", std, string)
+ DEFINE_ELEMENT (T_FMT_AMPM, "t_fmt_ampm", std, string)
+ DEFINE_ELEMENT (ERA, "era", opt, stringlist, 0, 100)
+ DEFINE_ELEMENT (ERA_YEAR, "era_year", opt, string)
+ DEFINE_ELEMENT (ERA_D_FMT, "era_d_fmt", opt, string)
+ DEFINE_ELEMENT (ALT_DIGITS, "alt_digits", opt, stringlist, 100, 100)
+ DEFINE_ELEMENT (ERA_D_T_FMT, "era_d_t_fmt", opt, string)
+ DEFINE_ELEMENT (ERA_T_FMT, "era_t_fmt", opt, string)
+#if 0
+ DEFINE_ELEMENT (_NL_TIME_ERA_NUM_ENTRIES, "time-era-num-entries", opt, word)
+ DEFINE_ELEMENT (_NL_TIME_ERA_ENTRIES, "time-era-entries", opt, string)
+ DEFINE_ELEMENT (_NL_WABDAY_1, "wide-abday", std, wstringarray, 7, 7)
+ DEFINE_ELEMENT (_NL_WDAY_1, "wide-day", std, wstringarray, 7, 7)
+ DEFINE_ELEMENT (_NL_WABMON_1, "wide-abmon", std, wstringarray, 12, 12)
+ DEFINE_ELEMENT (_NL_WMON_1, "wide-mon", std, wstringarray, 12, 12)
+ DEFINE_ELEMENT (_NL_WAM_STR, "wide-am_pm", std, wstringarray, 2, 2)
+ DEFINE_ELEMENT (_NL_WD_T_FMT, "wide-d_t_fmt", std, wstring)
+ DEFINE_ELEMENT (_NL_WD_FMT, "wide-d_fmt", std, wstring)
+ DEFINE_ELEMENT (_NL_WT_FMT, "wide-t_fmt", std, wstring)
+ DEFINE_ELEMENT (_NL_WT_FMT_AMPM, "wide-t_fmt_ampm", std, wstring)
+ DEFINE_ELEMENT (_NL_WERA_YEAR, "wide-era_year", opt, wstring)
+ DEFINE_ELEMENT (_NL_WERA_D_FMT, "wide-era_d_fmt", opt, wstring)
+ DEFINE_ELEMENT (_NL_WALT_DIGITS, "wide-alt_digits", opt, wstringlist, 1000, 100)
+ DEFINE_ELEMENT (_NL_WERA_D_T_FMT, "wide-era_d_t_fmt", opt, wstring)
+ DEFINE_ELEMENT (_NL_WERA_T_FMT, "wide-era_t_fmt", opt, wstring)
+ DEFINE_ELEMENT (_NL_TIME_WEEK_NDAYS, "week-ndays", std, byte)
+ DEFINE_ELEMENT (_NL_TIME_WEEK_1STDAY, "week-1stday", std, word)
+ DEFINE_ELEMENT (_NL_TIME_WEEK_1STWEEK, "week-1stweek", std, byte)
+ DEFINE_ELEMENT (_NL_TIME_FIRST_WEEKDAY, "first_weekday", std, byte)
+ DEFINE_ELEMENT (_NL_TIME_FIRST_WORKDAY, "first_workday", std, byte)
+ DEFINE_ELEMENT (_NL_TIME_CAL_DIRECTION, "cal_direction", std, byte)
+ DEFINE_ELEMENT (_NL_TIME_TIMEZONE, "timezone", std, string)
+ DEFINE_ELEMENT (_DATE_FMT, "date_fmt", opt, string)
+ DEFINE_ELEMENT (_NL_W_DATE_FMT, "wide-date_fmt", opt, wstring)
+ DEFINE_ELEMENT (_NL_TIME_CODESET, "time-codeset", std, string)
+#endif
+ ), NO_POSTLOAD)
+
+
+DEFINE_CATEGORY
+(
+ LC_MESSAGES, "LC_MESSAGES",
+ (
+ DEFINE_ELEMENT (YESEXPR, "yesexpr", std, string)
+ DEFINE_ELEMENT (NOEXPR, "noexpr", std, string)
+ DEFINE_ELEMENT (YESSTR, "yesstr", opt, string)
+ DEFINE_ELEMENT (NOSTR, "nostr", opt, string)
+#if 0
+ DEFINE_ELEMENT (_NL_MESSAGES_CODESET, "messages-codeset", std, string)
+#endif
+ ), NO_POSTLOAD)
+
+#if 0
+DEFINE_CATEGORY
+(
+ LC_PAPER, "LC_PAPER",
+ (
+ DEFINE_ELEMENT (_NL_PAPER_HEIGHT, "height", std, word)
+ DEFINE_ELEMENT (_NL_PAPER_WIDTH, "width", std, word)
+ DEFINE_ELEMENT (_NL_PAPER_CODESET, "paper-codeset", std, string)
+ ), NO_POSTLOAD)
+
+DEFINE_CATEGORY
+(
+ LC_NAME, "LC_NAME",
+ (
+ DEFINE_ELEMENT (_NL_NAME_NAME_FMT, "name_fmt", std, string)
+ DEFINE_ELEMENT (_NL_NAME_NAME_GEN, "name_gen", std, string)
+ DEFINE_ELEMENT (_NL_NAME_NAME_MR, "name_mr", std, string)
+ DEFINE_ELEMENT (_NL_NAME_NAME_MRS, "name_mrs", std, string)
+ DEFINE_ELEMENT (_NL_NAME_NAME_MISS, "name_miss", std, string)
+ DEFINE_ELEMENT (_NL_NAME_NAME_MS, "name_ms", std, string)
+ DEFINE_ELEMENT (_NL_NAME_CODESET, "name-codeset", std, string)
+ ), NO_POSTLOAD)
+
+DEFINE_CATEGORY
+(
+ LC_ADDRESS, "LC_ADDRESS",
+ (
+ DEFINE_ELEMENT (_NL_ADDRESS_POSTAL_FMT, "postal_fmt", std, string)
+ DEFINE_ELEMENT (_NL_ADDRESS_COUNTRY_NAME, "country_name", std, string)
+ DEFINE_ELEMENT (_NL_ADDRESS_COUNTRY_POST, "country_post", std, string)
+ DEFINE_ELEMENT (_NL_ADDRESS_COUNTRY_AB2, "country_ab2", std, string)
+ DEFINE_ELEMENT (_NL_ADDRESS_COUNTRY_AB3, "country_ab3", std, string)
+ DEFINE_ELEMENT (_NL_ADDRESS_COUNTRY_CAR, "country_car", std, string)
+ DEFINE_ELEMENT (_NL_ADDRESS_COUNTRY_NUM, "country_num", std, word)
+ DEFINE_ELEMENT (_NL_ADDRESS_COUNTRY_ISBN, "country_isbn", std, string)
+ DEFINE_ELEMENT (_NL_ADDRESS_LANG_NAME, "lang_name", std, string)
+ DEFINE_ELEMENT (_NL_ADDRESS_LANG_AB, "lang_ab", std, string)
+ DEFINE_ELEMENT (_NL_ADDRESS_LANG_TERM, "lang_term", std, string)
+ DEFINE_ELEMENT (_NL_ADDRESS_LANG_LIB, "lang_lib", std, string)
+ DEFINE_ELEMENT (_NL_ADDRESS_CODESET, "address-codeset", std, string)
+ ), NO_POSTLOAD)
+
+DEFINE_CATEGORY
+(
+ LC_TELEPHONE, "LC_TELEPHONE",
+ (
+ DEFINE_ELEMENT (_NL_TELEPHONE_TEL_INT_FMT, "tel_int_fmt", std, string)
+ DEFINE_ELEMENT (_NL_TELEPHONE_TEL_DOM_FMT, "tel_dom_fmt", std, string)
+ DEFINE_ELEMENT (_NL_TELEPHONE_INT_SELECT, "int_select", std, string)
+ DEFINE_ELEMENT (_NL_TELEPHONE_INT_PREFIX, "int_prefix", std, string)
+ DEFINE_ELEMENT (_NL_TELEPHONE_CODESET, "telephone-codeset", std, string)
+ ), NO_POSTLOAD)
+
+DEFINE_CATEGORY
+(
+ LC_MEASUREMENT, "LC_MEASUREMENT",
+ (
+ DEFINE_ELEMENT (_NL_MEASUREMENT_MEASUREMENT, "measurement", std, byte)
+ DEFINE_ELEMENT (_NL_MEASUREMENT_CODESET, "measurement-codeset", std, string)
+ ), NO_POSTLOAD)
+
+DEFINE_CATEGORY
+(
+ LC_IDENTIFICATION, "LC_IDENTIFICATION",
+ (
+ DEFINE_ELEMENT (_NL_IDENTIFICATION_TITLE, "title", std, string)
+ DEFINE_ELEMENT (_NL_IDENTIFICATION_SOURCE, "source", std, string)
+ DEFINE_ELEMENT (_NL_IDENTIFICATION_ADDRESS, "address", std, string)
+ DEFINE_ELEMENT (_NL_IDENTIFICATION_CONTACT, "contact", std, string)
+ DEFINE_ELEMENT (_NL_IDENTIFICATION_EMAIL, "email", std, string)
+ DEFINE_ELEMENT (_NL_IDENTIFICATION_TEL, "tel", std, string)
+ DEFINE_ELEMENT (_NL_IDENTIFICATION_FAX, "fax", std, string)
+ DEFINE_ELEMENT (_NL_IDENTIFICATION_LANGUAGE, "language", std, string)
+ DEFINE_ELEMENT (_NL_IDENTIFICATION_TERRITORY, "territory", std, string)
+ DEFINE_ELEMENT (_NL_IDENTIFICATION_AUDIENCE, "audience", std, string)
+ DEFINE_ELEMENT (_NL_IDENTIFICATION_APPLICATION, "application", std, string)
+ DEFINE_ELEMENT (_NL_IDENTIFICATION_ABBREVIATION, "abbreviation", std, string)
+ DEFINE_ELEMENT (_NL_IDENTIFICATION_REVISION, "revision", std, string)
+ DEFINE_ELEMENT (_NL_IDENTIFICATION_DATE, "date", std, string)
+ DEFINE_ELEMENT (_NL_IDENTIFICATION_CATEGORY, "category", std, stringarray, 13, 13)
+ DEFINE_ELEMENT (_NL_IDENTIFICATION_CODESET, "identification-codeset", std, string)
+ ), NO_POSTLOAD)
+#endif
diff --git a/extra/locale/programs/locale.c b/extra/locale/programs/locale.c
new file mode 100644
index 000000000..0ec9515fb
--- /dev/null
+++ b/extra/locale/programs/locale.c
@@ -0,0 +1,466 @@
+/*
+ *
+ * Copyright (c) 2008 STMicroelectronics Ltd
+ * Filippo Arcidiacono (filippo.arcidiacono@st.com)
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ *
+ * A 'locale' command implementation for uClibc.
+ *
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <langinfo.h>
+#include <getopt.h>
+
+typedef struct {
+ unsigned char idx_name;
+ char dot_cs; /* 0 if no codeset specified */
+ char cs;
+ unsigned char lc_ctype_row;
+ unsigned char lc_numeric_row;
+ unsigned char lc_monetary_row;
+ unsigned char lc_time_row;
+ unsigned char lc_collate_row;
+ unsigned char lc_messages_row;
+} locale_entry;
+
+/* Need to include this before locale.h and xlocale.h! */
+#include <bits/uClibc_locale.h>
+
+#undef CODESET_LIST
+#define CODESET_LIST (__locale_mmap->codeset_list)
+#include <locale.h>
+#define LOCALE_NAMES (__locale_mmap->locale_names5)
+#define LOCALES (__locale_mmap->locales)
+#define LOCALE_AT_MODIFIERS (__locale_mmap->locale_at_modifiers)
+#define CATEGORY_NAMES (__locale_mmap->lc_names)
+
+#define GET_CODESET_NAME(N) (CODESET_LIST + *(CODESET_LIST + N - 3))
+#define GET_LOCALE_ENTRY(R) (locale_entry *)(LOCALES + (__LOCALE_DATA_WIDTH_LOCALES * R))
+#define GET_CATEGORY_NAME(X) (CATEGORY_NAMES + *(CATEGORY_NAMES + X))
+#define GET_LOCALE_NAME(I) (const char *)(LOCALE_NAMES + 5 * (I - 1))
+
+static const char utf8[] = "UTF-8";
+static const char ascii[] = "ASCII";
+
+/* If set print the name of the category. */
+static int show_category_name = 0;
+
+/* If set print the name of the item. */
+static int show_keyword_name = 0;
+
+/* If set print the usage command. */
+static int show_usage = 0;
+
+/* Print names of all available locales. */
+static int do_all = 0;
+
+/* Print names of all available character maps. */
+static int do_charmaps = 0;
+
+static int remaining = 0;
+
+/* We can map the types of the entries into a few categories. */
+enum value_type
+{
+ none,
+ string,
+ stringarray,
+ byte,
+ bytearray,
+ word,
+ stringlist,
+ wordarray,
+ wstring,
+ wstringarray,
+ wstringlist
+};
+
+/* Definition of the data structure which represents a category and its
+ items. */
+struct category
+{
+ int cat_id;
+ const char *name;
+ size_t number;
+ struct cat_item
+ {
+ int item_id;
+ const char *name;
+ enum { std, opt } status;
+ enum value_type value_type;
+ int min;
+ int max;
+ } *item_desc;
+};
+
+/* Simple helper macro. */
+#define NELEMS(arr) ((sizeof (arr)) / (sizeof (arr[0])))
+
+/* For some tricky stuff. */
+#define NO_PAREN(Item, More...) Item, ## More
+
+/* We have all categories defined in `categories.def'. Now construct
+ the description and data structure used for all categories. */
+#define DEFINE_ELEMENT(Item, More...) { Item, ## More },
+#define DEFINE_CATEGORY(category, name, items, postload) \
+ static struct cat_item category##_desc[] = \
+ { \
+ NO_PAREN items \
+ };
+
+#include "categories.def"
+#undef DEFINE_CATEGORY
+
+static struct category category[] =
+ {
+#define DEFINE_CATEGORY(category, name, items, postload) \
+ [category] = { _NL_NUM_##category, name, NELEMS (category##_desc), \
+ category##_desc },
+#include "categories.def"
+#undef DEFINE_CATEGORY
+ };
+#define NCATEGORIES NELEMS (category)
+
+static void usage(const char *name);
+static void usage(const char *name)
+{
+ const char *s;
+
+ s = basename(name);
+ fprintf(stderr,
+ "Usage: %s [-ck] [--category-name] [--keyword-name] [--help] NAME\n"
+ "or: %s [OPTION...] [-a|-m] [--all-locales] [--charmaps] \n", s, s);
+}
+
+static int argp_parse(int argc, char *argv[]);
+static int argp_parse(int argc, char *argv[])
+{
+ static const struct option long_options[] =
+ {
+ {"all-locales", no_argument, NULL, 'a'},
+ {"charmaps", no_argument, NULL, 'm'},
+ {"category-name", no_argument, NULL, 'c'},
+ {"keyword-name", no_argument, NULL, 'k'},
+ {"help", no_argument, NULL, 'h'},
+ {NULL, 0, NULL, 0 }
+ };
+ int c;
+ char *progname;
+
+ progname = *argv;
+ while ((c = getopt_long (argc, argv, "amckh", long_options, NULL)) >= 0)
+ switch (c)
+ {
+ case 'a':
+ do_all = 1;
+ break;
+ case 'c':
+ show_category_name = 1;
+ break;
+ case 'm':
+ do_charmaps = 1;
+ break;
+ case 'k':
+ show_keyword_name = 1;
+ break;
+ case 'h':
+ show_usage = 1;
+ break;
+ case '?':
+ fprintf (stderr, "Unknown option.\n");
+ usage(progname);
+ return 1;
+
+ default:
+ fprintf (stderr, "This should never happen!\n");
+ return 1;
+ }
+
+ remaining = optind;
+
+ return 0;
+}
+
+static unsigned const char * find_at(char c);
+static unsigned const char * find_at(char c)
+{
+ const unsigned char *q;
+
+ q = LOCALE_AT_MODIFIERS;
+ do {
+ if (q[1] == c) {
+ return (unsigned const char *)q+2;
+ }
+ q += 2 + *q;
+ } while (*q);
+
+ return NULL;
+}
+
+static void find_locale_string(locale_entry *loc_rec, char *loc)
+{
+ char at = 0;
+ unsigned char idx;
+ uint16_t dotcs, cs;
+
+ idx = loc_rec->idx_name;
+ if (!idx) {
+ *loc++ = 'C'; /* jump the first locale (C) */
+ *loc = '\0';
+ }
+ else {
+ dotcs = (uint16_t) loc_rec->dot_cs;
+ cs = (uint16_t) loc_rec->cs;;
+ loc = strncpy(loc, GET_LOCALE_NAME(idx), 5);
+
+ if (loc[2] == '_') {
+ sprintf(loc, "%5.5s%c%s\0", loc, (dotcs != 0) ? '.' : ' ',
+ (cs == 1) ? ascii : ((cs == 2) ? utf8 : GET_CODESET_NAME(cs)));
+ } else {
+ at = loc[2];
+ loc[2] = '_';
+ sprintf(loc, "%5.5s%c%s@%s\0", loc, (dotcs != 0) ? '.' : ' ',
+ (cs == 1) ? ascii : ((cs == 2) ? utf8 : GET_CODESET_NAME(cs)),
+ find_at(at));
+ }
+ }
+}
+
+static void list_locale(void);
+static void list_locale()
+{
+ char loc[40];
+ uint16_t n = 0;
+ locale_entry *locales = (locale_entry *)LOCALES;
+
+ do {
+ find_locale_string(locales, loc);
+ printf("%s\n", loc);
+ ++n;
+ locales++;
+ } while (n < __LOCALE_DATA_NUM_LOCALES);
+}
+
+static void list_charmaps(void);
+static void list_charmaps()
+{
+ unsigned const char *cl;
+
+ cl = CODESET_LIST;
+ do {
+ printf("%s\n", CODESET_LIST + *cl);
+ } while (*++cl);
+
+}
+
+static void print_item (struct cat_item *item);
+static void print_item (struct cat_item *item)
+{
+ switch (item->value_type)
+ {
+ case string:
+ if (show_keyword_name)
+ printf ("%s=\"", item->name);
+ fputs (nl_langinfo (item->item_id) ? : "", stdout);
+ if (show_keyword_name)
+ putchar ('"');
+ putchar ('\n');
+ break;
+ case stringarray:
+ {
+ int cnt;
+ const char *val;
+
+ if (show_keyword_name)
+ printf ("%s=\"", item->name);
+
+ for (cnt = 0; cnt < item->max - 1; ++cnt)
+ {
+ val = nl_langinfo (item->item_id + cnt);
+ if (val != NULL)
+ fputs (val, stdout);
+ putchar (';');
+ }
+
+ val = nl_langinfo (item->item_id + cnt);
+ if (val != NULL)
+ fputs (val, stdout);
+
+ if (show_keyword_name)
+ putchar ('"');
+ putchar ('\n');
+ }
+ break;
+ case stringlist:
+ {
+ int first = 1;
+ const char *val = nl_langinfo (item->item_id) ? : "";
+ int cnt;
+
+ if (show_keyword_name)
+ printf ("%s=", item->name);
+
+ for (cnt = 0; cnt < item->max && *val != '\0'; ++cnt)
+ {
+ printf ("%s%s%s%s", first ? "" : ";",
+ show_keyword_name ? "\"" : "", val,
+ show_keyword_name ? "\"" : "");
+ val = strchr (val, '\0') + 1;
+ first = 0;
+ }
+ putchar ('\n');
+ }
+ break;
+ case byte:
+ {
+ const char *val = nl_langinfo (item->item_id);
+
+ if (show_keyword_name)
+ printf ("%s=", item->name);
+
+ if (val != NULL)
+ printf ("%d", *val == '\177' ? -1 : *val);
+ putchar ('\n');
+ }
+ break;
+ case bytearray:
+ {
+ const char *val = nl_langinfo (item->item_id);
+ int cnt = val ? strlen (val) : 0;
+
+ if (show_keyword_name)
+ printf ("%s=", item->name);
+
+ while (cnt > 1)
+ {
+ printf ("%d;", *val == '\177' ? -1 : *val);
+ --cnt;
+ ++val;
+ }
+
+ printf ("%d\n", cnt == 0 || *val == '\177' ? -1 : *val);
+ }
+ break;
+ case word:
+ {
+ union { unsigned int word; char *string; } val;
+ val.string = nl_langinfo (item->item_id);
+ if (show_keyword_name)
+ printf ("%s=", item->name);
+
+ printf ("%d\n", val.word);
+ }
+ break;
+ case wstring:
+ case wstringarray:
+ case wstringlist:
+ /* We don't print wide character information since the same
+ information is available in a multibyte string. */
+ default:
+ break;
+
+ }
+}
+
+/* Show the information request for NAME. */
+static void show_info(const char *name);
+static void show_info(const char *name)
+{
+ size_t cat_no, item_no;
+ const unsigned char *cat_name;
+
+ /* Now all categories in an unspecified order. */
+ for (cat_no = 0; cat_no < __LC_ALL; ++cat_no) {
+ cat_name = GET_CATEGORY_NAME(cat_no);
+ if (strcmp (name, (const char *)cat_name) == 0) {
+ if (show_category_name)
+ printf("%s\n", name);
+
+ for (item_no = 0; item_no < category[cat_no].number; ++item_no)
+ print_item (&category[cat_no].item_desc[item_no]);
+
+ return;
+ }
+
+ for (item_no = 0; item_no < category[cat_no].number; ++item_no)
+ if (strcmp (name, category[cat_no].item_desc[item_no].name) == 0) {
+ if (show_category_name != 0)
+ puts (category[cat_no].name);
+
+ print_item (&category[cat_no].item_desc[item_no]);
+ return;
+ }
+ }
+}
+
+static void show_locale_vars(void);
+static void show_locale_vars()
+{
+ size_t cat_no;
+ int row; /* locale row */
+ const char *lcall = getenv ("LC_ALL");
+ const char *lang = getenv ("LANG") ? : "";
+ unsigned char *cur_loc = __global_locale->cur_locale + 1;
+ char loc_name[40];
+ locale_entry *locales;
+
+ /* LANG has to be the first value. */
+ printf ("LANG=%s\n", lang);
+
+ /* Now all categories in an unspecified order. */
+ for (cat_no = 0; cat_no < __LC_ALL; ++cat_no) {
+ row = (((int)(*cur_loc & 0x7f)) << 7) + (cur_loc[1] & 0x7f);
+/* assert(row < __LOCALE_DATA_NUM_LOCALES); */
+
+ locales = GET_LOCALE_ENTRY(row);
+ find_locale_string(locales, loc_name);
+ printf("%s=%s\n", GET_CATEGORY_NAME(cat_no), loc_name);
+
+ cur_loc += 2;
+ }
+
+ /* The last is the LC_ALL value. */
+ printf ("LC_ALL=%s\n", lcall ? : "");
+}
+
+int
+main (int argc, char *argv[])
+{
+ /* Parse and process arguments. */
+ if (argp_parse(argc, argv))
+ return 1;
+
+ if (do_all) {
+ list_locale();
+ exit (EXIT_SUCCESS);
+ }
+
+ if (do_charmaps) {
+ list_charmaps();
+ exit (EXIT_SUCCESS);
+ }
+
+ if (show_usage) {
+ usage(*argv);
+ exit (EXIT_SUCCESS);
+ }
+
+ /* If no real argument is given we have to print the contents of the
+ current locale definition variables. These are LANG and the LC_*. */
+ if (remaining == argc && show_category_name == 0 && show_keyword_name == 0) {
+ show_locale_vars ();
+ exit (EXIT_SUCCESS);
+ }
+
+ /* Process all given names. */
+ while (remaining < argc)
+ show_info (argv[remaining++]);
+
+ exit (EXIT_SUCCESS);
+
+}
diff --git a/include/langinfo.h b/include/langinfo.h
index 837a87b83..12f008046 100644
--- a/include/langinfo.h
+++ b/include/langinfo.h
@@ -354,7 +354,6 @@ enum
_NL_CTYPE_EXTRA_MAP_12,
_NL_CTYPE_EXTRA_MAP_13,
_NL_CTYPE_EXTRA_MAP_14,
- _NL_NUM_LC_CTYPE,
#else /* 0 */
_NL_CTYPE_OUTDIGIT0_MB = _NL_ITEM (__LC_CTYPE, 0),
_NL_CTYPE_OUTDIGIT1_MB,
@@ -370,6 +369,7 @@ enum
CODESET = _NL_CTYPE_CODESET_NAME,
#define CODESET CODESET
#endif /* 0 */
+ _NL_NUM_LC_CTYPE,
/* LC_MONETARY category: formatting of monetary quantities.
These items each correspond to a member of `struct lconv',
diff --git a/utils/Makefile.in b/utils/Makefile.in
index 57a00b307..611e07efa 100644
--- a/utils/Makefile.in
+++ b/utils/Makefile.in
@@ -25,6 +25,8 @@ CFLAGS-iconv := $(CFLAGS-utils) $(CFLAGS-utils-shared) -DL_iconv_main
CFLAGS-readelf := $(CFLAGS-utils-shared)
+CFLAGS-locale := $(CFLAGS-utils)
+
BUILD_CFLAGS-utils := -include $(top_srcdir)include/elf.h
BUILD_CFLAGS-utils-common := $(CFLAGS-utils-common)
@@ -51,15 +53,17 @@ utils_OBJ += ldconfig ldd
endif
utils_ICONV_OBJ =
+utils_LOCALE_OBJ =
ifeq ($(UCLIBC_HAS_LOCALE),y)
utils_ICONV_OBJ := $(utils_OUT)/iconv
+utils_LOCALE_OBJ := $(utils_OUT)/locale
endif
utils_OBJ := $(patsubst %,$(utils_OUT)/%,$(utils_OBJ))
hostutils_OBJ := $(patsubst %,%.host,$(utils_OBJ))
-utils: $(utils_OBJ) $(utils_ICONV_OBJ)
+utils: $(utils_OBJ) $(utils_ICONV_OBJ) $(utils_LOCALE_OBJ)
# NOTE: We build the utils AFTER we have a uClibc-targeted toolchain.
@@ -69,6 +73,9 @@ $(utils_OBJ): $(utils_OUT)/% : $(utils_DIR)/%.c | $(libc)
$(utils_OUT)/iconv: $(top_srcdir)libc/misc/wchar/wchar.c | $(libc)
$(compile.u)
+$(utils_OUT)/locale: $(top_srcdir)extra/locale/programs/locale.c | $(libc)
+ $(compile.u)
+
hostutils: $(hostutils_OBJ)
$(hostutils_OBJ): $(utils_OUT)/%.host : $(utils_DIR)/%.c
@@ -86,9 +93,10 @@ ifeq ($(HAVE_SHARED),y)
endif
ifeq ($(UCLIBC_HAS_LOCALE),y)
$(INSTALL) -m 755 $(utils_OUT)/iconv $(PREFIX)$(RUNTIME_PREFIX)usr/bin/iconv
+ $(INSTALL) -m 755 $(utils_OUT)/locale $(PREFIX)$(RUNTIME_PREFIX)usr/bin/locale
endif
objclean-y += utils_clean
utils_clean:
- $(RM) $(utils_OUT)/{ldconfig,ldd,readelf,iconv,*.host}
+ $(RM) $(utils_OUT)/{ldconfig,ldd,readelf,iconv,locale,*.host}