[m-dev.] for review: sorting variables better in the debugger

Zoltan Somogyi zs at cs.mu.OZ.AU
Wed May 26 12:45:37 AEST 1999


This change addresses recent comments by our ARGo partners at Dassault.
It is for review by Erwan; i'd like him to check whether the external
debugger also works after this change (I can't easily test that myself).

Estimated hours taken: 12

Get the debugger to sort variables better.

trace/mercury_trace_vars.[ch]:
	A new module to manage the debugger's information about the variables
	live at the current program point (which can be defined as the
	combination of an specific event and an ancestor level).

	This new module centralizes the management of the (sorted) list of
	current variables. This in turn allows us to use a better sorting
	method, one that orders VarName15 correctly wrt both VarName2 and
	VarName.

	The new module also uses the type, not the name, of a variable
	to decide whether to exclude it from the list of variables
	that may be presented to the user (e.g. if it is a typeinfo
	or a typeclassinfo).

trace/mercury_trace_internal.c:
trace/mercury_trace_external.c:
	Use the new module's facilities. This factors out some "mostly"
	common code.

trace/Mmakefile:
	Add the new module.

runtime/mercury_layout_util.[ch]:
	Remove the code recently moved here from trace/mercury_trace_internal,
	as well as the filtered versions of some functions, since they are
	not needed anymore.

	Move the code for MR_make_var_list to trace/mercury_trace_external,
	since that is the only place where it is used (or is at all likely
	to be used). Since its new home is next to several very similar
	functions, this should also reduce the probability that any required
	maintenance will be overlooked. Also alter its coding style to conform
	to its new neighbours.

	Move the definition of MR_Var_Spec to trace/mercury_trace_vars.h.

tests/debugger/*.exp:
	Update the expected output files. In most cases, this is just because
	the new module outputs different white space, but in some cases, it
	also reflects that the debugger now prints variables in a different
	order.

Zoltan.

cvs diff: Diffing .
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/exceptions
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing library
cvs diff: Diffing lp_solve
cvs diff: Diffing profiler
cvs diff: Diffing runtime
Index: runtime/mercury_layout_util.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_layout_util.c,v
retrieving revision 1.9
diff -u -b -u -r1.9 mercury_layout_util.c
--- mercury_layout_util.c	1999/05/21 14:38:20	1.9
+++ mercury_layout_util.c	1999/05/25 09:10:52
@@ -107,88 +107,6 @@
 	}
 }
 
-Word
-MR_make_var_list(const MR_Stack_Layout_Label *layout, Word *saved_regs)
-{
-	const MR_Stack_Layout_Vars 	*vars;
-	int 				var_count;
-	int 				long_count;
-	const char			*name;
-
-	Word				univ_list;
-	Word				univ;
-	Word				value;
-	Word				type_info;
-	Word				*base_sp;
-	Word				*base_curfr;
-	Word				*type_params;
-
-	int				i;
-
-	vars = &layout->MR_sll_var_info;
-	var_count = MR_all_desc_var_count(vars);
-	long_count = MR_long_desc_var_count(vars);
-	base_sp = MR_saved_sp(saved_regs);
-	base_curfr = MR_saved_curfr(saved_regs);
-
-	/* build up the live variable list, starting from the end */
-	restore_transient_hp();
-	univ_list = list_empty();
-	save_transient_hp();
-
-	/* 
-	** If no information on live variables is available, return the 
-	** empty list.
-	*/
-	if (var_count <= 0) {
-		return univ_list;
-	} 
-		
-	type_params = MR_materialize_typeinfos_base(vars,
-	       	saved_regs, base_sp, base_curfr);
-    
-	for (i = var_count - 1; i >= 0; i--) {
-		/*
-		** Look up the name, the type and value
-		** (XXX we don't include the name or the inst
-		** in the list that we return)
-		*/
-
-		name = MR_name_if_present(vars, i);
-		if (! MR_get_type_and_value_filtered(vars, i, saved_regs,
-			name, type_params, &type_info, &value))
-		{
-			/*
-			** "variables" representing the saved values of
-			** succip, hp etc, which are the "variables" for which
-			** get_type_and_value fails, are not of interest to
-			** the user.
-			*/
-
-			continue;
-		}
-
-		/*
-		** Create a term of type `univ' to hold the type & value,
-		** and cons it onto the list.
-		** Note that the calls to save/restore_transient_hp()
-		** can't be hoisted out of the loop, because
-		** MR_get_type_and_value() calls MR_create_type_info()
-		** which may allocate memory using incr_saved_hp.
-		*/
-
-		restore_transient_hp();
-		incr_hp(univ, 2);
-		field(mktag(0), univ, UNIV_OFFSET_FOR_TYPEINFO) = type_info;
-		field(mktag(0), univ, UNIV_OFFSET_FOR_DATA) = value;
-		
-		univ_list = list_cons(univ, univ_list);
-		save_transient_hp();
-	}
-
-	return univ_list;
-}
-
 int
 MR_get_register_number_long(MR_Long_Lval locn)
 {
@@ -480,35 +398,6 @@
 	return TRUE;
 }
 
-/*
-** get_type_and_value() and get_type() will succeed to retrieve "variables"
-** beginning with `TypeInfo' and `TypeClassInfo'. As we can not print those
-** variables because of the fake arity of the type private_builtin:typeinfo/1,
-** we define filtered version of get_type_and_value() and get_type()
-** that will fail to retrieve such variables.
-*/
-
-bool
-MR_get_type_and_value_filtered(const MR_Stack_Layout_Vars *vars, int i,
-	Word *saved_regs, const char *name, Word *type_params, 
-	Word *type_info, Word *value)
-{
-	return ((strncmp(name, "TypeInfo", 8) != 0)
-	       && (strncmp(name, "TypeClassInfo", 13) != 0)
-	       && MR_get_type_and_value(vars, i, saved_regs, type_params,
-			type_info, value));
-}
-
-
-bool
-MR_get_type_filtered(const MR_Stack_Layout_Vars *vars, int i,
-	Word *saved_regs, const char *name, Word *type_params, Word *type_info)
-{
-	return ((strncmp(name, "TypeInfo", 8) != 0)
-	       && (strncmp(name, "TypeClassInfo", 13) != 0)
-	       && MR_get_type(vars, i, saved_regs, type_params, type_info));
-}
-
 void
 MR_write_variable(Word type_info, Word value)
 {
@@ -516,76 +405,4 @@
 
 	(*MR_io_stdout_stream)(&stdout_stream);
 	(*MR_io_print_to_stream)(type_info, stdout_stream, value);
-}
-
-/*
-** Find and validate the number of a variable given by a variable
-** specification in the given layout. If successful, store the
-** number of the variable in *which_var_ptr, and return a NULL 
-** string; otherwise return a string containing an error message.
-*/
-
-const char *
-MR_trace_find_var(const MR_Stack_Layout_Label *layout,
-	MR_Var_Spec var_spec, int *which_var_ptr)
-{
-	int		var_count;
-	const char 	*problem;
-
-	problem = MR_trace_validate_var_count(layout, &var_count);
-	if (problem != NULL) {
-		return problem;
-	}
-
-	if (var_spec.MR_var_spec_kind == VAR_NUMBER) {
-		*which_var_ptr = var_spec.MR_var_spec_number;
-		if (*which_var_ptr >= var_count) {
-			return "there is no such variable";
-		} else {
-			return NULL;	/* represents success */
-		}
-	} else if (var_spec.MR_var_spec_kind == VAR_NAME) {
-		const MR_Stack_Layout_Vars	*vars;
-		const char 			*name;
-		bool				collision = FALSE;
-		int				i;
-
-		vars = &layout->MR_sll_var_info;
-		*which_var_ptr = -1;
-		name = var_spec.MR_var_spec_name;
-		for (i = 0; i < var_count; i++) {
-			if (streq(name, MR_name_if_present(vars, i))) {
-				if (*which_var_ptr >= 0) {
-					collision = TRUE;
-				}
-
-				*which_var_ptr = i;
-			}
-		}
-
-		if (*which_var_ptr < 0) {
-			return "there is no variable with that name";
-		} else if (collision) {
-			return "variable name is not unique";
-		} else {
-			return NULL;	/* represents success */
-		}
-	} else {
-		return "internal error: bad var_spec kind";
-	}
-}
-
-const char *
-MR_trace_validate_var_count(const MR_Stack_Layout_Label *layout,
-	int *var_count_ptr)
-{
-	if (! MR_has_valid_var_count(&layout->MR_sll_var_info)) {
-		return "there is no information about live variables";
-	} else if (! MR_has_valid_var_info(&layout->MR_sll_var_info)) {
-		return "there are no live variables";
-	} else {
-		*var_count_ptr =
-			MR_all_desc_var_count(&layout->MR_sll_var_info);
-		return NULL;
-	}
 }
Index: runtime/mercury_layout_util.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_layout_util.h,v
retrieving revision 1.6
diff -u -b -u -r1.6 mercury_layout_util.h
--- mercury_layout_util.h	1999/05/21 14:38:20	1.6
+++ mercury_layout_util.h	1999/05/25 09:11:22
@@ -54,14 +54,6 @@
 			Word *base_sp, Word *base_curfr);
 
 /*
-** Given a stack layout and the saved copy of the registers,
-** get the values of the live variables as a list of univs.
-** Any memory needed is allocated on the Mercury heap.
-*/
-extern	Word	MR_make_var_list(const MR_Stack_Layout_Label *layout,
-			Word *saved_regs);
-
-/*
 ** If the given encoded location refers to a register, return its number.
 ** If it does not, return -1.
 */
@@ -111,10 +103,7 @@
 ** non-null.
 **
 ** MR_get_type and MR_get_type_base are similar but do not
