first partially working command parser
authorRobert Manea <gotmor@gmail.com>
Tue, 12 May 2009 13:33:46 +0000 (15:33 +0200)
committerRobert Manea <gotmor@gmail.com>
Tue, 12 May 2009 13:33:46 +0000 (15:33 +0200)
uzbl.c
uzbl.h

diff --git a/uzbl.c b/uzbl.c
index 127c585..8a951ee 100644 (file)
--- a/uzbl.c
+++ b/uzbl.c
 
 
 static Uzbl uzbl;
-
+char *foobar="Just a  test";
+
+/* define names and pointers to all config specific variables */
+const struct {
+    char *name;
+    void **ptr;
+} var_name_to_ptr[] = {
+    { "name",           (void *)&uzbl.state.instance_name   },
+    { "show_status",    (void *)&uzbl.behave.show_status    },
+    { "insert_mode",    (void *)&uzbl.behave.insert_mode    },
+    { NULL,             NULL                        }
+}, *n2v_p = var_name_to_ptr;
+
+/* construct a hash from the var_name_to_ptr array for quick access */
+static void
+make_var_to_name_hash() {
+    uzbl.comm.proto_var = g_hash_table_new(g_str_hash, g_str_equal);
+    while(n2v_p->name) {
+        g_hash_table_insert(uzbl.comm.proto_var, n2v_p->name, n2v_p->ptr);
+        n2v_p++;
+    }
+}
 
 /* commandline arguments (set initial values for the state variables) */
 static GOptionEntry entries[] =
@@ -714,40 +735,82 @@ create_fifo() {
     return;
 }
 
+static gboolean
+get_var_value(gchar *name) {
+    void **p = NULL;
+
+    if( (p = g_hash_table_lookup(uzbl.comm.proto_var, name)) ) {
+        if(!strcmp(name, "name")) {
+            printf("VAR: %s VALUE: %s\n", name, (char *)*p);
+        } else {
+            printf("VAR: %s VALUE: %d\n", name, (int)*p);
+        }
+    }
+    return TRUE;
+}
+
+static gboolean
+set_var_value(gchar *name, gchar *val) {
+    void **p = NULL;
+    char *endp = NULL;
+
+    if( (p = g_hash_table_lookup(uzbl.comm.proto_var, name)) ) {
+        if(!strcmp(name, "name")) {
+            free(*p);
+            *p = g_strdup(val);
+        } else {
+            *p = (int)strtoul(val, &endp, 10);
+        }
+    }
+    return TRUE;
+}
+
 static void
