summaryrefslogtreecommitdiff
path: root/locale.c
diff options
context:
space:
mode:
authorKonstantin <ria.freelander@gmail.com>2016-05-04 13:24:34 +0300
committerKonstantin <ria.freelander@gmail.com>2016-05-04 13:24:34 +0300
commita24e4fa0b990214b369b59704193eb64be27483c (patch)
treedc9fc5b6f6a3de9903cd968c5f6d4d9e7178032b /locale.c
downloadmusl-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.c233
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);
+}