-** return the value, whereas the functions with _filtered deliberately
-** do not suceed if the variable's name indicates that the value is likely
-** to be too big. This is a temporary measure only, until we get a better
-** term printer.
+** return the value.
 **
 ** All of these functions may need to allocate memory (to hold the
 ** type_infos that they return); any memory that they allocate will
@@ -133,13 +122,6 @@
 extern	bool	MR_get_type_base(const MR_Stack_Layout_Vars *vars, int var,
 			Word *saved_regs, Word *base_sp, Word *base_curfr,
 			Word *type_params, Word *type_info);
-extern	bool	MR_get_type_and_value_filtered(
-			const MR_Stack_Layout_Vars *vars, int var,
-			Word *saved_regs, const char *name,
-			Word *type_params, Word *type_info, Word *value);
-extern	bool	MR_get_type_filtered(const MR_Stack_Layout_Vars *vars, int var, 
-			Word *saved_regs, const char *name, Word *type_params, 
-			Word *type_info);
 
 /*
 ** MR_write_variable:
@@ -149,33 +131,5 @@
 */
 
 extern	void	MR_write_variable(Word type_info, Word value);
-
-/*
-** Type used in the term browser call
-*/
-
-typedef	enum {
-	VAR_NUMBER,
-	VAR_NAME
-} MR_Var_Spec_Kind;
-
-typedef struct {
-	MR_Var_Spec_Kind	MR_var_spec_kind;
-	int			MR_var_spec_number; /* valid if VAR_NUMBER */
-	const char		*MR_var_spec_name;  /* valid if VAR_NAME   */
-} MR_Var_Spec;
-
-/*
-** Find and validate the number of a variable given by a variable
-** specification in the given layout. If successful, store the
-** number of the variable in *which_var_ptr, and return a NULL 
-** string; otherwise return a string containing an error message.
-*/
-
-extern	const char *MR_trace_find_var(const MR_Stack_Layout_Label *layout,
-			MR_Var_Spec var_spec, int *which_var_ptr);
-
-extern	const char *MR_trace_validate_var_count(const MR_Stack_Layout_Label
-			*layout, int *var_count_ptr);
 
 #endif	/* MERCURY_LAYOUT_UTIL_H */
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing scripts
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
Index: tests/debugger/browser_test.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/browser_test.exp,v
retrieving revision 1.1
diff -u -b -u -r1.1 browser_test.exp
Index: tests/debugger/debugger_regs.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/debugger_regs.exp,v
retrieving revision 1.6
diff -u -b -u -r1.6 debugger_regs.exp
--- debugger_regs.exp	1999/04/08 16:03:36	1.6
+++ debugger_regs.exp	1999/05/25 09:00:52
@@ -7,6 +7,14 @@
        3:      2  2 EXIT pred debugger_regs:data/41-0 (det) 
 mdb> print *
        HeadVar__1           		[1, 2, 3, 4, 5]
+       HeadVar__2             	"a0"
+       HeadVar__3             	"a1"
+       HeadVar__4             	"a2"
+       HeadVar__5             	"a3"
+       HeadVar__6             	"a4"
+       HeadVar__7             	"a5"
+       HeadVar__8             	"a6"
+       HeadVar__9             	"a7"
        HeadVar__10          		"a8"
        HeadVar__11          		"a9"
        HeadVar__12          		"b0"
@@ -17,7 +25,6 @@
        HeadVar__17          		"b5"
        HeadVar__18          		"b6"
        HeadVar__19          		"b7"
-       HeadVar__2           		"a0"
        HeadVar__20          		"b8"
        HeadVar__21          		"b9"
        HeadVar__22          		"c0"
@@ -28,7 +35,6 @@
        HeadVar__27          		"c5"
        HeadVar__28          		"c6"
        HeadVar__29          		"c7"
-       HeadVar__3           		"a1"
        HeadVar__30          		"c8"
        HeadVar__31          		"c9"
        HeadVar__32          		"d0"
@@ -39,14 +45,8 @@
        HeadVar__37          		"d5"
        HeadVar__38          		"d6"
        HeadVar__39          		"d7"
-       HeadVar__4           		"a2"
        HeadVar__40          		"d8"
        HeadVar__41          		"d9"
-       HeadVar__5           		"a3"
-       HeadVar__6           		"a4"
-       HeadVar__7           		"a5"
-       HeadVar__8           		"a6"
-       HeadVar__9           		"a7"
 mdb> continue
 a0a1a2a3a4a5a6a7a8a9
 b0b1b2b3b4b5b6b7b8b9
Index: tests/debugger/existential_type_classes.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/existential_type_classes.exp,v
retrieving revision 1.6
diff -u -b -u -r1.6 existential_type_classes.exp
Index: tests/debugger/implied_instance.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/implied_instance.exp,v
retrieving revision 1.4
diff -u -b -u -r1.4 implied_instance.exp
Index: tests/debugger/interpreter.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/interpreter.exp,v
retrieving revision 1.8
diff -u -b -u -r1.8 interpreter.exp
Index: tests/debugger/multi_parameter.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/multi_parameter.exp,v
retrieving revision 1.5
diff -u -b -u -r1.5 multi_parameter.exp
Index: tests/debugger/queens.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/queens.exp,v
retrieving revision 1.10
diff -u -b -u -r1.10 queens.exp
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
Index: trace/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/Mmakefile,v
retrieving revision 1.9
diff -u -b -u -r1.9 Mmakefile
--- Mmakefile	1999/04/30 06:21:42	1.9
+++ Mmakefile	1999/05/25 02:05:25
@@ -46,7 +46,8 @@
 			mercury_trace_readline.h	\
 			mercury_trace_spy.h		\
 			mercury_trace_tables.h		\
-			mercury_trace_util.h
+			mercury_trace_util.h		\
+			mercury_trace_vars.h
 
 # keep this list in alphabetical order, please
 CFILES		= 	\
@@ -59,7 +60,8 @@
 			mercury_trace_internal.c	\
 			mercury_trace_readline.c	\
 			mercury_trace_spy.c		\
-			mercury_trace_tables.c
+			mercury_trace_tables.c		\
+			mercury_trace_vars.c
 
 # The object files in this directory depend on many of the header files
 # in the runtime. However, changes to many of these header files require
Index: trace/mercury_trace_external.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_external.c,v
retrieving revision 1.17
diff -u -b -u -r1.17 mercury_trace_external.c
--- mercury_trace_external.c	1999/05/21 14:38:21	1.17
+++ mercury_trace_external.c	1999/05/25 09:11:34
@@ -26,8 +26,8 @@
 #include "mercury_trace.h"
 #include "mercury_trace_external.h"
 #include "mercury_trace_util.h"
-#include "mercury_layout_util.h"
 #include "mercury_trace_browse.h"
+#include "mercury_trace_vars.h"
 
 #include "debugger_interface.h"
 #include "std_util.h"
@@ -114,12 +114,10 @@
 static void	MR_output_current_nth_var(Word var);
 static void	MR_output_current_live_var_names(Word var_names_list, 
 						 Word type_list);
-static Word	MR_trace_make_var_names_list(
-			const MR_Stack_Layout_Label *layout);
-static Word	MR_trace_make_type_list(const MR_Stack_Layout_Label *layout,
-			Word *saved_regs);
-static Word	MR_trace_make_nth_var(const MR_Stack_Layout_Label *layout, 
-			Word *saved_regs, Word debugger_request);
+static Word	MR_trace_make_var_list(void);
+static Word	MR_trace_make_var_names_list(void);
+static Word	MR_trace_make_type_list(void);
+static Word	MR_trace_make_nth_var(Word debugger_request);
 static int	MR_get_var_number(Word debugger_request);
 static void	MR_print_proc_id_to_socket(const MR_Stack_Layout_Entry *entry,
 			const char *extra, Word *base_sp, Word *base_curfr);
@@ -131,14 +129,7 @@
 static void	MR_get_mmc_options(Word debugger_request, 
 			String *mmc_options_ptr);
 static void	MR_get_variable_name(Word debugger_request, String *var_name_ptr);
-static void	MR_trace_browse_one_external(
-			const MR_Stack_Layout_Label *top_layout,
-			Word *saved_regs, int ancestor_level,
-			MR_Var_Spec which_var);
-static void	MR_trace_browse_var_external(const char *name, 
-			const MR_Stack_Layout_Vars *vars, int i, 
-			Word *saved_regs, Word *base_sp, Word *base_curfr, 
-			Word *type_params);
+static void	MR_trace_browse_one_external(MR_Var_Spec which_var);
 
 #if 0
 This pseudocode should go in the debugger process:
@@ -400,7 +391,6 @@
 	Word		*saved_regs = event_info->MR_saved_regs;
 	Integer		modules_list_length;
 	Word		modules_list;
-	int		ancestor_level;
 
 	/* 
 	** MR_mmc_options contains the options to pass to mmc when compiling 
@@ -409,8 +399,8 @@
 	static String	MR_mmc_options;
 	MR_TRACE_CALL_MERCURY(ML_DI_init_mercury_string(&MR_mmc_options));
 
-	/* by default, print variables from the current call */
-	ancestor_level = 0;
+	MR_trace_init_point_vars(event_info->MR_event_sll,
+		event_info->MR_saved_regs);
 
 	event_details.MR_call_seqno = MR_trace_call_seqno;
 	event_details.MR_call_depth = MR_trace_call_depth;
@@ -455,9 +445,8 @@
 						"_NAMES\n");
 				}
 				var_names_list = 
