[m-rev.] for review: print lists on breakpoints
Zoltan Somogyi
zs at cs.mu.OZ.AU
Thu Jan 27 16:07:43 AEDT 2005
Allow uses to associate with each breakpoint in mdb a list of print actions
that should be executed automatically when execution arrives at the breakpoint.
A new print list (a list of things to be printed) can be attached to an
existing breakpoint via the new "break_print" command, or it can be attached
to a breakpoint being created via the existing "break" command.
NEWS:
Mention the new capability.
doc/user_guide.texi:
Document the new capability.
trace/mercury_trace_spy.[ch]:
Keep a print list with every breakpoint, and add functions to
manipulate print lists.
Convert this module to four space indentation to keep indent levels
manageable.
trace/mercury_trace.c:
Conform to the updated interface of the mercury_trace_spy module.
trace/mercury_trace_internal.[ch]:
When the internal debugger is invoked at an event, whether
interactively or not, take an extra parameter specifying the
print list, if any, to be executed.
Implement the new "break_print" command and the new options of
the "break" command.
Conform to the updated interface of the mercury_trace_spy module.
trace/mercury_trace_declarative.c:
Conform to the updated interface of the mercury_trace_internal module.
tests/debugger/breakpoints.{inp,exp*}:
Test the new capability.
tests/debugger/completion.exp:
tests/debugger/mdb_command_test.inp:
Update to reflect the new command.
cvs diff: Diffing .
Index: NEWS
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/NEWS,v
retrieving revision 1.367
diff -u -b -r1.367 NEWS
--- NEWS 25 Jan 2005 06:19:51 -0000 1.367
+++ NEWS 27 Jan 2005 04:58:02 -0000
@@ -56,8 +56,10 @@
Changes to the Mercury debugger:
* Users can now limit the output from stack traces.
* Users can now put breakpoints on unify and compare predicates.
+* Users can now arrange to have the goal and/or some variables printed
+ every time execution arrives at a breakpoint.
* Users can now save runtime values to files.
-* Ability to tell the declarative debugger to trust entire modules or
+* Users can now tell the declarative debugger to trust entire modules or
individual predicates or functions.
Changes to the compiler back-ends:
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/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.412
diff -u -b -r1.412 user_guide.texi
--- doc/user_guide.texi 25 Jan 2005 07:10:56 -0000 1.412
+++ doc/user_guide.texi 25 Jan 2005 07:14:01 -0000
@@ -1922,6 +1922,19 @@
@sp 1
Neither of these will happen if the break point is disabled.
@sp 1
+Every break point has a print list.
+Every time execution stops at an event that matches the breakpoint,
+mdb implicitly executes a print command for each element
+in the breakpoint's print list.
+A print list element can be the word @samp{goal},
+which causes the goal to the printed as if by @samp{print goal};
+it can be the word @samp{*},
+which causes all the variables to the printed as if by @samp{print *};
+or it can be the name or number of a variable,
+possibly followed (without white space) by term path,
+which causes the specified variable or part thereof to the printed
+as if the element were given as an argument to the @samp{print} command.
+ at sp 1
@item strict commands
@cindex strict debugger commands
When a debugger command steps over some events
@@ -2887,7 +2900,7 @@
@sp 1
@table @code
- at item break [-PS] [-E at var{ignore-count}] [-I at var{ignore-count}] @var{filename}:@var{linenumber}
+ at item break [-PS] [-E at var{ignore-count}] [-I at var{ignore-count}] [-n] [-p at var{print-spec}]* @var{filename}:@var{linenumber}
@kindex break (mdb command)
Puts a break point on the specified line of the specified source file,
if there is an event or a call at that position.
@@ -2908,9 +2921,20 @@
until after @var{ignore-count} occurrences of interface events
that match the breakpoint.
@sp 1
-By default, the initial state of the break point is @samp{stop},
-and the ignore count is zero.
- at item break [-AOPSaei] [-E at var{ignore-count}] [-I at var{ignore-count}] @var{proc-spec}
+Each occurrence of the options
+ at samp{-p at var{printspec}} and @samp{--print-list @var{printspec}}
+tells the debugger to include the specified entity
+in the breakpoint's print list.
+ at sp 1
+Normally, if a variable with the given name or number doesn't exist
+when execution reaches the breakpoint, mdb will issue a warning.
+The option @samp{-n} or @samp{--no-warn}, if present, suppresses this warning.
+This can be useful if e.g. the name is the name of an output variable,
+which of course won't be present at call events.
+ at sp 1
+By default, the action of the break point is @samp{stop},
+the ignore count is zero, and the print list is empty.
+ at item break [-AOPSaei] [-E at var{ignore-count}] [-I at var{ignore-count}] [-n] [-p at var{print-spec}]* @var{proc-spec}
@c <module name> <predicate name> [<arity> [<mode> [<predfunc>]]]
Puts a break point on the specified procedure.
@sp 1
@@ -2947,11 +2971,22 @@
until after @var{ignore-count} occurrences of interface events
that match the breakpoint.
@sp 1
+Each occurrence of the options
+ at samp{-p at var{printspec}} and @samp{--print-list @var{printspec}}
+tells the debugger to include the specified entity
+in the breakpoint's print list.
+ at sp 1
+Normally, if a variable with the given name or number doesn't exist
+when execution reaches the breakpoint, mdb will issue a warning.
+The option @samp{-n} or @samp{--no-warn}, if present, suppresses this warning.
+This can be useful if e.g. the name is the name of an output variable,
+which of course won't be present at call events.
+ at sp 1
By default, the action of the break point is @samp{stop},
its invocation condition is @samp{interface},
-and the ignore count is zero.
+the ignore count is zero, and the print list is empty.
@sp 1
- at item break [-PS] [-E at var{ignore-count}] [-I at var{ignore-count}] here
+ at item break [-PS] [-E at var{ignore-count}] [-I at var{ignore-count}] [-n] [-p at var{print-spec}]* here
Puts a break point on the procedure referred to by the current event,
with the invocation condition being the event at the current location
in the procedure body.
@@ -2970,11 +3005,22 @@
until after @var{ignore-count} occurrences of interface events
that match the breakpoint.
@sp 1
-By default, the initial state of the break point is @samp{stop},
-and the ignore count is zero.
+Each occurrence of the options
+ at samp{-p at var{printspec}} and @samp{--print-list @var{printspec}}
+tells the debugger to include the specified entity
+in the breakpoint's print list.
+ at sp 1
+Normally, if a variable with the given name or number doesn't exist
+when execution reaches the breakpoint, mdb will issue a warning.
+The option @samp{-n} or @samp{--no-warn}, if present, suppresses this warning.
+This can be useful if e.g. the name is the name of an output variable,
+which of course won't be present at call events.
+ at sp 1
+By default, the action of the break point is @samp{stop},
+the ignore count is zero, and the print list is empty.
@sp 1
@item break info
-Lists the details and status of all break points.
+Lists the details, status and print lists of all break points.
@sp 1
@item ignore [-E at var{ignore-count}] [-I at var{ignore-count}] @var{num}
@sp 1
@@ -3009,6 +3055,27 @@
the default is to ignore one call event
that matches the most recently added breakpoint.
Reports an error if the most recently added breakpoint has since been deleted.
+ at sp 1
+ at item break_print [-fpv] [-e] [-n] @var{num} @var{print-spec}*
+ at sp 1
+Adds the specified print list elements (there may be more than one)
+to the print list of the brakpoint numbered @var{num}.
+ at sp 1
+Normally, if a variable with the given name or number doesn't exist
+when execution reaches the breakpoint, mdb will issue a warning.
+The option @samp{-n} or @samp{--no-warn}, if present, suppresses this warning.
+This can be useful if e.g. the name is the name of an output variable,
+which of course won't be present at call events.
+ at sp 1
+Normally, the specified elements will be added
+at the start of the breakpoint's print list.
+The option @samp{-e} or @samp{--end}, if present,
+causes them to be added at the end.
+ at sp 1
+By default, the the specified elements will be printed with format "flat".
+The options @samp{-f} or @samp{--flat}, @samp{-p} or @samp{--pretty},
+and @samp{-v} or @samp{--verbose}, if given,
+explicitly specify the format to use.
@sp 1
@item disable @var{num}
@kindex disable (mdb command)
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/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/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
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/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
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/odbc
cvs diff: Diffing extras/posix
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/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
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 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/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
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 tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
Index: tests/debugger/breakpoints.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/breakpoints.exp,v
retrieving revision 1.12
diff -u -b -r1.12 breakpoints.exp
--- tests/debugger/breakpoints.exp 17 Jan 2005 04:29:28 -0000 1.12
+++ tests/debugger/breakpoints.exp 25 Jan 2005 16:52:57 -0000
@@ -90,16 +90,51 @@
3: - stop entry pred breakpoints.qperm/2-0 (nondet)
mdb> break nodiag
0: + stop interface pred breakpoints.nodiag/3-0 (semidet)
+mdb> break_print -v -n 1 HeadVar__1 HeadVar__2
+ 1: + stop interface pred breakpoints.qperm/2-0 (nondet)
+ HeadVar__1 (verbose, nowarn), HeadVar__2 (verbose, nowarn)
mdb> continue
E3: C3 CALL pred breakpoints.qperm/2-0 (nondet) breakpoints.m:64 (breakpoints.m:61)
+ HeadVar__1
+[|]
+1-1
+2-[|]
+ 1-2
+ 2-[|]
+ 1-3
+ 2-[|]/2
+
+mdb> break_print 1 none
+ 1: + stop interface pred breakpoints.qperm/2-0 (nondet)
+mdb> set -p depth 10
+mdb> set -p size 20
+mdb> break_print -p -n 1 HeadVar__1 HeadVar__2
+ 1: + stop interface pred breakpoints.qperm/2-0 (nondet)
+ HeadVar__1 (pretty, nowarn), HeadVar__2 (pretty, nowarn)
mdb> continue
E4: C3 SWTC pred breakpoints.qperm/2-0 (nondet) s2; breakpoints.m:65
mdb> finish -N
E5: C4 CALL pred breakpoints.qperm/2-0 (nondet) breakpoints.m:64 (breakpoints.m:68)
+ HeadVar__1
+[2, 3, 4, 5]
mdb> finish -n
E6: C4 EXIT pred breakpoints.qperm/2-0 (nondet) breakpoints.m:64 (breakpoints.m:68)
+ HeadVar__1
+[2, 3, 4, 5]
+ HeadVar__2
+[2, 3, 4, 5]
+mdb> break_print 1 none
+ 1: + stop interface pred breakpoints.qperm/2-0 (nondet)
+mdb> break_print -f -n 1 HeadVar__1
+ 1: + stop interface pred breakpoints.qperm/2-0 (nondet)
+ HeadVar__1 (flat, nowarn)
+mdb> break_print -f -e -n 1 HeadVar__2
+ 1: + stop interface pred breakpoints.qperm/2-0 (nondet)
+ HeadVar__1 (flat, nowarn), HeadVar__2 (flat, nowarn)
mdb> continue
E7: C3 EXIT pred breakpoints.qperm/2-0 (nondet) breakpoints.m:64 (breakpoints.m:61)
+ HeadVar__1 [1, 2, 3, 4, 5]
+ HeadVar__2 [1, 2, 3, 4, 5]
mdb> continue
E8: C5 CALL pred breakpoints.safe/1-0 (semidet) breakpoints.m:74 (breakpoints.m:62)
mdb> finish
@@ -187,7 +222,36 @@
0: + stop interface func breakpoints.a.testmod.test_in_ab/0-0 (det)
mdb> break -O b.testmod.test_in_ab
1: + stop interface func breakpoints.b.testmod.test_in_ab/0-0 (det)
+mdb> delete *
+ 0: E stop interface func breakpoints.a.testmod.test_in_ab/0-0 (det)
+ 1: E stop interface func breakpoints.b.testmod.test_in_ab/0-0 (det)
+mdb> break -O -p goal test_in_a
+ 0: + stop interface func breakpoints.a.testmod.test_in_a/0-0 (det)
+ goal (flat)
+mdb> break -O -P -p HeadVar__1 test_in_b
+ 1: + print interface func breakpoints.b.testmod.test_in_b/0-0 (det)
+ HeadVar__1 (flat)
+mdb> break info
+ 0: + stop interface func breakpoints.a.testmod.test_in_a/0-0 (det)
+ goal (flat)
+ 1: + print interface func breakpoints.b.testmod.test_in_b/0-0 (det)
+ HeadVar__1 (flat)
mdb> continue
[1, 3, 5, 2, 4]
+ E14: C9 CALL func breakpoints.a.testmod.test_in_a/0-0 (det) breakpoints.a.testmod.m:10 (breakpoints.m:27)
+test_in_a = '_'
+mdb> break_print 0 none
+ 0: + stop interface func breakpoints.a.testmod.test_in_a/0-0 (det)
+mdb> break_print 0 *
+ 0: + stop interface func breakpoints.a.testmod.test_in_a/0-0 (det)
+ all (flat)
+mdb> continue
+ E15: C9 EXIT func breakpoints.a.testmod.test_in_a/0-0 (det) breakpoints.a.testmod.m:10 (breakpoints.m:27)
+ HeadVar__1 "a"
+mdb> continue
"a"
+ E16: C10 CALL func breakpoints.b.testmod.test_in_b/0-0 (det) breakpoints.b.testmod.m:10 (breakpoints.m:29)
+mdb: there is no variable named HeadVar__1.
+ E17: C10 EXIT func breakpoints.b.testmod.test_in_b/0-0 (det) breakpoints.b.testmod.m:10 (breakpoints.m:29)
+ HeadVar__1 "b"
"b"
Index: tests/debugger/breakpoints.exp2
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/breakpoints.exp2,v
retrieving revision 1.8
diff -u -b -r1.8 breakpoints.exp2
--- tests/debugger/breakpoints.exp2 17 Jan 2005 04:29:28 -0000 1.8
+++ tests/debugger/breakpoints.exp2 25 Jan 2005 19:28:16 -0000
@@ -98,16 +98,51 @@
3: - stop entry pred breakpoints.qperm/2-0 (nondet)
mdb> break nodiag
0: + stop interface pred breakpoints.nodiag/3-0 (semidet)
+mdb> break_print -v -n 1 HeadVar__1 HeadVar__2
+ 1: + stop interface pred breakpoints.qperm/2-0 (nondet)
+ HeadVar__1 (verbose, nowarn), HeadVar__2 (verbose, nowarn)
mdb> continue
E3: C3 CALL pred breakpoints.qperm/2-0 (nondet) breakpoints.m:64 (breakpoints.m:61)
+ HeadVar__1
+[|]
+1-1
+2-[|]
+ 1-2
+ 2-[|]
+ 1-3
+ 2-[|]/2
+
+mdb> break_print 1 none
+ 1: + stop interface pred breakpoints.qperm/2-0 (nondet)
+mdb> set -p depth 10
+mdb> set -p size 20
+mdb> break_print -p -n 1 HeadVar__1 HeadVar__2
+ 1: + stop interface pred breakpoints.qperm/2-0 (nondet)
+ HeadVar__1 (pretty, nowarn), HeadVar__2 (pretty, nowarn)
mdb> continue
E4: C3 SWTC pred breakpoints.qperm/2-0 (nondet) s2; breakpoints.m:65
mdb> finish -N
E5: C4 CALL pred breakpoints.qperm/2-0 (nondet) breakpoints.m:64 (breakpoints.m:68)
+ HeadVar__1
+[2, 3, 4, 5]
mdb> finish -n
E6: C4 EXIT pred breakpoints.qperm/2-0 (nondet) breakpoints.m:64 (breakpoints.m:68)
+ HeadVar__1
+[2, 3, 4, 5]
+ HeadVar__2
+[2, 3, 4, 5]
+mdb> break_print 1 none
+ 1: + stop interface pred breakpoints.qperm/2-0 (nondet)
+mdb> break_print -f -n 1 HeadVar__1
+ 1: + stop interface pred breakpoints.qperm/2-0 (nondet)
+ HeadVar__1 (flat, nowarn)
+mdb> break_print -f -e -n 1 HeadVar__2
+ 1: + stop interface pred breakpoints.qperm/2-0 (nondet)
+ HeadVar__1 (flat, nowarn), HeadVar__2 (flat, nowarn)
mdb> continue
E7: C3 EXIT pred breakpoints.qperm/2-0 (nondet) breakpoints.m:64 (breakpoints.m:61)
+ HeadVar__1 [1, 2, 3, 4, 5]
+ HeadVar__2 [1, 2, 3, 4, 5]
mdb> continue
E8: C5 CALL pred breakpoints.safe/1-0 (semidet) breakpoints.m:74 (breakpoints.m:62)
mdb> finish
@@ -195,7 +230,36 @@
0: + stop interface func breakpoints.a.testmod.test_in_ab/0-0 (det)
mdb> break -O b.testmod.test_in_ab
1: + stop interface func breakpoints.b.testmod.test_in_ab/0-0 (det)
+mdb> delete *
+ 0: E stop interface func breakpoints.a.testmod.test_in_ab/0-0 (det)
+ 1: E stop interface func breakpoints.b.testmod.test_in_ab/0-0 (det)
+mdb> break -O -p goal test_in_a
+ 0: + stop interface func breakpoints.a.testmod.test_in_a/0-0 (det)
+ goal (flat)
+mdb> break -O -P -p HeadVar__1 test_in_b
+ 1: + print interface func breakpoints.b.testmod.test_in_b/0-0 (det)
+ HeadVar__1 (flat)
+mdb> break info
+ 0: + stop interface func breakpoints.a.testmod.test_in_a/0-0 (det)
+ goal (flat)
+ 1: + print interface func breakpoints.b.testmod.test_in_b/0-0 (det)
+ HeadVar__1 (flat)
mdb> continue
[1, 3, 5, 2, 4]
+ E14: C9 CALL func breakpoints.a.testmod.test_in_a/0-0 (det) breakpoints.a.testmod.m:10 (breakpoints.m:27)
+test_in_a = '_'
+mdb> break_print 0 none
+ 0: + stop interface func breakpoints.a.testmod.test_in_a/0-0 (det)
+mdb> break_print 0 *
+ 0: + stop interface func breakpoints.a.testmod.test_in_a/0-0 (det)
+ all (flat)
+mdb> continue
+ E15: C9 EXIT func breakpoints.a.testmod.test_in_a/0-0 (det) breakpoints.a.testmod.m:10 (breakpoints.m:27)
+ HeadVar__1 "a"
+mdb> continue
"a"
+ E16: C10 CALL func breakpoints.b.testmod.test_in_b/0-0 (det) breakpoints.b.testmod.m:10 (breakpoints.m:29)
+mdb: there is no variable named HeadVar__1.
+ E17: C10 EXIT func breakpoints.b.testmod.test_in_b/0-0 (det) breakpoints.b.testmod.m:10 (breakpoints.m:29)
+ HeadVar__1 "b"
"b"
Index: tests/debugger/breakpoints.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/breakpoints.inp,v
retrieving revision 1.7
diff -u -b -r1.7 breakpoints.inp
--- tests/debugger/breakpoints.inp 17 Jan 2005 04:29:28 -0000 1.7
+++ tests/debugger/breakpoints.inp 25 Jan 2005 00:26:51 -0000
@@ -27,10 +27,18 @@
break info
disable 3
break nodiag
+break_print -v -n 1 HeadVar__1 HeadVar__2
continue
+break_print 1 none
+set -p depth 10
+set -p size 20
+break_print -p -n 1 HeadVar__1 HeadVar__2
continue
finish -N
finish -n
+break_print 1 none
+break_print -f -n 1 HeadVar__1
+break_print -f -e -n 1 HeadVar__2
continue
continue
finish
@@ -60,4 +68,12 @@
break -O testmod.test_in_ab
break -O a.testmod.test_in_ab
break -O b.testmod.test_in_ab
+delete *
+break -O -p goal test_in_a
+break -O -P -p HeadVar__1 test_in_b
+break info
+continue
+break_print 0 none
+break_print 0 *
+continue
continue
Index: tests/debugger/completion.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/completion.exp,v
retrieving revision 1.24
diff -u -b -r1.24 completion.exp
--- tests/debugger/completion.exp 17 Jan 2005 05:58:07 -0000 1.24
+++ tests/debugger/completion.exp 24 Jan 2005 06:32:47 -0000
@@ -3,38 +3,39 @@
Command echo enabled.
mdb> register --quiet
mdb>
-? excp quit
-P f r
-alias finish register
-all_class_decls flag retry
-all_procedures forward return
-all_regs g s
-all_type_ctors gen_stack save
-b goal_paths save_to_file
-break goto scope
-browse h scroll
-c help set
-cc_query histogram_all source
-class_decl histogram_exp stack
-clear_histogram ignore stack_default_limit
-consumer io_query stack_regs
-context label_stats step
-continue level subgoal
-current maxdepth table
-cut_stack mindepth table_io
-d mm_stacks term_size
-dd mmc_options trust
-dd_dd modules trusted
-debug_vars next type_ctor
-delete nondet_stack unalias
-disable p unhide_events
-document pneg_stack untrust
-document_category print up
-down print_optionals v
-e printlevel var_details
-echo proc_stats var_name_stats
-enable procedures vars
-exception query view
+? excp r
+P f register
+alias finish retry
+all_class_decls flag return
+all_procedures forward s
+all_regs g save
+all_type_ctors gen_stack save_to_file
+b goal_paths scope
+break goto scroll
+break_print h set
+browse help source
+c histogram_all stack
+cc_query histogram_exp stack_default_limit
+class_decl ignore stack_regs
+clear_histogram io_query step
+consumer label_stats subgoal
+context level table
+continue maxdepth table_io
+current mindepth term_size
+cut_stack mm_stacks trust
+d mmc_options trusted
+dd modules type_ctor
+dd_dd next unalias
+debug_vars nondet_stack unhide_events
+delete p untrust
+disable pneg_stack up
+document print v
+document_category print_optionals var_details
+down printlevel var_name_stats
+e proc_stats vars
+echo procedures view
+enable query
+exception quit
h help histogram_all histogram_exp
var_details var_name_stats vars view
var_details var_name_stats vars
Index: tests/debugger/mdb_command_test.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/mdb_command_test.inp,v
retrieving revision 1.35
diff -u -b -r1.35 mdb_command_test.inp
--- tests/debugger/mdb_command_test.inp 17 Jan 2005 05:58:08 -0000 1.35
+++ tests/debugger/mdb_command_test.inp 25 Jan 2005 19:27:01 -0000
@@ -25,6 +25,7 @@
save_to_file xyzzy xyzzy xyzzy xyzzy xyzzy
break xyzzy xyzzy xyzzy xyzzy xyzzy
ignore xyzzy xyzzy xyzzy xyzzy xyzzy
+break_print xyzzy xyzzy xyzzy xyzzy xyzzy
disable xyzzy xyzzy xyzzy xyzzy xyzzy
enable xyzzy xyzzy xyzzy xyzzy xyzzy
delete xyzzy xyzzy xyzzy xyzzy xyzzy
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/recompilation
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.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace.c,v
retrieving revision 1.76
diff -u -b -r1.76 mercury_trace.c
--- trace/mercury_trace.c 10 Jan 2005 05:23:53 -0000 1.76
+++ trace/mercury_trace.c 23 Jan 2005 14:47:36 -0000
@@ -69,9 +69,10 @@
};
MR_Code *MR_trace_real(const MR_Label_Layout *layout);
-static MR_Code *MR_trace_event(MR_Trace_Cmd_Info *cmd, MR_bool interactive,
- const MR_Label_Layout *layout, MR_Trace_Port port,
- MR_Unsigned seqno, MR_Unsigned depth);
+static MR_Code *MR_trace_event(MR_Trace_Cmd_Info *cmd,
+ MR_bool interactive, const MR_Label_Layout *layout,
+ MR_Trace_Port port, MR_Unsigned seqno,
+ MR_Unsigned depth);
static MR_bool MR_in_traced_region(const MR_Proc_Layout *proc_layout,
MR_Word *base_sp, MR_Word *base_curfr);
static MR_bool MR_is_io_state(MR_PseudoTypeInfo pti);
@@ -344,7 +345,21 @@
}
#endif
- match = MR_event_matches_spy_point(layout, port, &action);
+ {
+ /*
+ ** We ignore the print_list computed here, because we want to
+ ** execute the print list of a matched spy point even if the event
+ ** is the end event of a command. In that case, the code above
+ ** invokes MR_trace_event directly without coming here. We
+ ** therefore invoke MR_event_matches_spy_point in MR_trace_event.
+ ** The invocation here is only to find out if we want to stop.
+ */
+
+ MR_Spy_Print_List print_list;
+ match = MR_event_matches_spy_point(layout, port, &action,
+ &print_list);
+ }
+
if (! match) {
if (MR_trace_ctrl.MR_trace_print_level == MR_PRINT_LEVEL_ALL) {
return MR_trace_event(&MR_trace_ctrl, MR_FALSE, layout, port,
@@ -457,7 +472,12 @@
jumpaddr = MR_trace_event_external(cmd, &event_info);
} else {
- jumpaddr = MR_trace_event_internal(cmd, interactive, &event_info);
+ MR_Spy_Action action; /* ignored */
+ MR_Spy_Print_List print_list;
+
+ (void) MR_event_matches_spy_point(layout, port, &action, &print_list);
+ jumpaddr = MR_trace_event_internal(cmd, interactive, print_list,
+ &event_info);
}
#else
/*
Index: trace/mercury_trace_declarative.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_declarative.c,v
retrieving revision 1.78
diff -u -b -r1.78 mercury_trace_declarative.c
--- trace/mercury_trace_declarative.c 24 Jan 2005 07:53:38 -0000 1.78
+++ trace/mercury_trace_declarative.c 25 Jan 2005 02:51:08 -0000
@@ -318,7 +318,7 @@
(unsigned long) event_info->MR_event_number,
(unsigned long) MR_edt_last_event);
MR_trace_decl_mode = MR_TRACE_INTERACTIVE;
- return MR_trace_event_internal(cmd, MR_TRUE, event_info);
+ return MR_trace_event_internal(cmd, MR_TRUE, NULL, event_info);
}
if (!MR_PROC_LAYOUT_HAS_EXEC_TRACE(entry)) {
@@ -1427,7 +1427,7 @@
MR_trace_decl_mode = MR_TRACE_INTERACTIVE;
MR_debug_enabled = MR_TRUE;
MR_update_trace_func_enabled();
- return MR_trace_event_internal(cmd, MR_TRUE, event_info);
+ return MR_trace_event_internal(cmd, MR_TRUE, NULL, event_info);
}
return jumpaddr;
@@ -1552,7 +1552,7 @@
MR_trace_call_depth = event_details->MR_call_depth;
MR_trace_event_number = event_details->MR_event_number;
- return MR_trace_event_internal(cmd, MR_TRUE, event_info);
+ return MR_trace_event_internal(cmd, MR_TRUE, NULL, event_info);
}
if (MR_trace_decl_in_dd_dd_mode) {
@@ -1697,7 +1697,7 @@
MR_trace_decl_mode = MR_TRACE_INTERACTIVE;
MR_debug_enabled = MR_TRUE;
MR_update_trace_func_enabled();
- return MR_trace_event_internal(cmd, MR_TRUE, event_info);
+ return MR_trace_event_internal(cmd, MR_TRUE, NULL, event_info);
}
cmd->MR_trace_cmd = MR_CMD_GOTO;
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.188
diff -u -b -r1.188 mercury_trace_internal.c
--- trace/mercury_trace_internal.c 24 Jan 2005 07:53:38 -0000 1.188
+++ trace/mercury_trace_internal.c 25 Jan 2005 13:57:46 -0000
@@ -431,6 +431,7 @@
static MR_TraceCmdFunc MR_trace_cmd_save_to_file;
static MR_TraceCmdFunc MR_trace_cmd_break;
static MR_TraceCmdFunc MR_trace_cmd_ignore;
+static MR_TraceCmdFunc MR_trace_cmd_break_print;
static MR_TraceCmdFunc MR_trace_cmd_enable;
static MR_TraceCmdFunc MR_trace_cmd_disable;
static MR_TraceCmdFunc MR_trace_cmd_delete;
@@ -506,6 +507,9 @@
MR_bool detailed, int frame_limit, int line_limit);
static void MR_trace_cmd_nondet_stack_2(MR_Event_Info *event_info,
MR_bool detailed, int frame_limit, int line_limit);
+static MR_Spy_Print_List MR_add_to_print_list_end(MR_Browse_Format format,
+ char *word, MR_bool warn,
+ MR_Spy_Print_List print_list);
static MR_bool MR_trace_options_movement_cmd(MR_Trace_Cmd_Info *cmd,
char ***words, int *word_count,
@@ -517,6 +521,7 @@
static MR_bool MR_trace_options_when_action_multi_ignore(MR_Spy_When *when,
MR_Spy_Action *action, MR_MultiMatch *multi_match,
MR_Spy_Ignore_When *ignore_when, int *ignore_count,
+ MR_Spy_Print_List *print_list,
char ***words, int *word_count,
const char *cat, const char *item);
static MR_bool MR_trace_options_ignore_count(MR_Spy_Ignore_When *ignore_when,
@@ -526,6 +531,9 @@
int *word_count, const char *cat, const char *item);
static MR_bool MR_trace_options_ignore(MR_bool *ignore_errors, char ***words,
int *word_count, const char *cat, const char *item);
+static MR_bool MR_trace_options_break_print(MR_Browse_Format *format,
+ MR_bool *at_start, MR_bool *warn, char ***words,
+ int *word_count, const char *cat, const char *item);
static MR_bool MR_trace_options_detailed(MR_bool *detailed, char ***words,
int *word_count, const char *cat, const char *item);
static MR_bool MR_trace_options_stack_trace(MR_bool *detailed,
@@ -566,6 +574,9 @@
const char *item);
static void MR_trace_usage(const char *cat, const char *item);
static void MR_trace_do_noop(void);
+static void MR_mdb_print_proc_id_and_nl(void *data,
+ const MR_Proc_Layout *entry_layout);
+static int MR_trace_var_print_list(MR_Spy_Print_List print_list);
static const MR_Proc_Layout *
MR_find_single_matching_proc(MR_Proc_Spec *spec,
@@ -675,6 +686,10 @@
static void MR_trace_source_from_open_file(FILE *fp);
static char *MR_trace_getline_queue(void);
static MR_bool MR_trace_continue_line(char *ptr, MR_bool *quoted);
+static MR_Code *MR_trace_event_internal_report(MR_Trace_Cmd_Info *cmd,
+ MR_Spy_Print_List print_list,
+ MR_Event_Info *event_info);
+
static void MR_insert_line_at_head(const char *line);
static void MR_insert_line_at_tail(const char *line);
@@ -691,7 +706,7 @@
MR_Code *
MR_trace_event_internal(MR_Trace_Cmd_Info *cmd, MR_bool interactive,
- MR_Event_Info *event_info)
+ MR_Spy_Print_List print_list, MR_Event_Info *event_info)
{
MR_Code *jumpaddr;
char *line;
@@ -700,7 +715,8 @@
const char *prompt;
if (! interactive) {
- return MR_trace_event_internal_report(cmd, event_info);
+ return MR_trace_event_internal_report(cmd, print_list,
+ event_info);
}
if (MR_trace_decl_mode != MR_TRACE_INTERACTIVE) {
@@ -740,6 +756,8 @@
event_info->MR_saved_regs, event_info->MR_trace_port,
MR_print_optionals);
+ (void) MR_trace_var_print_list(print_list);
+
/* by default, return where we came from */
jumpaddr = NULL;
@@ -1384,6 +1402,72 @@
MR_print_proc_id_and_nl(fp, entry_layout);
}
+static int
+MR_trace_var_print_list(MR_Spy_Print_List print_list)
+{
+ MR_Spy_Print node;
+ const char *problem;
+ char *after_problem;
+ int count;
+
+ count = 0;
+ for (; print_list != NULL; print_list = print_list->pl_next) {
+ count++;
+ node = print_list->pl_cur;
+ after_problem = NULL;
+
+ switch (node->p_what) {
+ case MR_SPY_PRINT_ALL:
+ problem = MR_trace_browse_all(MR_mdb_out,
+ MR_trace_browse_internal,
+ node->p_format);
+ break;
+
+ case MR_SPY_PRINT_GOAL:
+ problem = MR_trace_browse_one_goal(MR_mdb_out,
+ MR_trace_browse_goal_internal,
+ MR_BROWSE_CALLER_PRINT,
+ node->p_format);
+ break;
+
+ case MR_SPY_PRINT_ONE:
+ problem = MR_trace_parse_browse_one(MR_mdb_out,
+ MR_TRUE, node->p_name,
+ MR_trace_browse_internal,
+ MR_BROWSE_CALLER_PRINT, node->p_format,
+ MR_FALSE);
+ if (problem != NULL && MR_streq(problem,
+ "there is no such variable"))
+ {
+ if (node->p_warn) {
+ problem = "there is no "
+ "variable named";
+ after_problem = node->p_name;
+ } else {
+ problem = NULL;
+ }
+ }
+
+ break;
+
+ default:
+ MR_fatal_error("invalid node->p_what");
+ break;
+ }
+
+ if (problem != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: %s", problem);
+ if (after_problem != NULL) {
+ fprintf(MR_mdb_err, " %s", after_problem);
+ }
+ fprintf(MR_mdb_err, ".\n");
+ }
+ }
+
+ return count;
+}
+
/* Options to pass to mmc when compiling queries. */
static char *MR_mmc_options = NULL;
@@ -2436,6 +2520,7 @@
MR_MultiMatch multi_match;
MR_Spy_Ignore_When ignore_when;
int ignore_count;
+ MR_Spy_Print_List print_list;
const char *file;
int line;
int breakline;
@@ -2450,7 +2535,7 @@
count = 0;
for (i = 0; i < MR_spy_point_next; i++) {
if (MR_spy_points[i]->spy_exists) {
- MR_print_spy_point(MR_mdb_out, i);
+ MR_print_spy_point(MR_mdb_out, i, MR_TRUE);
count++;
}
}
@@ -2472,8 +2557,9 @@
*/
ignore_when = MR_SPY_DONT_IGNORE;
ignore_count = 0;
+ print_list = NULL;
if (! MR_trace_options_when_action_multi_ignore(&when, &action,
- &multi_match, &ignore_when, &ignore_count,
+ &multi_match, &ignore_when, &ignore_count, &print_list,
&words, &word_count, "breakpoint", "break"))
{
; /* the usage message has already been printed */
@@ -2501,7 +2587,7 @@
MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
slot = MR_add_proc_spy_point(MR_SPY_SPECIFIC, action,
ignore_when, ignore_count,
- layout->MR_sll_entry, layout,
+ layout->MR_sll_entry, layout, print_list,
&problem);
MR_maybe_print_spy_point(slot, problem);
} else if (word_count == 2 && MR_parse_proc_spec(words[1], &spec)) {
@@ -2517,7 +2603,7 @@
} else if (matches.match_proc_next == 1) {
slot = MR_add_proc_spy_point(when, action,
ignore_when, ignore_count,
- matches.match_procs[0], NULL,
+ matches.match_procs[0], NULL, print_list,
&problem);
MR_maybe_print_spy_point(slot, problem);
} else if (multi_match == MR_MULTIMATCH_ALL) {
@@ -2528,7 +2614,7 @@
when, action,
ignore_when, ignore_count,
matches.match_procs[i], NULL,
- &problem);
+ print_list, &problem);
MR_maybe_print_spy_point(slot,
problem);
}
@@ -2570,7 +2656,7 @@
ignore_when,
ignore_count,
matches.match_procs[i],
- NULL, &problem);
+ NULL, print_list, &problem);
MR_maybe_print_spy_point(
slot, problem);
}
@@ -2585,7 +2671,7 @@
ignore_when,
ignore_count,
matches.match_procs[i],
- NULL, &problem);
+ NULL, print_list, &problem);
MR_maybe_print_spy_point(
slot, problem);
} else {
@@ -2604,7 +2690,7 @@
int slot;
slot = MR_add_line_spy_point(action, ignore_when,
- ignore_count, file, line, &problem);
+ ignore_count, file, line, print_list, &problem);
MR_maybe_print_spy_point(slot, problem);
} else if (word_count == 2 &&
MR_trace_is_natural_number(words[1], &breakline))
@@ -2614,7 +2700,7 @@
if (MR_find_context(layout, &file, &line)) {
slot = MR_add_line_spy_point(action,
ignore_when, ignore_count,
- file, breakline, &problem);
+ file, breakline, print_list, &problem);
MR_maybe_print_spy_point(slot, problem);
} else {
MR_fatal_error("cannot find current filename");
@@ -2697,6 +2783,97 @@
}
static MR_Next
+MR_trace_cmd_break_print(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
+ MR_Event_Info *event_info, MR_Event_Details *event_details,
+ MR_Code **jumpaddr)
+{
+ int n;
+ int i;
+ MR_Browse_Format format;
+ MR_bool at_start;
+ MR_bool warn;
+ MR_Spy_Print_List print_list;
+
+ if (! MR_trace_options_break_print(&format, &at_start, &warn,
+ &words, &word_count, "breakpoint", "break_print"))
+ {
+ ; /* the usage message has already been printed */
+ } else if (word_count > 2 && MR_trace_is_natural_number(words[1], &n))
+ {
+ if (word_count == 3 && MR_streq(words[2], "none")) {
+ MR_clear_spy_point_print_list(n);
+ MR_print_spy_point(MR_mdb_out, n, MR_TRUE);
+ } else if (0 <= n && n < MR_spy_point_next
+ && MR_spy_points[n]->spy_exists)
+ {
+ print_list = NULL;
+ for (i = 2; i < word_count; i++) {
+ print_list = MR_add_to_print_list_end(format,
+ words[i], warn, print_list);
+ }
+
+ if (at_start) {
+ MR_add_spy_point_print_list_start(n,
+ print_list);
+ } else {
+ MR_add_spy_point_print_list_end(n,
+ print_list);
+ }
+
+ MR_print_spy_point(MR_mdb_out, n, MR_TRUE);
+ } else {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: break point #%d "
+ "does not exist.\n",
+ n);
+ }
+ } else {
+ MR_trace_usage("breakpoint", "break_print");
+ }
+
+ return KEEP_INTERACTING;
+}
+
+static MR_Spy_Print_List
+MR_add_to_print_list_end(MR_Browse_Format format, char *word, MR_bool warn,
+ MR_Spy_Print_List print_list)
+{
+ MR_Spy_Print_List list;
+ MR_Spy_Print_List new_list;
+ MR_Spy_Print new_node;
+
+ new_node = MR_malloc(sizeof(struct MR_Spy_Print_Struct));
+ new_node->p_format = format;
+ new_node->p_warn = warn;
+ if (MR_streq(word, "*")) {
+ new_node->p_what = MR_SPY_PRINT_ALL;
+ new_node->p_name = NULL;
+ } else if (MR_streq(word, "goal")) {
+ new_node->p_what = MR_SPY_PRINT_GOAL;
+ new_node->p_name = NULL;
+ } else {
+ new_node->p_what = MR_SPY_PRINT_ONE;
+ new_node->p_name = MR_copy_string(word);
+ }
+
+ new_list = MR_malloc(sizeof(struct MR_Spy_Print_List_Struct));
+ new_list->pl_cur = new_node;
+ new_list->pl_next = NULL;
+
+ list = print_list;
+ if (list == NULL) {
+ return new_list;
+ }
+
+ while (list->pl_next != NULL) {
+ list = list->pl_next;
+ }
+
+ list->pl_next = new_list;
+ return print_list;
+}
+
+static MR_Next
MR_trace_cmd_enable(char **words, int word_count, MR_Trace_Cmd_Info *cmd,
MR_Event_Info *event_info, MR_Event_Details *event_details,
MR_Code **jumpaddr)
@@ -2708,7 +2885,7 @@
&& MR_spy_points[n]->spy_exists)
{
MR_spy_points[n]->spy_enabled = MR_TRUE;
- MR_print_spy_point(MR_mdb_out, n);
+ MR_print_spy_point(MR_mdb_out, n, MR_FALSE);
} else {
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: break point #%d "
@@ -2723,7 +2900,7 @@
for (i = 0; i < MR_spy_point_next; i++) {
if (MR_spy_points[i]->spy_exists) {
MR_spy_points[i]->spy_enabled = MR_TRUE;
- MR_print_spy_point(MR_mdb_out, i);
+ MR_print_spy_point(MR_mdb_out, i, MR_FALSE);
count++;
}
}
@@ -2741,7 +2918,7 @@
MR_spy_points[MR_most_recent_spy_point]
->spy_enabled = MR_TRUE;
MR_print_spy_point(MR_mdb_out,
- MR_most_recent_spy_point);
+ MR_most_recent_spy_point, MR_FALSE);
} else {
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: there is no "
@@ -2766,7 +2943,7 @@
&& MR_spy_points[n]->spy_exists)
{
MR_spy_points[n]->spy_enabled = MR_FALSE;
- MR_print_spy_point(MR_mdb_out, n);
+ MR_print_spy_point(MR_mdb_out, n, MR_FALSE);
} else {
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: break point #%d "
@@ -2782,7 +2959,7 @@
if (MR_spy_points[i]->spy_exists) {
MR_spy_points[i]->spy_enabled =
MR_FALSE;
- MR_print_spy_point(MR_mdb_out, i);
+ MR_print_spy_point(MR_mdb_out, i, MR_FALSE);
count++;
}
}
@@ -2801,7 +2978,7 @@
MR_spy_points[MR_most_recent_spy_point]
->spy_enabled = MR_FALSE;
MR_print_spy_point(MR_mdb_out,
- MR_most_recent_spy_point);
+ MR_most_recent_spy_point, MR_FALSE);
} else {
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "There is no "
@@ -2826,7 +3003,7 @@
&& MR_spy_points[n]->spy_exists)
{
MR_spy_points[n]->spy_exists = MR_FALSE;
- MR_print_spy_point(MR_mdb_out, n);
+ MR_print_spy_point(MR_mdb_out, n, MR_FALSE);
MR_delete_spy_point(n);
} else {
fflush(MR_mdb_out);
@@ -2842,7 +3019,7 @@
for (i = 0; i < MR_spy_point_next; i++) {
if (MR_spy_points[i]->spy_exists) {
MR_spy_points[i]->spy_exists = MR_FALSE;
- MR_print_spy_point(MR_mdb_out, i);
+ MR_print_spy_point(MR_mdb_out, i, MR_FALSE);
MR_delete_spy_point(i);
count++;
}
@@ -2863,7 +3040,7 @@
slot = MR_most_recent_spy_point;
MR_spy_points[slot]-> spy_exists = MR_FALSE;
- MR_print_spy_point(MR_mdb_out, slot);
+ MR_print_spy_point(MR_mdb_out, slot, MR_FALSE);
MR_delete_spy_point(slot);
} else {
fflush(MR_mdb_out);
@@ -5796,7 +5973,7 @@
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: %s.\n", problem);
} else {
- MR_print_spy_point(MR_mdb_out, slot);
+ MR_print_spy_point(MR_mdb_out, slot, MR_TRUE);
}
}
@@ -6086,6 +6263,8 @@
{ "interface", MR_no_argument, NULL, 'i' },
{ "ignore-entry", MR_required_argument, NULL, 'E' },
{ "ignore-interface", MR_required_argument, NULL, 'I' },
+ { "print-list", MR_no_argument, NULL, 'p' },
+ { "no-warn", MR_no_argument, NULL, 'n' },
{ "print", MR_no_argument, NULL, 'P' },
{ "stop", MR_no_argument, NULL, 'S' },
{ "select-all", MR_no_argument, NULL, 'A' },
@@ -6097,12 +6276,17 @@
MR_trace_options_when_action_multi_ignore(MR_Spy_When *when,
MR_Spy_Action *action, MR_MultiMatch *multi_match,
MR_Spy_Ignore_When*ignore_when, int *ignore_count,
+ MR_Spy_Print_List *print_list,
char ***words, int *word_count, const char *cat, const char *item)
{
int c;
+ MR_Spy_Print node;
+ MR_Spy_Print_List list;
+ MR_bool warn;
+ warn = MR_TRUE;
MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "AE:I:OPSaei",
+ while ((c = MR_getopt_long(*word_count, *words, "AE:I:OPSaeinp:",
MR_trace_when_action_multi_ignore_opts, NULL)) != EOF)
{
switch (c) {
@@ -6119,6 +6303,16 @@
*when = MR_SPY_INTERFACE;
break;
+ case 'n':
+ warn = MR_FALSE;
+ break;
+
+ case 'p':
+ *print_list = MR_add_to_print_list_end(
+ MR_BROWSE_FORMAT_FLAT, MR_optarg,
+ warn, *print_list);
+ break;
+
case 'E':
if (! MR_trace_is_natural_number(MR_optarg,
ignore_count))
@@ -6217,6 +6411,68 @@
return MR_TRUE;
}
+static struct MR_option MR_trace_break_print_opts[] =
+{
+ { "end", MR_no_argument, NULL, 'e' },
+ { "no-warn", MR_no_argument, NULL, 'n' },
+ { "flat", MR_no_argument, NULL, 'f' },
+ { "raw-pretty", MR_no_argument, NULL, 'r' },
+ { "verbose", MR_no_argument, NULL, 'v' },
+ { "pretty", MR_no_argument, NULL, 'p' },
+ { NULL, MR_no_argument, NULL, 0 }
+};
+
+static MR_bool
+MR_trace_options_break_print(MR_Browse_Format *format, MR_bool *at_start,
+ MR_bool *warn, char ***words, int *word_count, const char *cat,
+ const char *item)
+{
+ int c;
+
+ *format = MR_BROWSE_FORMAT_FLAT;
+ *at_start = MR_TRUE;
+ *warn = MR_TRUE;
+ MR_optind = 0;
+ while ((c = MR_getopt_long(*word_count, *words, "enfrvp",
+ MR_trace_break_print_opts, NULL)) != EOF)
+ {
+ switch (c) {
+
+ case 'e':
+ *at_start = MR_FALSE;
+ break;
+
+ case 'n':
+ *warn = MR_FALSE;
+ break;
+
+ case 'f':
+ *format = MR_BROWSE_FORMAT_FLAT;
+ break;
+
+ case 'r':
+ *format = MR_BROWSE_FORMAT_RAW_PRETTY;
+ break;
+
+ case 'v':
+ *format = MR_BROWSE_FORMAT_VERBOSE;
+ break;
+
+ case 'p':
+ *format = MR_BROWSE_FORMAT_PRETTY;
+ break;
+
+ default:
+ MR_trace_usage(cat, item);
+ return MR_FALSE;
+ }
+ }
+
+ *words = *words + MR_optind - 1;
+ *word_count = *word_count - MR_optind + 1;
+ return MR_TRUE;
+}
+
static struct MR_option MR_trace_detailed_opts[] =
{
{ "detailed", MR_no_argument, NULL, 'd' },
@@ -7359,15 +7615,23 @@
return (*quoted || escaped);
}
-MR_Code *
+static MR_Code *
MR_trace_event_internal_report(MR_Trace_Cmd_Info *cmd,
- MR_Event_Info *event_info)
+ MR_Spy_Print_List print_list, MR_Event_Info *event_info)
{
char *buf;
int i;
+ int len;
+ MR_Spy_Print_List list;
+
+ list = print_list;
+ len = 0;
+ for (; list != NULL; list = list->pl_next) {
+ len++;
+ }
/* We try to leave one line for the prompt itself. */
- if (MR_scroll_control && MR_scroll_next >= MR_scroll_limit - 1) {
+ if (MR_scroll_control && MR_scroll_next + len >= MR_scroll_limit - 1) {
try_again:
buf = MR_trace_getline("--more-- ", MR_mdb_in, MR_mdb_out);
if (buf != NULL) {
@@ -7395,7 +7659,7 @@
MR_free(buf);
return MR_trace_event_internal(
cmd, MR_TRUE,
- event_info);
+ NULL, event_info);
default:
fflush(MR_mdb_out);
@@ -7416,6 +7680,13 @@
MR_trace_event_print_internal_report(event_info);
MR_scroll_next++;
+ if (print_list != NULL) {
+ MR_trace_init_point_vars(event_info->MR_event_sll,
+ event_info->MR_saved_regs, event_info->MR_trace_port,
+ MR_print_optionals);
+ MR_scroll_next += MR_trace_var_print_list(print_list);
+ }
+
return NULL;
}
@@ -7617,6 +7888,8 @@
MR_trace_break_cmd_args, MR_trace_breakpoint_completer },
{ "breakpoint", "ignore", MR_trace_cmd_ignore,
MR_trace_ignore_cmd_args, MR_trace_null_completer },
+ { "breakpoint", "break_print", MR_trace_cmd_break_print,
+ NULL, MR_trace_null_completer },
{ "breakpoint", "enable", MR_trace_cmd_enable,
NULL, MR_trace_null_completer },
{ "breakpoint", "disable", MR_trace_cmd_disable,
Index: trace/mercury_trace_internal.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_internal.h,v
retrieving revision 1.18
diff -u -b -r1.18 mercury_trace_internal.h
--- trace/mercury_trace_internal.h 24 Jan 2005 07:53:39 -0000 1.18
+++ trace/mercury_trace_internal.h 25 Jan 2005 02:51:09 -0000
@@ -11,6 +11,7 @@
#include "mercury_trace.h" /* for MR_Event_Info, etc. */
#include "mercury_std.h" /* for MR_bool */
#include "mercury_trace_completion.h" /* for MR_Make_Completer */
+#include "mercury_trace_spy.h" /* for MR_Spy_Print_List */
#include <stdio.h> /* for FILE */
@@ -36,10 +37,7 @@
extern MR_Trace_Mode MR_trace_decl_mode;
extern MR_Code *MR_trace_event_internal(MR_Trace_Cmd_Info *cmd,
- MR_bool interactive, MR_Event_Info *event_info);
-
-
-extern MR_Code *MR_trace_event_internal_report(MR_Trace_Cmd_Info *cmd,
+ MR_bool interactive, MR_Spy_Print_List print_list,
MR_Event_Info *event_info);
/*
Index: trace/mercury_trace_spy.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_spy.c,v
retrieving revision 1.21
diff -u -b -r1.21 mercury_trace_spy.c
--- trace/mercury_trace_spy.c 24 Oct 2002 16:30:44 -0000 1.21
+++ trace/mercury_trace_spy.c 25 Jan 2005 13:59:12 -0000
@@ -1,4 +1,7 @@
/*
+** vim: ts=4 sw=4 expandtab
+*/
+/*
** Copyright (C) 1998-2002 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.
@@ -93,12 +96,15 @@
/**************************************************************************/
-static int MR_compare_addr(const void *address1, const void *address2);
+static int MR_compare_addr(const void *address1,
+ const void *address2);
static int MR_search_spy_table_for_proc(const MR_Proc_Layout *entry);
-static int MR_search_spy_table_for_label(const MR_Label_Layout *label);
-static void MR_add_line_spy_point_callback(const MR_Label_Layout *label,
- int spy_point_num);
+static int MR_search_spy_table_for_label(
+ const MR_Label_Layout *label);
+static void MR_add_line_spy_point_callback(
+ const MR_Label_Layout *label, int spy_point_num);
static int MR_compare_spied_labels(const void *, const void *);
+static void MR_delete_spy_print_list(MR_Spy_Print_List print_list);
static void MR_update_enabled_action(MR_Spy_Point *point,
MR_Trace_Port port, MR_Spy_Action *action_ptr,
MR_bool *enabled_ptr);
@@ -171,7 +177,8 @@
MR_bool
MR_event_matches_spy_point(const MR_Label_Layout *layout,
- MR_Trace_Port port, MR_Spy_Action *action_ptr)
+ MR_Trace_Port port, MR_Spy_Action *action_ptr,
+ MR_Spy_Print_List *print_list)
{
int slot;
MR_bool enabled;
@@ -184,40 +191,41 @@
enabled = MR_FALSE;
action = MR_SPY_PRINT;
+ *print_list = NULL;
if (MR_spied_label_next > 0) {
slot = MR_search_spy_table_for_label(layout);
if (slot >= 0) {
- point = MR_spy_points[
- MR_spied_labels[slot].spy_point_num];
+ point = MR_spy_points[MR_spied_labels[slot].spy_point_num];
if (point->spy_when != MR_SPY_LINENO) {
- MR_fatal_error("non-lineno spy point in "
- "spied labels array");
+ MR_fatal_error("non-lineno spy point in spied labels array");
}
- MR_update_enabled_action(point, port,
- &action, &enabled);
+ MR_update_enabled_action(point, port, &action, &enabled);
+ if (*print_list == NULL) {
+ *print_list = point->spy_print_list;
+ }
}
if (MR_port_is_interface(port)) {
MR_restore_transient_registers();
base_sp = MR_sp;
base_curfr = MR_curfr;
- parent = MR_find_nth_ancestor(layout, 1,
- &base_sp, &base_curfr, &problem);
+ parent = MR_find_nth_ancestor(layout, 1, &base_sp, &base_curfr,
+ &problem);
if (parent != NULL && 0 <=
(slot = MR_search_spy_table_for_label(parent)))
{
- point = MR_spy_points[MR_spied_labels[slot].
- spy_point_num];
+ point = MR_spy_points[MR_spied_labels[slot].spy_point_num];
if (point->spy_when != MR_SPY_LINENO) {
- MR_fatal_error("non-lineno "
- "spy point in "
+ MR_fatal_error("non-lineno spy point in "
"spied labels array");
}
- MR_update_enabled_action(point, port,
- &action, &enabled);
+ MR_update_enabled_action(point, port, &action, &enabled);
+ if (*print_list == NULL) {
+ *print_list = point->spy_print_list;
+ }
}
}
}
@@ -230,16 +238,19 @@
switch (point->spy_when) {
case MR_SPY_ALL:
- MR_update_enabled_action(point,
- port, &action,
- &enabled);
+ MR_update_enabled_action(point, port, &action, &enabled);
+ if (*print_list == NULL) {
+ *print_list = point->spy_print_list;
+ }
break;
case MR_SPY_ENTRY:
if (MR_port_is_entry(port)) {
- MR_update_enabled_action(point,
- port, &action,
+ MR_update_enabled_action(point, port, &action,
&enabled);
+ if (*print_list == NULL) {
+ *print_list = point->spy_print_list;
+ }
} else {
continue;
}
@@ -248,9 +259,11 @@
case MR_SPY_INTERFACE:
if (MR_port_is_interface(port)) {
- MR_update_enabled_action(point,
- port, &action,
+ MR_update_enabled_action(point, port, &action,
&enabled);
+ if (*print_list == NULL) {
+ *print_list = point->spy_print_list;
+ }
} else {
continue;
}
@@ -259,9 +272,11 @@
case MR_SPY_SPECIFIC:
if (layout == point->spy_label) {
- MR_update_enabled_action(point,
- port, &action,
+ MR_update_enabled_action(point, port, &action,
&enabled);
+ if (*print_list == NULL) {
+ *print_list = point->spy_print_list;
+ }
} else {
continue;
}
@@ -269,8 +284,7 @@
break;
case MR_SPY_LINENO:
- MR_fatal_error("lineno spy point in "
- "spied procs array");
+ MR_fatal_error("lineno spy point in spied procs array");
default:
MR_fatal_error("bad spy point when in "
@@ -329,6 +343,7 @@
MR_add_proc_spy_point(MR_Spy_When when, MR_Spy_Action action,
MR_Spy_Ignore_When ignore_when, int ignore_count,
const MR_Proc_Layout *entry, const MR_Label_Layout *label,
+ MR_Spy_Print_List print_list,
const char **problem)
{
MR_Spy_Point *point;
@@ -344,8 +359,7 @@
MR_INIT_SPIED_PROCS);
MR_prepare_insert_into_sorted(MR_spied_procs,
MR_spied_proc_next, proc_slot,
- MR_compare_addr(MR_spied_procs[proc_slot].spy_proc,
- entry));
+ MR_compare_addr(MR_spied_procs[proc_slot].spy_proc, entry));
MR_spied_procs[proc_slot].spy_proc = entry;
MR_spied_procs[proc_slot].spy_points = NULL;
}
@@ -358,6 +372,7 @@
point->spy_action = action;
point->spy_ignore_when = ignore_when;
point->spy_ignore_count = ignore_count;
+ point->spy_print_list = print_list;
point->spy_proc = entry;
point->spy_label = label;
point->spy_next = MR_spied_procs[proc_slot].spy_points;
@@ -370,8 +385,7 @@
}
}
- MR_ensure_room_for_next(MR_spy_point, MR_Spy_Point *,
- MR_INIT_SPY_POINTS);
+ MR_ensure_room_for_next(MR_spy_point, MR_Spy_Point *, MR_INIT_SPY_POINTS);
point_slot = MR_spy_point_next;
MR_spy_points[point_slot] = point;
MR_spy_point_next++;
@@ -387,7 +401,7 @@
int
MR_add_line_spy_point(MR_Spy_Action action, MR_Spy_Ignore_When ignore_when,
int ignore_count, const char *orig_filename, int linenumber,
- const char **problem)
+ MR_Spy_Print_List print_list, const char **problem)
{
MR_Spy_Point *point;
int point_slot;
@@ -418,12 +432,10 @@
/* there were no matching labels */
#ifdef MR_HAVE_A_SNPRINTF
snprintf(MR_error_msg_buf, MR_ERROR_MSG_BUF_SIZE,
- "there is no event at %s:%d",
- filename, linenumber);
+ "there is no event at %s:%d", filename, linenumber);
#else
/* not absolutely safe, but the risk of overflow is minimal */
- sprintf(MR_error_msg_buf,
- "there is no event at %s:%d",
+ sprintf(MR_error_msg_buf, "there is no event at %s:%d",
filename, linenumber);
if (strlen(MR_error_msg_buf) >= MR_ERROR_MSG_BUF_SIZE) {
MR_fatal_error("MR_add_line_spy_point: buf overflow");
@@ -448,6 +460,7 @@
point->spy_action = action;
point->spy_ignore_when = ignore_when;
point->spy_ignore_count = ignore_count;
+ point->spy_print_list = print_list;
point->spy_filename = filename;
point->spy_linenumber = linenumber;
@@ -485,6 +498,53 @@
- (MR_Integer) label2->spy_label);
}
+void
+MR_add_spy_point_print_list_start(int point_slot, MR_Spy_Print_List print_list)
+{
+ MR_Spy_Print_List list;
+
+ list = print_list;
+ if (list == NULL) {
+ return;
+ }
+
+ /* find the last node in print_list */
+ while (list->pl_next != NULL) {
+ list = list->pl_next;
+ }
+
+ /* add the existing spy_print_list at the end of print_list */
+ list->pl_next = MR_spy_points[point_slot]->spy_print_list;
+ MR_spy_points[point_slot]->spy_print_list = print_list;
+}
+
+void
+MR_add_spy_point_print_list_end(int point_slot, MR_Spy_Print_List print_list)
+{
+ MR_Spy_Print_List list;
+
+ list = MR_spy_points[point_slot]->spy_print_list;
+ if (list == NULL) {
+ MR_spy_points[point_slot]->spy_print_list = print_list;
+ return;
+ }
+
+ /* find the last node in print_list */
+ while (list->pl_next != NULL) {
+ list = list->pl_next;
+ }
+
+ /* add the print_list at the end of the existing spy_print_list */
+ list->pl_next = print_list;
+}
+
+void
+MR_clear_spy_point_print_list(int point_slot)
+{
+ MR_delete_spy_print_list(MR_spy_points[point_slot]->spy_print_list);
+ MR_spy_points[point_slot]->spy_print_list = NULL;
+}
+
const char *
MR_ignore_spy_point(int point_slot, MR_Spy_Ignore_When ignore_when,
int ignore_count)
@@ -510,6 +570,23 @@
return NULL;
}
+static void
+MR_delete_spy_print_list(MR_Spy_Print_List print_list)
+{
+ if (print_list == NULL) {
+ return;
+ }
+
+ MR_delete_spy_print_list(print_list->pl_next);
+
+ if (print_list->pl_cur->p_name != NULL) {
+ MR_free(print_list->pl_cur->p_name);
+ }
+
+ MR_free(print_list->pl_cur);
+ MR_free(print_list);
+}
+
void
MR_delete_spy_point(int point_table_slot)
{
@@ -526,6 +603,8 @@
MR_most_recent_spy_point = -1;
}
+ MR_delete_spy_print_list(point->spy_print_list);
+
if (point->spy_when == MR_SPY_LINENO) {
/* Release the storage acquired by MR_copy_string. */
MR_free(point->spy_filename);
@@ -536,9 +615,7 @@
label_slot = 0;
for (i = 0; i < MR_spied_label_next; i++) {
- if (MR_spied_labels[i].spy_point_num !=
- point_table_slot)
- {
+ if (MR_spied_labels[i].spy_point_num != point_table_slot) {
MR_spied_labels[label_slot].spy_label =
MR_spied_labels[i].spy_label;
MR_spied_labels[label_slot].spy_point_num =
@@ -556,8 +633,7 @@
proc_table_slot = MR_search_spy_table_for_proc(point->spy_proc);
if (proc_table_slot < 0) {
- MR_fatal_error("deleted spy point "
- "was not indexed by proc addr");
+ MR_fatal_error("deleted spy point was not indexed by proc addr");
}
cur_addr = &MR_spied_procs[proc_table_slot].spy_points;
@@ -568,8 +644,7 @@
}
if (cur == NULL) {
- MR_fatal_error("deleted spy point "
- "was not on proc index list");
+ MR_fatal_error("deleted spy point was not on proc index list");
}
*cur_addr = point->spy_next;
@@ -577,7 +652,7 @@
}
void
-MR_print_spy_point(FILE *fp, int spy_point_num)
+MR_print_spy_point(FILE *fp, int spy_point_num, MR_bool verbose)
{
MR_Spy_Point *point;
@@ -590,8 +665,7 @@
MR_spy_action_string(point->spy_action),
MR_spy_when_names[point->spy_when]);
if (point->spy_when == MR_SPY_LINENO) {
- fprintf(fp, "%s:%d",
- point->spy_filename, point->spy_linenumber);
+ fprintf(fp, "%s:%d", point->spy_filename, point->spy_linenumber);
} else {
MR_print_proc_id(fp, point->spy_proc);
}
@@ -606,6 +680,73 @@
} else {
fprintf(fp, "\n");
}
+
+ if (verbose && point->spy_print_list != NULL) {
+ MR_Spy_Print_List list;
+ MR_Spy_Print node;
+
+ fprintf(fp, "%12s", "");
+ for (list = point->spy_print_list; list != NULL; list = list->pl_next)
+ {
+ node = list->pl_cur;
+ switch (node->p_what) {
+ case MR_SPY_PRINT_GOAL:
+ fprintf(fp, "goal");
+ break;
+
+ case MR_SPY_PRINT_ALL:
+ fprintf(fp, "all");
+ break;
+
+ case MR_SPY_PRINT_ONE:
+ fprintf(fp, "%s", node->p_name);
+ break;
+
+ default:
+ MR_fatal_error("invalid node->p_name");
+ break;
+ }
+
+ fprintf(fp, " (");
+ switch (node->p_format) {
+ case MR_BROWSE_FORMAT_FLAT:
+ fprintf(fp, "flat");
+ break;
+
+ case MR_BROWSE_FORMAT_RAW_PRETTY:
+ fprintf(fp, "raw pretty");
+ break;
+
+ case MR_BROWSE_FORMAT_PRETTY:
+ fprintf(fp, "pretty");
+ break;
+
+ case MR_BROWSE_FORMAT_VERBOSE:
+ fprintf(fp, "verbose");
+ break;
+
+ case MR_BROWSE_DEFAULT_FORMAT:
+ fprintf(fp, "default");
+ break;
+
+ default:
+ MR_fatal_error("invalid node->p_format");
+ break;
+ }
+
+ if (! node->p_warn) {
+ fprintf(fp, ", nowarn");
+ }
+
+ fprintf(fp, ")");
+
+ if (list->pl_next == NULL) {
+ fprintf(fp, "\n");
+ } else {
+ fprintf(fp, ", ");
+ }
+ }
+ }
}
static const char *
@@ -694,17 +835,20 @@
break;
case MR_SPY_SPECIFIC:
- fprintf(err_fp, "mdb: cannot save "
- "breakpoint on specific "
- "internal label\n");
+ fprintf(err_fp, "mdb: cannot save breakpoint on "
+ "specific internal label\n");
break;
default:
- fprintf(err_fp, "mdb: internal error: "
- "unknown spy when\n");
+ fprintf(err_fp, "mdb: internal error: unknown spy when\n");
return MR_TRUE;
}
+ if (point->spy_print_list != NULL) {
+ /* XXX */
+ fprintf(fp, "\n");
+ }
+
if (!point->spy_enabled) {
fprintf(fp, "disable\n");
}
Index: trace/mercury_trace_spy.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_spy.h,v
retrieving revision 1.9
diff -u -b -r1.9 mercury_trace_spy.h
--- trace/mercury_trace_spy.h 18 Feb 2002 07:01:31 -0000 1.9
+++ trace/mercury_trace_spy.h 24 Jan 2005 14:07:21 -0000
@@ -16,6 +16,7 @@
#include "mercury_stack_layout.h" /* for MR_Proc_Layout etc */
#include "mercury_trace_base.h" /* for MR_Trace_Port etc */
+#include "mercury_trace_browse.h" /* for MR_Browse_Format */
typedef enum {
MR_SPY_PRINT, MR_SPY_STOP
@@ -41,6 +42,27 @@
extern const char *MR_spy_when_names[];
+typedef struct MR_Spy_Print_Struct *MR_Spy_Print;
+typedef struct MR_Spy_Print_List_Struct *MR_Spy_Print_List;
+
+typedef enum {
+ MR_SPY_PRINT_GOAL,
+ MR_SPY_PRINT_ALL,
+ MR_SPY_PRINT_ONE,
+} MR_Spy_Print_What;
+
+struct MR_Spy_Print_Struct {
+ MR_Browse_Format p_format;
+ MR_Spy_Print_What p_what;
+ char *p_name; /* if MR_SPY_PRINT_ONE */
+ MR_bool p_warn;
+};
+
+struct MR_Spy_Print_List_Struct {
+ MR_Spy_Print pl_cur;
+ MR_Spy_Print_List pl_next;
+};
+
typedef struct MR_Spy_Point_Struct MR_Spy_Point;
struct MR_Spy_Point_Struct {
@@ -50,6 +72,7 @@
MR_Spy_Action spy_action;
MR_Spy_Ignore_When spy_ignore_when;
int spy_ignore_count;
+ MR_Spy_Print_List spy_print_list;
const MR_Proc_Layout *spy_proc; /* if not LINENO */
const MR_Label_Layout *spy_label; /* if SPECIFIC */
char *spy_filename; /* if LINENO */
@@ -70,13 +93,15 @@
/*
** Check whether the event described by the given label layout and port
-** matches any spy points. If yes, return MR_TRUE and set *action to say what
-** action should be executed for the spy point.
+** matches any spy points. If yes, return MR_TRUE, set *action to say what
+** action should be executed for the spy point, and set print_list to the
+** variable print list of the first matching spy point.
*/
extern MR_bool MR_event_matches_spy_point(const MR_Label_Layout
*layout, MR_Trace_Port port,
- MR_Spy_Action *action);
+ MR_Spy_Action *action,
+ MR_Spy_Print_List *print_list);
/*
** Add a new spy point on a procedure (as opposed to on a line number)
@@ -90,6 +115,7 @@
int ignore_count,
const MR_Proc_Layout *entry,
const MR_Label_Layout *label,
+ MR_Spy_Print_List print_list,
const char **problem);
/*
@@ -102,9 +128,26 @@
MR_Spy_Ignore_When ignore_when,
int ignore_count,
const char *filename, int linenumber,
+ MR_Spy_Print_List print_list,
const char **problem);
/*
+** Add the given set of things to be printed to the spy point's list,
+** at either the start or the end of the existing list.
+*/
+
+extern void MR_add_spy_point_print_list_start(int point_slot,
+ MR_Spy_Print_List print_list);
+extern void MR_add_spy_point_print_list_end(int point_slot,
+ MR_Spy_Print_List print_list);
+
+/*
+** Empty the set of things to be printed at the spy point.
+*/
+
+extern void MR_clear_spy_point_print_list(int point_slot);
+
+/*
** Apply the given ignore specification to the given spy point.
** If the ignore specification is not appropriate for the spy point,
** return a non-NULL problem report.
@@ -125,7 +168,7 @@
** read to the given file.
*/
-extern void MR_print_spy_point(FILE *fp, int i);
+extern void MR_print_spy_point(FILE *fp, int i, MR_bool verbose);
/*
** Print the set of current spy points (including those that are currently
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: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list