+setup_regex() {
+    GError *err=NULL;
+
+    uzbl.comm.get_regex = g_regex_new("^GET\\s+([^ \\n]+)$", 0, 0, &err);
+    uzbl.comm.set_regex = g_regex_new("^SET\\s+([^ ]+)\\s*=\\s*([^\\n].*)$", 0, 0, &err);
+}
+
+static gboolean
 control_stdin(GIOChannel *gio, GIOCondition condition) {
-    gchar *ctl_line;
+    gchar *ctl_line = NULL;
+    gsize ctl_line_len = 0;
     GIOStatus ret;
     GError *err = NULL;
-    printf("stdin triggered\n");
+    gchar **tokens;
 
-    if (condition & G_IO_HUP) { //FIXME: for some reason, the last command is not interpreted. but when we get here gio->is_readable = FALSE.
+    if (condition & G_IO_HUP) { 
         ret = g_io_channel_shutdown (gio, FALSE, &err);
-        if (ret == G_IO_STATUS_ERROR) {
-            g_error ("Stdin: disconnected with HUP, but could not close it!\n");
-        } else {
-            printf("Stdin: closed on request with HUP\n");
-            return;
-        }
+        return FALSE;
     }
-    if(!gio)
-        g_error ("Stdin: GIOChannel broke\n");
 
-    ret = g_io_channel_read_line(gio, &ctl_line, NULL, NULL, &err);
-    if (ret == G_IO_STATUS_ERROR)
-        g_error ("Stdin: Error reading: %s\n", err->message);
-    if (ret == G_IO_STATUS_EOF) {
-        ret = g_io_channel_shutdown (gio, FALSE, &err);
-        if (ret == G_IO_STATUS_ERROR) {
-            g_error ("Stdin: disconnected without HUP, but could not close it!\n");
-        } else {
-            printf("Stdin: closed on request without HUP\n");
+    ret = g_io_channel_read_line(gio, &ctl_line, &ctl_line_len, NULL, &err);
+    if ( (ret == G_IO_STATUS_ERROR) || (ret == G_IO_STATUS_EOF) )
+        return FALSE;
+
+    /* SET command */
+    if(ctl_line[0] == 'S') {
+        tokens = g_regex_split(uzbl.comm.set_regex, ctl_line, 0);
+        if(tokens) {
+            set_var_value(tokens[1], tokens[2]);
+            g_strfreev(tokens);
         }
     }
-    parse_line(ctl_line);
+    /* GET command */
+    else if(ctl_line[0] == 'G') {
+        tokens = g_regex_split(uzbl.comm.get_regex, ctl_line, 0);
+        if(tokens) {
+            get_var_value(tokens[1]);
+            g_strfreev(tokens);
+        }
+    } else
+        printf("Command not understood (%s)\n", ctl_line);
+
     g_free(ctl_line);
-    printf("stdin...done\n");
-    return;
+
+    return TRUE;
 }
 
 static void
@@ -755,7 +818,7 @@ create_stdin () {
     GIOChannel *chan = NULL;
     GError *error = NULL;
 
-    chan = g_io_channel_unix_new (fileno(stdin));
+    chan = g_io_channel_unix_new(fileno(stdin));
     if (chan) {
         if (!g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_stdin, NULL)) {
             g_error ("Stdin: could not add watch\n");
@@ -1345,7 +1408,10 @@ main (int argc, char* argv[]) {
     if(setup_signal(SIGTERM, catch_sigterm) == SIG_ERR)
         fprintf(stderr, "uzbl: error hooking SIGTERM\n");
 
+
+    setup_regex();
     setup_scanner();
+
     if (!uzbl.behave.status_format)
         uzbl.behave.status_format = STATUS_DEFAULT;
     if (!uzbl.behave.show_status)
@@ -1354,11 +1420,12 @@ main (int argc, char* argv[]) {
         update_title();
 
 
+    make_var_to_name_hash();
+    create_stdin();
     if (uzbl.behave.fifo_dir)
         create_fifo ();
     if (uzbl.behave.socket_dir)
         create_socket ();
-    create_stdin ();
 
     gtk_main ();
     clean_up();
diff --git a/uzbl.h b/uzbl.h
index d414645..0f47304 100644 (file)
--- a/uzbl.h
+++ b/uzbl.h
@@ -57,6 +57,12 @@ enum { FIFO, SOCKET};
 typedef struct {
     char           fifo_path[64];
     char           socket_path[108];
+    /* stores (key)"variable name" -> (value)"pointer to this var*/
+    GHashTable     *proto_var;
+    /* command parsing regexes */
+    GRegex         *set_regex; 
+    GRegex         *get_regex; 
+    GRegex         *bind_regex; 
 } Communication;
 
 
@@ -64,7 +70,7 @@ typedef struct {
 typedef struct {
     gchar    *uri;
     gchar    *config_file;
-    gchar    *instance_name;
+    char    *instance_name;
     gchar    config_file_path[500];
     gchar    selected_url[500];
     char     executable_path[500];
@@ -224,7 +230,7 @@ control_fifo(GIOChannel *gio, GIOCondition condition);
 static void
 create_fifo();
 
-static void
+static gboolean
 control_stdin(GIOChannel *gio, GIOCondition condition);
 
 static void