-				  MR_trace_make_var_names_list(layout);
-				type_list = MR_trace_make_type_list(layout,
-						saved_regs);
+					MR_trace_make_var_names_list();
+				type_list = MR_trace_make_type_list();
 				MR_output_current_live_var_names(var_names_list,
 					type_list);
 				break;
@@ -467,9 +456,9 @@
 					fprintf(stderr, "\nMercury runtime: "
 						"REQUEST_CURRENT_VARS\n");
 				}
-				var_list = MR_make_var_list(layout, saved_regs);
+				var_list = MR_trace_make_var_list();
 				var_names_list = 
-				  MR_trace_make_var_names_list(layout);
+					MR_trace_make_var_names_list();
 				MR_output_current_vars(var_list, 
 						       var_names_list);
 				break;
@@ -479,8 +468,7 @@
 					fprintf(stderr, "\nMercury runtime: "
 						"REQUEST_NTH_CURRENT_VAR\n");
 				}
-				var = MR_trace_make_nth_var(layout, saved_regs,
-							    debugger_request);
+				var = MR_trace_make_nth_var(debugger_request);
 				MR_output_current_nth_var(var);
 				break;			
 			case MR_REQUEST_CURRENT_SLOTS:
@@ -630,10 +618,9 @@
 				}
 				MR_get_variable_name(debugger_request, 
 					&var_name);
-				var_spec.MR_var_spec_kind = VAR_NAME;
+				var_spec.MR_var_spec_kind = MR_VAR_SPEC_NAME;
 				var_spec.MR_var_spec_name = var_name;
-				MR_trace_browse_one_external(layout, saved_regs,
-					ancestor_level, var_spec);
+				MR_trace_browse_one_external(var_spec);
 				MR_send_message_to_socket("browser_end");
 				break;
 			  }
@@ -657,8 +644,6 @@
 	return jumpaddr;
 }
 
-
-
 static void
 MR_output_current_slots(const MR_Stack_Layout_Label *layout,
 	MR_Trace_Port port, Unsigned seqno, Unsigned depth, const char *path)
@@ -754,7 +739,6 @@
     );
 }
  
-
 static bool
 MR_found_match(const MR_Stack_Layout_Label *layout,
 	MR_Trace_Port port, Unsigned seqno, Unsigned depth,
@@ -824,8 +808,6 @@
        	MR_debugger_socket_out.line_number++;
 }
 
-
-
 static void
 MR_send_message_to_socket(const char *message)
 {
@@ -834,96 +816,120 @@
 	MR_debugger_socket_out.line_number++;
 }
 
+/*
+** This function returns the list of the currently live variables
+** as a list of univs.
+** The memory needed will be allocated on the Mercury heap.
+**
+** If no information on live variables is available, or if there
+** are no live variables, return the empty list.
+*/
+
+static Word
+MR_trace_make_var_list(void)
+{
+	const char	*problem;
+	int		var_count;
+	int		i;
+	Word		type_info;
+	Word		value;
+	Word		univ;
+	Word		var_list;
+
+	var_count = MR_trace_var_count();
+
+	MR_TRACE_USE_HP(
+		var_list = list_empty();
+	);
+
+	for (i = var_count - 1; i >= 0; i--) {
+		problem = MR_trace_return_var_info(i, NULL,
+				&type_info, &value);
+		if (problem != NULL) {
+			fatal_error(problem);
+		}
+
+		MR_TRACE_USE_HP(
+			incr_hp(univ, 2);
+		);
+
+		field(mktag(0), univ, UNIV_OFFSET_FOR_TYPEINFO) = type_info;
+		field(mktag(0), univ, UNIV_OFFSET_FOR_DATA) = value;
+
+		MR_TRACE_USE_HP(
+			var_list = list_cons(univ, var_list);
+		);
+	}
 
+	return var_list;
+}
+
 /*
 ** This function returns the list of the internal names of currently live
 ** variables.
 ** The memory needed will be allocated on the Mercury heap.
+**
+** If no information on live variables is available, or if there
+** are no live variables, return the empty list.
 */
 
 static Word
-MR_trace_make_var_names_list(const MR_Stack_Layout_Label *layout)
+MR_trace_make_var_names_list(void)
 {
+	const char	*problem;
 	int 				var_count;
-	const MR_Stack_Layout_Vars 	*vars;
 	int				i;
 	const char			*name;
-
 	Word				var_names_list;
 
-	vars = &layout->MR_sll_var_info;
-	var_count = MR_all_desc_var_count(vars);
+	var_count = MR_trace_var_count();
 
     MR_TRACE_USE_HP(
 	var_names_list = list_empty();
+	);
+
 	for (i = var_count - 1; i >= 0; i--) {
-		name = MR_name_if_present(vars, i);
-		/*
-		** XXX The printing of type_infos is buggy at the moment
-		** due to the fake arity of the type private_builtin:typeinfo/1.
-		*/
-		if ((strncmp(name, "TypeInfo", 8) == 0)
-			|| (strncmp(name, "TypeClassInfo", 13) == 0))
-		{
-			continue;
+		problem = MR_trace_return_var_info(i, &name, NULL, NULL);
+		if (problem != NULL) {
+			fatal_error(problem);
 		}
 
+		MR_TRACE_USE_HP(
 		var_names_list = list_cons(name, var_names_list);
-	}
     );
+	}
 
 	return var_names_list;
 }
 
-
 /*
 ** This function returns the list of types of currently live variables.
 ** The memory needed will be allocated on the Mercury heap.
+**
+** If no information on live variables is available, or if there
+** are no live variables, return the empty list.
 */
 
 static Word
