diff options
author | Thomas White <taw@physics.org> | 2021-06-20 14:07:17 +0200 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2021-06-20 14:07:17 +0200 |
commit | d9bbee4fa984cb641e868b69331b4587f2281ddc (patch) | |
tree | 7be9556042a0720c8a721e258c3e40a7fe73acc6 /src | |
parent | 3b1227ccc5ed3ddb9f13199cefe05baf34156c22 (diff) |
Fixture display: Get the fixture names from Starlet
Diffstat (limited to 'src')
-rw-r--r-- | src/repl-connection.c | 48 | ||||
-rw-r--r-- | src/repl-connection.h | 4 | ||||
-rw-r--r-- | src/starlet-fixture-display.c | 83 |
3 files changed, 117 insertions, 18 deletions
diff --git a/src/repl-connection.c b/src/repl-connection.c index 622e260..a159c0b 100644 --- a/src/repl-connection.c +++ b/src/repl-connection.c @@ -24,9 +24,11 @@ #include <string.h> #include <stdlib.h> #include <stdio.h> +#include <ctype.h> #include <glib.h> #include <gio/gio.h> #include <gio/gunixsocketaddress.h> +#include <libguile.h> #include <libintl.h> #define _(x) gettext(x) @@ -38,6 +40,8 @@ struct _replconnection GSocketConnection *conn; char inbuf[1024]; char input[2048]; + void (*process_func)(SCM sexp, void *data); + void *process_func_data; }; @@ -71,10 +75,46 @@ static char *strip_crap(const char *line_orig) } +static int find_reply(const char *line) +{ + const char *eq; + size_t eq_pos; + int i; + + if ( line[0] != '$' ) return 0; + + eq = strstr(line, " = "); + if ( eq == NULL ) return 0; + eq_pos = eq - line; + + for ( i=1; i<eq_pos; i++ ) { + if ( !isdigit(line[i]) ) return 0; + } + + return eq_pos+3; +} + + static void process_line(const char *line_orig, ReplConnection *repl) { + SCM port, str, sexp; + int eq_pos; char *line = strip_crap(line_orig); + printf("%p: '%s'\n", repl, line); + eq_pos = find_reply(line); + if ( eq_pos == 0 ) { + free(line); + return; + } + + str = scm_from_utf8_string(line+eq_pos); + port = scm_open_input_string(str); + sexp = scm_read(port); + + repl->process_func(sexp, repl->process_func_data); + + scm_close_port(port); free(line); } @@ -129,7 +169,9 @@ static void input_ready(GObject *source, GAsyncResult *res, gpointer vp) } -ReplConnection *repl_connection_new(const char *socket) +ReplConnection *repl_connection_new(const char *socket, + void (*process_func)(SCM sexp, void *data), + void *data) { ReplConnection *repl; GSocketClient *client; @@ -151,6 +193,10 @@ ReplConnection *repl_connection_new(const char *socket) } repl->input[0] = '\0'; + scm_init_guile(); + + repl->process_func = process_func; + repl->process_func_data = data; g_input_stream_read_async(g_io_stream_get_input_stream(G_IO_STREAM(repl->conn)), repl->inbuf, 1023, G_PRIORITY_DEFAULT, NULL, diff --git a/src/repl-connection.h b/src/repl-connection.h index 8245c38..f8b82f6 100644 --- a/src/repl-connection.h +++ b/src/repl-connection.h @@ -26,7 +26,9 @@ typedef struct _replconnection ReplConnection; -extern ReplConnection *repl_connection_new(const char *socket); +extern ReplConnection *repl_connection_new(const char *socket, + void (*process_func)(SCM sexp, void *data), + void *data); extern int repl_send(ReplConnection *repl, const char *line); #endif /* REPL_CONNECTION_H */ diff --git a/src/starlet-fixture-display.c b/src/starlet-fixture-display.c index 366e0e6..535403f 100644 --- a/src/starlet-fixture-display.c +++ b/src/starlet-fixture-display.c @@ -28,6 +28,7 @@ #include <sys/stat.h> #include <glib.h> #include <glib/gstdio.h> +#include <libguile.h> #include <libintl.h> #define _(x) gettext(x) @@ -219,28 +220,78 @@ static gboolean redraw_cb(gpointer data) } -static void get_fixture_list(struct fixture_display *fixd) +static void show_help(const char *s) +{ + printf(_("Syntax: %s [options]\n\n"), s); + printf(_("Show fixtures in Starlet" + " -s, --socket REPL socket for Starlet process (default guile.socket).\n" + " -h, --help Display this help message.\n")); +} + + +static int is_list(SCM list) +{ + return scm_is_true(scm_list_p(list)); +} + + +static int symbol_eq(SCM symbol, const char *val) { - repl_send(fixd->repl, "(patched-fixture-names)"); + return scm_is_true(scm_eq_p(symbol, scm_from_utf8_symbol(val))); +} - /* FIXME: Dummy */ + +static void handle_patched_fixtures(struct fixture_display *fixd, + SCM list) +{ int i; - fixd->fixtures = malloc(32*sizeof(struct fixture)); - fixd->n_fixtures = 32; - for ( i=0; i<32; i++ ) { - char tmp[32]; - snprintf(tmp, 31, "mh%i", 1+i); - fixd->fixtures[i].label = strdup(tmp); + int nfix; + + if ( !is_list(list) ) { + fprintf(stderr, "Invalid patched fixture list\n"); + return; + } + + nfix = scm_to_int(scm_length(list)); + + free(fixd->fixtures); + fixd->fixtures = malloc(nfix*sizeof(struct fixture)); + fixd->n_fixtures = nfix; + + for ( i=0; i<nfix; i++ ) { + SCM item = scm_list_ref(list, scm_from_int(i)); + if ( is_list(item) && (scm_to_int(scm_length(item)) == 3) ) { + + char tmp[64]; + SCM group_name = scm_list_ref(item, scm_from_int(1)); + SCM idx = scm_list_ref(item, scm_from_int(2)); + SCM name = scm_symbol_to_string(group_name); + snprintf(tmp, 63, "%s/%i", + scm_to_locale_string(name), + scm_to_int(idx)); + fixd->fixtures[i].label = strdup(tmp); + + } else { + SCM name = scm_symbol_to_string(item); + fixd->fixtures[i].label = scm_to_locale_string(name); + } } } -static void show_help(const char *s) +static void process_line(SCM sexp, void *data) { - printf(_("Syntax: %s [options]\n\n"), s); - printf(_("Show fixtures in Starlet" - " -s, --socket REPL socket for Starlet process (default guile.socket).\n" - " -h, --help Display this help message.\n")); + struct fixture_display *fixd = data; + + if ( is_list(sexp) && scm_to_int(scm_length(sexp)) == 2 ) { + SCM tag = scm_list_ref(sexp, scm_from_int(0)); + SCM contents = scm_list_ref(sexp, scm_from_int(1)); + if ( scm_is_symbol(tag) ) { + if ( symbol_eq(tag, "patched-fixtures") ) { + handle_patched_fixtures(fixd, contents); + } + } + } } @@ -318,8 +369,8 @@ int main(int argc, char *argv[]) g_timeout_add(50, redraw_cb, &fixd); - fixd.repl = repl_connection_new(socket); - get_fixture_list(&fixd); + fixd.repl = repl_connection_new(socket, process_line, &fixd); + repl_send(fixd.repl, "(list 'patched-fixtures (patched-fixture-names))"); gtk_main(); |