Skip to content

Commit

Permalink
Merge pull request #349 from keis/async-chain
Browse files Browse the repository at this point in the history
Async chain
  • Loading branch information
keis committed Feb 18, 2017
2 parents f994763 + 0157bae commit f4051e1
Show file tree
Hide file tree
Showing 2 changed files with 151 additions and 18 deletions.
80 changes: 62 additions & 18 deletions src/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -910,7 +910,7 @@ DECLARE_COMMAND (spawn_sh);
DECLARE_COMMAND (spawn_sh_sync);

/* Uzbl commands */
DECLARE_COMMAND (chain);
DECLARE_TASK (chain);
DECLARE_COMMAND (include);
DECLARE_COMMAND (exit);

Expand All @@ -926,6 +926,8 @@ DECLARE_COMMAND (event);
DECLARE_COMMAND (choose);
DECLARE_COMMAND (request);

#define COMMAND(x) (UzblCommandCallback) x

static const UzblCommand
builtin_command_table[] = {
/* name function split send_event task*/
Expand Down Expand Up @@ -975,7 +977,7 @@ builtin_command_table[] = {
{ "inspector", cmd_inspector, TRUE, TRUE, FALSE },

/* Execution commands */
{ "js", (UzblCommandCallback) cmd_js, TRUE, TRUE, TRUE },
{ "js", COMMAND (cmd_js), TRUE, TRUE, TRUE },
/* TODO: Consolidate into one command. */
{ "spawn", cmd_spawn, TRUE, TRUE, FALSE },
{ "spawn_sync", cmd_spawn_sync, TRUE, TRUE, FALSE },
Expand All @@ -984,7 +986,7 @@ builtin_command_table[] = {
{ "spawn_sh_sync", cmd_spawn_sh_sync, TRUE, TRUE, FALSE },

/* Uzbl commands */
{ "chain", cmd_chain, TRUE, TRUE, FALSE },
{ "chain", COMMAND (cmd_chain), TRUE, TRUE, TRUE },
{ "include", cmd_include, FALSE, TRUE, FALSE },
{ "exit", cmd_exit, TRUE, TRUE, FALSE },

Expand Down Expand Up @@ -2451,28 +2453,70 @@ IMPLEMENT_COMMAND (spawn_sh_sync)

/* Uzbl commands */

IMPLEMENT_COMMAND (chain)
{
ARG_CHECK (argv, 1);
struct _ChainData {
GArray *argv;
guint idx;
GString *result;
};
typedef struct _ChainData ChainData;

guint i = 0;
const gchar *cmd;
while ((cmd = argv_idx (argv, i++))) {
GString *res = NULL;
static void
chain_next (GTask *task,
ChainData *data);

if (result) {
res = g_string_new ("");
}
static void
chain_command_cb (GObject *source,
GAsyncResult *res,
gpointer data);

uzbl_commands_run (cmd, res);
IMPLEMENT_TASK (chain)
{
TASK_ARG_CHECK (task, argv, 1);

if (result) {
g_string_append (result, res->str);
g_string_free (res, TRUE);
}
ChainData *cd = g_new (ChainData, 1);
cd->argv = argv;
cd->idx = 0;
cd->result = g_task_get_task_data (task);
g_task_set_task_data (task, cd, g_free);
chain_next (task, cd);
}

void
chain_next (GTask *task,
ChainData *data)
{
const gchar *cmd;
if ((cmd = argv_idx (data->argv, data->idx++))) {
uzbl_commands_run_string_async (cmd, !!data->result,
chain_command_cb,
(gpointer) task);
} else {
g_task_return_pointer (task, NULL, NULL);
}
}

void
chain_command_cb (GObject *source,
GAsyncResult *res,
gpointer data)
{
GTask *task = G_TASK (data);
ChainData *cd = g_task_get_task_data (task);
GString *str;
GError *err = NULL;
str = uzbl_commands_run_finish (source, res, &err);
if (err) {
g_task_return_error (task, err);
return;
}
if (cd->result) {
g_string_append (cd->result, str->str);
}
g_string_free (str, TRUE);
chain_next (task, cd);
}


IMPLEMENT_COMMAND (include)
{
UZBL_UNUSED (result);
Expand Down
89 changes: 89 additions & 0 deletions tests/core-tests.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,106 @@ test_parse_escaped_at ()
g_assert_cmpstr (g_array_index (argv, gchar*, 0), ==, "@");
}

static void
commands_chain_cb (GObject *source,
GAsyncResult *res,
gpointer data)
{
GMainLoop *loop = (GMainLoop*) data;
GError *err = NULL;
GString *r = uzbl_commands_run_finish (source, res, &err);

g_assert_null (err);
g_assert_cmpstr (r->str, ==, "foobar");

g_main_loop_quit (loop);
}

static void
test_commands_chain ()
{
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
GArray *argv = uzbl_commands_args_new ();
const UzblCommand *cmd = uzbl_commands_parse (
"chain 'print foo' 'print bar'", argv);

uzbl_commands_run_async (cmd, argv, TRUE, commands_chain_cb,
(gpointer) loop);
g_main_loop_run (loop);
}

static void
commands_js_cb (GObject *source,
GAsyncResult *res,
gpointer data)
{
GMainLoop *loop = (GMainLoop*) data;
GError *err = NULL;
GString *r = uzbl_commands_run_finish (source, res, &err);

g_assert_null (err);
g_assert_cmpstr (r->str, ==, "foobar");

g_main_loop_quit (loop);
}

static void
test_commands_js ()
{
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
GArray *argv = uzbl_commands_args_new ();
const UzblCommand *cmd = uzbl_commands_parse (
"js clean string '\"foo\" + \"bar\"'", argv);

uzbl_commands_run_async (cmd, argv, TRUE, commands_js_cb,
(gpointer) loop);
g_main_loop_run (loop);
}

static void
commands_chain_js_cb (GObject *source,
GAsyncResult *res,
gpointer data)
{
GMainLoop *loop = (GMainLoop*) data;
GError *err = NULL;
GString *r = uzbl_commands_run_finish (source, res, &err);

g_assert_null (err);
g_assert_cmpstr (r->str, ==, "foobar");

g_main_loop_quit (loop);
}

static void
test_commands_chain_js ()
{
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
GArray *argv = uzbl_commands_args_new ();
const UzblCommand *cmd = uzbl_commands_parse (
"chain 'js clean string \\'\"foo\"\\'' 'print bar'", argv);

uzbl_commands_run_async (cmd, argv, TRUE, commands_chain_js_cb,
(gpointer) loop);
g_main_loop_run (loop);
}

int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);

uzbl_commands_init ();
uzbl_variables_init ();
uzbl_io_init ();

g_test_add_func ("/uzbl/commands/parse_simple", test_parse_simple);
g_test_add_func ("/uzbl/commands/parse_quoted", test_parse_quoted);
g_test_add_func ("/uzbl/commands/parse_extra_whitespace", test_parse_extra_whitespace);
g_test_add_func ("/uzbl/commands/parse_escaped_at", test_parse_escaped_at);
g_test_add_func ("/uzbl/commands/chain", test_commands_chain);
g_test_add_func ("/uzbl/commands/js", test_commands_js);
g_test_add_func ("/uzbl/commands/chain_js", test_commands_chain_js);

return g_test_run ();
}

0 comments on commit f4051e1

Please sign in to comment.