| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232 |
- /*
- * Copyright © 2020 Red Hat, Inc.
- * SPDX-License-Identifier: MIT
- */
- #include "config.h"
- #include <assert.h>
- #include <getopt.h>
- #include <locale.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include "xkbcommon/xkbregistry.h"
- static void
- usage(const char *progname, FILE *fp)
- {
- fprintf(fp,
- "Usage: %s [OPTIONS] [/path/to/xkb_base_directory [/path2]...]\n"
- "\n"
- "Options:\n"
- " --verbose, -v .......... Increase verbosity, use multiple times for debugging output\n"
- " --ruleset=foo .......... Load the 'foo' ruleset\n"
- " --skip-default-paths ... Do not load the default XKB paths\n"
- " --load-exotic .......... Load the exotic (extra) rulesets\n"
- " --help ................. Print this help and exit\n"
- " --version .............. Print version information and exit\n"
- "\n"
- "Trailing arguments are treated as XKB base directory installations.\n",
- progname);
- }
- int
- main(int argc, char **argv)
- {
- int rc = 1;
- struct rxkb_context *ctx = NULL;
- struct rxkb_model *m;
- struct rxkb_layout *l;
- struct rxkb_option_group *g;
- enum rxkb_context_flags flags = RXKB_CONTEXT_NO_FLAGS;
- bool load_defaults = true;
- int verbosity = 0;
- const char *ruleset = DEFAULT_XKB_RULES;
- static const struct option opts[] = {
- {"help", no_argument, 0, 'h'},
- {"version", no_argument, 0, 'V'},
- {"verbose", no_argument, 0, 'v'},
- {"load-exotic", no_argument, 0, 'e'},
- {"skip-default-paths", no_argument, 0, 'd'},
- {"ruleset", required_argument, 0, 'r'},
- {0, 0, 0, 0},
- };
- setlocale(LC_ALL, "");
- while (1) {
- int c;
- int option_index = 0;
- c = getopt_long(argc, argv, "hedrvV", opts, &option_index);
- if (c == -1)
- break;
- switch (c) {
- case 'h':
- usage(argv[0], stdout);
- return EXIT_SUCCESS;
- case 'd':
- load_defaults = false;
- break;
- case 'e':
- flags |= RXKB_CONTEXT_LOAD_EXOTIC_RULES;
- break;
- case 'r':
- ruleset = optarg;
- break;
- case 'v':
- verbosity++;
- break;
- case 'V':
- printf("%s\n", LIBXKBCOMMON_VERSION);
- exit(EXIT_SUCCESS);
- default:
- usage(argv[0], stderr);
- return EXIT_INVALID_USAGE;
- }
- }
- if (optind < argc)
- flags |= RXKB_CONTEXT_NO_DEFAULT_INCLUDES;
- ctx = rxkb_context_new(flags);
- if (!ctx) {
- fprintf(stderr, "Failed to create a registry context\n");
- rc = EXIT_FAILURE;
- goto err;
- }
- switch (verbosity) {
- case 0:
- rxkb_context_set_log_level(ctx, RXKB_LOG_LEVEL_ERROR);
- break;
- case 1:
- rxkb_context_set_log_level(ctx, RXKB_LOG_LEVEL_INFO);
- break;
- default:
- rxkb_context_set_log_level(ctx, RXKB_LOG_LEVEL_DEBUG);
- break;
- }
- if (optind < argc) {
- for (int i = optind; i < argc; i++) {
- if (!rxkb_context_include_path_append(ctx, argv[i])) {
- fprintf(stderr, "Failed to append include path '%s'\n",
- argv[i]);
- goto err;
- }
- }
- if (load_defaults) {
- if (!rxkb_context_include_path_append_default(ctx)) {
- fprintf(stderr, "Failed to include default paths.\n");
- goto err;
- }
- }
- }
- if (!rxkb_context_parse(ctx, ruleset)) {
- fprintf(stderr, "Failed to parse XKB descriptions.\n");
- goto err;
- }
- printf("models:\n");
- m = rxkb_model_first(ctx);
- assert(m); /* Empty model list is usually a bug or a bad xml file */
- while (m) {
- const char *vendor = rxkb_model_get_vendor(m);
- printf("- name: %s\n"
- " vendor: %s\n"
- " description: %s\n",
- rxkb_model_get_name(m),
- vendor ? vendor : "''",
- rxkb_model_get_description(m));
- m = rxkb_model_next(m);
- }
- printf("\n");
- printf("layouts:\n");
- l = rxkb_layout_first(ctx);
- assert(l); /* Empty layout list is usually a bug or a bad xml file */
- while (l) {
- struct rxkb_iso639_code *iso639;
- struct rxkb_iso3166_code *iso3166;
- const char *variant = rxkb_layout_get_variant(l);
- const char *brief = rxkb_layout_get_brief(l);
- printf("- layout: '%s'\n"
- " variant: '%s'\n"
- " brief: '%s'\n"
- " description: %s\n",
- rxkb_layout_get_name(l),
- variant ? variant : "",
- brief ? brief : "''",
- rxkb_layout_get_description(l));
- printf(" iso639: [");
- iso639 = rxkb_layout_get_iso639_first(l);
- if (iso639) {
- const char *sep = "";
- while (iso639) {
- printf("%s'%s'", sep, rxkb_iso639_code_get_code(iso639));
- iso639 = rxkb_iso639_code_next(iso639);
- sep = ", ";
- }
- }
- printf("]\n");
- printf(" iso3166: [");
- iso3166 = rxkb_layout_get_iso3166_first(l);
- if (iso3166) {
- const char *sep = "";
- while (iso3166) {
- printf("%s'%s'", sep, rxkb_iso3166_code_get_code(iso3166));
- iso3166 = rxkb_iso3166_code_next(iso3166);
- sep = ", ";
- }
- }
- printf("]\n");
- l = rxkb_layout_next(l);
- }
- printf("\n");
- printf("option_groups:\n");
- g = rxkb_option_group_first(ctx);
- assert(g); /* Empty option goups list is usually a bug or a bad xml file */
- while (g) {
- struct rxkb_option *o;
- printf("- name: '%s'\n"
- " description: %s\n"
- " allows_multiple: %s\n"
- " options:\n",
- rxkb_option_group_get_name(g),
- rxkb_option_group_get_description(g),
- rxkb_option_group_allows_multiple(g) ? "true" : "false");
- o = rxkb_option_first(g);
- assert(o); /* Empty option list is usually a bug or a bad xml file */
- while (o) {
- const char *brief = rxkb_option_get_brief(o);
- printf(" - name: '%s'\n"
- " brief: '%s'\n"
- " description: '%s'\n"
- " layout-specific: %s\n",
- rxkb_option_get_name(o),
- brief ? brief : "",
- rxkb_option_get_description(o),
- rxkb_option_is_layout_specific(o) ? "true" : "false");
- o = rxkb_option_next(o);
- }
- g = rxkb_option_group_next(g);
- }
- rc = EXIT_SUCCESS;
- err:
- rxkb_context_unref(ctx);
- return rc;
- }
|