From fc5abf4933bebea46105b5bb9cd81b77ae670fc9 Mon Sep 17 00:00:00 2001 From: Carmelo Amoroso Date: Fri, 2 May 2008 13:57:02 +0000 Subject: Added implementation for 'locale' command. Signed-off-by: Filippo Arcidiacono --- extra/locale/programs/categories.def | 357 +++++++++++++++++++++++++++ extra/locale/programs/locale.c | 466 +++++++++++++++++++++++++++++++++++ include/langinfo.h | 2 +- utils/Makefile.in | 12 +- 4 files changed, 834 insertions(+), 3 deletions(-) create mode 100644 extra/locale/programs/categories.def create mode 100644 extra/locale/programs/locale.c 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 +#include +#include +#include +#include + +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 + +#undef CODESET_LIST +#define CODESET_LIST (__locale_mmap->codeset_list) +#include +#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} -- cgit v1.2.3