linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH BlueZ 1/4] shared/shell: Introduce bt_shell_{get,set}_env
@ 2018-02-05 12:48 Luiz Augusto von Dentz
  2018-02-05 12:48 ` [PATCH BlueZ 2/4] shared/shell: Make bt_shell_hexdump use util_hexdump Luiz Augusto von Dentz
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-05 12:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

These function can be used to share environment variable accross
different files.
---
 src/shared/shell.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/shared/shell.h |  3 +++
 2 files changed, 66 insertions(+)

diff --git a/src/shared/shell.c b/src/shared/shell.c
index f1b85f202..f724c9881 100644
--- a/src/shared/shell.c
+++ b/src/shared/shell.c
@@ -56,6 +56,11 @@
 
 static GMainLoop *main_loop;
 
+struct bt_shell_env {
+	char *name;
+	void *value;
+};
+
 static struct {
 	struct io *input;
 
@@ -66,6 +71,8 @@ static struct {
 	const struct bt_shell_menu *menu;
 	const struct bt_shell_menu *main;
 	struct queue *submenus;
+
+	struct queue *envs;
 } data;
 
 static void shell_print_menu(void);
@@ -759,6 +766,14 @@ static void rl_cleanup(void)
 	rl_callback_handler_remove();
 }
 
+static void env_destroy(void *data)
+{
+	struct bt_shell_env *env = data;
+
+	free(env->name);
+	free(env);
+}
+
 void bt_shell_run(void)
 {
 	struct io *signal;
@@ -775,6 +790,11 @@ void bt_shell_run(void)
 	g_main_loop_unref(main_loop);
 	main_loop = NULL;
 
+	if (data.envs) {
+		queue_destroy(data.envs, env_destroy);
+		data.envs = NULL;
+	}
+
 	rl_cleanup();
 }
 
@@ -849,3 +869,46 @@ bool bt_shell_detach(void)
 
 	return true;
 }
+
+static bool match_env(const void *data, const void *user_data)
+{
+	const struct bt_shell_env *env = data;
+	const char *name = user_data;
+
+	return !strcmp(env->name, name);
+}
+
+void bt_shell_set_env(const char *name, void *value)
+{
+	struct bt_shell_env *env;
+
+	if (!data.envs) {
+		data.envs = queue_new();
+		goto done;
+	}
+
+	env = queue_remove_if(data.envs, match_env, (void *) name);
+	if (env)
+		env_destroy(env);
+
+done:
+	env = new0(struct bt_shell_env, 1);
+	env->name = strdup(name);
+	env->value = value;
+
+	queue_push_tail(data.envs, env);
+}
+
+void *bt_shell_get_env(const char *name)
+{
+	const struct bt_shell_env *env;
+
+	if (!data.envs)
+		return NULL;
+
+	env = queue_find(data.envs, match_env, name);
+	if (!env)
+		return NULL;
+
+	return env->value;
+}
diff --git a/src/shared/shell.h b/src/shared/shell.h
index 8b8b1f634..359629896 100644
--- a/src/shared/shell.h
+++ b/src/shared/shell.h
@@ -87,4 +87,7 @@ int bt_shell_release_prompt(const char *input);
 bool bt_shell_attach(int fd);
 bool bt_shell_detach(void);
 
+void bt_shell_set_env(const char *name, void *value);
+void *bt_shell_get_env(const char *name);
+
 void bt_shell_cleanup(void);
-- 
2.14.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH BlueZ 2/4] shared/shell: Make bt_shell_hexdump use util_hexdump
  2018-02-05 12:48 [PATCH BlueZ 1/4] shared/shell: Introduce bt_shell_{get,set}_env Luiz Augusto von Dentz
@ 2018-02-05 12:48 ` Luiz Augusto von Dentz
  2018-02-05 12:48 ` [PATCH BlueZ 3/4] shared/shell: Add tab completion for argument values Luiz Augusto von Dentz
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-05 12:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 src/shared/shell.c | 43 ++++++-------------------------------------
 1 file changed, 6 insertions(+), 37 deletions(-)

diff --git a/src/shared/shell.c b/src/shared/shell.c
index f724c9881..69f303b51 100644
--- a/src/shared/shell.c
+++ b/src/shared/shell.c
@@ -386,45 +386,14 @@ void bt_shell_printf(const char *fmt, ...)
 	}
 }
 
-void bt_shell_hexdump(const unsigned char *buf, size_t len)
+static void print_string(const char *str, void *user_data)
 {
-	static const char hexdigits[] = "0123456789abcdef";
-	char str[68];
-	size_t i;
-
-	if (!len)
-		return;
-
-	str[0] = ' ';
-
-	for (i = 0; i < len; i++) {
-		str[((i % 16) * 3) + 1] = ' ';
-		str[((i % 16) * 3) + 2] = hexdigits[buf[i] >> 4];
-		str[((i % 16) * 3) + 3] = hexdigits[buf[i] & 0xf];
-		str[(i % 16) + 51] = isprint(buf[i]) ? buf[i] : '.';
-
-		if ((i + 1) % 16 == 0) {
-			str[49] = ' ';
-			str[50] = ' ';
-			str[67] = '\0';
-			bt_shell_printf("%s\n", str);
-			str[0] = ' ';
-		}
-	}
+	bt_shell_printf("%s\n", str);
+}
 
-	if (i % 16 > 0) {
-		size_t j;
-		for (j = (i % 16); j < 16; j++) {
-			str[(j * 3) + 1] = ' ';
-			str[(j * 3) + 2] = ' ';
-			str[(j * 3) + 3] = ' ';
-			str[j + 51] = ' ';
-		}
-		str[49] = ' ';
-		str[50] = ' ';
-		str[67] = '\0';
-		bt_shell_printf("%s\n", str);
-	}
+void bt_shell_hexdump(const unsigned char *buf, size_t len)
+{
+	util_hexdump(' ', buf, len, print_string, NULL);
 }
 
 void bt_shell_prompt_input(const char *label, const char *msg,
-- 
2.14.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH BlueZ 3/4] shared/shell: Add tab completion for argument values
  2018-02-05 12:48 [PATCH BlueZ 1/4] shared/shell: Introduce bt_shell_{get,set}_env Luiz Augusto von Dentz
  2018-02-05 12:48 ` [PATCH BlueZ 2/4] shared/shell: Make bt_shell_hexdump use util_hexdump Luiz Augusto von Dentz
