for review: print variables by name

Zoltan Somogyi zs at cs.mu.OZ.AU
Tue Nov 10 22:33:28 AEDT 1998


Estimated hours taken: 4

Allow (uniquely-named) variables to be printed by name in the debugger.

trace/mercury_trace_internal.c:
	Implement the new functionality. Factor out some common code.
	Make some error messages conform to our conventions.

doc/user_guide.texi:
	Document the new functionality.

tests/queens.{inp,exp}:
	Test the new functionality.

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 bytecode/test
cvs diff: Diffing compiler
cvs diff: Diffing compiler/notes
cvs diff: Diffing doc
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.141
diff -u -u -r1.141 user_guide.texi
--- user_guide.texi	1998/11/05 03:53:04	1.141
+++ user_guide.texi	1998/11/10 06:58:00
@@ -3315,8 +3315,18 @@
 together with an ordinal number for each variable.
 @sp 1
 @item print @var{num}
-Prints the value of the variable with the given ordinal number
-in the current environment.
+Prints the value of the variable
+with the given ordinal number in the current environment.
+ at sp 1
+At the moment this command prints the entire value of the variable,
+even if this is very big. Later it will merely invoke a configurable
+dynamic term browser, which will eventually have its own sublanguage.
+ at sp 1
+ at item print @var{name}
+Prints the value of the variable
+with the given name in the current environment.
+Report an error if the name is ambiguous
+or if there is no information available about a variable with that name.
 @sp 1
 At the moment this command prints the entire value of the variable,
 even if this is very big. Later it will merely invoke a configurable
cvs diff: Diffing extras
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/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/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 lp_solve/lp_examples
cvs diff: Diffing profiler
cvs diff: Diffing runtime
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 scripts
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
Index: tests/debugger/queens.exp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/queens.exp,v
retrieving revision 1.4
diff -u -u -r1.4 queens.exp
--- queens.exp	1998/11/04 04:20:18	1.4
+++ queens.exp	1998/11/10 07:42:56
@@ -5,7 +5,7 @@
 mdb> 
        2:      2  2 CALL pred queens:data/1-0 (det) 
 mdb> print *
-mdb: there are no live variables
+mdb: there are no live variables.
 mdb> 
        3:      2  2 EXIT pred queens:data/1-0 (det) 
 mdb> print *
@@ -44,9 +44,11 @@
        HeadVar__1           		[1, 2, 3, 4, 5]
 mdb> 
        9:      5  4 EXIT pred queens:qdelete/3-0 (nondet) 
-mdb> print *
+mdb> print HeadVar__1
        HeadVar__1           		1
+mdb> print HeadVar__2
        HeadVar__2           		[1, 2, 3, 4, 5]
+mdb> print HeadVar__3
        HeadVar__3           		[2, 3, 4, 5]
 mdb> 
       10:      6  4 CALL pred queens:qperm/2-0 (nondet) 
Index: tests/debugger/queens.inp
===================================================================
RCS file: /home/mercury1/repository/tests/debugger/queens.inp,v
retrieving revision 1.3
diff -u -u -r1.3 queens.inp
--- queens.inp	1998/10/16 06:19:46	1.3
+++ queens.inp	1998/11/10 07:00:43
@@ -20,7 +20,9 @@
 vars
 print *
 
-print *
+print HeadVar__1
+print HeadVar__2
+print HeadVar__3
 
 print *
 
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/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.9
diff -u -u -r1.9 mercury_trace_internal.c
--- mercury_trace_internal.c	1998/11/06 10:35:41	1.9
+++ mercury_trace_internal.c	1998/11/10 07:41:25
@@ -107,6 +107,17 @@
 	STOP_INTERACTING
 } MR_Next;
 
+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;
+
 static	void	MR_trace_internal_ensure_init(void);
 static	bool	MR_trace_internal_init_from_env(const char *env_var);
 static	bool	MR_trace_internal_init_from_file(const char *filename);
@@ -145,13 +156,18 @@
 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, int which_var);
+			Word *saved_regs, int ancestor_level,
+			MR_Var_Spec which_var);
 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_Var *var,
 			Word *saved_regs, Word *base_sp, Word *base_curfr,
 			Word *type_params);
+static	const char *MR_trace_validate_var_count(const MR_Stack_Layout_Label
+			*layout, int *var_count_ptr);
+static	const char *MR_trace_find_var(const MR_Stack_Layout_Label *layout,
+			MR_Var_Spec var_spec, int *which_var_ptr);
 
 static	const char *MR_trace_read_help_text(void);
 static	bool	MR_trace_is_number(char *word, int *value);
