Add FreeBSD specific keyword 'list' implementation. 'locale -k list' can

be used to retrieve list of all available keywords now.
This commit is contained in:
Alexey Zelkin 2003-06-22 08:34:27 +00:00
parent d8dca302fb
commit 3f101ba0a5

View File

@ -27,16 +27,12 @@
*/
/*
* XXX: implement missing int_* (LC_MONETARY) and era_* (LC_CTIME) keywords
* (require libc modification)
* XXX: implement missing int_* (LC_MONETARY) (require libc modification) and
* era_* (LC_TIME) keywords (require libc & nl_langinfo(3) extensions)
*
* XXX: correctly handle reserved 'charmap' keyword and '-m' option (require
* localedef(1) implementation). Currently it's handled via
* nl_langinfo(CODESET).
*
* XXX: implement '-k list' to show all available keywords. Add descriptions
* for all of keywords (and mention FreeBSD only there)
*
*/
#include <sys/types.h>
@ -54,9 +50,11 @@
/* Local prototypes */
void init_locales_list(void);
void list_locales(void);
const char *lookup_localecat(int);
char *kwval_lconv(int);
int kwval_lookup(char *, char **, int *, int *);
void showdetails(char *);
void showkeywordslist(void);
void showlocale(void);
void usage(void);
@ -106,87 +104,93 @@ struct _kwinfo {
int isstr; /* true - string, false - number */
int catid; /* LC_* */
int value_ref;
const char *comment;
} kwinfo [] = {
{ "charmap", 1, LC_CTYPE, CODESET }, /* hack */
{ "charmap", 1, LC_CTYPE, CODESET, "" }, /* hack */
{ "decimal_point", 1, LC_NUMERIC, RADIXCHAR },
{ "thousands_sep", 1, LC_NUMERIC, THOUSEP },
{ "grouping", 1, LC_NUMERIC, KW_GROUPING },
{ "radixchar", 1, LC_NUMERIC, RADIXCHAR }, /* compat */
{ "thousep", 1, LC_NUMERIC, THOUSEP}, /* compat */
{ "decimal_point", 1, LC_NUMERIC, RADIXCHAR, "" },
{ "thousands_sep", 1, LC_NUMERIC, THOUSEP, "" },
{ "grouping", 1, LC_NUMERIC, KW_GROUPING, "" },
{ "radixchar", 1, LC_NUMERIC, RADIXCHAR,
"Same as decimal_point (FreeBSD only)" }, /* compat */
{ "thousep", 1, LC_NUMERIC, THOUSEP,
"Same as thousands_sep (FreeBSD only)" }, /* compat */
{ "int_curr_symbol", 1, LC_MONETARY, KW_INT_CURR_SYMBOL },
{ "currency_symbol", 1, LC_MONETARY, KW_CURRENCY_SYMBOL },
{ "mon_decimal_point", 1, LC_MONETARY, KW_MON_DECIMAL_POINT },
{ "mon_thousands_sep", 1, LC_MONETARY, KW_MON_THOUSANDS_SEP },
{ "mon_grouping", 1, LC_MONETARY, KW_MON_GROUPING },
{ "positive_sign", 1, LC_MONETARY, KW_POSITIVE_SIGN },
{ "negative_sign", 1, LC_MONETARY, KW_NEGATIVE_SIGN },
{ "int_curr_symbol", 1, LC_MONETARY, KW_INT_CURR_SYMBOL, "" },
{ "currency_symbol", 1, LC_MONETARY, KW_CURRENCY_SYMBOL, "" },
{ "mon_decimal_point", 1, LC_MONETARY, KW_MON_DECIMAL_POINT, "" },
{ "mon_thousands_sep", 1, LC_MONETARY, KW_MON_THOUSANDS_SEP, "" },
{ "mon_grouping", 1, LC_MONETARY, KW_MON_GROUPING, "" },
{ "positive_sign", 1, LC_MONETARY, KW_POSITIVE_SIGN, "" },
{ "negative_sign", 1, LC_MONETARY, KW_NEGATIVE_SIGN, "" },
{ "int_frac_digits", 0, LC_MONETARY, KW_INT_FRAC_DIGITS },
{ "frac_digits", 0, LC_MONETARY, KW_FRAC_DIGITS },
{ "p_cs_precedes", 0, LC_MONETARY, KW_P_CS_PRECEDES },
{ "p_sep_by_space", 0, LC_MONETARY, KW_P_SEP_BY_SPACE },
{ "n_cs_precedes", 0, LC_MONETARY, KW_N_CS_PRECEDES },
{ "n_sep_by_space", 0, LC_MONETARY, KW_N_SEP_BY_SPACE },
{ "p_sign_posn", 0, LC_MONETARY, KW_P_SIGN_POSN },
{ "n_sign_posn", 0, LC_MONETARY, KW_N_SIGN_POSN },
{ "int_frac_digits", 0, LC_MONETARY, KW_INT_FRAC_DIGITS, "" },
{ "frac_digits", 0, LC_MONETARY, KW_FRAC_DIGITS, "" },
{ "p_cs_precedes", 0, LC_MONETARY, KW_P_CS_PRECEDES, "" },
{ "p_sep_by_space", 0, LC_MONETARY, KW_P_SEP_BY_SPACE, "" },
{ "n_cs_precedes", 0, LC_MONETARY, KW_N_CS_PRECEDES, "" },
{ "n_sep_by_space", 0, LC_MONETARY, KW_N_SEP_BY_SPACE, "" },
{ "p_sign_posn", 0, LC_MONETARY, KW_P_SIGN_POSN, "" },
{ "n_sign_posn", 0, LC_MONETARY, KW_N_SIGN_POSN, "" },
{ "d_t_fmt", 1, LC_TIME, D_T_FMT },
{ "d_fmt", 1, LC_TIME, D_FMT },
{ "t_fmt", 1, LC_TIME, T_FMT },
{ "am_str", 1, LC_TIME, AM_STR },
{ "pm_str", 1, LC_TIME, PM_STR },
{ "t_fmt_ampm", 1, LC_TIME, T_FMT_AMPM },
{ "day_1", 1, LC_TIME, DAY_1 },
{ "day_2", 1, LC_TIME, DAY_2 },
{ "day_3", 1, LC_TIME, DAY_3 },
{ "day_4", 1, LC_TIME, DAY_4 },
{ "day_5", 1, LC_TIME, DAY_5 },
{ "day_6", 1, LC_TIME, DAY_6 },
{ "day_7", 1, LC_TIME, DAY_7 },
{ "abday_1", 1, LC_TIME, ABDAY_1 },
{ "abday_2", 1, LC_TIME, ABDAY_2 },
{ "abday_3", 1, LC_TIME, ABDAY_3 },
{ "abday_4", 1, LC_TIME, ABDAY_4 },
{ "abday_5", 1, LC_TIME, ABDAY_5 },
{ "abday_6", 1, LC_TIME, ABDAY_6 },
{ "abday_7", 1, LC_TIME, ABDAY_7 },
{ "mon_1", 1, LC_TIME, MON_1 },
{ "mon_2", 1, LC_TIME, MON_2 },
{ "mon_3", 1, LC_TIME, MON_3 },
{ "mon_4", 1, LC_TIME, MON_4 },
{ "mon_5", 1, LC_TIME, MON_5 },
{ "mon_6", 1, LC_TIME, MON_6 },
{ "mon_7", 1, LC_TIME, MON_7 },
{ "mon_8", 1, LC_TIME, MON_8 },
{ "mon_9", 1, LC_TIME, MON_9 },
{ "mon_10", 1, LC_TIME, MON_10 },
{ "mon_11", 1, LC_TIME, MON_11 },
{ "mon_12", 1, LC_TIME, MON_12 },
{ "abmon_1", 1, LC_TIME, ABMON_1 },
{ "abmon_2", 1, LC_TIME, ABMON_2 },
{ "abmon_3", 1, LC_TIME, ABMON_3 },
{ "abmon_4", 1, LC_TIME, ABMON_4 },
{ "abmon_5", 1, LC_TIME, ABMON_5 },
{ "abmon_6", 1, LC_TIME, ABMON_6 },
{ "abmon_7", 1, LC_TIME, ABMON_7 },
{ "abmon_8", 1, LC_TIME, ABMON_8 },
{ "abmon_9", 1, LC_TIME, ABMON_9 },
{ "abmon_10", 1, LC_TIME, ABMON_10 },
{ "abmon_11", 1, LC_TIME, ABMON_11 },
{ "abmon_12", 1, LC_TIME, ABMON_12 },
{ "era", 1, LC_TIME, ERA },
{ "era_d_fmt", 1, LC_TIME, ERA_D_FMT },
{ "era_d_t_fmt", 1, LC_TIME, ERA_D_T_FMT },
{ "era_t_fmt", 1, LC_TIME, ERA_T_FMT },
{ "alt_digits", 1, LC_TIME, ALT_DIGITS },
{ "d_md_order", 1, LC_TIME, D_MD_ORDER }, /* local */
{ "d_t_fmt", 1, LC_TIME, D_T_FMT, "" },
{ "d_fmt", 1, LC_TIME, D_FMT, "" },
{ "t_fmt", 1, LC_TIME, T_FMT, "" },
{ "am_str", 1, LC_TIME, AM_STR, "" },
{ "pm_str", 1, LC_TIME, PM_STR, "" },
{ "t_fmt_ampm", 1, LC_TIME, T_FMT_AMPM, "" },
{ "day_1", 1, LC_TIME, DAY_1, "" },
{ "day_2", 1, LC_TIME, DAY_2, "" },
{ "day_3", 1, LC_TIME, DAY_3, "" },
{ "day_4", 1, LC_TIME, DAY_4, "" },
{ "day_5", 1, LC_TIME, DAY_5, "" },
{ "day_6", 1, LC_TIME, DAY_6, "" },
{ "day_7", 1, LC_TIME, DAY_7, "" },
{ "abday_1", 1, LC_TIME, ABDAY_1, "" },
{ "abday_2", 1, LC_TIME, ABDAY_2, "" },
{ "abday_3", 1, LC_TIME, ABDAY_3, "" },
{ "abday_4", 1, LC_TIME, ABDAY_4, "" },
{ "abday_5", 1, LC_TIME, ABDAY_5, "" },
{ "abday_6", 1, LC_TIME, ABDAY_6, "" },
{ "abday_7", 1, LC_TIME, ABDAY_7, "" },
{ "mon_1", 1, LC_TIME, MON_1, "" },
{ "mon_2", 1, LC_TIME, MON_2, "" },
{ "mon_3", 1, LC_TIME, MON_3, "" },
{ "mon_4", 1, LC_TIME, MON_4, "" },
{ "mon_5", 1, LC_TIME, MON_5, "" },
{ "mon_6", 1, LC_TIME, MON_6, "" },
{ "mon_7", 1, LC_TIME, MON_7, "" },
{ "mon_8", 1, LC_TIME, MON_8, "" },
{ "mon_9", 1, LC_TIME, MON_9, "" },
{ "mon_10", 1, LC_TIME, MON_10, "" },
{ "mon_11", 1, LC_TIME, MON_11, "" },
{ "mon_12", 1, LC_TIME, MON_12, "" },
{ "abmon_1", 1, LC_TIME, ABMON_1, "" },
{ "abmon_2", 1, LC_TIME, ABMON_2, "" },
{ "abmon_3", 1, LC_TIME, ABMON_3, "" },
{ "abmon_4", 1, LC_TIME, ABMON_4, "" },
{ "abmon_5", 1, LC_TIME, ABMON_5, "" },
{ "abmon_6", 1, LC_TIME, ABMON_6, "" },
{ "abmon_7", 1, LC_TIME, ABMON_7, "" },
{ "abmon_8", 1, LC_TIME, ABMON_8, "" },
{ "abmon_9", 1, LC_TIME, ABMON_9, "" },
{ "abmon_10", 1, LC_TIME, ABMON_10, "" },
{ "abmon_11", 1, LC_TIME, ABMON_11, "" },
{ "abmon_12", 1, LC_TIME, ABMON_12, "" },
{ "era", 1, LC_TIME, ERA, "(unavailable)" },
{ "era_d_fmt", 1, LC_TIME, ERA_D_FMT, "(unavailable)" },
{ "era_d_t_fmt", 1, LC_TIME, ERA_D_T_FMT, "(unavailable)" },
{ "era_t_fmt", 1, LC_TIME, ERA_T_FMT, "(unavailable)" },
{ "alt_digits", 1, LC_TIME, ALT_DIGITS, "" },
{ "d_md_order", 1, LC_TIME, D_MD_ORDER,
"(FreeBSD only)" }, /* local */
{ "yesexpr", 1, LC_MESSAGES, YESEXPR },
{ "noexpr", 1, LC_MESSAGES, NOEXPR },
{ "yesstr", 1, LC_MESSAGES, YESSTR }, /* local */
{ "nostr", 1, LC_MESSAGES, NOSTR } /* local */
{ "yesexpr", 1, LC_MESSAGES, YESEXPR, "" },
{ "noexpr", 1, LC_MESSAGES, NOEXPR, "" },
{ "yesstr", 1, LC_MESSAGES, YESSTR,
"(POSIX legacy)" }, /* compat */
{ "nostr", 1, LC_MESSAGES, NOSTR,
"(POSIX legacy)" } /* compat */
};
#define NKWINFO (sizeof(kwinfo)/sizeof(kwinfo[0]))
@ -195,6 +199,7 @@ int
main(int argc, char *argv[])
{
char ch;
int tmp;
while ((ch = getopt(argc, argv, "ackm")) != -1) {
switch (ch) {
@ -242,6 +247,15 @@ main(int argc, char *argv[])
exit(1);
}
/* check for special case '-k list' */
tmp = 0;
if (prt_keywords && argc > 0)
while (tmp < argc)
if (strcasecmp(argv[tmp++], "list") == 0) {
showkeywordslist();
exit(0);
}
/* process '-c' and/or '-k' */
if (prt_categories || prt_keywords || argc > 0) {
setlocale(LC_ALL, "");
@ -494,9 +508,7 @@ void
showdetails(char *kw)
{
int isstr, cat, tmpval;
size_t i;
char *kwval;
const char *tmps;
if (kwval_lookup(kw, &kwval, &cat, &isstr) == 0) {
/*
@ -507,15 +519,7 @@ showdetails(char *kw)
}
if (prt_categories) {
tmps = NULL;
for (i = 0; i < NLCINFO; i++)
if (lcinfo[i].id == cat) {
tmps = lcinfo[i].name;
break;
}
if (tmps == NULL)
tmps = "UNKNOWN";
printf("%s\n", tmps);
printf("%s\n", lookup_localecat(cat));
}
if (prt_keywords) {
@ -536,3 +540,40 @@ showdetails(char *kw)
}
}
}
/*
* Convert locale category id into string
*/
const char *
lookup_localecat(int cat)
{
size_t i;
for (i = 0; i < NLCINFO; i++)
if (lcinfo[i].id == cat) {
return (lcinfo[i].name);
}
return ("UNKNOWN");
}
/*
* Show list of keywords
*/
void
showkeywordslist(void)
{
size_t i;
#define FMT "%-20s %-12s %-7s %-20s\n"
printf("List of available keywords\n\n");
printf(FMT, "Keyword", "Category", "Type", "Comment");
printf("-------------------- ------------ ------- --------------------\n");
for (i = 0; i < NKWINFO; i++) {
printf(FMT,
kwinfo[i].name,
lookup_localecat(kwinfo[i].catid),
(kwinfo[i].isstr == 0) ? "number" : "string",
kwinfo[i].comment);
}
}