[m-rev.] for post-commit review: fix mantis bug #45

Zoltan Somogyi zs at csse.unimelb.edu.au
Wed Feb 20 13:58:57 AEDT 2008


Fix Mantis bug #45, which was that mdb effectively ignored some commands
in .mdbrc files.

trace/mercury_trace_internal.[ch]:
trace/mercury_trace_command_queue.[ch]:
	Move the code for manipulating the command queue from
	mercury_trace_internal.c to a new module. This improves the level of
	abstraction. The ultimate cause of the bug was a lack of abstraction.

	The old code put commands from startup files in the command queue
	in a mixed order: respecting order within each startup file, but
	reversing order among startup files. The cause of the bug was
	that the commands from .mdbrc files were put into the queue
	*after* the commands from the system's standard startup file in time,
	but *before* them in order, so the commands in the standard startup
	file could override commands from .mdbrc files.

	The fix is to consistently put commands in order: from the standard
	system startup file, from .mdbrc, and from the environment.

	Give better names to some functions.

	Provide a mechanism for debugging the command queue mechanism.

trace/mercury_trace_cmd_backward.c:
	Use those better names.

trace/Mmakefile:
	Add the new module.

tests/debugger/mdbrc_test.{m,inp,exp,mdbrc}:
	Add a regression test for this bug, a minimally modified version
	of the bug demo program in Mantis.

tests/debugger/Mmakefile:
	Enable the new test case, which specifies its own .mdbrc file.

tests/Mmake.common:
	Provide a way for a test case to not use the .mdbrc file used by all
	the other debugger tests, so it could specify its own.

Zoltan.

cvs diff: Diffing .
cvs diff: Diffing analysis
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/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
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/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_glut
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/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
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/c_interface/standalone_c
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing ssdb
cvs diff: Diffing tests
Index: tests/Mmake.common
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/Mmake.common,v
retrieving revision 1.51
diff -u -b -r1.51 Mmake.common
--- tests/Mmake.common	20 Jul 2007 06:13:22 -0000	1.51
+++ tests/Mmake.common	19 Feb 2008 13:01:23 -0000
@@ -60,11 +60,16 @@
 MDB = HOME=/nonexistent MERCURY_SUPPRESS_MDB_BANNER=yes \
 	MERCURY_DEBUGGER_INIT=$(TESTS_DIR)/mdbrc mdb
 
+MDB_NOINIT = HOME=/nonexistent MERCURY_SUPPRESS_MDB_BANNER=yes \
+	MERCURY_DEBUGGER_INIT="" mdb
+
 # Debugger test cases can standardize the reported event numbers and call
 # sequence numbers by using $(MDB_STD) instead of $(MDB) on the command line.
 
 MDB_STD = MERCURY_OPTIONS="$$MERCURY_OPTIONS -de" $(MDB)
 
+MDB_STD_NOINIT = MERCURY_OPTIONS="$$MERCURY_OPTIONS -de" $(MDB_NOINIT)
+
 ifeq ($(TARGET_ASM),yes)
 PARAMS_MSG = in grade $(GRADE) with --target asm
 else
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
Index: tests/debugger/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/Mmakefile,v
retrieving revision 1.139
diff -u -b -r1.139 Mmakefile
--- tests/debugger/Mmakefile	27 Sep 2007 07:28:23 -0000	1.139
+++ tests/debugger/Mmakefile	19 Feb 2008 13:00:45 -0000
@@ -40,6 +40,7 @@
 	lambdatest			\
 	loopcheck			\
 	lval_desc_array			\
+	mdbrc_test			\
 	multi_parameter			\
 	poly_io_retry			\
 	poly_io_retry2			\
@@ -430,6 +431,14 @@
 	$(MDB) ./lval_desc_array < lval_desc_array.inp \
 		> lval_desc_array.out 2>&1
 
