From 5cb7ce2b677a227a3a14c8de2203ceb23bf3e1b6 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Tue, 4 Oct 2011 22:18:47 +0000 Subject: add toggle command --- src/commands.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/commands.h | 1 + src/variables.c | 100 ++++++++++++++++++++++++++++---------------------- src/variables.h | 8 ++++ tests/test-command.c | 49 +++++++++++++++++++++++++ 5 files changed, 217 insertions(+), 43 deletions(-) diff --git a/src/commands.c b/src/commands.c index 8896250..708ed49 100644 --- a/src/commands.c +++ b/src/commands.c @@ -34,6 +34,7 @@ CommandInfo cmdlist[] = { "search_clear", search_clear, TRUE }, { "dehilight", dehilight, 0 }, { "set", set_var, TRUE }, + { "toggle", toggle_var, 0 }, { "dump_config", act_dump_config, 0 }, { "dump_config_as_events", act_dump_config_as_events, 0 }, { "chain", chain, 0 }, @@ -165,6 +166,107 @@ set_var(WebKitWebView *page, GArray *argv, GString *result) { g_strfreev(split); } +void +toggle_var(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; (void) result; + + if(!argv_idx(argv, 0)) + return; + + const gchar *var_name = argv_idx(argv, 0); + + uzbl_cmdprop *c = get_var_c(var_name); + + switch(c->type) { + case TYPE_STR: + { + const gchar *next; + + if(argv->len >= 3) { + gchar *current = get_var_value_string_c(c); + + guint i = 2; + const gchar *first = argv_idx(argv, 1); + const gchar *this = first; + next = argv_idx(argv, 2); + + while(next && strcmp(current, this)) { + this = next; + next = argv_idx(argv, ++i); + } + + if(!next) + next = first; + + g_free(current); + } else + next = ""; + + set_var_value_string_c(c, next); + break; + } + case TYPE_INT: + { + int current = get_var_value_int_c(c); + int next; + + if(argv->len >= 3) { + guint i = 2; + + int first = strtoul(argv_idx(argv, 1), NULL, 10); + int this = first; + + const gchar *next_s = argv_idx(argv, 2); + + while(next_s && this != current) { + this = strtoul(next_s, NULL, 10); + next_s = argv_idx(argv, ++i); + } + + if(next_s) + next = strtoul(next_s, NULL, 10); + else + next = first; + } else + next = !current; + + set_var_value_int_c(c, next); + break; + } + case TYPE_FLOAT: + { + float current = get_var_value_float_c(c); + float next; + + if(argv->len >= 3) { + guint i = 2; + + float first = strtod(argv_idx(argv, 1), NULL); + float this = first; + + const gchar *next_s = argv_idx(argv, 2); + + while(next_s && this != current) { + this = strtod(next_s, NULL); + next_s = argv_idx(argv, ++i); + } + + if(next_s) + next = strtod(next_s, NULL); + else + next = first; + } else + next = !current; + + set_var_value_float_c(c, next); + break; + } + default: + g_assert_not_reached(); + } + + send_set_var_event(var_name, c); +} void event(WebKitWebView *page, GArray *argv, GString *result) { diff --git a/src/commands.h b/src/commands.h index b8cf095..38bd5f2 100644 --- a/src/commands.h +++ b/src/commands.h @@ -58,6 +58,7 @@ void delete_cookie(WebKitWebView *page, GArray *argv, GString *result); void clear_cookies(WebKitWebView *pag, GArray *argv, GString *result); void download(WebKitWebView *pag, GArray *argv, GString *result); void set_var(WebKitWebView *page, GArray *argv, GString *result); +void toggle_var(WebKitWebView *page, GArray *argv, GString *result); void run_js (WebKitWebView * web_view, GArray *argv, GString *result); void run_external_js (WebKitWebView * web_view, GArray *argv, GString *result); void toggle_zoom_type (WebKitWebView* page, GArray *argv, GString *result); diff --git a/src/variables.c b/src/variables.c index 3bd941b..ed76f95 100644 --- a/src/variables.c +++ b/src/variables.c @@ -5,6 +5,11 @@ #include "io.h" #include "util.h" +uzbl_cmdprop * +get_var_c(const gchar *name) { + return g_hash_table_lookup(uzbl.behave.proto_var, name); +} + void send_set_var_event(const char *name, const uzbl_cmdprop *c) { /* check for the variable type */ @@ -41,8 +46,8 @@ send_set_var_event(const char *name, const uzbl_cmdprop *c) { void expand_variable(GString *buf, const gchar *name) { - uzbl_cmdprop* c; - if((c = g_hash_table_lookup(uzbl.behave.proto_var, name))) { + uzbl_cmdprop* c = get_var_c(name); + if(c) { if(c->type == TYPE_STR) { gchar *v = get_var_value_string_c(c); g_string_append(buf, v); @@ -54,50 +59,59 @@ expand_variable(GString *buf, const gchar *name) { } } +void +set_var_value_string_c(uzbl_cmdprop *c, const gchar *val) { + if(c->setter) + ((void (*)(const gchar *))c->setter)(val); + else { + g_free(*(c->ptr.s)); + *(c->ptr.s) = g_strdup(val); + } +} + +void +set_var_value_int_c(uzbl_cmdprop *c, int i) { + if(c->setter) + ((void (*)(int))c->setter)(i); + else + *(c->ptr.i) = i; +} + +void +set_var_value_float_c(uzbl_cmdprop *c, float f) { + if(c->setter) + ((void (*)(float))c->setter)(f); + else + *(c->ptr.f) = f; +} + gboolean set_var_value(const gchar *name, gchar *val) { - uzbl_cmdprop *c = NULL; - g_assert(val != NULL); - if( (c = g_hash_table_lookup(uzbl.behave.proto_var, name)) ) { + uzbl_cmdprop *c = get_var_c(name); + + if(c) { if(!c->writeable) return FALSE; - if(c->setter) { - switch(c->type) { - case TYPE_STR: - ((void (*)(const gchar *))c->setter)(val); - break; - case TYPE_INT: - { - int i = (int)strtoul(val, NULL, 10); - ((void (*)(int))c->setter)(i); - break; - } - case TYPE_FLOAT: - { - float f = strtod(val, NULL); - ((void (*)(float))c->setter)(f); - break; - } - default: - g_assert_not_reached(); - } - } else { - switch(c->type) { - case TYPE_STR: - g_free(*(c->ptr.s)); - *(c->ptr.s) = g_strdup(val); - break; - case TYPE_INT: - *(c->ptr.i) = (int)strtoul(val, NULL, 10); - break; - case TYPE_FLOAT: - *(c->ptr.f) = strtod(val, NULL); - break; - default: - g_assert_not_reached(); - } + switch(c->type) { + case TYPE_STR: + set_var_value_string_c(c, val); + break; + case TYPE_INT: + { + int i = (int)strtoul(val, NULL, 10); + set_var_value_int_c(c, i); + break; + } + case TYPE_FLOAT: + { + float f = strtod(val, NULL); + set_var_value_float_c(c, f); + break; + } + default: + g_assert_not_reached(); } send_set_var_event(name, c); @@ -148,7 +162,7 @@ get_var_value_string_c(const uzbl_cmdprop *c) { gchar* get_var_value_string(const gchar *name) { - uzbl_cmdprop *c = g_hash_table_lookup(uzbl.behave.proto_var, name); + uzbl_cmdprop *c = get_var_c(name); return get_var_value_string_c(c); } @@ -166,7 +180,7 @@ get_var_value_int_c(const uzbl_cmdprop *c) { int get_var_value_int(const gchar *name) { - uzbl_cmdprop *c = g_hash_table_lookup(uzbl.behave.proto_var, name); + uzbl_cmdprop *c = get_var_c(name); return get_var_value_int_c(c); } @@ -184,7 +198,7 @@ get_var_value_float_c(const uzbl_cmdprop *c) { float get_var_value_float(const gchar *name) { - uzbl_cmdprop *c = g_hash_table_lookup(uzbl.behave.proto_var, name); + uzbl_cmdprop *c = get_var_c(name); return get_var_value_float_c(c); } diff --git a/src/variables.h b/src/variables.h index 4f85474..dade652 100644 --- a/src/variables.h +++ b/src/variables.h @@ -10,6 +10,8 @@ #include "type.h" +uzbl_cmdprop *get_var_c(const gchar *name); + gboolean set_var_value(const gchar *name, gchar *val); void expand_variable(GString *buf, const gchar *name); void variables_hash(); @@ -21,6 +23,12 @@ int get_var_value_int(const char *name); float get_var_value_float_c(const uzbl_cmdprop *c); float get_var_value_float(const char *name); +void set_var_value_string_c(uzbl_cmdprop *c, const gchar *val); +void set_var_value_int_c(uzbl_cmdprop *c, int f); +void set_var_value_float_c(uzbl_cmdprop *c, float f); + +void send_set_var_event(const char *name, const uzbl_cmdprop *c); + void dump_config(); void dump_config_as_events(); diff --git a/tests/test-command.c b/tests/test-command.c index db08097..9b01928 100644 --- a/tests/test-command.c +++ b/tests/test-command.c @@ -308,6 +308,51 @@ test_no_such_command (void) { /* if we didn't crash then we're ok! */ } +// TODO: test toggling emits an event +void +test_toggle_int (void) { + g_assert_cmpint(0, ==, uzbl.behave.forward_keys); + + parse_cmd_line("toggle forward_keys", NULL); + g_assert_cmpint(1, ==, uzbl.behave.forward_keys); + + parse_cmd_line("toggle forward_keys", NULL); + g_assert_cmpint(0, ==, uzbl.behave.forward_keys); + + // if cycle values are specified it should use those + parse_cmd_line("toggle forward_keys 1 2", NULL); + g_assert_cmpint(1, ==, uzbl.behave.forward_keys); + + parse_cmd_line("toggle forward_keys 1 2", NULL); + g_assert_cmpint(2, ==, uzbl.behave.forward_keys); + + // and wrap to the first value when it reaches the end. + parse_cmd_line("toggle forward_keys 1 2", NULL); + g_assert_cmpint(1, ==, uzbl.behave.forward_keys); +} + +void +test_toggle_string (void) { + parse_cmd_line("set useragent = something interesting", NULL); + g_assert_cmpstr("something interesting", ==, uzbl.net.useragent); + + // when something was set, it gets reset + parse_cmd_line("toggle useragent", NULL); + g_assert_cmpstr("", ==, uzbl.net.useragent); + + // if cycle values are specified it should use those + parse_cmd_line("set useragent = something interesting", NULL); + parse_cmd_line("toggle useragent 'x' 'y'", NULL); + g_assert_cmpstr("x", ==, uzbl.net.useragent); + + parse_cmd_line("toggle useragent 'x' 'y'", NULL); + g_assert_cmpstr("y", ==, uzbl.net.useragent); + + // and wrap to the first value when it reaches the end. + parse_cmd_line("toggle useragent 'x' 'y'", NULL); + g_assert_cmpstr("x", ==, uzbl.net.useragent); +} + int main (int argc, char *argv[]) { /* set up tests */ @@ -329,6 +374,10 @@ main (int argc, char *argv[]) { g_test_add_func("/test-command/no-such-command", test_no_such_command); + g_test_add_func("/test-command/toggle-int", test_toggle_int); + // we should probably test toggle float, but meh. + g_test_add_func("/test-command/toggle-string", test_toggle_string); + /* set up uzbl */ initialize(argc, argv); -- cgit v1.2.3