-MR_trace_make_type_list(const MR_Stack_Layout_Label *layout, Word *saved_regs)
+MR_trace_make_type_list(void)
 {
+	const char	*problem;
 	int 				var_count;
-	const MR_Stack_Layout_Vars 	*vars;
 	int				i;
-	const char			*name;
 	Word				type_info;
 	String		      		type_info_string;
-	Word				*base_sp;
-	Word				*base_curfr;
-	Word				*type_params;
-
 	Word				type_list;
-
-	vars = &layout->MR_sll_var_info;
-	var_count = MR_all_desc_var_count(vars);
 
-	base_sp = MR_saved_sp(saved_regs);
-	base_curfr = MR_saved_curfr(saved_regs);
+	var_count = MR_trace_var_count();
 
         MR_TRACE_USE_HP(
 		type_list = list_empty();
         );
 
-	/* 
-	** If no information on live variables is available, or if there
-	** are no live variables, return the empty list.
-	*/
-	if (! MR_has_valid_var_info(vars)) {
-		return type_list;
-	}
-
-	type_params = MR_materialize_typeinfos_base(vars,
-	      	saved_regs, base_sp, base_curfr);
-
 	for (i = var_count - 1; i >= 0; i--) {
-
-		name = MR_name_if_present(vars, i);
-		if (! MR_get_type_filtered(vars, i, saved_regs,
-			name, type_params, &type_info))
-		{
-			continue;
+		problem = MR_trace_return_var_info(i, NULL, &type_info, NULL);
+		if (problem != NULL) {
+			fatal_error(problem);
 		}
 
 		MR_TRACE_CALL_MERCURY(
@@ -937,53 +943,30 @@
 	return type_list;
 }
 
-
 /*
 ** This function returns the requested live variable, as a univ.
 ** Any memory needed will be allocated on the Mercury heap.
 */
 
 static Word
-MR_trace_make_nth_var(const MR_Stack_Layout_Label *layout, Word *saved_regs,
-		      Word debugger_request)
+MR_trace_make_nth_var(Word debugger_request)
 {
+	const char	*problem;
 	int 				var_number;
-	const MR_Stack_Layout_Vars 	*vars;
-	const char			*name;
-	Word				value;
 	Word				type_info;
-	Word				*base_sp;
-	Word				*base_curfr;
-	Word				*type_params;
-
+	Word		value;
 	Word				univ;
 
 	var_number = MR_get_var_number(debugger_request);
 		/* debugger_request should be of the form: 
 		   current_nth_var(var_number) */
-	vars = &layout->MR_sll_var_info;
-	name = MR_name_if_present(vars, var_number);
-	base_sp = MR_saved_sp(saved_regs);
-	base_curfr = MR_saved_curfr(saved_regs);
-	
-	/*
-	** Should never occur since we check in the external debugger
-	** process if a variable is live before retrieving it.
-	*/
-	if (! MR_has_valid_var_info(vars)) {
-		fatal_error("try to retrieve a non-live variable");
-	}
-
-       	type_params = MR_materialize_typeinfos_base(vars,
-	       	saved_regs, base_sp, base_curfr);
-
 	MR_TRACE_USE_HP(
 		incr_hp(univ, 2);
 	);
 
-	if (MR_get_type_and_value_filtered(vars, var_number, saved_regs, name,
-			type_params, &type_info, &value))
-	{
+	problem = MR_trace_return_var_info(var_number, NULL,
+			&type_info, &value);
+	if (problem == NULL) {
 		field(mktag(0), univ, UNIV_OFFSET_FOR_TYPEINFO) = type_info;
 		field(mktag(0), univ, UNIV_OFFSET_FOR_DATA) = value;
 	} else {
@@ -991,13 +974,12 @@
 		** Should never occur since we check in the external debugger
 		** process if a variable is live before retrieving it.
 		*/
-		fatal_error("try to retrieve a non-live variable");
+		fatal_error(problem);
 	}
 
 	return univ;
 }
 
-
 /*
 ** This function is called only when debugger_request = current_nth_var(n).
 ** It returns the integer 'n'.  
@@ -1048,7 +1030,6 @@
 	MR_print_proc_id_to_socket(entry_layout, NULL, base_sp, base_curfr);
 }
 
-
 static void
 MR_print_proc_id_to_socket(const MR_Stack_Layout_Entry *entry,
 	const char *extra, Word *base_sp, Word *base_curfr)
@@ -1189,7 +1170,6 @@
 		);
 }
 
-
 /*
 ** This function does the same thing as MR_trace_browse_one() defined in 
 ** mercury_trace_internal.c except it sends/receives program-readable terms
@@ -1198,85 +1178,16 @@
 */
 
 static void
-MR_trace_browse_one_external(const MR_Stack_Layout_Label *top_layout,
-	Word *saved_regs, int ancestor_level, MR_Var_Spec var_spec)
+MR_trace_browse_one_external(MR_Var_Spec var_spec)
 {
-	const MR_Stack_Layout_Label	*level_layout;
-	Word				*base_sp;
-	Word				*base_curfr;
-	Word				*type_params;
-	Word				*valid_saved_regs;
-	int				which_var;
-	const MR_Stack_Layout_Vars	*vars;
 	const char 			*problem;
-
-	base_sp = MR_saved_sp(saved_regs);
-	base_curfr = MR_saved_curfr(saved_regs);
-	level_layout = MR_find_nth_ancestor(top_layout, ancestor_level,
-				&base_sp, &base_curfr, &problem);
 
-	if (level_layout == NULL) {
-		MR_send_message_to_socket_format("error(\"%s\").\n", problem);
-		return;
-	}
+	problem = MR_trace_browse_one(NULL, var_spec, MR_trace_browse_external,
+			TRUE);
 
-	problem = MR_trace_find_var(level_layout, var_spec, &which_var);
 	if (problem != NULL) {
 		MR_send_message_to_socket_format("error(\"%s\").\n", problem);
-		return;
-	}
-
-	if (ancestor_level == 0) {
-		valid_saved_regs = saved_regs;
-	} else {
-		valid_saved_regs = NULL;
 	}
-	vars = &level_layout->MR_sll_var_info;
-	type_params = MR_materialize_typeinfos_base(vars,
-				valid_saved_regs, base_sp, base_curfr);
-	MR_trace_browse_var_external(MR_name_if_present(vars, which_var),
-		vars, which_var, valid_saved_regs,
-		base_sp, base_curfr, type_params);
-	free(type_params);
 }
-
-
-/*
-** This function does the same thing as MR_trace_browse_var() defined in 
-** mercury_trace_internal.c except it always calls the term browser and it  
-** calls MR_trace_browse_external() instead of MR_trace_browse().
-*/
-
-static void
-MR_trace_browse_var_external(const char *name, const MR_Stack_Layout_Vars *vars,
-	int i, Word *saved_regs, Word *base_sp, Word *base_curfr, 
-	Word *type_params)
-{
-	Word	value;
-	Word	type_info;
-	bool	print_value;
-
-	/*
-	** XXX The printing of type_infos is buggy at the moment
-	** due to the fake arity of the type private_builtin:typeinfo/1.
-	*/
-
-	if ((strncmp(name, "TypeInfo", 8) == 0)
-	|| (strncmp(name, "TypeClassInfo", 13) == 0))
-		return;
-
-	/*
-	** "variables" representing the saved values of succip, hp etc,
-	** which are the "variables" for which get_type_and_value fails,
-	** are not of interest to the user.
-	*/
-
-	print_value = MR_get_type_and_value_base(vars, i, saved_regs,
-			base_sp, base_curfr, type_params, &type_info, &value);
-	if (print_value) {
-		MR_trace_browse_external(type_info, value);		
-	}
-}
-
 
 #endif /* MR_USE_EXTERNAL_DEBUGGER */
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.43
diff -u -b -u -r1.43 mercury_trace_internal.c
--- mercury_trace_internal.c	1999/05/21 14:38:20	1.43
+++ mercury_trace_internal.c	1999/05/25 09:47:41
@@ -20,6 +20,7 @@
 #include "mercury_trace_spy.h"
 #include "mercury_trace_tables.h"
 #include "mercury_trace_util.h"
+#include "mercury_trace_vars.h"
 #include "mercury_trace_readline.h"
 #include "mercury_layout_util.h"
 #include "mercury_array_macros.h"
@@ -134,12 +135,10 @@
 static	void	MR_trace_internal_init_from_home_dir(void);
 static	MR_Next	MR_trace_debug_cmd(char *line, MR_Trace_Cmd_Info *cmd,
 			MR_Event_Info *event_info, 
-			MR_Event_Details *event_details, int *ancestor_level,
-			Code **jumpaddr);
+			MR_Event_Details *event_details, Code **jumpaddr);
 static	MR_Next	MR_trace_handle_cmd(char **words, int word_count,
 			MR_Trace_Cmd_Info *cmd, MR_Event_Info *event_info,
-			MR_Event_Details *event_details, int *ancestor_level,
-			Code **jumpaddr);
+			MR_Event_Details *event_details, Code **jumpaddr);
 static	bool	MR_trace_options_strict_print(MR_Trace_Cmd_Info *cmd,
 			char ***words, int *word_count,
 			const char *cat, const char *item);
@@ -159,24 +158,12 @@
 			const MR_Stack_Layout_Entry *entry,
 			const MR_Stack_Layout_Label *label);
 static	void	MR_print_spy_point(int i);
-static	void	MR_trace_list_vars(const MR_Stack_Layout_Label *top_layout,
-			Word *saved_regs, int ancestor_level);
-static	void	MR_trace_set_level(const MR_Stack_Layout_Label *top_layout,
-			Word *saved_regs, int *ancestor_level,
-			int new_ancestor_level);
-static	const char *MR_trace_browse_check_level(const MR_Stack_Layout_Label
-			*top_layout, Word *saved_regs, int ancestor_level);
-static	void	MR_trace_browse_one(const MR_Stack_Layout_Label *top_layout,
-			Word *saved_regs, int ancestor_level,
-			MR_Var_Spec which_var, bool browse);
-static	void	MR_trace_browse_all(const MR_Stack_Layout_Label *top_layout,
-			Word *saved_regs, int ancestor_level);
-static	void	MR_trace_browse_var(const char *name,
-			const MR_Stack_Layout_Vars *vars, int i,
-			Word *saved_regs, Word *base_sp, Word *base_curfr,
-			Word *type_params, bool browse);
 static	void	MR_trace_do_noop(void);
 
+static	void	MR_trace_set_level_and_report(int ancestor_level);
+static	void	MR_trace_print_var(Word type_info, Word value);
+static	void	MR_trace_browse_var(Word type_info, Word value);
+
 static	const char *MR_trace_read_help_text(void);
 static	bool	MR_trace_is_number(const char *word, int *value);
 static	bool	MR_trace_is_number_prefix(char *word, char **suffix,
@@ -207,7 +194,6 @@
 	int			c;
 	int			count;
 	bool			count_given;
-	int			ancestor_level;
 	Code			*jumpaddr;
 	char			*line;
 	MR_Next			res;
@@ -240,8 +226,8 @@
 	event_details.MR_call_depth = MR_trace_call_depth;
 	event_details.MR_event_number = MR_trace_event_number;
 
-	/* by default, print variables from the current call */
-	ancestor_level = 0;
+	MR_trace_init_point_vars(event_info->MR_event_sll,
+		event_info->MR_saved_regs);
 
 	/* by default, return where we came from */
 	jumpaddr = NULL;
@@ -249,7 +235,7 @@
 	do {
 		line = MR_trace_getline("mdb> ");
 		res = MR_trace_debug_cmd(line, cmd, event_info, &event_details,
-				&ancestor_level, &jumpaddr);
+				&jumpaddr);
 	} while (res == KEEP_INTERACTING);
 
 	cmd->MR_trace_must_check = (! cmd->MR_trace_strict) ||
@@ -372,6 +358,43 @@
 }
 
 static void
+MR_trace_set_level_and_report(int ancestor_level)
+{
+	const char			*problem;
+	const MR_Stack_Layout_Entry	*entry;
+	Word				*base_sp;
+	Word				*base_curfr;
+
+	problem = MR_trace_set_level(ancestor_level);
+	if (problem == NULL) {
+		MR_trace_current_level_details(&entry, &base_sp, &base_curfr);
+		fprintf(MR_mdb_out, "%4d ", ancestor_level);
+		MR_print_proc_id(MR_mdb_out, entry, "", base_sp, base_curfr);
+		fprintf(MR_mdb_out, "Ancestor level set to %d.\n",
+			ancestor_level);
+	} else {
+		fflush(MR_mdb_out);
+		fprintf(MR_mdb_err, "%s.\n", problem);
+	}
+}
+
+static void
+MR_trace_print_var(Word type_info, Word value)
+{
+	fprintf(MR_mdb_out, "\t");
+	fflush(MR_mdb_out);
+	/* XXX should use MR_mdb_out */
+	MR_trace_print(type_info, value);
+}
+
+static void
+MR_trace_browse_var(Word type_info, Word value)
+{
+	/* XXX should use MR_mdb_in and MR_mdb_out */
+	MR_trace_browse(type_info, value);
+}
+
+static void
 MR_trace_do_noop(void)
 {
 	fflush(MR_mdb_out);
@@ -398,7 +421,7 @@
 static MR_Next
 MR_trace_debug_cmd(char *line, MR_Trace_Cmd_Info *cmd,
 	MR_Event_Info *event_info, MR_Event_Details *event_details,
-	int *ancestor_level, Code **jumpaddr)
+	Code **jumpaddr)
 {
 	char		**words;
 	char		**orig_words = NULL;
@@ -459,7 +482,7 @@
 		** Call the command dispatcher
 		*/
 		next = MR_trace_handle_cmd(words, word_count, cmd,
-			event_info, event_details, ancestor_level, jumpaddr);
+			event_info, event_details, jumpaddr);
 	}
 
 	free(line);