+# The use of MDB_STD_NOINIT here is to override the default mdbrc file
+# specified by the MDB make variable.
+mdbrc_test.out: mdbrc_test mdbrc_test.inp mdbrc_test.mdbrc
+	cp mdbrc_test.mdbrc .mdbrc
+	$(MDB_STD_NOINIT) ./mdbrc_test < mdbrc_test.inp \
+		> mdbrc_test.out 2>&1
+	/bin/rm .mdbrc
+
 # We need to pipe the output through sed to avoid hard-coding dependencies on
 # particular line numbers in the standard library source code.
 multi_parameter.out: multi_parameter multi_parameter.inp
Index: tests/debugger/mdbrc_test.exp
===================================================================
RCS file: tests/debugger/mdbrc_test.exp
diff -N tests/debugger/mdbrc_test.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/mdbrc_test.exp	19 Feb 2008 13:02:26 -0000
@@ -0,0 +1,13 @@
+      E1:     C1 CALL pred mdbrc_test.main/2-0 (det) mdbrc_test.m:15
+mdb> echo on
+Command echo enabled.
+mdb> context none
+Contexts will not be printed.
+mdb> step
+      E2:     C2 CALL pred mdbrc_test.p/2-0 (det)
+mdb> finish
+      E3:     C2 EXIT pred mdbrc_test.p/2-0 (det)
+mdb> print B
+       B (arg 2)              	[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, ...]
+mdb> continue
+[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
Index: tests/debugger/mdbrc_test.inp
===================================================================
RCS file: tests/debugger/mdbrc_test.inp
diff -N tests/debugger/mdbrc_test.inp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/mdbrc_test.inp	19 Feb 2008 13:01:54 -0000
@@ -0,0 +1,6 @@
+echo on
+context none
+step
+finish
+print B
+continue
Index: tests/debugger/mdbrc_test.m
===================================================================
RCS file: tests/debugger/mdbrc_test.m
diff -N tests/debugger/mdbrc_test.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/mdbrc_test.m	19 Feb 2008 12:32:25 -0000
@@ -0,0 +1,23 @@
+% This is a regression test for Mantis bug #45.
+
+:- module mdbrc_test.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module list.
+
+main(!IO) :-
+    p(0 .. 100, L),
+    io.write(L, !IO),
+    nl(!IO).
+
+:- pred p(T::in, T::out) is det.
+
+p(A, B) :-
+	B = A.
Index: tests/debugger/mdbrc_test.mdbrc
===================================================================
RCS file: tests/debugger/mdbrc_test.mdbrc
diff -N tests/debugger/mdbrc_test.mdbrc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/debugger/mdbrc_test.mdbrc	19 Feb 2008 12:59:19 -0000
@@ -0,0 +1,3 @@
+format_param depth 10000
+format_param lines 10000
+format_param size 80
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
Index: trace/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/Mmakefile,v
retrieving revision 1.55
diff -u -b -r1.55 Mmakefile
--- trace/Mmakefile	3 Oct 2007 12:11:59 -0000	1.55
+++ trace/Mmakefile	19 Feb 2008 08:29:35 -0000
@@ -12,6 +12,7 @@
 # The list of human-written C header files of the trace library.
 # Keep this list in alphabetical order, please.
 HAND_TRACE_HDRS	=	\
+			mercury_trace.h			\
 			mercury_trace_alias.h		\
 			mercury_trace_browse.h		\
 			mercury_trace_cmd_backward.h	\
@@ -24,12 +25,12 @@
 			mercury_trace_cmd_misc.h	\
 			mercury_trace_cmd_parameter.h	\
 			mercury_trace_cmd_queries.h	\
-			mercury_trace_cmds.h		\
 			mercury_trace_cmd_table_io.h	\
+			mercury_trace_cmds.h		\
+			mercury_trace_command_queue.h	\
 			mercury_trace_completion.h	\
 			mercury_trace_declarative.h	\
 			mercury_trace_external.h	\
-			mercury_trace.h			\
 			mercury_trace_help.h		\
 			mercury_trace_hold_vars.h	\
 			mercury_trace_internal.h	\
@@ -43,9 +44,9 @@
 # The list of human-written C source files of the trace library.
 # Keep this list in alphabetical order, please.
 HAND_TRACE_SRCS	=	\
+			mercury_trace.c			\
 			mercury_trace_alias.c		\
 			mercury_trace_browse.c		\
-			mercury_trace.c			\
 			mercury_trace_cmd_backward.c	\
 			mercury_trace_cmd_breakpoint.c	\
 			mercury_trace_cmd_browsing.c	\
@@ -58,6 +59,7 @@
 			mercury_trace_cmd_parameter.c	\
 			mercury_trace_cmd_queries.c	\
 			mercury_trace_cmd_table_io.c	\
+			mercury_trace_command_queue.c		\
 			mercury_trace_completion.c	\
 			mercury_trace_declarative.c	\
 			mercury_trace_external.c	\
Index: trace/mercury_trace_cmd_backward.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_cmd_backward.c,v
retrieving revision 1.4
diff -u -b -r1.4 mercury_trace_cmd_backward.c
--- trace/mercury_trace_cmd_backward.c	2 Oct 2007 17:04:37 -0000	1.4
+++ trace/mercury_trace_cmd_backward.c	19 Feb 2008 08:39:53 -0000
@@ -28,6 +28,7 @@
 #include "mercury_trace_cmds.h"
 #include "mercury_trace_cmd_backward.h"
 #include "mercury_trace_cmd_parameter.h"
+#include "mercury_trace_command_queue.h"
 #include "mercury_trace_util.h"
 
 /****************************************************************************/
@@ -101,7 +102,7 @@
 
         /* Arrange to retry the call once it is finished. */
         /* XXX we should use the same options as the original retry */
-        MR_insert_line_at_head("retry -o");
+        MR_insert_command_line_at_head("retry -o");
         return STOP_INTERACTING;
 
     case MR_RETRY_OK_FAIL_FIRST:
@@ -112,7 +113,7 @@
 
         /* Arrange to retry the call once it is finished. */
         /* XXX we should use the same options as the original retry */
-        MR_insert_line_at_head("retry -o");
+        MR_insert_command_line_at_head("retry -o");
         return STOP_INTERACTING;
 
     case MR_RETRY_ERROR:
Index: trace/mercury_trace_command_queue.c
===================================================================
RCS file: trace/mercury_trace_command_queue.c
diff -N trace/mercury_trace_command_queue.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_command_queue.c	19 Feb 2008 12:48:42 -0000
@@ -0,0 +1,140 @@
+/*
+** vim: ts=4 sw=4 expandtab
+*/
+/*
+** Copyright (C) 2008 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 a queue of lines containing commands for mdb.
+** Its main use is during initialization.
+**
+** Main author: Zoltan Somogyi.
+*/
+
+#include "mercury_imp.h"
+#include "mercury_trace_command_queue.h"
+#include "mercury_trace_internal.h" /* for MR_trace_echo_queue_commands */
+
+/*
+** MR_cmd_queue_head points to the first node in the list, while
+** MR_cmd_queue_tail points to the last. It is an invariant that
+** if one of these two variables is NULL, the other is NULL as well.
+*/
+
+static  MR_CmdLines *MR_cmd_queue_head = NULL;
+static  MR_CmdLines	*MR_cmd_queue_tail = NULL;
+
+void
+MR_insert_command_line_at_head(const char *line_contents)
+{
+    MR_CmdLines *cmd_line;
+
+    cmd_line = MR_NEW(MR_CmdLines);
+    cmd_line->MR_cmd_line_contents = MR_copy_string(line_contents);
+    cmd_line->MR_cmd_line_next = MR_cmd_queue_head;
+
+    MR_cmd_queue_head = cmd_line;
+    if (MR_cmd_queue_tail == NULL) {
+        MR_cmd_queue_tail = MR_cmd_queue_head;
+    }
+}
+
+void
+MR_insert_command_line_at_tail(const char *line_contents)
+{
+    MR_CmdLines *cmd_line;
+
+    cmd_line = MR_NEW(MR_CmdLines);
+    cmd_line->MR_cmd_line_contents = MR_copy_string(line_contents);
+    cmd_line->MR_cmd_line_next = NULL;
+
+    if (MR_cmd_queue_tail == NULL) {
+        MR_cmd_queue_head = cmd_line;
+        MR_cmd_queue_tail = cmd_line;
+    } else {
+        MR_cmd_queue_tail->MR_cmd_line_next = cmd_line;
+        MR_cmd_queue_tail = cmd_line;
+    }
+}
+
+void
+MR_insert_command_lines_at_head(MR_CmdLines *new_lines)
+{
+    MR_CmdLines *last_new_node;
+
+    if (new_lines == NULL) {
+        return;
+    }
+
+    for (last_new_node = new_lines;
+        last_new_node->MR_cmd_line_next != NULL;
+        last_new_node = last_new_node->MR_cmd_line_next)
+    {
+        /* do nothing */
+    }
+
+    MR_assert(last_new_node->MR_cmd_line_next == NULL);
+    last_new_node->MR_cmd_line_next = MR_cmd_queue_head;
+
+    MR_cmd_queue_head = new_lines;
+    if (MR_cmd_queue_tail == NULL) {
+        MR_cmd_queue_tail = last_new_node;
+    }
+}
+
+void
+MR_insert_command_lines_at_tail(MR_CmdLines *new_lines)
+{
+    MR_CmdLines *last_new_node;
+
+    if (new_lines == NULL) {
+        return;
+    }
+
+    for (last_new_node = new_lines;
+        last_new_node->MR_cmd_line_next != NULL;
+        last_new_node = last_new_node->MR_cmd_line_next)
+    {
+        /* do nothing */
+    }
+
+    MR_assert(last_new_node->MR_cmd_line_next == NULL);
+
+    if (MR_cmd_queue_tail == NULL) {
+        MR_cmd_queue_head = new_lines;
+        MR_cmd_queue_tail = last_new_node;
+    } else {
+        MR_cmd_queue_tail->MR_cmd_line_next = new_lines;
+        MR_cmd_queue_tail = last_new_node;
+    }
+}
+
+char *
+MR_trace_getline_command_queue(void)
+{
+    if (MR_cmd_queue_head != NULL) {
+        MR_CmdLines *old;
+        char        *line_contents;
+
+        old = MR_cmd_queue_head;
+        line_contents = MR_cmd_queue_head->MR_cmd_line_contents;
+        MR_cmd_queue_head = MR_cmd_queue_head->MR_cmd_line_next;
+
+        if (MR_cmd_queue_head == NULL) {
+            MR_cmd_queue_tail = NULL;
+        }
+
+        if (MR_trace_echo_queue_commands) {
+            printf("queue command <%s>\n", line_contents);
+            fflush(stdout);
+        }
+
+        MR_free(old);
+        return line_contents;
+    } else {
+        return NULL;
+    }
+}
Index: trace/mercury_trace_command_queue.h
===================================================================
RCS file: trace/mercury_trace_command_queue.h
diff -N trace/mercury_trace_command_queue.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ trace/mercury_trace_command_queue.h	19 Feb 2008 09:01:01 -0000
@@ -0,0 +1,42 @@
+/*
+** vim: ts=4 sw=4 expandtab
+*/
+/*
+** Copyright (C) 2008 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.
+*/
+
+#ifndef MERCURY_TRACE_COMMAND_QUEUE_H
+#define MERCURY_TRACE_COMMAND_QUEUE_H
+
+/*
+** The structure of the queue of command lines, and the operations
+** that work on it.
+**
+** The contents of each command line should be allocated with MR_malloc().
+*/
+
+typedef struct MR_CmdLines_Struct	MR_CmdLines;
+
+struct MR_CmdLines_Struct {
+    char            *MR_cmd_line_contents;
+    MR_CmdLines     *MR_cmd_line_next;
+};
+
+extern  void        MR_insert_command_line_at_head(const char *line);
+extern  void        MR_insert_command_line_at_tail(const char *line);
+
+extern  void        MR_insert_command_lines_at_head(MR_CmdLines *lines);
+extern  void        MR_insert_command_lines_at_tail(MR_CmdLines *lines);
+
+/*
+** If there any lines waiting in the queue, return the first of these.
+** The memory for the line will have been allocated with MR_malloc(),
+** and it is the caller's responsibility to MR_free() it when appropriate.
+** If there are no lines in the queue, this function returns NULL.
+*/
+
+extern  char        *MR_trace_getline_command_queue(void);
+
+#endif 	/* MERCURY_TRACE_COMMAND_QUEUE_H */
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.240
diff -u -b -r1.240 mercury_trace_internal.c
--- trace/mercury_trace_internal.c	14 Jan 2008 00:08:04 -0000	1.240
+++ trace/mercury_trace_internal.c	19 Feb 2008 12:49:14 -0000
@@ -39,6 +39,7 @@
 #include "mercury_trace_hold_vars.h"
 #include "mercury_trace_readline.h"
 #include "mercury_trace_source.h"
+#include "mercury_trace_command_queue.h"
 
 #include "mercury_trace_cmd_forward.h"
 #include "mercury_trace_cmd_backward.h"
@@ -160,8 +161,7 @@
 
 MR_bool             MR_trace_internal_interacting = MR_FALSE;
 
-static  MR_Line     *MR_line_head = NULL;
-static  MR_Line     *MR_line_tail = NULL;
+MR_bool             MR_trace_echo_queue_commands = MR_FALSE;
 
 static  void        MR_trace_internal_ensure_init(void);
 static  MR_bool     MR_trace_internal_create_mdb_window(void);
@@ -334,14 +334,21 @@
             fprintf(MR_mdb_out, MR_trace_banner, MR_VERSION);
         }
 
