From c3d60e6df33c47401813c4529d23d25a76c6a982 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 6 Jun 2011 17:04:59 +0800 Subject: 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 --- common/complete.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 90 insertions(+), 6 deletions(-) (limited to 'common') 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); -- cgit v1.2.3