summaryrefslogtreecommitdiffhomepage
path: root/mixlib
diff options
context:
space:
mode:
authorJose Antonio Ortega Ruiz <jao@gnu.org>2001-07-19 00:24:23 +0000
committerJose Antonio Ortega Ruiz <jao@gnu.org>2001-07-19 00:24:23 +0000
commit9d46df7ae76533833c26df9f0b0bf24e086c25b2 (patch)
tree83c0375e6d4345a16035f7f756a156142e7e6e64 /mixlib
parentb18af386c53f81e31f98a1c1b699666ec69a7aa4 (diff)
downloadmdk-9d46df7ae76533833c26df9f0b0bf24e086c25b2.tar.gz
mdk-9d46df7ae76533833c26df9f0b0bf24e086c25b2.tar.bz2
cond bp support
Diffstat (limited to 'mixlib')
-rw-r--r--mixlib/Makefile.am5
-rw-r--r--mixlib/mix_config.c19
-rw-r--r--mixlib/mix_predicate.c207
-rw-r--r--mixlib/mix_predicate.h75
-rw-r--r--mixlib/mix_predicate_list.c111
-rw-r--r--mixlib/mix_predicate_list.h61
-rw-r--r--mixlib/mix_vm.c41
-rw-r--r--mixlib/mix_vm.h11
-rw-r--r--mixlib/mix_vm_command.c9
-rw-r--r--mixlib/xmix_vm.h3
10 files changed, 528 insertions, 14 deletions
diff --git a/mixlib/Makefile.am b/mixlib/Makefile.am
index 2c1f818..475fad3 100644
--- a/mixlib/Makefile.am
+++ b/mixlib/Makefile.am
@@ -29,7 +29,10 @@ libmix_a_SOURCES = mix.h mix.c \
mix_src_file.c mix_src_file.h \
mix_vm_clock.c mix_vm_clock.h \
mix_vm_command.c mix_vm_command.h \
- mix_config.c mix_config.h
+ mix_config.c mix_config.h \
+ mix_predicate.c mix_predicate.h \
+ mix_predicate_list.c mix_predicate_list.h
+
diff --git a/mixlib/mix_config.c b/mixlib/mix_config.c
index ba9ad19..fd3505e 100644
--- a/mixlib/mix_config.c
+++ b/mixlib/mix_config.c
@@ -143,24 +143,28 @@ mix_config_get_integer (const mix_config_t *config, const gchar *key)
void
mix_config_update (mix_config_t *config, const gchar *key, const gchar *value)
{
- gpointer tmp = NULL;
+ gpointer okey = NULL;
+ gpointer oval = NULL;
g_return_if_fail (config != NULL);
g_return_if_fail (key != NULL);
g_return_if_fail (value != NULL);
- tmp = g_hash_table_lookup (config->items, key);
- if (tmp)
+ if (g_hash_table_lookup_extended (config->items, key, &okey, &oval))
{
- g_free (tmp);
- tmp = (gpointer)key;
+ if (oval != value)
+ {
+ g_free (oval);
+ oval = (gpointer)g_strdup (value);
+ }
}
else
{
- tmp = (gpointer)g_strdup (key);
+ okey = (gpointer)g_strdup (key);
+ oval = (gpointer)g_strdup (value);
}
- g_hash_table_insert (config->items, tmp, g_strdup (value));
+ g_hash_table_insert (config->items, okey, oval);
}
void
@@ -170,7 +174,6 @@ mix_config_update_integer (mix_config_t *config, const gchar *key, gint value)
g_return_if_fail (config != NULL);
g_return_if_fail (key != NULL);
- g_return_if_fail (value != NULL);
val = g_strdup_printf ("%d", value);
mix_config_update (config, key, val);
diff --git a/mixlib/mix_predicate.c b/mixlib/mix_predicate.c
new file mode 100644
index 0000000..544da64
--- /dev/null
+++ b/mixlib/mix_predicate.c
@@ -0,0 +1,207 @@
+/* -*-c-*- -------------- mix_predicate.c :
+ * Implementation of the functions declared in mix_predicate.h
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: "2001-07-16 01:15:51 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 "mix_vm.h"
+#include "mix_predicate.h"
+
+/* predicate data */
+typedef union pred_data_t
+{
+ mix_word_t regA;
+ mix_word_t regX;
+ mix_short_t regI;
+ mix_cmpflag_t cmp;
+ gboolean over;
+ mix_word_t mem;
+} pred_data_t;
+
+/* the predicate function type */
+typedef gboolean (*mix_predicate_fun_t) (mix_predicate_t *pred,
+ const mix_vm_t *vm);
+
+/* the predicate type */
+struct mix_predicate_t
+{
+ mix_predicate_type_t type;
+ pred_data_t data;
+ guint control;
+};
+
+/* predicate funcs */
+static gboolean
+pred_func_rA (mix_predicate_t *pred, const mix_vm_t *vm)
+{
+ mix_word_t val = mix_vm_get_rA (vm);
+ if (pred->data.regA == val) return FALSE;
+ pred->data.regA = val;
+ return TRUE;
+}
+
+static gboolean
+pred_func_rX (mix_predicate_t *pred, const mix_vm_t *vm)
+{
+ mix_word_t val = mix_vm_get_rX (vm);
+ if (pred->data.regX == val) return FALSE;
+ pred->data.regX = val;
+ return TRUE;
+}
+
+static gboolean
+pred_func_rI (mix_predicate_t *pred, const mix_vm_t *vm)
+{
+ mix_short_t val = (pred->control == 0) ? mix_vm_get_rJ (vm)
+ : mix_vm_get_rI (vm, pred->control);
+ if (pred->data.regI == val) return FALSE;
+ pred->data.regI = val;
+ return TRUE;
+}
+
+static gboolean
+pred_func_mem (mix_predicate_t *pred, const mix_vm_t *vm)
+{
+ mix_word_t val =
+ mix_vm_get_addr_contents (vm, (mix_address_t)pred->control);
+ if (pred->data.mem == val) return FALSE;
+ pred->data.mem = val;
+ return TRUE;
+}
+
+static gboolean
+pred_func_cmp (mix_predicate_t *pred, const mix_vm_t *vm)
+{
+ mix_cmpflag_t val = mix_vm_get_cmpflag (vm);
+ if (pred->data.cmp == val) return FALSE;
+ pred->data.cmp = val;
+ return TRUE;
+}
+
+static gboolean
+pred_func_over (mix_predicate_t *pred, const mix_vm_t *vm)
+{
+ gboolean val = mix_vm_get_overflow (vm);
+ if (pred->data.over == val) return FALSE;
+ pred->data.over = val;
+ return TRUE;
+}
+
+static mix_predicate_fun_t PRED_FUNCS_[] = {
+ pred_func_rA, pred_func_rX, pred_func_rI, pred_func_rI, pred_func_rI,
+ pred_func_rI, pred_func_rI, pred_func_rI, pred_func_rI,
+ pred_func_over, pred_func_cmp, pred_func_mem
+};
+
+/* create predicates based on vm status */
+mix_predicate_t *
+mix_predicate_new (mix_predicate_type_t type)
+{
+ mix_predicate_t *result;
+ g_return_val_if_fail (type <= MIX_PRED_MEM, NULL);
+ result = g_new (mix_predicate_t, 1);
+ result->type = type;
+ result->data.regA = MIX_WORD_ZERO;
+ if (type >= MIX_PRED_REG_I1 && type <= MIX_PRED_REG_I6)
+ result->control = 1 + type - MIX_PRED_REG_I1;
+ else
+ result->control = 0;
+ return result;
+}
+
+/* delete a predicate */
+void
+mix_predicate_delete (mix_predicate_t *predicate)
+{
+ g_return_if_fail (predicate != NULL);
+ g_free (predicate);
+}
+
+/* test a predicate */
+gboolean
+mix_predicate_eval(mix_predicate_t *pred, const mix_vm_t *vm)
+{
+ g_return_val_if_fail (pred != NULL, FALSE);
+ g_return_val_if_fail (vm != NULL, FALSE);
+ return PRED_FUNCS_[pred->type] (pred, vm);
+}
+
+/* change mem address of a MIX_PRED_MEM predicate */
+void
+mix_predicate_set_mem_address (mix_predicate_t *predicate,
+ mix_address_t address)
+{
+ g_return_if_fail (predicate != NULL);
+ predicate->control = address;
+}
+
+/* get message about predicate evaluation */
+const gchar *
+mix_predicate_get_message (const mix_predicate_t *predicate)
+{
+ enum {SIZE = 256};
+ static gchar BUFFER[SIZE];
+ static const gchar *CMP_STRINGS[] = { "L", "E", "G"};
+
+ g_return_val_if_fail (predicate != NULL, NULL);
+
+ switch (predicate->type)
+ {
+ case MIX_PRED_REG_A:
+ snprintf (BUFFER, SIZE, "Register A changed to %s%d",
+ mix_word_is_negative (predicate->data.regA)? "-" : "+",
+ mix_word_magnitude (predicate->data.regA));
+ break;
+ case MIX_PRED_REG_X:
+ snprintf (BUFFER, SIZE, "Register X changed to %s%d",
+ mix_word_is_negative (predicate->data.regX)? "-" : "+",
+ mix_word_magnitude (predicate->data.regX));
+ break;
+ case MIX_PRED_REG_J:
+ snprintf (BUFFER, SIZE, "Register J changed to %d",
+ mix_short_magnitude (predicate->data.regI));
+ break;
+ case MIX_PRED_REG_I1: case MIX_PRED_REG_I2: case MIX_PRED_REG_I3:
+ case MIX_PRED_REG_I4: case MIX_PRED_REG_I5: case MIX_PRED_REG_I6:
+ snprintf (BUFFER, SIZE, "Register I%d changed to %s%d",
+ predicate->control,
+ mix_short_is_negative (predicate->data.regI)? "-" : "+",
+ mix_short_magnitude (predicate->data.regI));
+ break;
+ case MIX_PRED_CMP:
+ snprintf (BUFFER, SIZE, "Comparison flag changed to %s",
+ CMP_STRINGS[predicate->data.cmp]);
+ break;
+ case MIX_PRED_OVER:
+ snprintf (BUFFER, SIZE, "Overflow toggled %s",
+ predicate->data.over ? "ON" : "OFF");
+ break;
+ case MIX_PRED_MEM:
+ snprintf (BUFFER, SIZE, "Memory address %d changed to %s%d",
+ predicate->control,
+ mix_word_is_negative (predicate->data.mem)? "-" : "+",
+ mix_word_magnitude (predicate->data.mem));
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ return BUFFER;
+}
+
diff --git a/mixlib/mix_predicate.h b/mixlib/mix_predicate.h
new file mode 100644
index 0000000..df76afb
--- /dev/null
+++ b/mixlib/mix_predicate.h
@@ -0,0 +1,75 @@
+/* -*-c-*- ---------------- mix_predicate.h :
+ * Predicates and lists of predicates testing vm status.
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: <2001-07-13 22:32:42 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 MIX_PREDICATE_H
+#define MIX_PREDICATE_H
+
+#include "mix.h"
+#include "mix_types.h"
+#include "mix_ins.h"
+
+/* the predicate type */
+typedef struct mix_predicate_t mix_predicate_t;
+
+/* predicate types */
+typedef enum {
+ MIX_PRED_REG_A,
+ MIX_PRED_REG_X,
+ MIX_PRED_REG_J,
+ MIX_PRED_REG_I1,
+ MIX_PRED_REG_I2,
+ MIX_PRED_REG_I3,
+ MIX_PRED_REG_I4,
+ MIX_PRED_REG_I5,
+ MIX_PRED_REG_I6,
+ MIX_PRED_OVER,
+ MIX_PRED_CMP,
+ MIX_PRED_MEM
+} mix_predicate_type_t;
+
+/* create predicates based on vm status */
+extern mix_predicate_t *
+mix_predicate_new (mix_predicate_type_t type);
+
+/* delete a predicate */
+extern void
+mix_predicate_delete (mix_predicate_t *predicate);
+
+/* change mem address of a MIX_PRED_MEM predicate */
+extern void
+mix_predicate_set_mem_address (mix_predicate_t *predicate,
+ mix_address_t address);
+
+/* get message about predicate evaluation */
+extern const gchar *
+mix_predicate_get_message (const mix_predicate_t *predicate);
+
+/* test a predicate */
+#include "mix_vm.h"
+
+extern gboolean
+mix_predicate_eval(mix_predicate_t *pred, const mix_vm_t *vm);
+
+#endif /* MIX_PREDICATE_H */
+
diff --git a/mixlib/mix_predicate_list.c b/mixlib/mix_predicate_list.c
new file mode 100644
index 0000000..3e4fe08
--- /dev/null
+++ b/mixlib/mix_predicate_list.c
@@ -0,0 +1,111 @@
+/* -*-c-*- -------------- mix_predicate_list.c :
+ * Implementation of the functions declared in mix_predicate_list.h
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: "01/07/18 23:02:26 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 "mix_predicate_list.h"
+
+/* the predicate list type */
+struct mix_predicate_list_t
+{
+ GSList *predicates;
+ const mix_vm_t *vm;
+ const mix_predicate_t *last;
+};
+
+/* a list of predicates */
+mix_predicate_list_t *
+mix_predicate_list_new (const mix_vm_t *vm)
+{
+ mix_predicate_list_t *result;
+ g_return_val_if_fail (vm != NULL, NULL);
+ result = g_new (mix_predicate_list_t, 1);
+ result->predicates = NULL;
+ result->vm = vm;
+ result->last = NULL;
+ return result;
+}
+
+void
+mix_predicate_list_delete (mix_predicate_list_t *list)
+{
+ g_return_if_fail (list != NULL);
+ g_slist_free (list->predicates);
+ g_free (list);
+}
+
+/* evaluate the predicate list */
+gboolean
+mix_predicate_list_eval (mix_predicate_list_t *list)
+{
+ GSList *node;
+
+ g_return_val_if_fail (list != NULL, FALSE);
+ node = list->predicates;
+ while (node) {
+ mix_predicate_t *pred = (mix_predicate_t *)(node->data);
+ if (mix_predicate_eval (pred, list->vm))
+ {
+ list->last = pred;
+ return TRUE;
+ }
+ node = node->next;
+ }
+ list->last = NULL;
+ return FALSE;
+}
+
+/* add/remove predicates to the list */
+void
+mix_predicate_list_add (mix_predicate_list_t *list, mix_predicate_t *predicate)
+{
+ g_return_if_fail (list != NULL);
+ g_return_if_fail (predicate != NULL);
+ if (!g_slist_find (list->predicates, predicate))
+ list->predicates = g_slist_append (list->predicates, (gpointer)predicate);
+ (void)mix_predicate_eval (predicate, list->vm);
+}
+
+void
+mix_predicate_list_remove (mix_predicate_list_t *list,
+ mix_predicate_t *predicate)
+{
+ g_return_if_fail (list != NULL);
+ g_return_if_fail (predicate != NULL);
+ list->predicates = g_slist_remove (list->predicates, predicate);
+}
+
+void
+mix_predicate_list_clear (mix_predicate_list_t *list)
+{
+ g_return_if_fail (list != NULL);
+ g_slist_free (list->predicates);
+ list->predicates = NULL;
+ list->last = NULL;
+}
+
+const mix_predicate_t *
+mix_predicate_list_last_true_eval (const mix_predicate_list_t *list)
+{
+ g_return_val_if_fail (list != NULL, NULL);
+ return list->last;
+}
diff --git a/mixlib/mix_predicate_list.h b/mixlib/mix_predicate_list.h
new file mode 100644
index 0000000..416f3db
--- /dev/null
+++ b/mixlib/mix_predicate_list.h
@@ -0,0 +1,61 @@
+/* -*-c-*- ---------------- mix_predicate_list.h :
+ * A list of predicates.
+ * ------------------------------------------------------------------
+ * Last change: Time-stamp: <01/07/18 23:02:40 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 MIX_PREDICATE_LIST_H
+#define MIX_PREDICATE_LIST_H
+
+#include "mix.h"
+#include "mix_vm.h"
+#include "mix_predicate.h"
+
+/* the predicate list type */
+typedef struct mix_predicate_list_t mix_predicate_list_t;
+
+/* create/destroy a list of predicates */
+extern mix_predicate_list_t *
+mix_predicate_list_new (const mix_vm_t *vm);
+
+extern void
+mix_predicate_list_delete (mix_predicate_list_t *list);
+
+/* evaluate the predicate list */
+extern gboolean
+mix_predicate_list_eval (mix_predicate_list_t *list);
+
+extern const mix_predicate_t *
+mix_predicate_list_last_true_eval (const mix_predicate_list_t *list);
+
+/* add/remove predicates to the list */
+extern void
+mix_predicate_list_add (mix_predicate_list_t *list, mix_predicate_t *predicate);
+
+extern void
+mix_predicate_list_remove (mix_predicate_list_t *list,
+ mix_predicate_t *predicate);
+
+extern void
+mix_predicate_list_clear (mix_predicate_list_t *list);
+
+#endif /* MIX_PREDICATE_LIST_H */
+
diff --git a/mixlib/mix_vm.c b/mixlib/mix_vm.c
index f41c60a..8929527 100644
--- a/mixlib/mix_vm.c
+++ b/mixlib/mix_vm.c
@@ -65,7 +65,8 @@ vm_reset_reload_ (mix_vm_t *vm, gboolean is_reload)
mix_device_delete (vm->devices[k]);
vm->devices[k] = NULL;
}
- if (!is_reload) bp_clear_all_ (vm);
+ if (!is_reload)
+ mix_vm_clear_all_breakpoints (vm);
}
@@ -80,6 +81,7 @@ mix_vm_new (void)
vm->address_table = NULL;
vm->symbol_table = NULL;
vm->src_file = NULL;
+ vm->pred_list = mix_predicate_list_new (vm);
for (i = 0; i < BD_NO_; ++i)
vm->devices[i] = NULL;
@@ -451,6 +453,8 @@ mix_vm_run (mix_vm_t *vm)
update_time_ (vm, &ins);
if (bp_is_set_ (vm, get_loc_ (vm)))
return MIX_VM_BREAK;
+ if (mix_predicate_list_eval (get_pred_list_ (vm)))
+ return MIX_VM_COND_BREAK;
if (get_loc_ (vm) >= MIX_VM_CELL_NO) halt_ (vm, TRUE);
}
return MIX_VM_HALT;
@@ -470,7 +474,10 @@ mix_vm_exec_next (mix_vm_t *vm)
else
update_time_ (vm, &ins);
if (is_halted_ (vm)) return MIX_VM_HALT;
- return bp_is_set_ (vm, get_loc_ (vm)) ? MIX_VM_BREAK : MIX_VM_OK;
+ if (bp_is_set_ (vm, get_loc_ (vm))) return MIX_VM_BREAK;
+ if (mix_predicate_list_eval (get_pred_list_ (vm)))
+ return MIX_VM_COND_BREAK;
+ return MIX_VM_OK;
}
/* Breakpoints */
@@ -590,6 +597,36 @@ mix_vm_clear_all_breakpoints (mix_vm_t *vm)
{
g_return_if_fail (vm != NULL);
bp_clear_all_ (vm);
+ mix_predicate_list_clear (get_pred_list_ (vm));
+}
+
+
+gint
+mix_vm_set_conditional_breakpoint (mix_vm_t *vm, mix_predicate_t *pred)
+{
+ g_return_val_if_fail (vm != NULL, MIX_VM_BP_ERROR);
+ g_return_val_if_fail (pred != NULL, MIX_VM_BP_ERROR);
+ mix_predicate_list_add (get_pred_list_ (vm), pred);
+ return MIX_VM_BP_OK;
+}
+
+gint
+mix_vm_clear_conditional_breakpoint (mix_vm_t *vm, mix_predicate_t *pred)
+{
+ g_return_val_if_fail (vm != NULL, MIX_VM_BP_ERROR);
+ g_return_val_if_fail (pred != NULL, MIX_VM_BP_ERROR);
+ mix_predicate_list_remove (get_pred_list_ (vm), pred);
+ return MIX_VM_BP_OK;
+}
+
+const gchar *
+mix_vm_get_last_breakpoint_message (const mix_vm_t *vm)
+{
+ const mix_predicate_t *last = NULL;
+ g_return_val_if_fail (vm != NULL, NULL);
+ if ((last = mix_predicate_list_last_true_eval (get_pred_list_ (vm))) != NULL)
+ return mix_predicate_get_message (last);
+ return NULL;
}
/* Get the vm uptime, defined as the time spent executing instructions */
diff --git a/mixlib/mix_vm.h b/mixlib/mix_vm.h
index a8b826e..663062b 100644
--- a/mixlib/mix_vm.h
+++ b/mixlib/mix_vm.h
@@ -162,6 +162,7 @@ mix_vm_reset_program (mix_vm_t *vm);
enum {
MIX_VM_ERROR, /* error executing instructions */
MIX_VM_BREAK, /* breakpoint found */
+ MIX_VM_COND_BREAK, /* conditional breakpoint found */
MIX_VM_HALT, /* end of execution */
MIX_VM_OK /* successful instruction execution */
};
@@ -205,6 +206,16 @@ mix_vm_has_breakpoint_at_address (const mix_vm_t *vm, guint address);
extern void
mix_vm_clear_all_breakpoints (mix_vm_t *vm);
+#include "mix_predicate.h"
+extern gint
+mix_vm_set_conditional_breakpoint (mix_vm_t *vm, mix_predicate_t *pred);
+
+extern gint
+mix_vm_clear_conditional_breakpoint (mix_vm_t *vm, mix_predicate_t *pred);
+
+extern const gchar *
+mix_vm_get_last_breakpoint_message (const mix_vm_t *vm);
+
/* Get the vm uptime, defined as the time spent executing instructions */
extern mix_time_t
mix_vm_get_uptime (const mix_vm_t *vm);
diff --git a/mixlib/mix_vm_command.c b/mixlib/mix_vm_command.c
index bb4b67f..9344618 100644
--- a/mixlib/mix_vm_command.c
+++ b/mixlib/mix_vm_command.c
@@ -37,6 +37,9 @@
# include <readline/history.h>
#endif
+#ifdef HAVE_LIBREADLINE
+# include <readline/readline.h>
+#endif
/* hooks */
typedef struct
@@ -268,14 +271,14 @@ mix_vm_cmd_dispatcher_new_with_config (FILE *out, FILE *err,
val = mix_config_get (result->config, TIMING_KEY_);
if (val) cmd_timing_ (result, val);
val = mix_config_get_devices_dir (result->config);
- if (!val)
+ if (!val || !mix_stat_dir (val, "devices"))
{
gchar *dirname = g_dirname (mix_config_get_filename (config));
cmd_devdir_ (result, dirname);
g_free (dirname);
}
else
- cmd_devdir_ (result, val);
+ mix_device_set_dir (val);
#ifdef HAVE_LIBHISTORY
val = mix_config_get_history_file (result->config);
hsize = mix_config_get_history_size (result->config);
@@ -361,7 +364,7 @@ mix_vm_cmd_dispatcher_get_src_file_path (const mix_vm_cmd_dispatcher_t *dis)
g_free (PATH);
PATH = NULL;
}
-
+
if (f)
PATH = mix_file_complete_name (mix_src_file_get_path (f), MIX_SRC_DEFEXT);
diff --git a/mixlib/xmix_vm.h b/mixlib/xmix_vm.h
index d5cbff4..4ed1e42 100644
--- a/mixlib/xmix_vm.h
+++ b/mixlib/xmix_vm.h
@@ -29,6 +29,7 @@
#include "mix_symbol_table.h"
#include "mix_device.h"
#include "mix_src_file.h"
+#include "mix_predicate_list.h"
#include "mix_vm.h"
/* The mix_vm_t type */
@@ -50,6 +51,7 @@ struct mix_vm_t
mix_symbol_table_t *symbol_table;
mix_src_file_t *src_file; /* source of last loaded code file */
mix_device_factory_t factory; /* the factory for new devices */
+ mix_predicate_list_t *pred_list; /* predicates for conditional bps */
};
/* Macros for accessing/modifying the above structure.
@@ -72,6 +74,7 @@ enum { A_ = 0, X_, J_, I1_, I2_, I3_, I4_, I5_, I6_ };
#define get_over_(vm) (vm->overflow)
#define get_loc_(vm) (vm->loc_count)
#define get_clock_(vm) (vm->clock)
+#define get_pred_list_(vm) (vm->pred_list)
#define set_reg_(vm,r,x) \
do { \