+        if (getenv("MERCURY_DEBUG_ECHO_QUEUE_COMMANDS") != NULL) {
+            MR_trace_echo_queue_commands = MR_TRUE;
+        }
+
         env = getenv("LINES");
         if (env != NULL && MR_trace_is_natural_number(env, &n)) {
             MR_scroll_limit = n;
         }
 
         /*
-        ** These functions add the commands to the front of the queue, so
-        ** we call them in the reverse order we want the commands executed.
+        ** We call these functions in this order because we want the .mdbrc
+        ** file in the current (local) directory to be able to override
+        ** any actions from the system's standard .mdbrc file, and the
+        ** .mdbrc file (if any) referred to by the current setting of the
+        ** MERCURY_DEBUGGER_INIT environment to override both.
         */
         MR_trace_internal_init_from_home_dir();
         MR_trace_internal_init_from_local();
@@ -624,7 +631,7 @@
     char    *init;
 
     init = getenv("MERCURY_DEBUGGER_INIT");
-    if (init != NULL) {
+    if (init != NULL && strlen(init) > 0) {
         (void) MR_trace_source(init, MR_FALSE, NULL, 0);
         /* If the source failed, the error message has been printed. */
     }
@@ -693,12 +700,16 @@
 MR_trace_source_from_open_file(FILE *fp, char **args, int num_args)
 {
     char    *contents;
-    MR_Line *line;
-    MR_Line *prev_line;
-    MR_Line *old_head;
+    MR_CmdLines *line;
+    MR_CmdLines *first_line;
+    MR_CmdLines *prev_line;
+
+    /*
+    ** Invariant: either both first_line and prev_line are NULL, or neither is.
+    */
 
+    first_line = NULL;
     prev_line = NULL;
-    old_head = MR_line_head;
 
     /*
     ** Insert the sourced commands at the front of the command queue,
@@ -708,24 +719,21 @@
     while ((contents = MR_trace_readline_from_script(fp, args, num_args))
         != NULL)
     {
-        line = MR_NEW(MR_Line);
-        line->MR_line_contents = MR_copy_string(contents);
+        line = MR_NEW(MR_CmdLines);
+        line->MR_cmd_line_contents = MR_copy_string(contents);
+        line->MR_cmd_line_next = NULL;
 
-        if (prev_line == NULL) {
-            MR_line_head = line;
+        if (first_line == NULL) {
+            first_line = line;
         } else {
-            prev_line->MR_line_next = line;
+            MR_assert(prev_line != NULL);
+            prev_line->MR_cmd_line_next = line;
         }
 
         prev_line = line;
     }
 
-    if (prev_line != NULL) {
-        prev_line->MR_line_next = old_head;
-        if (MR_line_tail == NULL) {
-            MR_line_tail = prev_line;
-        }
-    }
+    MR_insert_command_lines_at_tail(first_line);
 
     MR_trace_internal_interacting = MR_FALSE;
 }
@@ -1233,7 +1241,7 @@
 {
     char    *line;
 
-    line = MR_trace_getline_queue();
+    line = MR_trace_getline_command_queue();
     if (line != NULL) {
         return line;
     }
@@ -1251,67 +1259,6 @@
 }
 
 /*
-** If there any lines waiting in the queue, return the first of these.
-** The memory for the line will have been allocated with MR_malloc(),
-** and it is the caller's resposibility to MR_free() it when appropriate.
-** If there are no lines in the queue, this function returns NULL.
-*/
-
-char *
-MR_trace_getline_queue(void)
-{
-    if (MR_line_head != NULL) {
-        MR_Line *old;
-        char    *contents;
-
-        old = MR_line_head;
-        contents = MR_line_head->MR_line_contents;
-        MR_line_head = MR_line_head->MR_line_next;
-        if (MR_line_head == NULL) {
-            MR_line_tail = NULL;
-        }
-
-        MR_free(old);
-        return contents;
-    } else {
-        return NULL;
-    }
-}
-
-void
-MR_insert_line_at_head(const char *contents)
-{
-    MR_Line *line;
-
-    line = MR_NEW(MR_Line);
-    line->MR_line_contents = MR_copy_string(contents);
-    line->MR_line_next = MR_line_head;
-
-    MR_line_head = line;
-    if (MR_line_tail == NULL) {
-        MR_line_tail = MR_line_head;
-    }
-}
-
-void
-MR_insert_line_at_tail(const char *contents)
-{
-    MR_Line *line;
-
-    line = MR_NEW(MR_Line);
-    line->MR_line_contents = MR_copy_string(contents);
-    line->MR_line_next = NULL;
-
-    if (MR_line_tail == NULL) {
-        MR_line_tail = line;
-        MR_line_head = line;
-    } else {
-        MR_line_tail->MR_line_next = line;
-        MR_line_tail = line;
-    }
-}
-
-/*
 ** This returns MR_TRUE iff the given line continues on to the next line,
 ** because the newline is in quotes or escaped.  The second parameter
 ** indicates whether we are inside quotes or not, and is updated by
@@ -1342,7 +1289,7 @@
             ** later.
             */
             *ptr = '\0';
-            MR_insert_line_at_head(MR_copy_string(ptr + 1));
+            MR_insert_command_line_at_head(MR_copy_string(ptr + 1));
             return MR_FALSE;
         }
 
Index: trace/mercury_trace_internal.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_internal.h,v
retrieving revision 1.24
diff -u -b -r1.24 mercury_trace_internal.h
--- trace/mercury_trace_internal.h	29 Nov 2006 05:18:40 -0000	1.24
+++ trace/mercury_trace_internal.h	19 Feb 2008 12:49:50 -0000
@@ -29,7 +29,6 @@
 extern  void        MR_trace_event_print_internal_report(
                         MR_EventInfo *event_info);
 
-
 /*
 ** Debugger I/O streams.
 ** Replacements for stdin/stdout/stderr respectively.
@@ -51,25 +50,11 @@
 extern  MR_bool         MR_trace_internal_interacting;
 
 /*
-** The structure of the input queue, and the operations that work on it.
-*/
-
-typedef struct MR_Line_Struct {
-    char                    *MR_line_contents;
-    struct MR_Line_Struct   *MR_line_next;
-} MR_Line;
-
-extern  void        MR_insert_line_at_head(const char *contents);
-extern  void        MR_insert_line_at_tail(const char *contents);
-
-/*
-** If there any lines waiting in the queue, return the first of these.
-** The memory for the line will have been allocated with MR_malloc(),
-** and it is the caller's resposibility to MR_free() it when appropriate.
-** If there are no lines in the queue, this function returns NULL.
+** If this true, we print every command we get from the command queue
+** just before it is executed. This is intended for debugging the debugger.
 */
         
-extern  char        *MR_trace_getline_queue(void);
+extern  MR_bool         MR_trace_echo_queue_commands;
 
 /*  
 ** The details of the source server, if any.
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list