diff options
author | Konstantin <ria.freelander@gmail.com> | 2016-05-04 13:24:34 +0300 |
---|---|---|
committer | Konstantin <ria.freelander@gmail.com> | 2016-05-04 13:24:34 +0300 |
commit | a24e4fa0b990214b369b59704193eb64be27483c (patch) | |
tree | dc9fc5b6f6a3de9903cd968c5f6d4d9e7178032b /locale.c | |
download | musl-locales-a24e4fa0b990214b369b59704193eb64be27483c.tar.gz musl-locales-a24e4fa0b990214b369b59704193eb64be27483c.tar.bz2 musl-locales-a24e4fa0b990214b369b59704193eb64be27483c.tar.xz musl-locales-a24e4fa0b990214b369b59704193eb64be27483c.zip |
First working version.
Diffstat (limited to 'locale.c')
-rw-r--r-- | locale.c | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/locale.c b/locale.c new file mode 100644 index 0000000..6079076 --- /dev/null +++ b/locale.c @@ -0,0 +1,233 @@ +/* vi: set sw=4 ts=4: */ +/* + * + * 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 <string.h> +#include <stddef.h> +#include <stdio.h> +#include <libgen.h> +#include <stdlib.h> +#include <langinfo.h> +#include <unistd.h> +#include <getopt.h> +#include <stdint.h> +#include <dirent.h> +#include <locale.h> +#include <stdbool.h> +#include "categories.h" + + +/* If set print the name of the category. */ +static bool show_category_name = 0; + +/* If set print the name of the item. */ +static bool show_keyword_name = 0; + +/* If set print the usage command. */ +static bool show_usage = 0; + +/* Print names of all available locales. */ +static bool do_all = 0; + +/* Print names of all available character maps. */ +static bool do_charmaps = 0; + +static int remaining = 0; + +static void usage(char *name) +{ + char *s; + + s = basename(name); + fprintf(stderr, + "Usage: %s [-a | -m] [FORMAT] name...\n\n" + "\t-a, --all-locales\tWrite names of all available locales\n" + "\t-m, --charmaps\tWrite names of available charmaps\n" + "\nFORMAT:\n" + "\t-c, --category-name\tWrite names of selected categories\n" + "\t-k, --keyword-name\tWrite names of selected keywords\n" + , s); + free(s); +} + +static int argp_parse(int argc, char *argv[]) +{ + int c; + char *progname; + 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}}; + 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 void list_locale() +{ + const char *locpath = getenv("MUSL_LOCPATH"); + DIR *dir = opendir(locpath); + struct dirent *pDir; + printf("C"); + printf("C.UTF-8"); + while ((pDir = readdir(dir)) != NULL){ + printf("%s.%s\n",pDir->d_name,"UTF-8"); + } +} + +static void list_charmaps() +{ + printf("ASCII\n"); + printf("UTF-8\n"); + return; +} + +static void print_item (struct cat_item item) +{ + switch (item.type) + { + case CAT_TYPE_STRING: + if (show_keyword_name) + printf ("%s=\"", item.name); + fputs (nl_langinfo (item.id) ? : "", stdout); + if (show_keyword_name) + putchar ('"'); + putchar ('\n'); + break; + case CAT_TYPE_STRINGARRAY: + { + const char *val; + if (show_keyword_name) + printf ("%s=\"", item.name); + + for (int cnt = item.min; cnt <= item.max; ++cnt) + { + val = nl_langinfo (item.id); + if (val != NULL) + fputs (val, stdout); + putchar (';'); + } + if (show_keyword_name) + putchar ('"'); + putchar ('\n'); + } + break; + } +} + +/* Show the information request for NAME. */ +static void show_info(const char *name) +{ + for (size_t cat_no = 0; cat_no < LC_ALL; ++cat_no) + { + if (strcmp (name, get_name_for_cat(cat_no)) == 0) + /* Print the whole category. */ + { + if (show_category_name != 0) + puts (get_name_for_cat(cat_no)); + const struct cat_item* items = get_cat_for_locale_cat(cat_no); + for(int j = 0; items[j].type != CAT_TYPE_END; j++) + print_item(items[j]); + return; + } + else + { + if (show_category_name != 0) + puts (get_name_for_cat(cat_no)); + print_item(get_cat_item_for_name(name)); + } + + } +} + +static void show_locale_vars() +{ + const char *lcall = getenv("LC_ALL") ? : "\0"; + const char *lang = getenv("LANG") ? : ""; + + /* LANG has to be the first value. */ + printf("LANG=%s\n", lang); + for (size_t cat_no = 0; cat_no < LC_ALL; ++cat_no) + { + printf("%s=%s\n",get_name_for_cat(cat_no),lcall[0] != '\0' ? lcall + : lang[0] != '\0' ? lang + : "POSIX"); + } + /* 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); +} |