1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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);
}
|