@@ -476,7 +499,7 @@
 static MR_Next
 MR_trace_handle_cmd(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
 	MR_Event_Info *event_info, MR_Event_Details *event_details,
-	int *ancestor_level, Code **jumpaddr)
+	Code **jumpaddr)
 {
 	const MR_Stack_Layout_Label
 		*layout = event_info->MR_event_sll;
@@ -707,58 +730,68 @@
 	} else if (streq(words[0], "level")) {
 		int	n;
 		if (word_count == 2 && MR_trace_is_number(words[1], &n)) {
-			MR_trace_set_level(layout, saved_regs, ancestor_level,
-				n);
+			MR_trace_set_level_and_report(n);
 		} else {
 			MR_trace_usage("browsing", "level");
 		}
 	} else if (streq(words[0], "up")) {
 		int	n;
 		if (word_count == 2 && MR_trace_is_number(words[1], &n)) {
-			MR_trace_set_level(layout, saved_regs, ancestor_level,
-				*ancestor_level + n);
+			MR_trace_set_level_and_report(
+				MR_trace_current_level() + n);
 		} else if (word_count == 1) {
-			MR_trace_set_level(layout, saved_regs, ancestor_level,
-				*ancestor_level + 1);
+			MR_trace_set_level_and_report(
+				MR_trace_current_level() + 1);
 		} else {
 			MR_trace_usage("browsing", "up");
 		}
 	} else if (streq(words[0], "down")) {
 		int	n;
 		if (word_count == 2 && MR_trace_is_number(words[1], &n)) {
-			MR_trace_set_level(layout, saved_regs, ancestor_level,
-				*ancestor_level - n);
+			MR_trace_set_level_and_report(
+				MR_trace_current_level() - n);
 		} else if (word_count == 1) {
-			MR_trace_set_level(layout, saved_regs, ancestor_level,
-				*ancestor_level - 1);
+			MR_trace_set_level_and_report(
+				MR_trace_current_level() - 1);
 		} else {
 			MR_trace_usage("browsing", "down");
 		}
 	} else if (streq(words[0], "vars")) {
 		if (word_count == 1) {
-			MR_trace_list_vars(layout, saved_regs,
-				*ancestor_level);
+			const char	*problem;
+
+			problem = MR_trace_list_vars(MR_mdb_out);
+			if (problem != NULL) {
+				fflush(MR_mdb_out);
+				fprintf(MR_mdb_err, "mdb: %s.\n", problem);
+			}
 		} else {
 			MR_trace_usage("browsing", "vars");
 		}
 	} else if (streq(words[0], "print")) {
 		if (word_count == 2) {
 			MR_Var_Spec	var_spec;
+			const char	*problem;
 			int		n;
 
 			if streq(words[1], "*") {
-				MR_trace_browse_all(layout, saved_regs,
-					*ancestor_level);
+				problem = MR_trace_browse_all(MR_mdb_out,
+					MR_mdb_err, MR_trace_print_var);
 			} else if (MR_trace_is_number(words[1], &n)) {
-				var_spec.MR_var_spec_kind = VAR_NUMBER;
+				var_spec.MR_var_spec_kind = MR_VAR_SPEC_NUMBER;
 				var_spec.MR_var_spec_number = n;
-				MR_trace_browse_one(layout, saved_regs,
-					*ancestor_level, var_spec, FALSE);
+				problem = MR_trace_browse_one(MR_mdb_out,
+					var_spec, MR_trace_print_var, FALSE);
 			} else {
-				var_spec.MR_var_spec_kind = VAR_NAME;
+				var_spec.MR_var_spec_kind = MR_VAR_SPEC_NAME;
 				var_spec.MR_var_spec_name = words[1];
-				MR_trace_browse_one(layout, saved_regs,
-					*ancestor_level, var_spec, FALSE);
+				problem = MR_trace_browse_one(MR_mdb_out,
+					var_spec, MR_trace_print_var, FALSE);
+			}
+
+			if (problem != NULL) {
+				fflush(MR_mdb_out);
+				fprintf(MR_mdb_err, "mdb: %s.\n", problem);
 			}
 		} else {
 			MR_trace_usage("browsing", "print");
@@ -766,18 +799,24 @@
 	} else if (streq(words[0], "browse")) {
 		if (word_count == 2) {
 			MR_Var_Spec	var_spec;
+			const char	*problem;
 			int		n;
 
 			if (MR_trace_is_number(words[1], &n)) {
-				var_spec.MR_var_spec_kind = VAR_NUMBER;
+				var_spec.MR_var_spec_kind = MR_VAR_SPEC_NUMBER;
 				var_spec.MR_var_spec_number = n;
-				MR_trace_browse_one(layout, saved_regs,
-					*ancestor_level, var_spec, TRUE);
+				problem = MR_trace_browse_one(NULL, var_spec,
+					MR_trace_browse_var, TRUE);
 			} else {
-				var_spec.MR_var_spec_kind = VAR_NAME;
+				var_spec.MR_var_spec_kind = MR_VAR_SPEC_NAME;
 				var_spec.MR_var_spec_name = words[1];
-				MR_trace_browse_one(layout, saved_regs,
-					*ancestor_level, var_spec, TRUE);
+				problem = MR_trace_browse_one(NULL, var_spec,
+					MR_trace_browse_var, TRUE);
+			}
+
+			if (problem != NULL) {
+				fflush(MR_mdb_out);
+				fprintf(MR_mdb_err, "mdb: %s.\n", problem);
 			}
 		} else {
 			MR_trace_usage("browsing", "browse");
@@ -1617,243 +1656,6 @@
 		NULL, NULL, NULL);
 }
 
-static void
-MR_trace_list_vars(const MR_Stack_Layout_Label *top_layout, Word *saved_regs,
-	int ancestor_level)
-{
-	const MR_Stack_Layout_Label	*level_layout;
-	Word				*base_sp;
-	Word				*base_curfr;
-	Word				*type_params;
-	int				var_count;
-	const MR_Stack_Layout_Vars	*vars;
-	int				i;
-	const char 			*problem;
-
-	base_sp = MR_saved_sp(saved_regs);
-	base_curfr = MR_saved_curfr(saved_regs);
-	level_layout = MR_find_nth_ancestor(top_layout, ancestor_level,
-				&base_sp, &base_curfr, &problem);
-
-	if (level_layout == NULL) {
-		fflush(MR_mdb_out);
-		fprintf(MR_mdb_err, "%s\n", problem);
-		return;
-	}
-
-	problem = MR_trace_validate_var_count(level_layout, &var_count);
-	if (problem != NULL) {
-		fflush(MR_mdb_out);
-		fprintf(MR_mdb_err, "mdb: %s.\n", problem);
-		return;
-	}
-
-	vars = &level_layout->MR_sll_var_info;
-	for (i = 0; i < var_count; i++) {
-		fprintf(MR_mdb_out, "%9d %s\n",
-			i, MR_name_if_present(vars, i));
-	}
-}
-
-static void
-MR_trace_set_level(const MR_Stack_Layout_Label *layout,
-	Word *saved_regs, int *ancestor_level, int new_ancestor_level)
-{
-	const char *problem;
-	
-	problem = MR_trace_browse_check_level(layout, saved_regs,
-		new_ancestor_level);
-	if (problem == NULL) {
-		*ancestor_level = new_ancestor_level;
-		fprintf(MR_mdb_out, "Ancestor level set to %d.\n",
-			*ancestor_level);
-	} else {
-		fflush(MR_mdb_out);
-		fprintf(MR_mdb_err, "%s.\n", problem);
-	}
-}
-
-static const char *
-MR_trace_browse_check_level(const MR_Stack_Layout_Label *top_layout,
-	Word *saved_regs, int ancestor_level)
-{
-	Word				*base_sp;
-	Word				*base_curfr;
-	const char 			*problem;
-	const MR_Stack_Layout_Label	*label_layout;
-	const MR_Stack_Layout_Entry	*entry;
-
-	base_sp = MR_saved_sp(saved_regs);
-	base_curfr = MR_saved_curfr(saved_regs);
-	label_layout = MR_find_nth_ancestor(top_layout, ancestor_level,
-			&base_sp, &base_curfr, &problem);
-
-	if (label_layout == NULL) {
-		return problem;
-	} else {
-		entry = label_layout->MR_sll_entry;
-		fprintf(MR_mdb_out, "%4d ", ancestor_level);
-		MR_print_proc_id(MR_mdb_out, entry, "", base_sp, base_curfr);
-		if (MR_ENTRY_LAYOUT_HAS_EXEC_TRACE(entry)) {
-			return NULL;
-		} else {
-			return "this procedure does not have debugging info";
-		}
-	}
-}
-
-static void
-MR_trace_browse_one(const MR_Stack_Layout_Label *top_layout,
-	Word *saved_regs, int ancestor_level, MR_Var_Spec var_spec,
-	bool browse)
-{
-	const MR_Stack_Layout_Label	*level_layout;
-	Word				*base_sp;
-	Word				*base_curfr;
-	Word				*type_params;
-	Word				*valid_saved_regs;
-	int				which_var;
-	const MR_Stack_Layout_Vars	*vars;
-	const char 			*problem;
-
-	base_sp = MR_saved_sp(saved_regs);
-	base_curfr = MR_saved_curfr(saved_regs);
-	level_layout = MR_find_nth_ancestor(top_layout, ancestor_level,
-				&base_sp, &base_curfr, &problem);
-
-	if (level_layout == NULL) {
-		fflush(MR_mdb_out);
-		fprintf(MR_mdb_err, "mdb: %s.\n", problem);
-		return;
-	}
-
-	problem = MR_trace_find_var(level_layout, var_spec, &which_var);
-	if (problem != NULL) {
-		fflush(MR_mdb_out);
-		fprintf(MR_mdb_err, "mdb: %s.\n", problem);
-		return;
-	}
-
-	if (ancestor_level == 0) {
-		valid_saved_regs = saved_regs;
-	} else {
-		valid_saved_regs = NULL;
-	}
-
-	vars = &level_layout->MR_sll_var_info;
-	type_params = MR_materialize_typeinfos_base(vars,
-				valid_saved_regs, base_sp, base_curfr);
-	MR_trace_browse_var(MR_name_if_present(vars, which_var),
-		vars, which_var, valid_saved_regs,
-		base_sp, base_curfr, type_params, browse);
-	free(type_params);
-}
-
-static void 
-MR_trace_browse_all(const MR_Stack_Layout_Label *top_layout,
-	Word *saved_regs, int ancestor_level)
-{
-	const MR_Stack_Layout_Label	*level_layout;
-	Word				*base_sp;
-	Word				*base_curfr;
-	Word				*type_params;
-	Word				*valid_saved_regs;
-	int				var_count;
-	const MR_Stack_Layout_Vars	*vars;
-	const char 			*problem;
-	int				i;
-
-	base_sp = MR_saved_sp(saved_regs);
-	base_curfr = MR_saved_curfr(saved_regs);
-	level_layout = MR_find_nth_ancestor(top_layout, ancestor_level,
-				&base_sp, &base_curfr, &problem);
-
-	if (level_layout == NULL) {
-		fflush(MR_mdb_out);
-		fprintf(MR_mdb_err, "mdb: %s.\n", problem);
-		return;
-	}
-
-	problem = MR_trace_validate_var_count(level_layout, &var_count);
-	if (problem != NULL) {
-		fflush(MR_mdb_out);
-		fprintf(MR_mdb_err, "mdb: %s.\n", problem);
-		return;
-	}
-
-	vars = &level_layout->MR_sll_var_info;
-	if (ancestor_level == 0) {
-		valid_saved_regs = saved_regs;
-	} else {
-		valid_saved_regs = NULL;
-	}
-
-	type_params = MR_materialize_typeinfos_base(vars,
-				valid_saved_regs, base_sp, base_curfr);
-
-	for (i = 0; i < var_count; i++) {
-		MR_trace_browse_var(MR_name_if_present(vars, i),
-			vars, i, valid_saved_regs,
-			base_sp, base_curfr, type_params, FALSE);
-	}
-
-	free(type_params);
-}
-
-static void
-MR_trace_browse_var(const char *name, const MR_Stack_Layout_Vars *vars, int i,
-	Word *saved_regs, Word *base_sp, Word *base_curfr, Word *type_params,
-	bool browse)
-{
-	Word	value;
-	Word	type_info;
-	bool	print_value;
-
-	/*
-	** XXX The printing of type_infos is buggy at the moment
-	** due to the fake arity of the type private_builtin:typeinfo/1.
-	*/
-
-	if ((strncmp(name, "TypeInfo", 8) == 0)
-	|| (strncmp(name, "TypeClassInfo", 13) == 0))
-		return;
-
-	/* The initial blanks are to visually separate */
-	/* the variable names from the prompt. */
-
-	if (!browse) {
-		if (name != NULL) {
-			fprintf(MR_mdb_out, "%7s%-21s\t", "", name);
-		} else {
-			fprintf(MR_mdb_out, "%7s%-21s\t", "",
-				"anonymous variable");
-		}
-
-		fflush(MR_mdb_out);
-	}
-
-
-	/*
-	** "variables" representing the saved values of succip, hp etc,
-	** which are the "variables" for which get_type_and_value fails,
-	** are not of interest to the user.
-	*/
-
-	print_value = MR_get_type_and_value_base(vars, i, saved_regs,
-			base_sp, base_curfr, type_params, &type_info, &value);
-	if (print_value) {
-		if (browse) {
-			/* XXX should use MR_mdb_in and MR_mdb_out */
-			MR_trace_browse(type_info, value);
-		} else {
-			fprintf(MR_mdb_out, "\t");
-			fflush(MR_mdb_out);
-			/* XXX should use MR_mdb_out */
-			MR_trace_print(type_info, value);
-		}
-	}
-}
-
 /*
 ** Read lines until we find one that contains only "end".
 ** Return the lines concatenated together.
Index: trace/mercury_trace_vars.c
===================================================================
RCS file: mercury_trace_vars.c
diff -N mercury_trace_vars.c
--- /dev/null	Wed May 28 10:49:58 1997
+++ mercury_trace_vars.c	Tue May 25 19:46:56 1999
@@ -0,0 +1,585 @@
+/*
+** Copyright (C) 1999 The University of Melbourne.
+** This file may only be copied under the terms of the GNU Library General
+** Public License - see the file COPYING.LIB in the Mercury distribution.
+*/
+
+/*
+** This file contains the code for managing information about the
+** variables of the program being debugged for both the internal
+** and external debuggers.
+**
+** Main author: Zoltan Somogyi.
+*/
+
+#include "mercury_imp.h"
+#include "mercury_array_macros.h"
+#include "mercury_layout_util.h"
+#include "mercury_trace_vars.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+typedef struct {
+	char				*MR_var_fullname;
+	char				*MR_var_basename;
+	char				*MR_var_basename_malloc;
+	int				MR_var_num_suffix;
+	bool				MR_var_has_suffix;
+	bool				MR_var_is_headvar;
+	bool				MR_var_is_ambiguous;
+	int				MR_var_hlds_number;
+	Word				MR_var_value;
+	Word				MR_var_type;
+} MR_Var_Details;
+
+typedef struct {
+	const MR_Stack_Layout_Label	*MR_point_top_layout;
+	Word				*MR_point_top_saved_regs;
+	const char			*MR_point_problem;
+	int				MR_point_level;
+	const MR_Stack_Layout_Entry	*MR_point_level_entry;
+	Word				*MR_point_level_base_sp;
+	Word				*MR_point_level_base_curfr;
+	int				MR_point_var_count;
+	int				MR_point_var_max;
+	MR_Var_Details			*MR_point_vars;
+} MR_Point;
+
+static	bool	MR_trace_type_is_ignored(Word type_info);
+static	int	MR_trace_compare_var_details(const void *arg1,
+			const void *arg2);
+static	void	MR_trace_browse_var(FILE *out, MR_Var_Details *var,
+			MR_Browser browser);
+static	int	MR_trace_print_var_name(FILE *out, MR_Var_Details *var);
+
+#define	MR_INIT_VAR_DETAIL_COUNT	20
+#define	MR_TRACE_PADDED_VAR_NAME_LENGTH	23
+
+static	MR_Point			MR_point;
+
+/*
+** These extern declarations are necessary because the modules defining
+** these structures (some which are in Mercury and some of which are in C)
+** do not export them. The types are a lie, but a safe lie.
+*/
+
+extern	Word	mercury_data_private_builtin__type_ctor_info_type_info_1;
+extern	Word	mercury_data_private_builtin__type_ctor_info_type_ctor_info_1;
+extern	Word	mercury_data_private_builtin__type_ctor_info_typeclass_info_1;
+extern	Word	mercury_data_private_builtin__type_ctor_info_base_typeclass_info_1;
+extern	Word	mercury_data___type_ctor_info_func_0;
+extern	Word	mercury_data___type_ctor_info_pred_0;
+extern	Word	mercury_data___type_ctor_info_void_0;
+extern	Word	mercury_data___type_ctor_info_succip_0;
+extern	Word	mercury_data___type_ctor_info_hp_0;
+extern	Word	mercury_data___type_ctor_info_curfr_0;
+extern	Word	mercury_data___type_ctor_info_maxfr_0;
+extern	Word	mercury_data___type_ctor_info_redoip_0;
+extern	Word	mercury_data___type_ctor_info_redofr_0;
+
+static	Word *
+MR_trace_ignored_type_ctors[] =
+{
+	/* we ignore these until the debugger can handle their varying arity */
+	(Word *) &mercury_data_private_builtin__type_ctor_info_type_info_1,
+	(Word *) &mercury_data_private_builtin__type_ctor_info_type_ctor_info_1,
+	(Word *) &mercury_data_private_builtin__type_ctor_info_typeclass_info_1,
+	(Word *) &mercury_data_private_builtin__type_ctor_info_base_typeclass_info_1,
+
+	/* we ignore these until the debugger can print higher-order terms */
+	(Word *) &mercury_data___type_ctor_info_func_0,
+	(Word *) &mercury_data___type_ctor_info_pred_0,
+
+	/* we ignore these because they should never be needed */
+	(Word *) &mercury_data___type_ctor_info_void_0,
+
+	/* we ignore these because they are not interesting */
+	(Word *) &mercury_data___type_ctor_info_succip_0,
+	(Word *) &mercury_data___type_ctor_info_hp_0,
+	(Word *) &mercury_data___type_ctor_info_curfr_0,
+	(Word *) &mercury_data___type_ctor_info_maxfr_0,
+	(Word *) &mercury_data___type_ctor_info_redoip_0,
+	(Word *) &mercury_data___type_ctor_info_redofr_0,
+};
+
+static bool
+MR_trace_type_is_ignored(Word type_info_as_word)
+{
+	Word	*type_info;
+	Word	*type_ctor_info;
+	int	ignore_type_ctor_count;
+	int	i;
+
+	type_info = (Word *) type_info_as_word;
+
+	if (type_info[OFFSET_FOR_COUNT] == 0) {
+		type_ctor_info = type_info;
+	} else {
+		type_ctor_info = (Word *) type_info[0];
+	}
+
+	ignore_type_ctor_count = sizeof(MR_trace_ignored_type_ctors)
+					/ sizeof(Word *);
+
+	for (i = 0; i < ignore_type_ctor_count; i++) {
+		if (type_ctor_info == MR_trace_ignored_type_ctors[i]) {
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+void
+MR_trace_init_point_vars(const MR_Stack_Layout_Label *top_layout,
+	Word *saved_regs)
+{
+	MR_point.MR_point_top_layout = top_layout;
+	MR_point.MR_point_top_saved_regs = saved_regs;
+	MR_point.MR_point_level = 0;
+	MR_point.MR_point_problem = MR_trace_set_level(0);
+}
+
+const char *
+MR_trace_set_level(int ancestor_level)
+{
+	const char			*problem;
+	Word				*base_sp;
+	Word				*base_curfr;
+	const MR_Stack_Layout_Label	*top_layout;
+	const MR_Stack_Layout_Label	*level_layout;
+	const MR_Stack_Layout_Entry	*entry;
+	const MR_Stack_Layout_Vars	*vars;
+	Word				*valid_saved_regs;
+	int				var_count;
+	Word				*type_params;
+	Word				value;
+	Word				type_info;
+	int				i;
+	int				slot;
+	int				slot_max;
+	int				copylen;
+	char				*copy;
+	char				*s;
+	const char			*name;
+
+	problem = NULL;
+	top_layout = MR_point.MR_point_top_layout;
+	base_sp = MR_saved_sp(MR_point.MR_point_top_saved_regs);
+	base_curfr = MR_saved_curfr(MR_point.MR_point_top_saved_regs);
+	level_layout = MR_find_nth_ancestor(top_layout, ancestor_level,
+			&base_sp, &base_curfr, &problem);
+
+	if (level_layout != NULL) {
+		entry = level_layout->MR_sll_entry;
+		if (! MR_ENTRY_LAYOUT_HAS_EXEC_TRACE(entry)) {
+			return "this procedure does not have "
+				"debugging information";
+		}
+	} else {
+		if (problem == NULL) {
+			fatal_error("MR_find_nth_ancestor failed "
+					"without reporting a problem");
+		}
+
+		return problem;
+	}
+
+	vars = &level_layout->MR_sll_var_info;
+	if (! MR_has_valid_var_count(vars)) {
+		return "there is no information about live variables";
+	}
+
+	/*
+	** After this point, we cannot find any more problems
+	** that would prevent us from assembling an accurate picture
+	** of the set of live variables at the given level,
+	** so we are free to modify the MR_point structure.
+	*/
+
+	MR_point.MR_point_problem = NULL;
+	MR_point.MR_point_level = ancestor_level;
+	MR_point.MR_point_level_entry = entry;
+	MR_point.MR_point_level_base_sp = base_sp;
+	MR_point.MR_point_level_base_curfr = base_curfr;
+
+	if (MR_has_valid_var_info(vars)) {
+		var_count = MR_all_desc_var_count(vars);
+	} else {
+		/*
+		** If the count of variables is zero, then the rest of the
+		** information about the set of live variables (e.g. the
+		** type parameter array pointer) is not present. Continuing
+		** would therefore lead to a core dump.
+		**
+		** Instead, we set up the remaining meaningful fields
+		** of MR_point.
+		*/
+
+		MR_point.MR_point_var_count = 0;
+		return NULL;
+	}
+
+	if (ancestor_level == 0) {
+		valid_saved_regs = MR_point.MR_point_top_saved_regs;
+	} else {
+		valid_saved_regs = NULL;
+	}
+
+	type_params = MR_materialize_typeinfos_base(vars,
+				valid_saved_regs, base_sp, base_curfr);
+
+	MR_ensure_big_enough(var_count, MR_point.MR_point_var, 
+		MR_Var_Details, MR_INIT_VAR_DETAIL_COUNT);
+
+	for (slot = 0; slot < MR_point.MR_point_var_count; slot++) {
+		/* free the memory allocated by previous strdups */
+		free(MR_point.MR_point_vars[slot].MR_var_fullname);
+		free(MR_point.MR_point_vars[slot].MR_var_basename_malloc);
+	}
+
+	slot = 0;
+	for (i = 0; i < var_count; i++) {
+		name = MR_name_if_present(vars, i);
+		if (name == NULL || streq(name, "")) {
+			continue;
+		}
+
+		if (! MR_get_type_and_value_base(vars, i, valid_saved_regs,
+			base_sp, base_curfr, type_params, &type_info, &value))
+		{
+			/* this indicates that the value is not a variable */
+			continue;
+		}
+
+		if (MR_trace_type_is_ignored(type_info)) {
+			continue;
+		}
+
+		copy = strdup(name);
+		MR_point.MR_point_vars[slot].MR_var_fullname = copy;
+		MR_point.MR_point_vars[slot].MR_var_value = value;
+		MR_point.MR_point_vars[slot].MR_var_type = type_info;
+
+		/* we need another copy we can cut apart */
+		copy = strdup(MR_numbered_name_if_present(vars, i));
+		MR_point.MR_point_vars[slot].MR_var_basename_malloc = copy;
+		s = strchr(copy, ':');
+		*s = '\0';
+		MR_point.MR_point_vars[slot].MR_var_hlds_number = atoi(copy);
+
+		copy = s + 1;
+		copylen = strlen(copy);
+		s = copy + copylen - 1;
+		while (s > copy && isdigit(*s)) {
+			s--;
+		}
+
+		if (s == copy + copylen - 1) {
+			MR_point.MR_point_vars[slot].MR_var_has_suffix = FALSE;
+			/* num_suffix should not be used */
+			MR_point.MR_point_vars[slot].MR_var_num_suffix = -1;
+			MR_point.MR_point_vars[slot].MR_var_basename = copy;
+		} else {
+			if (isdigit(*s)) {
+				fatal_error("variable name starts with digit");
+			}
+
+			MR_point.MR_point_vars[slot].MR_var_has_suffix = TRUE;
+			MR_point.MR_point_vars[slot].MR_var_num_suffix
+				= atoi(s + 1);
+			*(s + 1) = '\0';
+			MR_point.MR_point_vars[slot].MR_var_basename = copy;
+		}
+
+		if (streq(MR_point.MR_point_vars[slot].MR_var_basename,
+			"HeadVar__"))
+		{
+			MR_point.MR_point_vars[slot].MR_var_is_headvar = TRUE;
+		} else {
+			MR_point.MR_point_vars[slot].MR_var_is_headvar = FALSE;
+		}
+
+		MR_point.MR_point_vars[slot].MR_var_is_headvar
+			= FALSE;
+		slot++;
+	}
+
+	slot_max = slot;
+	free(type_params);
+
+	if (slot_max > 0) {
+		qsort(MR_point.MR_point_vars, slot_max,
+			sizeof(MR_Var_Details),
+			MR_trace_compare_var_details);
+
+		slot = 1;
+		for (i = 1; i < slot_max; i++) {
+			if (MR_point.MR_point_vars[i].MR_var_hlds_number ==
+				MR_point.MR_point_vars[i-1].MR_var_hlds_number)
+			{
+				continue;
+			}
+
+			MR_memcpy(&MR_point.MR_point_vars[slot],
+				&MR_point.MR_point_vars[i],
+				sizeof(MR_Var_Details));
+
+			if (streq(MR_point.MR_point_vars[slot].MR_var_fullname,
+				MR_point.MR_point_vars[slot-1].MR_var_fullname))
+			{
+				MR_point.MR_point_vars[slot - 1].
+					MR_var_is_ambiguous = TRUE;
+				MR_point.MR_point_vars[slot].
+					MR_var_is_ambiguous = TRUE;
+			}
+
+			slot++;
+		}
+
+		slot_max = slot;
+	}
+
+	MR_point.MR_point_var_count = slot_max;
+	return NULL;
+}
+
+static int
+MR_trace_compare_var_details(const void *arg1, const void *arg2)
+{
+	MR_Var_Details	*var1;
+	MR_Var_Details	*var2;
+	int		diff;
+
+	var1 = (MR_Var_Details *) arg1;
+	var2 = (MR_Var_Details *) arg2;
+
+	if (var1->MR_var_is_headvar && ! var2->MR_var_is_headvar) {
+		return -1;
+	} else if (! var1->MR_var_is_headvar && var2->MR_var_is_headvar) {
+		return 1;
+	}
+
+	diff = strcmp(var1->MR_var_basename, var2->MR_var_basename);
+	if (diff != 0) {
+		return diff;
+	}
+
+	if (var1->MR_var_has_suffix && ! var2->MR_var_has_suffix) {
+		return -1;
+	} else if (! var1->MR_var_has_suffix && var2->MR_var_has_suffix) {
+		return 1;
+	}
+
+	diff = var1->MR_var_num_suffix - var2->MR_var_num_suffix;
+	if (diff != 0) {
+		return diff;
+	}
+
+	return var1->MR_var_hlds_number - var2->MR_var_hlds_number;
+}
+
+int
+MR_trace_current_level(void)
+{
+	return MR_point.MR_point_level;
+}
+
+void
+MR_trace_current_level_details(const MR_Stack_Layout_Entry **entry_ptr,
+	Word **base_sp_ptr, Word **base_curfr_ptr)
+{
+	if (MR_point.MR_point_problem != NULL) {
+		fatal_error("cannot get details about current level");
+	}
+
+	if (entry_ptr != NULL) {
+		*entry_ptr = MR_point.MR_point_level_entry;
+	}
+
+	if (base_sp_ptr != NULL) {
+		*base_sp_ptr = MR_point.MR_point_level_base_sp;
+	}
+
+	if (base_curfr_ptr != NULL) {
+		*base_curfr_ptr = MR_point.MR_point_level_base_curfr;
+	}
+}
+
+int
+MR_trace_var_count(void)
+{
+	if (MR_point.MR_point_problem != NULL) {
+		return -1;
+	}
+
+	return MR_point.MR_point_var_count;
+}
+
+const char *
+MR_trace_list_vars(FILE *out)
+{
+	int	i;
+
+	if (MR_point.MR_point_problem != NULL) {
+		return MR_point.MR_point_problem;
+	}
+
+	for (i = 0; i < MR_point.MR_point_var_count; i++) {
+		fprintf(out, "%9d ", i);
+		MR_trace_print_var_name(out, &MR_point.MR_point_vars[i]);
+		fprintf(out, "\n");
+	}
+
+	return NULL;
+}
+
+const char *
+MR_trace_return_var_info(int var_number, const char **name_ptr,
+	Word *type_info_ptr, Word *value_ptr)
+{
+	if (MR_point.MR_point_problem != NULL) {
+		return MR_point.MR_point_problem;
+	}
+
+	if (var_number >= MR_point.MR_point_var_count) {
+		return "there aren't that many variables";
+	}
+
+	if (name_ptr != NULL) {
+		*name_ptr = MR_point.MR_point_vars[var_number].MR_var_fullname;
+	}
+
+	if (type_info_ptr != NULL) {
+		*type_info_ptr = MR_point.MR_point_vars[var_number].MR_var_type;
+	}
+
+	if (value_ptr != NULL) {
+		*value_ptr = MR_point.MR_point_vars[var_number].MR_var_value;
+	}
+
+	return NULL;
+}
+
+const char *
+MR_trace_browse_one(FILE *out, MR_Var_Spec var_spec, MR_Browser browser,
+	bool must_be_unique)
+{
+	int	i;
+	bool	found;
+
+	if (MR_point.MR_point_problem != NULL) {
+		return MR_point.MR_point_problem;
+	}
+
+	if (var_spec.MR_var_spec_kind == MR_VAR_SPEC_NUMBER) {
+		if (var_spec.MR_var_spec_number < MR_point.MR_point_var_count)
+		{
+			MR_trace_browse_var(out, &MR_point.MR_point_vars
+				[var_spec.MR_var_spec_number], browser);
+		} else {
+			return "there aren't that many variables";
+		}
+	} else if (var_spec.MR_var_spec_kind == MR_VAR_SPEC_NAME) {
+		found = FALSE;
+		for (i = 0; i < MR_point.MR_point_var_count; i++) {
+			if (streq(var_spec.MR_var_spec_name,
+				MR_point.MR_point_vars[i].MR_var_fullname))
+			{
+				found = TRUE;
+				break;
+			}
+		}
+
+		if (MR_point.MR_point_vars[i].MR_var_is_ambiguous) {
+			if (must_be_unique) {
+				return "variable name is not unique";
+			}
+
+			do {
+				MR_trace_browse_var(out,
+					&MR_point.MR_point_vars[i], browser);
+				i++;
+			} while (i < MR_point.MR_point_var_count &&
+				streq(var_spec.MR_var_spec_name,
+				MR_point.MR_point_vars[i].MR_var_fullname));
+		} else {
+			MR_trace_browse_var(out, &MR_point.MR_point_vars[i],
+				browser);
+		}
+	} else {
+		fatal_error("internal error: bad var_spec kind");
+	}
+
+	return NULL;
+}
+
+const char *
+MR_trace_browse_all(FILE *out, FILE *err, MR_Browser browser)
+{
+	int				i;
+
+	if (MR_point.MR_point_problem != NULL) {
+		return MR_point.MR_point_problem;
+	}
+
+	if (MR_point.MR_point_var_count == 0 && out != NULL) {
+		fprintf(out, "mdb: there are no live variables.\n");
+	}
+
+	for (i = 0; i < MR_point.MR_point_var_count; i++) {
+		MR_trace_browse_var(out, &MR_point.MR_point_vars[i], browser);
+	}
+
+	return NULL;
+}
+
+static void
+MR_trace_browse_var(FILE *out, MR_Var_Details *var, MR_Browser browser)
+{
+	int	len;
+
+	if (out != NULL) {
+		/*
+		** The initial blanks are to visually separate
+		** the variable names from the prompt.
+		*/
+
+		fprintf(out, "%7s", "");
+		len = MR_trace_print_var_name(out, var);
+		while (len < MR_TRACE_PADDED_VAR_NAME_LENGTH) {
+			fputc(' ', out);
+			len++;
+		}
+
+		/*
+		** We flush the output in case the browser is interactive.
+		** XXX we should pass out (and in, and err) to the browser.
+		*/
+
+		fflush(out);
+	}
+
+	(*browser)(var->MR_var_type, var->MR_var_value);
+}
+
+static int
+MR_trace_print_var_name(FILE *out, MR_Var_Details *var)
+{
+	int	len;
+
+	len = strlen(var->MR_var_fullname);
+	fputs(var->MR_var_fullname, out);
+	if (var->MR_var_is_ambiguous) {
+		char	buf[256]; /* this should be plenty big enough */
+
+		sprintf(buf, "(%d)", var->MR_var_hlds_number);
+		len += strlen(buf);
+		fputs(buf, out);
+	}
+
+	return len;
+}
Index: trace/mercury_trace_vars.h
===================================================================
RCS file: mercury_trace_vars.h
diff -N mercury_trace_vars.h
--- /dev/null	Wed May 28 10:49:58 1997
+++ mercury_trace_vars.h	Tue May 25 19:47:08 1999
@@ -0,0 +1,105 @@
+/*
+** Copyright (C) 1999 The University of Melbourne.
+** This file may only be copied under the terms of the GNU Library General
+** Public License - see the file COPYING.LIB in the Mercury distribution.
+**
+** This module looks after the debugger's information about the variables
+** that are live at a given program point.
+**
+** When execution arrives at an event, the debugger should call the function
+** MR_trace_point_init_vars to initialize this module's data structures
+** to reflect the variables that are live at that event. During the processing
+** of the various debugger commands while at that event, the debugger may
+** call MR_trace_set_level zero or more times to change this module's notion
+** of the "current" set of variables to refer instead to the variables that
+** are live at the return address in a given ancestor. This module maintains
+** its own record of what the current ancestor level is; the enquery function
+** MR_trace_current_level returns this information, while enquery function
+** MR_trace_current_level_details returns information about this level.
+**
+** The five functions MR_trace_var_count, MR_trace_list_vars,
+** MR_trace_return_var_info, MR_trace_browse_one and MR_trace_browse_all
+** all work in the context established by the MR_trace_init_point_vars and
+** possibly MR_trace_set_level.
+**
+** This context may say that there is no information available about
+** the variables live at the current location (this is possible if the
+** relevant module was not compiled with the right debugging flags).
+** If this is the case, or if some other reason prevents these functions
+** from carrying out their assigned tasks, most of these functions return
+** a non-NULL string describing the problem; they return NULL if everything
+** went OK. (MR_trace_set_level also returns a pointer to an error message
+** -and refuses to change levels- if something goes wrong.)
+*/
+
+#ifndef	MERCURY_TRACE_VARS_H
+#define	MERCURY_TRACE_VARS_H
+
+#include <stdio.h>
+#include "mercury_types.h"
+#include "mercury_stack_layout.h"
+
+typedef	void	(*MR_Browser)(Word type_info, Word value);
+
+typedef	enum {
+	MR_VAR_SPEC_NUMBER,
+	MR_VAR_SPEC_NAME
+} MR_Var_Spec_Kind;
+
+typedef struct {
+	MR_Var_Spec_Kind	MR_var_spec_kind;
+	int			MR_var_spec_number; /* valid if VAR_NUMBER */
+	const char		*MR_var_spec_name;  /* valid if VAR_NAME   */
+} MR_Var_Spec;
+
+extern	void		MR_trace_init_point_vars(const MR_Stack_Layout_Label
+				*top_layout, Word *saved_regs);
+extern	const char	*MR_trace_set_level(int ancestor_level);
+extern	int		MR_trace_current_level(void);
+extern	void		MR_trace_current_level_details(
+				const MR_Stack_Layout_Entry **entry_ptr,
+				Word **base_sp_ptr, Word **base_curfr_ptr);
+
+/*
+** Return the number of live variables at the current point. If the required
+** information is missing, return a negative number.
+*/
+
+extern	int		MR_trace_var_count(void);
+
+/*
+** Print the list of the names of variables live at the current point
+** on the given file.
+*/
+
+extern	const char	*MR_trace_list_vars(FILE *out);
+
+/*
+** Return the name, type and value of the specified variable in the specified
+** locations, except those which are NULL.
+*/
+
+extern	const char	*MR_trace_return_var_info(int n, const char **name_ptr,
+				Word *type_info_ptr, Word *value_ptr);
+
+/*
+** Print the (names and) values of the specified variables.
+** The names are printed to the given file if the file pointer is non-NULL.
+** The values are printed by giving them to the specified browser.
+** The last argument governs whether this function returns an error
+** if the given variable specification is ambiguous.
+*/
+
+extern	const char	*MR_trace_browse_one(FILE *out, MR_Var_Spec var_spec,
+				MR_Browser browser, bool must_be_unique);
+
+/*
+** Print the list of the names and values of all variables live at the current
+** point. The variables names are printed directly to the given file; the
+** variable values are printed by calling the given browser function on them.
+*/
+
+extern	const char 	*MR_trace_browse_all(FILE *out, FILE *err,
+				MR_Browser browser);
+
+#endif	/* MERCURY_TRACE_VARS_H */
cvs diff: Diffing trial
cvs diff: Diffing util
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list