summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2011-06-06 17:04:59 +0800
committerJean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>2012-04-30 20:22:24 +0800
commitc3d60e6df33c47401813c4529d23d25a76c6a982 (patch)
tree0408ace96e70a26115497afa55ad243249d565ab /common
parentf152f6a7701b943cfa67c6bfb42a22086861daa3 (diff)
downloadbarebox-c3d60e6df33c47401813c4529d23d25a76c6a982.tar.gz
barebox-c3d60e6df33c47401813c4529d23d25a76c6a982.tar.xz
complete: add var and device param complete support
with $xx or xx= or if device $xx.yy or xx.yy= Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Diffstat (limited to 'common')
-rw-r--r--common/complete.c96
1 files changed, 90 insertions, 6 deletions
diff --git a/common/complete.c b/common/complete.c
index 6d5349b509..9d749e0fc1 100644
--- a/common/complete.c
+++ b/common/complete.c
@@ -134,14 +134,95 @@ static int path_command_complete(struct string_list *sl, char *instr)
static int command_complete(struct string_list *sl, char *instr)
{
struct command *cmdtp;
- char cmd[128];
+
+ if (!instr)
+ instr = "";
for_each_command(cmdtp) {
- if (!strncmp(instr, cmdtp->name, strlen(instr))) {
- strcpy(cmd, cmdtp->name);
- cmd[strlen(cmdtp->name)] = ' ';
- cmd[strlen(cmdtp->name) + 1] = 0;
- string_list_add(sl, cmd);
+ if (strncmp(instr, cmdtp->name, strlen(instr)))
+ continue;
+
+ string_list_add_asprintf(sl, "%s ", cmdtp->name);
+ }
+
+ return 0;
+}
+
+static int device_param_complete(char *begin, struct device_d *dev,
+ struct string_list *sl, char *instr)
+{
+ struct param_d *param;
+ int len;
+
+ if (!instr)
+ instr = "";
+
+ len = strlen(instr);
+
+ list_for_each_entry(param, &dev->parameters, list) {
+ if (strncmp(instr, param->name, len))
+ continue;
+
+ string_list_add_asprintf(sl, "%s%s.%s%c",
+ begin ? begin : "", dev_name(dev), param->name,
+ begin ? ' ' : '=');
+ }
+
+ return 0;
+}
+
+static int env_param_complete(struct string_list *sl, char *instr, int eval)
+{
+ struct device_d *dev;
+ struct variable_d *var;
+ struct env_context *c, *current_c;
+ char *instr_param;
+ int len;
+ char end = '=';
+ char *begin = "";
+
+ if (!instr)
+ instr = "";
+
+ if (eval) {
+ begin = "$";
+ end = ' ';
+ }
+
+ instr_param = strrchr(instr, '.');
+ len = strlen(instr);
+
+ current_c = get_current_context();
+ for(var = current_c->local->next; var; var = var->next) {
+ if (strncmp(instr, var_name(var), len))
+ continue;
+ string_list_add_asprintf(sl, "%s%s%c",
+ begin, var_name(var), end);
+ }
+
+ for (c = get_current_context(); c; c = c->parent) {
+ for (var = c->global->next; var; var = var->next) {
+ if (strncmp(instr, var_name(var), len))
+ continue;
+ string_list_add_asprintf(sl, "%s%s%c",
+ begin, var_name(var), end);
+ }
+ }
+
+ if (instr_param) {
+ len = (instr_param - instr);
+ instr_param++;
+ } else {
+ len = strlen(instr);
+ instr_param = "";
+ }
+
+ for_each_device(dev) {
+ if (!strncmp(instr, dev_name(dev), len)) {
+ if (eval)
+ device_param_complete("$", dev, sl, instr_param);
+ else
+ device_param_complete(NULL, dev, sl, instr_param);
}
}
@@ -188,7 +269,10 @@ int complete(char *instr, char **outstr)
} else {
command_complete(&sl, instr);
path_command_complete(&sl, instr);
+ env_param_complete(&sl, instr, 0);
}
+ if (*instr == '$')
+ env_param_complete(&sl, instr + 1, 1);
pos = strlen(instr);