@ 2018-02-05 12:48 ` Luiz Augusto von Dentz
  2018-02-05 12:48 ` [PATCH BlueZ 4/4] client: Don't set generators for modes Luiz Augusto von Dentz
  2018-02-06 12:03 ` [PATCH BlueZ 1/4] shared/shell: Introduce bt_shell_{get,set}_env Luiz Augusto von Dentz
  3 siblings, 0 replies; 5+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-05 12:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

In case a command don't have a generator parse its argument string and
generate a list of possible values.
---
 src/shared/shell.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 73 insertions(+), 5 deletions(-)

diff --git a/src/shared/shell.c b/src/shared/shell.c
index 69f303b51..2958a66b5 100644
--- a/src/shared/shell.c
+++ b/src/shared/shell.c
@@ -518,8 +518,76 @@ static char *cmd_generator(const char *text, int state)
 	return find_cmd(text, data.menu->entries, &index);
 }
 
+static wordexp_t args;
+
+static char *arg_generator(const char *text, int state)
+{
+	static unsigned int index, len;
+	const char *arg;
+
+	if (!state) {
+		index = 0;
+		len = strlen(text);
+	}
+
+	while (index < args.we_wordc) {
+		arg = args.we_wordv[index];
+		index++;
+
+		if (!strncmp(arg, text, len))
+			return strdup(arg);
+	}
+
+	return NULL;
+}
+
+static char **args_completion(const struct bt_shell_menu_entry *entry, int argc,
+							const char *text)
+{
+	char **matches = NULL;
+	char *str;
+	int index;
+
+	index = text[0] == '\0' ? argc - 1 : argc - 2;
+	if (index < 0)
+		return NULL;
+
+	if (!entry->arg)
+		goto done;
+
+	str = strdup(entry->arg);
+
+	if (parse_args(str, &args, "<>[]", WRDE_NOCMD))
+		goto done;
+
+	/* Check if argument is valid */
+	if ((unsigned) index > args.we_wordc - 1)
+		goto done;
+
+	/* Check if there are multiple values */
+	if (!strrchr(entry->arg, '/'))
+		goto done;
+
+	/* Split values separated by / */
+	str = g_strdelimit(args.we_wordv[index], "/", ' ');
+
+	if (wordexp(str, &args, WRDE_NOCMD))
+		goto done;
+
+	rl_completion_display_matches_hook = NULL;
+	matches = rl_completion_matches(text, arg_generator);
+
+done:
+	if (!matches && text[0] == '\0')
+		bt_shell_printf("Usage: %s %s\n", entry->cmd,
+					entry->arg ? entry->arg : "");
+
+	wordfree(&args);
+	return matches;
+}
+
 static char **menu_completion(const struct bt_shell_menu_entry *entry,
-				const char *text, char *input_cmd)
+				const char *text, int argc, char *input_cmd)
 {
 	char **matches = NULL;
 
@@ -528,9 +596,7 @@ static char **menu_completion(const struct bt_shell_menu_entry *entry,
 			continue;
 
 		if (!entry->gen) {
-			if (text[0] == '\0')
-				bt_shell_printf("Usage: %s %s\n", entry->cmd,
-						entry->arg ? entry->arg : "");
+			matches = args_completion(entry, argc, text);
 			break;
 		}
 
@@ -555,9 +621,11 @@ static char **shell_completion(const char *text, int start, int end)
 		if (wordexp(rl_line_buffer, &w, WRDE_NOCMD))
 			return NULL;
 
-		matches = menu_completion(default_menu, text, w.we_wordv[0]);
+		matches = menu_completion(default_menu, text, w.we_wordc,
+							w.we_wordv[0]);
 		if (!matches)
 			matches = menu_completion(data.menu->entries, text,
+							w.we_wordc,
 							w.we_wordv[0]);
 
 		wordfree(&w);
-- 
2.14.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH BlueZ 4/4] client: Don't set generators for modes
  2018-02-05 12:48 [PATCH BlueZ 1/4] shared/shell: Introduce bt_shell_{get,set}_env Luiz Augusto von Dentz
  2018-02-05 12:48 ` [PATCH BlueZ 2/4] shared/shell: Make bt_shell_hexdump use util_hexdump Luiz Augusto von Dentz
  2018-02-05 12:48 ` [PATCH BlueZ 3/4] shared/shell: Add tab completion for argument values Luiz Augusto von Dentz
@ 2018-02-05 12:48 ` Luiz Augusto von Dentz
  2018-02-06 12:03 ` [PATCH BlueZ 1/4] shared/shell: Introduce bt_shell_{get,set}_env Luiz Augusto von Dentz
  3 siblings, 0 replies; 5+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-05 12:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Commands that already have all values set on the argument string don't
need to add a generator since bt_shell can now auto complete them.
---
 client/main.c | 26 +++++++-------------------
 1 file changed, 7 insertions(+), 19 deletions(-)

diff --git a/client/main.c b/client/main.c
index 85803f1a3..a6adb70d2 100644
--- a/client/main.c
+++ b/client/main.c
@@ -65,12 +65,6 @@ static GDBusProxy *default_dev;
 static GDBusProxy *default_attr;
 static GList *ctrl_list;
 
-static const char *mode_arguments[] = {
-	"on",
-	"off",
-	NULL
-};
-
 static const char *agent_arguments[] = {
 	"on",
 	"off",
@@ -2156,11 +2150,6 @@ static char *argument_generator(const char *text, int state,
 	return NULL;
 }
 
-static char *mode_generator(const char *text, int state)
-{
-	return argument_generator(text, state, mode_arguments);
-}
-
 static char *capability_generator(const char *text, int state)
 {
 	return argument_generator(text, state, agent_arguments);
@@ -2321,7 +2310,7 @@ static const struct bt_shell_menu advertise_menu = {
 			"Set advertise manufacturer data" },
 	{ "tx-power", "[on/off]", cmd_advertise_tx_power,
 			"Enable/disable TX power to be advertised",
-							mode_generator },
+							NULL },
 	{ "name", "[on/off/name]", cmd_advertise_name,
 			"Enable/disable local name to be advertised" },
 	{ "appearance", "[value]", cmd_advertise_appearance,
@@ -2347,7 +2336,7 @@ static const struct bt_shell_menu scan_menu = {
 				"Set/Get transport filter" },
 	{ "duplicate-data", "[on/off]", cmd_scan_filter_duplicate_data,
 				"Set/Get duplicate data filter",
-				mode_generator },
+				NULL },
 	{ "clear", "[uuids/rssi/pathloss/transport/duplicate-data]",
 				cmd_scan_filter_clear,
 				"Clears discovery filter.",
@@ -2377,7 +2366,7 @@ static const struct bt_shell_menu gatt_menu = {
 	{ "release-notify", NULL, cmd_release_notify,
 					"Release Notify file descriptor" },
 	{ "notify",       "<on/off>", cmd_notify, "Notify attribute value",
-							mode_generator },
+							NULL },
 	{ "register-application", "[UUID ...]", cmd_register_app,
 						"Register profile to connect" },
 	{ "unregister-application", NULL, cmd_unregister_app,
@@ -2417,13 +2406,13 @@ static const struct bt_shell_menu main_menu = {
 	{ "reset-alias",  NULL,       cmd_reset_alias,
 					"Reset controller alias" },
 	{ "power",        "<on/off>", cmd_power, "Set controller power",
-							mode_generator },
+							NULL },
 	{ "pairable",     "<on/off>", cmd_pairable,
 					"Set controller pairable mode",
-							mode_generator },
+							NULL },
 	{ "discoverable", "<on/off>", cmd_discoverable,
 					"Set controller discoverable mode",
-							mode_generator },
+							NULL },
 	{ "agent",        "<on/off/capability>", cmd_agent,
 				"Enable/disable agent with given capability",
 							capability_generator},
@@ -2433,8 +2422,7 @@ static const struct bt_shell_menu main_menu = {
 				"Enable/disable advertising with given type",
 							ad_generator},
 	{ "set-alias",    "<alias>",  cmd_set_alias, "Set device alias" },
-	{ "scan",         "<on/off>", cmd_scan, "Scan for devices",
-							mode_generator },
+	{ "scan",         "<on/off>", cmd_scan, "Scan for devices", NULL },
 	{ "info",         "[dev]",    cmd_info, "Device information",
 							dev_generator },
 	{ "pair",         "[dev]",    cmd_pair, "Pair with device",
-- 
2.14.3


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH BlueZ 1/4] shared/shell: Introduce bt_shell_{get,set}_env
  2018-02-05 12:48 [PATCH BlueZ 1/4] shared/shell: Introduce bt_shell_{get,set}_env Luiz Augusto von Dentz
                   ` (2 preceding siblings ...)
  2018-02-05 12:48 ` [PATCH BlueZ 4/4] client: Don't set generators for modes Luiz Augusto von Dentz
@ 2018-02-06 12:03 ` Luiz Augusto von Dentz
  3 siblings, 0 replies; 5+ messages in thread
