aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Hoffmann <kraxel@redhat.com>2020-01-02 14:56:21 +0100
committerGerd Hoffmann <kraxel@redhat.com>2020-01-02 14:56:21 +0100
commit9d9260615369a488b21b12514e7cade5e90fd3a6 (patch)
tree1c2d3ce5564ff02afc86e6f817be77def56a4049
parent52814e38dd418a4f78de810305cc753114bda149 (diff)
downloaddrminfo-9d9260615369a488b21b12514e7cade5e90fd3a6.tar.gz
add completion source files
-rw-r--r--complete.c69
-rw-r--r--complete.h1
2 files changed, 70 insertions, 0 deletions
diff --git a/complete.c b/complete.c
new file mode 100644
index 0000000..a9e64f3
--- /dev/null
+++ b/complete.c
@@ -0,0 +1,69 @@
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <getopt.h>
+
+#include "complete.h"
+
+/*
+ * generate simple bash completion for getopt long,
+ * using "complete -W".
+ */
+#define CASE_IMAGE \
+ " --image)\n" \
+ " COMPREPLY=( $(compgen -f -- \"$cur\") )\n" \
+ " ;;\n"
+
+void complete_bash(const char *command, struct option *opts)
+{
+ bool have_image = false;
+ char opt_all[1024];
+ char opt_arg[1024];
+ int pos_all = 0;
+ int pos_arg = 0;
+ int i;
+
+ for (i = 0; opts[i].name != NULL; i++) {
+ /* options with argument completion */
+ if (strcmp(opts[i].name, "image") == 0) {
+ have_image = true;
+
+ } else if (opts[i].has_arg) {
+ /* options without argument completion */
+ pos_arg += snprintf(opt_arg+pos_arg, sizeof(opt_arg)-pos_arg,
+ "%s--%s",
+ pos_arg ? " | " : "",
+ opts[i].name);
+ }
+
+ /* (long) option completion */
+ pos_all += snprintf(opt_all+pos_all, sizeof(opt_all)-pos_all,
+ "%s--%s",
+ pos_all ? " " : "",
+ opts[i].name);
+ }
+ if (!pos_arg)
+ snprintf(opt_arg+pos_arg, sizeof(opt_arg)-pos_arg, "--dummy");
+
+ printf("_%s_complete()\n"
+ "{\n"
+ " local cur prev\n"
+ " cur=\"${COMP_WORDS[COMP_CWORD]}\"\n"
+ " prev=\"${COMP_WORDS[COMP_CWORD-1]}\"\n"
+ " case \"$prev\" in\n"
+ "%s"
+ " %s)\n"
+ " COMPREPLY=()\n"
+ " ;;\n"
+ " *)\n"
+ " COMPREPLY=( $(compgen -W \"%s\" -- \"$cur\") )\n"
+ " ;;\n"
+ " esac\n"
+ " return 0\n"
+ "}\n"
+ "complete -F _%s_complete %s\n"
+ "\n",
+ command,
+ have_image ? CASE_IMAGE : "",
+ opt_arg, opt_all, command, command);
+}
diff --git a/complete.h b/complete.h
new file mode 100644
index 0000000..a1fd02b
--- /dev/null
+++ b/complete.h
@@ -0,0 +1 @@
+void complete_bash(const char *command, struct option *opts);