#include <stdlib.h>
#include <string.h>
+#include "xkbcommon/xkbcommon.h"
+#if ENABLE_PRIVATE_APIS
#include "xkbcomp/xkbcomp-priv.h"
#include "xkbcomp/rules.h"
-#include "xkbcommon/xkbcommon.h"
+#endif
+#include "tools-common.h"
#define DEFAULT_INCLUDE_PATH_PLACEHOLDER "__defaults__"
FORMAT_KCCGST,
FORMAT_KEYMAP_FROM_XKB,
} output_format = FORMAT_KEYMAP;
-static darray(const char *) includes;
+static const char *includes[64];
+static size_t num_includes = 0;
static void
usage(char **argv)
"Compile the given RMLVO to a keymap and print it\n"
"\n"
"Options:\n"
+ " --help\n"
+ " Print this help and exit\n"
" --verbose\n"
" Enable verbose debugging output\n"
+#if ENABLE_PRIVATE_APIS
" --kccgst\n"
" Print a keymap which only includes the KcCGST component names instead of the full keymap\n"
+#endif
" --rmlvo\n"
" Print the full RMLVO with the defaults filled in for missing elements\n"
" --from-xkb\n"
- " Load the XKB file from stdin, ignore RMLVO options. This option\n"
- " must not be used with --kccgst.\n"
+ " Load the XKB file from stdin, ignore RMLVO options.\n"
+#if ENABLE_PRIVATE_APIS
+ " This option must not be used with --kccgst.\n"
+#endif
" --include\n"
" Add the given path to the include path list. This option is\n"
" order-dependent, include paths given first are searched first.\n"
static struct option opts[] = {
{"help", no_argument, 0, 'h'},
{"verbose", no_argument, 0, OPT_VERBOSE},
+#if ENABLE_PRIVATE_APIS
{"kccgst", no_argument, 0, OPT_KCCGST},
+#endif
{"rmlvo", no_argument, 0, OPT_RMLVO},
{"from-xkb", no_argument, 0, OPT_FROM_XKB},
{"include", required_argument, 0, OPT_INCLUDE},
output_format = FORMAT_KEYMAP_FROM_XKB;
break;
case OPT_INCLUDE:
- darray_append(includes, optarg);
+ if (num_includes >= ARRAY_SIZE(includes)) {
+ fprintf(stderr, "error: too many includes\n");
+ exit(EXIT_INVALID_USAGE);
+ }
+ includes[num_includes++] = optarg;
break;
case OPT_INCLUDE_DEFAULTS:
- darray_append(includes, DEFAULT_INCLUDE_PATH_PLACEHOLDER);
+ if (num_includes >= ARRAY_SIZE(includes)) {
+ fprintf(stderr, "error: too many includes\n");
+ exit(EXIT_INVALID_USAGE);
+ }
+ includes[num_includes++] = DEFAULT_INCLUDE_PATH_PLACEHOLDER;
break;
case OPT_RULES:
names->rules = optarg;
break;
default:
usage(argv);
- exit(1);
+ exit(EXIT_INVALID_USAGE);
}
}
static bool
print_kccgst(struct xkb_context *ctx, const struct xkb_rule_names *rmlvo)
{
+#if ENABLE_PRIVATE_APIS
struct xkb_component_names kccgst;
if (!xkb_components_from_rules(ctx, rmlvo, &kccgst))
free(kccgst.symbols);
return true;
+#else
+ return false;
+#endif
}
static bool
{
struct xkb_context *ctx;
struct xkb_rule_names names = {
- .rules = NULL,
- .model = NULL,
+ .rules = DEFAULT_XKB_RULES,
+ .model = DEFAULT_XKB_MODEL,
+ /* layout and variant are tied together, so we either get user-supplied for
+ * both or default for both, see below */
.layout = NULL,
.variant = NULL,
- .options = NULL,
+ .options = DEFAULT_XKB_OPTIONS,
};
int rc = 1;
- const char **path;
- if (argc <= 1) {
+ if (argc < 1) {
usage(argv);
- return 1;
+ return EXIT_INVALID_USAGE;
}
if (!parse_options(argc, argv, &names))
- return 1;
+ return EXIT_INVALID_USAGE;
+
+ /* Now fill in the layout */
+ if (!names.layout || !*names.layout) {
+ if (names.variant && *names.variant) {
+ fprintf(stderr, "Error: a variant requires a layout\n");
+ return EXIT_INVALID_USAGE;
+ }
+ names.layout = DEFAULT_XKB_LAYOUT;
+ names.variant = DEFAULT_XKB_VARIANT;
+ }
ctx = xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES);
assert(ctx);
xkb_context_set_log_verbosity(ctx, 10);
}
- xkb_context_sanitize_rule_names(ctx, &names);
- if (darray_empty(includes))
- darray_append(includes, DEFAULT_INCLUDE_PATH_PLACEHOLDER);
+ if (num_includes == 0)
+ includes[num_includes++] = DEFAULT_INCLUDE_PATH_PLACEHOLDER;
- darray_foreach(path, includes) {
- if (streq(*path, DEFAULT_INCLUDE_PATH_PLACEHOLDER))
+ for (size_t i = 0; i < num_includes; i++) {
+ const char *include = includes[i];
+ if (strcmp(include, DEFAULT_INCLUDE_PATH_PLACEHOLDER) == 0)
xkb_context_include_path_append_default(ctx);
else
- xkb_context_include_path_append(ctx, *path);
+ xkb_context_include_path_append(ctx, include);
}
if (output_format == FORMAT_RMLVO) {