client: cmd argument completion based on properties

This commit is contained in:
Tim Kourt 2017-04-26 16:08:37 -07:00 committed by Denis Kenzior
parent 7882390e81
commit e04df7f282
3 changed files with 98 additions and 1 deletions

View File

@ -44,6 +44,27 @@ static struct l_dbus *dbus;
static struct l_queue *proxy_interfaces;
static struct l_queue *proxy_interface_types;
static const void *proxy_interface_property_tostr(
const struct proxy_interface *proxy,
const char *name)
{
size_t i;
const struct proxy_interface_property *property_table =
proxy->type->properties;
for (i = 0; property_table[i].name; i++) {
if (strcmp(property_table[i].name, name))
continue;
if (!property_table[i].tostr)
break;
return property_table[i].tostr(proxy->data);
}
return NULL;
}
static void proxy_interface_property_set(struct proxy_interface *proxy,
const char *name,
struct l_dbus_message_iter *variant)
@ -85,6 +106,43 @@ static void interface_update_properties(struct proxy_interface *proxy,
proxy_interface_property_set(proxy, name, NULL);
}
char *proxy_property_str_completion(const struct proxy_interface_type *type,
proxy_property_match_func_t function,
const char *property_name,
const char *value, int state)
{
static struct l_queue *match;
static const struct l_queue_entry *entry;
if (!state) {
match = proxy_interface_find_all(type->interface, function,
value);
if (!match)
return NULL;
entry = l_queue_get_entries(match);
}
while (entry) {
const struct proxy_interface *proxy = entry->data;
const char *str;
entry = entry->next;
str = proxy_interface_property_tostr(proxy, property_name);
if (!str)
return NULL;
return l_strdup(str);
}
l_queue_destroy(match, NULL);
match = NULL;
entry = NULL;
return NULL;
}
bool dbus_message_has_error(struct l_dbus_message *message)
{
const char *name;

View File

@ -70,6 +70,11 @@ bool proxy_interface_method_call(const struct proxy_interface *proxy,
const char *name, const char *signature,
l_dbus_message_func_t callback, ...);
char *proxy_property_str_completion(const struct proxy_interface_type *type,
proxy_property_match_func_t function,
const char *property_name,
const char *value, int state);
void *proxy_interface_get_data(const struct proxy_interface *proxy);
const char *proxy_interface_get_interface(const struct proxy_interface *proxy);
const char *proxy_interface_get_identity_str(

View File

@ -341,6 +341,14 @@ static bool match_by_name(const void *a, const void *b)
return !strcmp(device->name, name);
}
static bool match_by_partial_name(const void *a, const void *b)
{
const struct device *device = a;
const char *text = b;
return !strncmp(device->name, text, strlen(text));
}
static const struct proxy_interface *get_device_proxy_by_name(
const char *device_name)
{
@ -471,7 +479,33 @@ static const struct command device_commands[] = {
static char *family_arg_completion(const char *text, int state)
{
return NULL;
static bool first_pass;
static size_t index;
static size_t len;
const char *cmd;
if (!state) {
index = 0;
len = strlen(text);
first_pass = true;
}
while ((cmd = device_commands[index].cmd)) {
if (device_commands[index++].entity)
continue;
if (!strncmp(cmd, text, len))
return l_strdup(cmd);
}
if (first_pass) {
state = 0;
first_pass = false;
}
return proxy_property_str_completion(&device_interface_type,
match_by_partial_name, "Name",
text, state);
}
static char *entity_arg_completion(const char *text, int state)