summaryrefslogtreecommitdiffhomepage
path: root/mixguile
diff options
context:
space:
mode:
Diffstat (limited to 'mixguile')
-rw-r--r--mixguile/Makefile.am3
-rw-r--r--mixguile/mixguile.c41
-rw-r--r--mixguile/mixguile.h22
-rw-r--r--mixguile/mixguile_cmd_dispatcher.c148
-rw-r--r--mixguile/mixguile_cmd_dispatcher.h24
-rw-r--r--mixguile/xmixguile_cmd_dispatcher.c90
-rw-r--r--mixguile/xmixguile_cmd_dispatcher.h72
7 files changed, 384 insertions, 16 deletions
diff --git a/mixguile/Makefile.am b/mixguile/Makefile.am
index 15d6308..664c7cd 100644
--- a/mixguile/Makefile.am
+++ b/mixguile/Makefile.am
@@ -16,7 +16,8 @@ noinst_LIBRARIES = libmixguile.a
if MAKE_GUILE
libmixguile_a_SOURCES = mixguile.h mixguile.c \
- mixguile_cmd_dispatcher.h mixguile_cmd_dispatcher.c
+ mixguile_cmd_dispatcher.h mixguile_cmd_dispatcher.c \
+ xmixguile_cmd_dispatcher.h xmixguile_cmd_dispatcher.c
else
libmixguile_a_SOURCES =
diff --git a/mixguile/mixguile.c b/mixguile/mixguile.c
index 478c3d8..52321ca 100644
--- a/mixguile/mixguile.c
+++ b/mixguile/mixguile.c
@@ -1,7 +1,7 @@
/* -*-c-*- -------------- mixguile.c :
* Implementation of the functions declared in mixguile.h
* ------------------------------------------------------------------
- * Last change: Time-stamp: "01/08/21 02:26:10 jao"
+ * Last change: Time-stamp: "01/08/22 01:10:33 jao"
* ------------------------------------------------------------------
* Copyright (C) 2001 Free Software Foundation, Inc.
*
@@ -21,17 +21,16 @@
*
*/
-
+#include "mixguile_cmd_dispatcher.h"
#include "mixguile.h"
-static mixguile_cmd_dispatcher_t *dispatcher_;
+static mixguile_cmd_dispatcher_t *dispatcher_ = NULL;
static main_func_t main_fun_;
/* do local initialisation and enter the user provided main */
static void
real_main_ (int argc, char *argv[])
{
- dispatcher_ = mixguile_cmd_dispatcher_new ();
(*main_fun_)(argc, argv);
}
@@ -47,10 +46,40 @@ mixguile_init (int argc, char *argv[], main_func_t main_fun)
gh_enter (argc, argv, real_main_);
}
+/* enter the guile repl */
+void
+mixguile_enter_repl (int argc, char *argv[])
+{
+ mixguile_cmd_dispatcher_prepare (dispatcher_);
+ gh_repl (argc, argv);
+}
+
+/* set the command dispatcher */
+void
+mixguile_set_cmd_dispatcher (mix_vm_cmd_dispatcher_t *dis)
+{
+ g_return_if_fail (dis != NULL);
+ if (dispatcher_) mixguile_cmd_dispatcher_delete (dispatcher_);
+ dispatcher_ = mixguile_cmd_dispatcher_new (dis);
+ g_assert (dispatcher_);
+}
+
/* access the mixguile comand dispatcher */
-mixguile_cmd_dispatcher_t *
+mix_vm_cmd_dispatcher_t *
mixguile_get_cmd_dispatcher (void)
{
- return dispatcher_;
+ return mixguile_cmd_dispatcher_get_vm_dispatcher (dispatcher_);
+}
+
+/* execute a string or file using the guile interpreter */
+void
+mixguile_interpret_file (const gchar *path)
+{
+ mixguile_cmd_dispatcher_interpret_file (dispatcher_, path);
}
+void
+mixguile_interpret_command (const gchar *command)
+{
+ mixguile_cmd_dispatcher_interpret_command (dispatcher_, command);
+}
diff --git a/mixguile/mixguile.h b/mixguile/mixguile.h
index 319eb36..8897d29 100644
--- a/mixguile/mixguile.h
+++ b/mixguile/mixguile.h
@@ -1,7 +1,7 @@
/* -*-c-*- ---------------- mixguile.h :
* Interface to the mixguile interpreter.
* ------------------------------------------------------------------
- * Last change: Time-stamp: <01/08/21 02:26:18 jao>
+ * Last change: Time-stamp: <01/08/21 23:48:15 jao>
* ------------------------------------------------------------------
* Copyright (C) 2001 Free Software Foundation, Inc.
*
@@ -26,8 +26,8 @@
#define MIXGUILE_H
#include <mixlib/mix.h>
+#include <mixlib/mix_vm_command.h>
#include <guile/gh.h>
-#include "mixguile_cmd_dispatcher.h"
/* the main function type */
typedef void (*main_func_t) (int argc, char *argv[]);
@@ -39,10 +39,24 @@ typedef void (*main_func_t) (int argc, char *argv[]);
extern void
mixguile_init (int argc, char *argv[], main_func_t main_fun);
-/* access the mixguile comand dispatcher */
-extern mixguile_cmd_dispatcher_t *
+/* set the command dispatcher */
+extern void
+mixguile_set_cmd_dispatcher (mix_vm_cmd_dispatcher_t *dis);
+
+/* enter the guile repl */
+extern void
+mixguile_enter_repl (int argc, char *argv[]);
+
+/* access the comand dispatcher */
+extern mix_vm_cmd_dispatcher_t *
mixguile_get_cmd_dispatcher (void);
+/* execute a string or file using the guile interpreter */
+extern void
+mixguile_interpret_file (const gchar *path);
+
+extern void
+mixguile_interpret_command (const gchar *command);
#endif /* MIXGUILE_H */
diff --git a/mixguile/mixguile_cmd_dispatcher.c b/mixguile/mixguile_cmd_dispatcher.c
index 2d7161a..4676c43 100644
--- a/mixguile/mixguile_cmd_dispatcher.c
+++ b/mixguile/mixguile_cmd_dispatcher.c
@@ -1,7 +1,7 @@
/* -*-c-*- -------------- mixguile_cmd_dispatcher.c :
* Implementation of the functions declared in mixguile_cmd_dispatcher.h
* ------------------------------------------------------------------
- * Last change: Time-stamp: "01/08/21 02:27:50 jao"
+ * Last change: Time-stamp: "01/08/22 02:29:34 jao"
* ------------------------------------------------------------------
* Copyright (C) 2001 Free Software Foundation, Inc.
*
@@ -21,6 +21,150 @@
*
*/
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <guile/gh.h>
#include "mixguile.h"
-#include "mixguile_cmd_dispatcher.h"
+#include "xmixguile_cmd_dispatcher.h"
+
+/* create/destroy cmd dispatcher */
+mixguile_cmd_dispatcher_t *
+mixguile_cmd_dispatcher_new (mix_vm_cmd_dispatcher_t *dis)
+{
+ static gboolean REGISTERED = FALSE;
+ mixguile_cmd_dispatcher_t *result = NULL;
+ int fildes[2], r;
+ FILE *out;
+
+ g_return_val_if_fail (dis != NULL, NULL);
+
+ if (!REGISTERED)
+ {
+ register_scm_commands_ (DEFAULT_SCM_COMMANDS_);
+ REGISTERED = TRUE;
+ }
+
+ r = pipe (fildes);
+ g_return_val_if_fail (r == 0, NULL);
+ out = fdopen (fildes[1], "w");
+ g_return_val_if_fail (out != NULL, NULL);
+ r = fcntl (fildes[0], F_GETFL, 0);
+ g_return_val_if_fail (r != -1, NULL);
+ r = fcntl (fildes[0], F_SETFL, r | O_NONBLOCK);
+ g_return_val_if_fail (r != -1, NULL);
+
+ result = g_new (mixguile_cmd_dispatcher_t, 1);
+ result->dispatcher = dis;
+ result->err = result->out = NULL;
+ result->guile_out = out;
+ result->fildes[0] = fildes[0];
+ result->fildes[1] = fildes[1];
+ result->result = NULL;
+
+ register_cmd_dispatcher_ (result);
+
+ return result;
+}
+
+
+void
+mixguile_cmd_dispatcher_delete (mixguile_cmd_dispatcher_t *dis)
+{
+ g_return_if_fail (dis != NULL);
+ fclose (dis->guile_out);
+ close (dis->fildes[0]);
+ close (dis->fildes[1]);
+ mix_vm_cmd_dispatcher_delete (dis->dispatcher);
+}
+
+/* get the underlying vm dispatcher */
+mix_vm_cmd_dispatcher_t *
+mixguile_cmd_dispatcher_get_vm_dispatcher (const mixguile_cmd_dispatcher_t *dis)
+{
+ g_return_val_if_fail (dis != NULL, NULL);
+ return dis->dispatcher;
+}
+
+/* get the result string of last executed command */
+const gchar *
+mixguile_cmd_dispatcher_last_result (mixguile_cmd_dispatcher_t *dis)
+{
+ enum {BLKSIZE = 256};
+ static gchar BUFFER[BLKSIZE + 1];
+
+ ssize_t k;
+ gchar *tmp = NULL;
+
+ g_return_val_if_fail (dis != NULL, NULL);
+ if (dis->result) g_free (dis->result);
+ dis->result = NULL;
+ fflush (dis->guile_out);
+ while ((k = read (dis->fildes[0], BUFFER, BLKSIZE)) != 0)
+ {
+ if (k == -1 && errno != EINTR) break;
+ if (k != -1)
+ {
+ tmp = dis->result;
+ BUFFER[k] = '\0';
+ dis->result = g_strconcat (tmp ? tmp : "", BUFFER, NULL);
+ g_free (tmp);
+ }
+ }
+
+ if (dis->result && dis->result[strlen (dis->result) - 1] == '\n')
+ dis->result[strlen (dis->result) - 1] = '\0';
+
+ return dis->result;
+}
+
+/* prepare dispatcher for repl */
+static void
+prepare_dispatcher_ (mixguile_cmd_dispatcher_t *dis)
+{
+ dis->out = mix_vm_cmd_dispatcher_set_out_stream (dis->dispatcher,
+ dis->guile_out);
+ dis->err = mix_vm_cmd_dispatcher_set_error_stream (dis->dispatcher,
+ dis->guile_out);
+}
+
+void
+mixguile_cmd_dispatcher_prepare (mixguile_cmd_dispatcher_t *dis)
+{
+ g_return_if_fail (dis != NULL);
+ prepare_dispatcher_ (dis);
+}
+
+/* interpret commands from file or string */
+static void
+reset_dispatcher_ (mixguile_cmd_dispatcher_t *dis)
+{
+ (void) mix_vm_cmd_dispatcher_set_out_stream (dis->dispatcher, dis->out);
+ (void) mix_vm_cmd_dispatcher_set_error_stream (dis->dispatcher, dis->err);
+}
+
+
+void
+mixguile_cmd_dispatcher_interpret_file (mixguile_cmd_dispatcher_t *dis,
+ const gchar *path)
+{
+ g_return_if_fail (dis != NULL);
+ g_return_if_fail (path != NULL);
+ prepare_dispatcher_ (dis);
+ (void) gh_eval_file ((char *)path);
+ reset_dispatcher_ (dis);
+}
+
+void
+mixguile_cmd_dispatcher_interpret_command (mixguile_cmd_dispatcher_t *dis,
+ const gchar *command)
+{
+ g_return_if_fail (dis != NULL);
+ g_return_if_fail (command != NULL);
+ prepare_dispatcher_ (dis);
+ (void) gh_eval_str ((char *)command);
+ reset_dispatcher_ (dis);
+}
diff --git a/mixguile/mixguile_cmd_dispatcher.h b/mixguile/mixguile_cmd_dispatcher.h
index 5be1d13..4dba9d0 100644
--- a/mixguile/mixguile_cmd_dispatcher.h
+++ b/mixguile/mixguile_cmd_dispatcher.h
@@ -1,7 +1,7 @@
/* -*-c-*- ---------------- mixguile_cmd_dispatcher.h :
* Command dispatcher with guile support
* ------------------------------------------------------------------
- * Last change: Time-stamp: <01/08/21 02:24:45 jao>
+ * Last change: Time-stamp: <01/08/22 01:15:23 jao>
* ------------------------------------------------------------------
* Copyright (C) 2001 Free Software Foundation, Inc.
*
@@ -33,14 +33,32 @@ typedef struct mixguile_cmd_dispatcher_t mixguile_cmd_dispatcher_t;
/* create/destroy cmd dispatcher */
extern mixguile_cmd_dispatcher_t *
-mixguile_cmd_dispatcher_new (void);
+mixguile_cmd_dispatcher_new (mix_vm_cmd_dispatcher_t *dis);
extern void
mixguile_cmd_dispatcher_delete (mixguile_cmd_dispatcher_t *dis);
/* get the underlying vm dispatcher */
extern mix_vm_cmd_dispatcher_t *
-mixguile_cmd_dispatcher_get_vm_dispatcher (const mix_vm_cmd_dispatcher_t *disp);
+mixguile_cmd_dispatcher_get_vm_dispatcher (const
+ mixguile_cmd_dispatcher_t *disp);
+
+/* get the result string of last executed command */
+extern const gchar *
+mixguile_cmd_dispatcher_last_result (mixguile_cmd_dispatcher_t *disp);
+
+/* prepare dispatcher for repl */
+extern void
+mixguile_cmd_dispatcher_prepare (mixguile_cmd_dispatcher_t *dis);
+
+/* interpret commands from file or string */
+extern void
+mixguile_cmd_dispatcher_interpret_file (mixguile_cmd_dispatcher_t *dis,
+ const gchar *path);
+
+extern void
+mixguile_cmd_dispatcher_interpret_command (mixguile_cmd_dispatcher_t *dis,
+ const gchar *command);
#endif /* MIXGUILE_CMD_DISPATCHER_H */
diff --git a/mixguile/xmixguile_cmd_dispatcher.c b/mixguile/xmixguile_cmd_dispatcher.c
new file mode 100644
index 0000000..38a1200
--- /dev/null
+++ b/mixguile/xmixguile_cmd_dispatcher.c
@@ -0,0 +1,90 @@
+/* -*-c-*- -------------- xmixguile_cmd_dispatcher.c :
+ * Implementation of the functions declared in xmixguile_cmd_dispatcher.h
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: "01/08/21 23:55:06 jao"
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <mixlib/mix.h>
+#include <guile/gh.h>
+#include "xmixguile_cmd_dispatcher.h"
+
+/* cmd dispatcher for use within the scm commands */
+static mixguile_cmd_dispatcher_t *dispatcher_;
+static mix_vm_cmd_dispatcher_t *vm_dispatcher_;
+
+/* register a NULL-terminated list of scm commands */
+void
+register_scm_commands_ (const scm_command_t *commands)
+{
+ int k = 0;
+ g_return_if_fail (commands != NULL);
+ while (commands[k].name)
+ {
+ gh_new_procedure (commands[k].name, commands[k].func,
+ commands[k].argno, commands[k].opt_argno,
+ commands[k].restp);
+ ++k;
+ }
+}
+
+/* register the mixvm cmd dispatcher to use with commands */
+void
+register_cmd_dispatcher_ (mixguile_cmd_dispatcher_t *dis)
+{
+ g_return_if_fail (dis != NULL);
+ dispatcher_ = dis;
+ vm_dispatcher_ = mixguile_cmd_dispatcher_get_vm_dispatcher (dis);
+}
+
+/* commands */
+static SCM
+mix_command_ (SCM cmd, SCM arg)
+{
+ char *com, *argu;
+ int len;
+ gboolean result;
+
+ SCM_DEFER_INTS;
+ SCM_ASSERT (SCM_STRINGP (cmd), cmd, SCM_ARG1, "mix-command");
+ SCM_ASSERT (SCM_STRINGP (arg), arg, SCM_ARG2, "mix-command");
+ com = gh_scm2newstr (cmd, &len);
+ argu = gh_scm2newstr (arg, &len);
+ result = mix_vm_cmd_dispatcher_dispatch (vm_dispatcher_,
+ mix_vm_command_from_string (com),
+ argu);
+ g_free (com);
+ g_free (argu);
+ SCM_ALLOW_INTS;
+ com = (char *) mixguile_cmd_dispatcher_last_result (dispatcher_);
+ if (!com || strlen (com) == 0)
+ com = result? "ok" : "fail";
+ return gh_str02scm (com);
+}
+
+/* NULL-terminated list of available scm commands */
+const scm_command_t DEFAULT_SCM_COMMANDS_[] = {
+ {"mix-command", mix_command_, 2, 0, 0},
+ {NULL}
+};
+
+
+
+
+
diff --git a/mixguile/xmixguile_cmd_dispatcher.h b/mixguile/xmixguile_cmd_dispatcher.h
new file mode 100644
index 0000000..c399632
--- /dev/null
+++ b/mixguile/xmixguile_cmd_dispatcher.h
@@ -0,0 +1,72 @@
+/* -*-c-*- ---------------- xmixguile_cmd_dispatcher.h :
+ * Internal declarations for mixguile_cmd_dispatcher_t
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: <01/08/22 01:11:20 jao>
+ * ------------------------------------------------------------------
+ * Copyright (C) 2001 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+
+#ifndef XMIXGUILE_CMD_DISPATCHER_H
+#define XMIXGUILE_CMD_DISPATCHER_H
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <guile/gh.h>
+#include "mixguile_cmd_dispatcher.h"
+
+/* the cmd dispatcher type */
+struct mixguile_cmd_dispatcher_t
+{
+ mix_vm_cmd_dispatcher_t *dispatcher;
+ FILE *err; /* the vm dispatcher err stream */
+ FILE *out; /* the vm dispatcher out stream */
+ FILE *guile_out; /* output file of the dispatcher */
+ int fildes[2]; /* pipe for communication with dispatcher */
+ gchar *result; /* last result string */
+};
+
+/* scm commands types */
+/* prototype of a function implementing a new scm function */
+typedef SCM (*scm_func_t) ();
+
+/* record for a new scm command */
+typedef struct scm_command_t
+{
+ gchar *name; /* name of the scheme command */
+ scm_func_t func; /* implementation of the command */
+ int argno; /* no. of arguments */
+ int opt_argno; /* no. of optional arguments */
+ int restp; /* if 1, receive a list of remaining args */
+} scm_command_t;
+
+/* NULL-terminated list of available scm commands */
+extern const scm_command_t DEFAULT_SCM_COMMANDS_[];
+
+/* register a NULL-terminated list of scm commands */
+extern void
+register_scm_commands_ (const scm_command_t *commands);
+
+/* register the mixvm cmd dispatcher to use with commands */
+extern void
+register_cmd_dispatcher_ (mixguile_cmd_dispatcher_t *dis);
+
+
+#endif /* XMIXGUILE_CMD_DISPATCHER_H */
+