From: Luiz Augusto von Dentz @ 2018-02-06 12:03 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org

Hi,

On Mon, Feb 5, 2018 at 10:48 AM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> These function can be used to share environment variable accross
> different files.
> ---
>  src/shared/shell.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/shared/shell.h |  3 +++
>  2 files changed, 66 insertions(+)
>
> diff --git a/src/shared/shell.c b/src/shared/shell.c
> index f1b85f202..f724c9881 100644
> --- a/src/shared/shell.c
> +++ b/src/shared/shell.c
> @@ -56,6 +56,11 @@
>
>  static GMainLoop *main_loop;
>
> +struct bt_shell_env {
> +       char *name;
> +       void *value;
> +};
> +
>  static struct {
>         struct io *input;
>
> @@ -66,6 +71,8 @@ static struct {
>         const struct bt_shell_menu *menu;
>         const struct bt_shell_menu *main;
>         struct queue *submenus;
> +
> +       struct queue *envs;
>  } data;
>
>  static void shell_print_menu(void);
> @@ -759,6 +766,14 @@ static void rl_cleanup(void)
>         rl_callback_handler_remove();
>  }
>
> +static void env_destroy(void *data)
> +{
> +       struct bt_shell_env *env = data;
> +
> +       free(env->name);
> +       free(env);
> +}
> +
>  void bt_shell_run(void)
>  {
>         struct io *signal;
> @@ -775,6 +790,11 @@ void bt_shell_run(void)
>         g_main_loop_unref(main_loop);
>         main_loop = NULL;
>
> +       if (data.envs) {
> +               queue_destroy(data.envs, env_destroy);
> +               data.envs = NULL;
> +       }
> +
>         rl_cleanup();
>  }
>
> @@ -849,3 +869,46 @@ bool bt_shell_detach(void)
>
>         return true;
>  }
> +
> +static bool match_env(const void *data, const void *user_data)
> +{
> +       const struct bt_shell_env *env = data;
> +       const char *name = user_data;
> +
> +       return !strcmp(env->name, name);
> +}
> +
> +void bt_shell_set_env(const char *name, void *value)
> +{
> +       struct bt_shell_env *env;
> +
> +       if (!data.envs) {
> +               data.envs = queue_new();
> +               goto done;
> +       }
> +
> +       env = queue_remove_if(data.envs, match_env, (void *) name);
> +       if (env)
> +               env_destroy(env);
> +
> +done:
> +       env = new0(struct bt_shell_env, 1);
> +       env->name = strdup(name);
> +       env->value = value;
> +
> +       queue_push_tail(data.envs, env);
> +}
> +
> +void *bt_shell_get_env(const char *name)
> +{
> +       const struct bt_shell_env *env;
> +
> +       if (!data.envs)
> +               return NULL;
> +
> +       env = queue_find(data.envs, match_env, name);
> +       if (!env)
> +               return NULL;
> +
> +       return env->value;
> +}
> diff --git a/src/shared/shell.h b/src/shared/shell.h
> index 8b8b1f634..359629896 100644
> --- a/src/shared/shell.h
> +++ b/src/shared/shell.h
> @@ -87,4 +87,7 @@ int bt_shell_release_prompt(const char *input);
>  bool bt_shell_attach(int fd);
>  bool bt_shell_detach(void);
>
> +void bt_shell_set_env(const char *name, void *value);
> +void *bt_shell_get_env(const char *name);
> +
>  void bt_shell_cleanup(void);
> --
> 2.14.3

Applied.


-- 
Luiz Augusto von Dentz

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-02-06 12:03 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-02-05 12:48 [PATCH BlueZ 1/4] shared/shell: Introduce bt_shell_{get,set}_env Luiz Augusto von Dentz
2018-02-05 12:48 ` [PATCH BlueZ 2/4] shared/shell: Make bt_shell_hexdump use util_hexdump Luiz Augusto von Dentz
2018-02-05 12:48 ` [PATCH BlueZ 3/4] shared/shell: Add tab completion for argument values Luiz Augusto von Dentz
2018-02-05 12:48 ` [PATCH BlueZ 4/4] client: Don't set generators for modes Luiz Augusto von Dentz
2018-02-06 12:03 ` [PATCH BlueZ 1/4] shared/shell: Introduce bt_shell_{get,set}_env Luiz Augusto von Dentz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).