@@ -704,14 +720,21 @@
 		}
 	} else if (streq(words[0], "print")) {
 		if (word_count == 2) {
-			if (MR_trace_is_number(words[1], &n)) {
-				MR_trace_browse_one(layout, saved_regs,
-					*ancestor_level, n);
-			} else if streq(words[1], "*") {
+			MR_Var_Spec	var_spec;
+
+			if streq(words[1], "*") {
 				MR_trace_browse_all(layout, saved_regs,
 					*ancestor_level);
+			} else if (MR_trace_is_number(words[1], &n)) {
+				var_spec.MR_var_spec_kind = VAR_NUMBER;
+				var_spec.MR_var_spec_number = n;
+				MR_trace_browse_one(layout, saved_regs,
+					*ancestor_level, var_spec);
 			} else {
-				MR_trace_help_cat_item("browsing", "print");
+				var_spec.MR_var_spec_kind = VAR_NAME;
+				var_spec.MR_var_spec_name = words[1];
+				MR_trace_browse_one(layout, saved_regs,
+					*ancestor_level, var_spec);
 			}
 		} else {
 			MR_trace_help_cat_item("browsing", "print");
@@ -1543,12 +1566,9 @@
 		return;
 	}
 
-	var_count = (int) level_layout->MR_sll_var_count;
-	if (var_count < 0) {
-		printf("mdb: there is no information about live variables\n");
-		return;
-	} else if (var_count == 0) {
-		printf("mdb: there are no live variables\n");
+	problem = MR_trace_validate_var_count(level_layout, &var_count);
+	if (problem != NULL) {
+		printf("mdb: %s.\n", problem);
 		return;
 	}
 
@@ -1579,14 +1599,14 @@
 
 static void
 MR_trace_browse_one(const MR_Stack_Layout_Label *top_layout,
-	Word *saved_regs, int ancestor_level, int which_var)
+	Word *saved_regs, int ancestor_level, 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				var_count;
+	int				which_var;
 	const MR_Stack_Layout_Vars	*vars;
 	const char 			*problem;
 
@@ -1596,26 +1616,23 @@
 				&base_sp, &base_curfr, &problem);
 
 	if (level_layout == NULL) {
-		printf("%s\n", problem);
+		printf("mdb: %s.\n", problem);
 		return;
 	}
 
-	var_count = (int) level_layout->MR_sll_var_count;
-	if (var_count < 0) {
-		printf("mdb: there is no information about live variables\n");
-		return;
-	} else if (which_var >= var_count) {
-		printf("mdb: there is no such variable\n");
+	problem = MR_trace_find_var(level_layout, var_spec, &which_var);
+	if (problem != NULL) {
+		printf("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;
 	}
 
+	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),
@@ -1644,16 +1661,13 @@
 				&base_sp, &base_curfr, &problem);
 
 	if (level_layout == NULL) {
-		printf("%s\n", problem);
+		printf("mdb: %s.\n", problem);
 		return;
 	}
 
-	var_count = (int) level_layout->MR_sll_var_count;
-	if (var_count < 0) {
-		printf("mdb: there is no information about live variables\n");
-		return;
-	} else if (var_count == 0) {
-		printf("mdb: there are no live variables\n");
+	problem = MR_trace_validate_var_count(level_layout, &var_count);
+	if (problem != NULL) {
+		printf("mdb: %s.\n", problem);
 		return;
 	}
 
@@ -1726,6 +1740,77 @@
 	}
 
 	printf("\n");
+}
+
+static const char *
+MR_trace_validate_var_count(const MR_Stack_Layout_Label *layout,
+	int *var_count_ptr)
+{
+	*var_count_ptr = (int) layout->MR_sll_var_count;
+	if (*var_count_ptr < 0) {
+		return "there is no information about live variables";
+	} else if (*var_count_ptr == 0) {
+		return "there are no live variables";
+	} else {
+		return NULL;
+	}
+}
+
+/*
+** Find and validate the number of a variable given by a variable
+** specification in the given layout. If successful, return the
+** number of the variable in *which_var_ptr, and a NULL string;
+** otherwise a return a string containing an error message.
+*/
+
+static 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";
+	}
 }
 
 /*
cvs diff: Diffing trial
cvs diff: Diffing util



More information about the developers mailing list