Tools: Add bash completions for xkbcli
[platform/upstream/libxkbcommon.git] / tools / compile-keymap.c
index be2eaeb..f49aa3c 100644 (file)
 #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__"
 
@@ -44,7 +47,8 @@ static enum output_format {
     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)
@@ -54,15 +58,21 @@ 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"
@@ -111,7 +121,9 @@ parse_options(int argc, char **argv, struct xkb_rule_names *names)
     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},
@@ -148,10 +160,18 @@ parse_options(int argc, char **argv, struct xkb_rule_names *names)
             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;
@@ -191,6 +211,7 @@ print_rmlvo(struct xkb_context *ctx, const struct xkb_rule_names *rmlvo)
 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))
@@ -209,6 +230,9 @@ print_kccgst(struct xkb_context *ctx, const struct xkb_rule_names *rmlvo)
         free(kccgst.symbols);
 
         return true;
+#else
+        return false;
+#endif
 }
 
 static bool
@@ -299,9 +323,8 @@ main(int argc, char **argv)
         .options = DEFAULT_XKB_OPTIONS,
     };
     int rc = 1;
-    const char **path;
 
-    if (argc <= 1) {
+    if (argc < 1) {
         usage(argv);
         return EXIT_INVALID_USAGE;
     }
@@ -310,8 +333,8 @@ main(int argc, char **argv)
         return EXIT_INVALID_USAGE;
 
     /* Now fill in the layout */
-    if (isempty(names.layout)) {
-        if (!isempty(names.variant)) {
+    if (!names.layout || !*names.layout) {
+        if (names.variant && *names.variant) {
             fprintf(stderr, "Error: a variant requires a layout\n");
             return EXIT_INVALID_USAGE;
         }
@@ -327,14 +350,15 @@ main(int argc, char **argv)
         xkb_context_set_log_verbosity(ctx, 10);
     }
 
-    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) {