2 * Copyright © 2020 Red Hat, Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
30 #include "xkbcommon/xkbregistry.h"
33 usage(const char *progname, FILE *fp)
36 "Usage: %s [OPTIONS] [/path/to/xkb_base_directory [/path2]...]\n"
39 " --verbose, -v .......... Increase verbosity, use multiple times for debugging output\n"
40 " --ruleset=foo .......... Load the 'foo' ruleset\n"
41 " --skip-default-paths ... Do not load the default XKB paths\n"
42 " --load-exotic .......... Load the exotic (extra) rulesets\n"
43 " --help ................. Print this help and exit\n"
45 "Trailing arguments are treated as XKB base directory installations.\n",
50 main(int argc, char **argv)
53 struct rxkb_context *ctx = NULL;
55 struct rxkb_layout *l;
56 struct rxkb_option_group *g;
57 enum rxkb_context_flags flags = RXKB_CONTEXT_NO_FLAGS;
58 bool load_defaults = true;
60 const char *ruleset = DEFAULT_XKB_RULES;
62 static const struct option opts[] = {
63 {"help", no_argument, 0, 'h'},
64 {"verbose", no_argument, 0, 'v'},
65 {"load-exotic", no_argument, 0, 'e'},
66 {"skip-default-paths", no_argument, 0, 'd'},
67 {"ruleset", required_argument, 0, 'r'},
75 c = getopt_long(argc, argv, "hev", opts, &option_index);
81 usage(argv[0], stdout);
84 usage(argv[0], stderr);
85 return EXIT_INVALID_USAGE;
87 load_defaults = false;
90 flags |= RXKB_CONTEXT_LOAD_EXOTIC_RULES;
102 flags |= RXKB_CONTEXT_NO_DEFAULT_INCLUDES;
104 ctx = rxkb_context_new(flags);
109 rxkb_context_set_log_level(ctx, RXKB_LOG_LEVEL_ERROR);
112 rxkb_context_set_log_level(ctx, RXKB_LOG_LEVEL_INFO);
115 rxkb_context_set_log_level(ctx, RXKB_LOG_LEVEL_DEBUG);
120 for (int i = optind; i < argc; i++) {
121 if (!rxkb_context_include_path_append(ctx, argv[i])) {
122 fprintf(stderr, "Failed to append include path '%s'\n",
129 if (!rxkb_context_include_path_append_default(ctx)) {
130 fprintf(stderr, "Failed to include default paths.\n");
135 if (!rxkb_context_parse(ctx, ruleset)) {
136 fprintf(stderr, "Failed to parse XKB descriptions.\n");
141 m = rxkb_model_first(ctx);
142 assert(m); /* Empty model list is usually a bug or a bad xml file */
144 const char *vendor = rxkb_model_get_vendor(m);
145 printf("- name: %s\n"
147 " description: %s\n",
148 rxkb_model_get_name(m),
149 vendor ? vendor : "''",
150 rxkb_model_get_description(m));
151 m = rxkb_model_next(m);
155 printf("layouts:\n");
156 l = rxkb_layout_first(ctx);
157 assert(l); /* Empty layout list is usually a bug or a bad xml file */
159 struct rxkb_iso639_code *iso639;
160 struct rxkb_iso3166_code *iso3166;
161 const char *variant = rxkb_layout_get_variant(l);
162 const char *brief = rxkb_layout_get_brief(l);
164 printf("- layout: '%s'\n"
167 " description: %s\n",
168 rxkb_layout_get_name(l),
169 variant ? variant : "",
170 brief ? brief : "''",
171 rxkb_layout_get_description(l));
173 printf(" iso639: [");
174 iso639 = rxkb_layout_get_iso639_first(l);
176 const char *sep = "";
178 printf("%s'%s'", sep, rxkb_iso639_code_get_code(iso639));
179 iso639 = rxkb_iso639_code_next(iso639);
184 printf(" iso3166: [");
185 iso3166 = rxkb_layout_get_iso3166_first(l);
187 const char *sep = "";
189 printf("%s'%s'", sep, rxkb_iso3166_code_get_code(iso3166));
190 iso3166 = rxkb_iso3166_code_next(iso3166);
195 l = rxkb_layout_next(l);
198 printf("option_groups:\n");
199 g = rxkb_option_group_first(ctx);
200 assert(g); /* Empty option goups list is usually a bug or a bad xml file */
202 struct rxkb_option *o;
204 printf("- name: '%s'\n"
206 " allows_multiple: %s\n"
208 rxkb_option_group_get_name(g),
209 rxkb_option_group_get_description(g),
210 rxkb_option_group_allows_multiple(g) ? "true" : "false");
212 o = rxkb_option_first(g);
213 assert(o); /* Empty option list is usually a bug or a bad xml file */
215 const char *brief = rxkb_option_get_brief(o);
217 printf(" - name: '%s'\n"
219 " description: '%s'\n",
220 rxkb_option_get_name(o),
222 rxkb_option_get_description(o));
223 o = rxkb_option_next(o);
226 g = rxkb_option_group_next(g);
233 rxkb_context_unref(ctx);