xref: /aosp_15_r20/external/libxkbcommon/tools/registry-list.c (revision 2b949d0487e80d67f1fda82db69e101e761f8064)
1*2b949d04SAndroid Build Coastguard Worker /*
2*2b949d04SAndroid Build Coastguard Worker  * Copyright © 2020 Red Hat, Inc.
3*2b949d04SAndroid Build Coastguard Worker  *
4*2b949d04SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*2b949d04SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*2b949d04SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*2b949d04SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*2b949d04SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*2b949d04SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*2b949d04SAndroid Build Coastguard Worker  *
11*2b949d04SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*2b949d04SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*2b949d04SAndroid Build Coastguard Worker  * Software.
14*2b949d04SAndroid Build Coastguard Worker  *
15*2b949d04SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*2b949d04SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*2b949d04SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*2b949d04SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*2b949d04SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*2b949d04SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21*2b949d04SAndroid Build Coastguard Worker  * DEALINGS IN THE SOFTWARE.
22*2b949d04SAndroid Build Coastguard Worker  */
23*2b949d04SAndroid Build Coastguard Worker 
24*2b949d04SAndroid Build Coastguard Worker #include "config.h"
25*2b949d04SAndroid Build Coastguard Worker 
26*2b949d04SAndroid Build Coastguard Worker #include <assert.h>
27*2b949d04SAndroid Build Coastguard Worker #include <stdio.h>
28*2b949d04SAndroid Build Coastguard Worker #include <getopt.h>
29*2b949d04SAndroid Build Coastguard Worker 
30*2b949d04SAndroid Build Coastguard Worker #include "xkbcommon/xkbregistry.h"
31*2b949d04SAndroid Build Coastguard Worker 
32*2b949d04SAndroid Build Coastguard Worker static void
usage(const char * progname,FILE * fp)33*2b949d04SAndroid Build Coastguard Worker usage(const char *progname, FILE *fp)
34*2b949d04SAndroid Build Coastguard Worker {
35*2b949d04SAndroid Build Coastguard Worker     fprintf(fp,
36*2b949d04SAndroid Build Coastguard Worker             "Usage: %s [OPTIONS] [/path/to/xkb_base_directory [/path2]...]\n"
37*2b949d04SAndroid Build Coastguard Worker             "\n"
38*2b949d04SAndroid Build Coastguard Worker             "Options:\n"
39*2b949d04SAndroid Build Coastguard Worker             "  --verbose, -v .......... Increase verbosity, use multiple times for debugging output\n"
40*2b949d04SAndroid Build Coastguard Worker             "  --ruleset=foo .......... Load the 'foo' ruleset\n"
41*2b949d04SAndroid Build Coastguard Worker             "  --skip-default-paths ... Do not load the default XKB paths\n"
42*2b949d04SAndroid Build Coastguard Worker             "  --load-exotic .......... Load the exotic (extra) rulesets\n"
43*2b949d04SAndroid Build Coastguard Worker             "\n"
44*2b949d04SAndroid Build Coastguard Worker             "Trailing arguments are treated as XKB base directory installations.\n",
45*2b949d04SAndroid Build Coastguard Worker             progname);
46*2b949d04SAndroid Build Coastguard Worker }
47*2b949d04SAndroid Build Coastguard Worker 
48*2b949d04SAndroid Build Coastguard Worker int
main(int argc,char ** argv)49*2b949d04SAndroid Build Coastguard Worker main(int argc, char **argv)
50*2b949d04SAndroid Build Coastguard Worker {
51*2b949d04SAndroid Build Coastguard Worker     int rc = 1;
52*2b949d04SAndroid Build Coastguard Worker     struct rxkb_context *ctx = NULL;
53*2b949d04SAndroid Build Coastguard Worker     struct rxkb_model *m;
54*2b949d04SAndroid Build Coastguard Worker     struct rxkb_layout *l;
55*2b949d04SAndroid Build Coastguard Worker     struct rxkb_option_group *g;
56*2b949d04SAndroid Build Coastguard Worker     enum rxkb_context_flags flags = RXKB_CONTEXT_NO_FLAGS;
57*2b949d04SAndroid Build Coastguard Worker     bool load_defaults = true;
58*2b949d04SAndroid Build Coastguard Worker     int verbosity = 0;
59*2b949d04SAndroid Build Coastguard Worker     const char *ruleset = DEFAULT_XKB_RULES;
60*2b949d04SAndroid Build Coastguard Worker 
61*2b949d04SAndroid Build Coastguard Worker     static const struct option opts[] = {
62*2b949d04SAndroid Build Coastguard Worker         {"help",                no_argument,        0, 'h'},
63*2b949d04SAndroid Build Coastguard Worker         {"verbose",             no_argument,        0, 'v'},
64*2b949d04SAndroid Build Coastguard Worker         {"load-exotic",         no_argument,        0, 'e'},
65*2b949d04SAndroid Build Coastguard Worker         {"skip-default-paths",  no_argument,        0, 'd'},
66*2b949d04SAndroid Build Coastguard Worker         {"ruleset",             required_argument,  0, 'r'},
67*2b949d04SAndroid Build Coastguard Worker         {0, 0, 0, 0},
68*2b949d04SAndroid Build Coastguard Worker     };
69*2b949d04SAndroid Build Coastguard Worker 
70*2b949d04SAndroid Build Coastguard Worker     while (1) {
71*2b949d04SAndroid Build Coastguard Worker         int c;
72*2b949d04SAndroid Build Coastguard Worker         int option_index = 0;
73*2b949d04SAndroid Build Coastguard Worker 
74*2b949d04SAndroid Build Coastguard Worker         c = getopt_long(argc, argv, "hev", opts, &option_index);
75*2b949d04SAndroid Build Coastguard Worker         if (c == -1)
76*2b949d04SAndroid Build Coastguard Worker             break;
77*2b949d04SAndroid Build Coastguard Worker 
78*2b949d04SAndroid Build Coastguard Worker         switch (c) {
79*2b949d04SAndroid Build Coastguard Worker             case 'h':
80*2b949d04SAndroid Build Coastguard Worker                 usage(argv[0], stdout);
81*2b949d04SAndroid Build Coastguard Worker                 return 0;
82*2b949d04SAndroid Build Coastguard Worker             case '?':
83*2b949d04SAndroid Build Coastguard Worker                 usage(argv[0], stderr);
84*2b949d04SAndroid Build Coastguard Worker                 return EXIT_INVALID_USAGE;
85*2b949d04SAndroid Build Coastguard Worker             case 'd':
86*2b949d04SAndroid Build Coastguard Worker                 load_defaults = false;
87*2b949d04SAndroid Build Coastguard Worker                 break;
88*2b949d04SAndroid Build Coastguard Worker             case 'e':
89*2b949d04SAndroid Build Coastguard Worker                 flags |= RXKB_CONTEXT_LOAD_EXOTIC_RULES;
90*2b949d04SAndroid Build Coastguard Worker                 break;
91*2b949d04SAndroid Build Coastguard Worker             case 'r':
92*2b949d04SAndroid Build Coastguard Worker                 ruleset = optarg;
93*2b949d04SAndroid Build Coastguard Worker                 break;
94*2b949d04SAndroid Build Coastguard Worker             case 'v':
95*2b949d04SAndroid Build Coastguard Worker                 verbosity++;
96*2b949d04SAndroid Build Coastguard Worker                 break;
97*2b949d04SAndroid Build Coastguard Worker         }
98*2b949d04SAndroid Build Coastguard Worker     }
99*2b949d04SAndroid Build Coastguard Worker 
100*2b949d04SAndroid Build Coastguard Worker     if (optind < argc)
101*2b949d04SAndroid Build Coastguard Worker         flags |= RXKB_CONTEXT_NO_DEFAULT_INCLUDES;
102*2b949d04SAndroid Build Coastguard Worker 
103*2b949d04SAndroid Build Coastguard Worker     ctx = rxkb_context_new(flags);
104*2b949d04SAndroid Build Coastguard Worker     assert(ctx);
105*2b949d04SAndroid Build Coastguard Worker 
106*2b949d04SAndroid Build Coastguard Worker     switch (verbosity) {
107*2b949d04SAndroid Build Coastguard Worker         case 0:
108*2b949d04SAndroid Build Coastguard Worker             rxkb_context_set_log_level(ctx, RXKB_LOG_LEVEL_ERROR);
109*2b949d04SAndroid Build Coastguard Worker             break;
110*2b949d04SAndroid Build Coastguard Worker         case 1:
111*2b949d04SAndroid Build Coastguard Worker             rxkb_context_set_log_level(ctx, RXKB_LOG_LEVEL_INFO);
112*2b949d04SAndroid Build Coastguard Worker             break;
113*2b949d04SAndroid Build Coastguard Worker         default:
114*2b949d04SAndroid Build Coastguard Worker             rxkb_context_set_log_level(ctx, RXKB_LOG_LEVEL_DEBUG);
115*2b949d04SAndroid Build Coastguard Worker             break;
116*2b949d04SAndroid Build Coastguard Worker     }
117*2b949d04SAndroid Build Coastguard Worker 
118*2b949d04SAndroid Build Coastguard Worker     if (optind < argc) {
119*2b949d04SAndroid Build Coastguard Worker         for (int i = optind; i < argc; i++) {
120*2b949d04SAndroid Build Coastguard Worker             if (!rxkb_context_include_path_append(ctx, argv[i])) {
121*2b949d04SAndroid Build Coastguard Worker                 fprintf(stderr, "Failed to append include path '%s'\n",
122*2b949d04SAndroid Build Coastguard Worker                         argv[i]);
123*2b949d04SAndroid Build Coastguard Worker                 goto err;
124*2b949d04SAndroid Build Coastguard Worker             }
125*2b949d04SAndroid Build Coastguard Worker         }
126*2b949d04SAndroid Build Coastguard Worker 
127*2b949d04SAndroid Build Coastguard Worker         if (load_defaults) {
128*2b949d04SAndroid Build Coastguard Worker             if (!rxkb_context_include_path_append_default(ctx)) {
129*2b949d04SAndroid Build Coastguard Worker                 fprintf(stderr, "Failed to include default paths.\n");
130*2b949d04SAndroid Build Coastguard Worker                 goto err;
131*2b949d04SAndroid Build Coastguard Worker             }
132*2b949d04SAndroid Build Coastguard Worker         }
133*2b949d04SAndroid Build Coastguard Worker     }
134*2b949d04SAndroid Build Coastguard Worker     if (!rxkb_context_parse(ctx, ruleset)) {
135*2b949d04SAndroid Build Coastguard Worker         fprintf(stderr, "Failed to parse XKB descriptions.\n");
136*2b949d04SAndroid Build Coastguard Worker         goto err;
137*2b949d04SAndroid Build Coastguard Worker     }
138*2b949d04SAndroid Build Coastguard Worker 
139*2b949d04SAndroid Build Coastguard Worker     printf("models:\n");
140*2b949d04SAndroid Build Coastguard Worker     m = rxkb_model_first(ctx);
141*2b949d04SAndroid Build Coastguard Worker     assert(m); /* Empty model list is usually a bug or a bad xml file */
142*2b949d04SAndroid Build Coastguard Worker     while (m) {
143*2b949d04SAndroid Build Coastguard Worker         const char *vendor = rxkb_model_get_vendor(m);
144*2b949d04SAndroid Build Coastguard Worker         printf("- name: %s\n"
145*2b949d04SAndroid Build Coastguard Worker                "  vendor: %s\n"
146*2b949d04SAndroid Build Coastguard Worker                "  description: %s\n",
147*2b949d04SAndroid Build Coastguard Worker                rxkb_model_get_name(m),
148*2b949d04SAndroid Build Coastguard Worker                vendor ? vendor : "''",
149*2b949d04SAndroid Build Coastguard Worker                rxkb_model_get_description(m));
150*2b949d04SAndroid Build Coastguard Worker         m = rxkb_model_next(m);
151*2b949d04SAndroid Build Coastguard Worker     }
152*2b949d04SAndroid Build Coastguard Worker 
153*2b949d04SAndroid Build Coastguard Worker     printf("\n");
154*2b949d04SAndroid Build Coastguard Worker     printf("layouts:\n");
155*2b949d04SAndroid Build Coastguard Worker     l = rxkb_layout_first(ctx);
156*2b949d04SAndroid Build Coastguard Worker     assert(l); /* Empty layout list is usually a bug or a bad xml file */
157*2b949d04SAndroid Build Coastguard Worker     while (l) {
158*2b949d04SAndroid Build Coastguard Worker         struct rxkb_iso639_code *iso639;
159*2b949d04SAndroid Build Coastguard Worker         struct rxkb_iso3166_code *iso3166;
160*2b949d04SAndroid Build Coastguard Worker         const char *variant = rxkb_layout_get_variant(l);
161*2b949d04SAndroid Build Coastguard Worker         const char *brief = rxkb_layout_get_brief(l);
162*2b949d04SAndroid Build Coastguard Worker 
163*2b949d04SAndroid Build Coastguard Worker         printf("- layout: '%s'\n"
164*2b949d04SAndroid Build Coastguard Worker                "  variant: '%s'\n"
165*2b949d04SAndroid Build Coastguard Worker                "  brief: '%s'\n"
166*2b949d04SAndroid Build Coastguard Worker                "  description: %s\n",
167*2b949d04SAndroid Build Coastguard Worker                rxkb_layout_get_name(l),
168*2b949d04SAndroid Build Coastguard Worker                variant ? variant : "",
169*2b949d04SAndroid Build Coastguard Worker                brief ? brief : "''",
170*2b949d04SAndroid Build Coastguard Worker                rxkb_layout_get_description(l));
171*2b949d04SAndroid Build Coastguard Worker 
172*2b949d04SAndroid Build Coastguard Worker         printf("  iso639: [");
173*2b949d04SAndroid Build Coastguard Worker         iso639 = rxkb_layout_get_iso639_first(l);
174*2b949d04SAndroid Build Coastguard Worker         if (iso639) {
175*2b949d04SAndroid Build Coastguard Worker             const char *sep = "";
176*2b949d04SAndroid Build Coastguard Worker             while (iso639) {
177*2b949d04SAndroid Build Coastguard Worker                 printf("%s'%s'", sep, rxkb_iso639_code_get_code(iso639));
178*2b949d04SAndroid Build Coastguard Worker                 iso639 = rxkb_iso639_code_next(iso639);
179*2b949d04SAndroid Build Coastguard Worker                 sep = ", ";
180*2b949d04SAndroid Build Coastguard Worker             }
181*2b949d04SAndroid Build Coastguard Worker         }
182*2b949d04SAndroid Build Coastguard Worker         printf("]\n");
183*2b949d04SAndroid Build Coastguard Worker         printf("  iso3166: [");
184*2b949d04SAndroid Build Coastguard Worker         iso3166 = rxkb_layout_get_iso3166_first(l);
185*2b949d04SAndroid Build Coastguard Worker         if (iso3166) {
186*2b949d04SAndroid Build Coastguard Worker             const char *sep = "";
187*2b949d04SAndroid Build Coastguard Worker             while (iso3166) {
188*2b949d04SAndroid Build Coastguard Worker                 printf("%s'%s'", sep, rxkb_iso3166_code_get_code(iso3166));
189*2b949d04SAndroid Build Coastguard Worker                 iso3166 = rxkb_iso3166_code_next(iso3166);
190*2b949d04SAndroid Build Coastguard Worker                 sep = ", ";
191*2b949d04SAndroid Build Coastguard Worker             }
192*2b949d04SAndroid Build Coastguard Worker         }
193*2b949d04SAndroid Build Coastguard Worker         printf("]\n");
194*2b949d04SAndroid Build Coastguard Worker         l = rxkb_layout_next(l);
195*2b949d04SAndroid Build Coastguard Worker     }
196*2b949d04SAndroid Build Coastguard Worker     printf("\n");
197*2b949d04SAndroid Build Coastguard Worker     printf("option_groups:\n");
198*2b949d04SAndroid Build Coastguard Worker     g = rxkb_option_group_first(ctx);
199*2b949d04SAndroid Build Coastguard Worker     assert(g); /* Empty option goups list is usually a bug or a bad xml file */
200*2b949d04SAndroid Build Coastguard Worker     while (g) {
201*2b949d04SAndroid Build Coastguard Worker         struct rxkb_option *o;
202*2b949d04SAndroid Build Coastguard Worker 
203*2b949d04SAndroid Build Coastguard Worker         printf("- name: '%s'\n"
204*2b949d04SAndroid Build Coastguard Worker                "  description: %s\n"
205*2b949d04SAndroid Build Coastguard Worker                "  allows_multiple: %s\n"
206*2b949d04SAndroid Build Coastguard Worker                "  options:\n",
207*2b949d04SAndroid Build Coastguard Worker                rxkb_option_group_get_name(g),
208*2b949d04SAndroid Build Coastguard Worker                rxkb_option_group_get_description(g),
209*2b949d04SAndroid Build Coastguard Worker                rxkb_option_group_allows_multiple(g) ? "true" : "false");
210*2b949d04SAndroid Build Coastguard Worker 
211*2b949d04SAndroid Build Coastguard Worker         o = rxkb_option_first(g);
212*2b949d04SAndroid Build Coastguard Worker         assert(o); /* Empty option list is usually a bug or a bad xml file */
213*2b949d04SAndroid Build Coastguard Worker         while (o) {
214*2b949d04SAndroid Build Coastguard Worker             const char *brief = rxkb_option_get_brief(o);
215*2b949d04SAndroid Build Coastguard Worker 
216*2b949d04SAndroid Build Coastguard Worker             printf("  - name: '%s'\n"
217*2b949d04SAndroid Build Coastguard Worker                    "    brief: '%s'\n"
218*2b949d04SAndroid Build Coastguard Worker                    "    description: '%s'\n",
219*2b949d04SAndroid Build Coastguard Worker                    rxkb_option_get_name(o),
220*2b949d04SAndroid Build Coastguard Worker                    brief ? brief : "",
221*2b949d04SAndroid Build Coastguard Worker                    rxkb_option_get_description(o));
222*2b949d04SAndroid Build Coastguard Worker             o = rxkb_option_next(o);
223*2b949d04SAndroid Build Coastguard Worker         }
224*2b949d04SAndroid Build Coastguard Worker 
225*2b949d04SAndroid Build Coastguard Worker         g = rxkb_option_group_next(g);
226*2b949d04SAndroid Build Coastguard Worker     }
227*2b949d04SAndroid Build Coastguard Worker 
228*2b949d04SAndroid Build Coastguard Worker     rc = 0;
229*2b949d04SAndroid Build Coastguard Worker 
230*2b949d04SAndroid Build Coastguard Worker err:
231*2b949d04SAndroid Build Coastguard Worker     if (ctx)
232*2b949d04SAndroid Build Coastguard Worker         rxkb_context_unref(ctx);
233*2b949d04SAndroid Build Coastguard Worker 
234*2b949d04SAndroid Build Coastguard Worker     return rc;
235*2b949d04SAndroid Build Coastguard Worker }
236