[m-rev.] for review: breakpoints on user events
Zoltan Somogyi
zs at csse.unimelb.edu.au
Fri Jan 19 15:41:15 AEDT 2007
On 15-Jan-2007, Zoltan Somogyi <zs at csse.unimelb.edu.au> wrote:
> Implement breakpoints on user events. Users may specify an event set,
> an event name, both, or neither. Four forms of the mdb "break" command
> create such breakpoints:
In the absence of a review, I am committing this updated diff, which also
contains a fix for a bug in the implementation of the "break_print" mdb
command.
Zoltan.
Implement breakpoints on user events. Users may specify an event set,
an event name, both, or neither. Four forms of the mdb "break" command
create such breakpoints:
break [the usual options] user_event <event_name>
break [the usual options] user_event <event_set_name> <event_name>
break [the usual options] user_event_set
break [the usual options] user_event_set <event_set_name>
In addition, the command
break [the usual options] user_event
is also accepted, as a synonym for
break [the usual options] user_event_set
Since user events are not interface events or entry events, add a new, simple
ignore specification, which decrements the ignore count on every match of the
event.
Make the "break_print" mdb command consistent with the other command that
operates on existing breakpoints ("condition") by making it apply by default
to the most recently created breakpoint.
Make "condition" and "break_print" use the same option letter (-b) to introduce
the breakpoint number.
Fix a bug in the implementation of "break_print" that led to printing out
the selected variable, but not the selected *path* within the selected
variable. The reason was that we recorded what to print (variable spec plus
path) in a string, but that the process of using that record to print out
what was wanted destroyed the string (by putting a NULL between the variable
specification and the path), so that *later* uses of that string would find
an empty path. The fix is to record a var_spec/path pair in the print list.
Fix some slightly misleading output: when printing part of a variable, we
printed the name of the variable without any indication that the value printed
wasn't the whole value of the variable. We now print the path as well.
doc/user_guide.texi:
Document the changes above.
Document the usage "break_print [options] none", which we have always
supported, but which was not documented.
runtime/mercury_stack_layout.h:
Add a utility macro.
trace/mercury_trace.c:
Fix a bug which left a variable uninitialized.
trace/mercury_trace_cmd_breakpoint.c:
Implement the new command forms and options described above.
trace/mercury_trace_spy.[ch]:
Implement data structures for keeping track of the new forms of
breakpoints, and add the necessary functions for manipulating them.
Update the function that checks whether the current event matches.
Factor some common code out of that function, as well as out of the
functions for adding new breakpoints.
Change the print list data structure as described above.
Add some utility functions.
Add MR_ prefixes to the names of structure fields that previously
lacked them.
trace/mercury_trace_cmd_misc.c:
Handle the new breakpoint types.
trace/mercury_trace_tables.c:
trace/mercury_trace_internal.c:
We used to parse the event set descriptions in module layout structures
when the debugger was initialized (in mercury_trace_internal.c).
However, we delay registering all the modules until this is needed,
so at that time we don't yet *have* the list of module layout
structures, so we used to parse nothing. This diff moves the code
for doing the parsing to the time when the module layout structures
are registered (in mercury_trace_tables.c).
Don't test whether the module layout structure contains the fields
for user event descriptions, since that diff has been installed on
all our systems weeks ago.
trace/mercury_trace_internal.c:
Conform to the new print list structure.
trace/mercury_trace_vars.[ch]:
Print any selected path together with a variable name when printing a
value. (This is the last bug fix mentioned at the top.)
Export a function for use in mercury_trace_internal.c.
Add some utility functions.
Improve some error messages.
trace/mercury_trace_tables.h:
Add a const qualifier.
tests/debugger/user_event.{inp,exp}:
Extend this test case to test the new functionality.
tests/debugger/breakpoints.{inp,exp,exp2}:
Conform to the change to the break_print command.
tests/queens.{inp,exp}:
Change the input to test the bug fix to the break_print command,
and the expected output.
tests/browser_test.exp:
tests/field_names.exp:
Conform to the fact that we now print paths after variables names.
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
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.507
diff -u -b -r1.507 user_guide.texi
--- doc/user_guide.texi 15 Jan 2007 07:47:55 -0000 1.507
+++ doc/user_guide.texi 16 Jan 2007 00:46:56 -0000
@@ -3186,13 +3186,69 @@
By default, the action of the break point is @samp{stop},
the ignore count is zero, and the print list is empty.
@sp 1
+ at item break [-PS] [-X at var{ignore-count}] [-n] [-p at var{print-spec}]* user_event [@var{user-event-set}] @var{user-event-name}
+Puts a break point on all user events named @var{user-event-name},
+or, if @var{user-event-set} is specified as well,
+on the user event named @var{user-event-name} in that event set.
+ at sp 1
+The options @samp{-P} or @samp{--print}, and @samp{-S} or @samp{--stop}
+specify the action to be taken at the break point.
+ at sp 1
+The options @samp{-X at var{ignore-count}}
+and @samp{--ignore @var{ignore-count}}
+tell the debugger to ignore the breakpoint
+until after @var{ignore-count} occurrences of an event
+that matches the breakpoint.
+ at 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},
+the ignore count is zero, and the print list is empty.
+ at sp 1
+ at item break [-PS] [-X at var{ignore-count}] [-n] [-p at var{print-spec}]* user_event_set [@var{user-event-set}]
+Puts a break point either on all user events in all event sets,
+or, if @var{user-event-set} is specified,
+on all user events in the event set of the given name.
+ at sp 1
+The options @samp{-P} or @samp{--print}, and @samp{-S} or @samp{--stop}
+specify the action to be taken at the break point.
+ at sp 1
+The options @samp{-X at var{ignore-count}}
+and @samp{--ignore @var{ignore-count}}
+tell the debugger to ignore the breakpoint
+until after @var{ignore-count} occurrences of an event
+that matches the breakpoint.
+ at 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},
+the ignore count is zero, and the print list is empty.
+ at sp 1
@item break info
Lists the details, status and print lists of all break points.
@sp 1
- at item condition [-n at var{break-num}] [-p] [-v] @var{varname}[@var{pathspec}] @var{op} @var{term}
+ at item condition [-b at var{break-num}] [-p] [-v] @var{varname}[@var{pathspec}] @var{op} @var{term}
@kindex condition (mdb command)
Attaches a condition to the most recent breakpoint,
-or, if the @samp{-n} or @samp{--break-num} is given,
+or, if the @samp{-b} or @samp{--break-num} is given,
to the breakpoint whose number is given as the argument.
Execution won't stop at the breakpoint if the condition is false.
@sp 1
@@ -3227,6 +3283,8 @@
If the @samp{-v} or @samp{--dont-require-var} option is given,
execution won't stop at breakpoints at which
the specified variable itself doesn't exist.
+The @samp{-v} or @samp{--dont-require-var} option is implicitly assumed
+if the specified breakpoint is on all user events.
@sp 1
@item ignore [-E at var{ignore-count}] [-I at var{ignore-count}] @var{num}
@kindex ignore (mdb command)
@@ -3261,10 +3319,12 @@
that matches the most recently added breakpoint.
Reports an error if the most recently added breakpoint has since been deleted.
@sp 1
- at item break_print [-fpv] [-e] [-n] @var{num} @var{print-spec}*
+ at item break_print [-fpv] [-e] [-n] [-b @var{num}] @var{print-spec}*
@kindex break_print (mdb command)
Adds the specified print list elements (there may be more than one)
-to the print list of the breakpoint numbered @var{num}.
+to the print list of the breakpoint numbered @var{num}
+(if the @samp{-b} or @samp{--break-num} option is given),
+or to the print list of the most recent breakpoint (if it is not given).
@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.
@@ -3282,6 +3342,12 @@
and @samp{-v} or @samp{--verbose}, if given,
explicitly specify the format to use.
@sp 1
+ at item break_print [-b @var{num}] none
+ at kindex break_print (mdb command)
+Clears the print list of the breakpoint numbered @var{num}
+(if the @samp{-b} or @samp{--break-num} option is given),
+or the print list of the most recent breakpoint (if it is not given).
+ at sp 1
@item disable @var{num}
@kindex disable (mdb command)
Disables the break point with the given number.
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_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/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/stream
cvs diff: Diffing extras/stream/tests
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
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.109
diff -u -b -r1.109 mercury_stack_layout.h
--- runtime/mercury_stack_layout.h 10 Jan 2007 16:08:20 -0000 1.109
+++ runtime/mercury_stack_layout.h 11 Jan 2007 15:21:29 -0000
@@ -344,6 +344,10 @@
MR_ml_user_event_specs[label_layout->MR_sll_user_event-> \
MR_ue_event_number]
+#define MR_user_event_set_name(label_layout) \
+ label_layout->MR_sll_entry->MR_sle_module_layout-> \
+ MR_ml_user_event_set_name
+
/*-------------------------------------------------------------------------*/
/*
** Definitions for MR_LabelLayout
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 slice
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.16
diff -u -b -r1.16 breakpoints.exp
--- tests/debugger/breakpoints.exp 6 Jan 2007 10:56:25 -0000 1.16
+++ tests/debugger/breakpoints.exp 12 Jan 2007 14:11:03 -0000
@@ -90,7 +90,7 @@
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
+mdb> break_print -v -n -b1 HeadVar__1 HeadVar__2
1: + stop interface pred breakpoints.qperm/2-0 (nondet)
HeadVar__1 (verbose, nowarn), HeadVar__2 (verbose, nowarn)
mdb> continue
@@ -104,11 +104,11 @@
1-3
2-[|]/2
-mdb> break_print 1 none
+mdb> break_print -b1 none
1: + stop interface pred breakpoints.qperm/2-0 (nondet)
mdb> format_param -p depth 10
mdb> format_param -p size 20
-mdb> break_print -p -n 1 HeadVar__1 HeadVar__2
+mdb> break_print -p -n -b1 HeadVar__1 HeadVar__2
1: + stop interface pred breakpoints.qperm/2-0 (nondet)
HeadVar__1 (pretty, nowarn), HeadVar__2 (pretty, nowarn)
mdb> continue
@@ -123,12 +123,12 @@
[2, 3, 4, 5]
HeadVar__2
[2, 3, 4, 5]
-mdb> break_print 1 none
+mdb> break_print -b1 none
1: + stop interface pred breakpoints.qperm/2-0 (nondet)
-mdb> break_print -f -n 1 HeadVar__1
+mdb> break_print -f -n -b1 HeadVar__1
1: + stop interface pred breakpoints.qperm/2-0 (nondet)
HeadVar__1 (flat, nowarn)
-mdb> break_print -f -e -n 1 HeadVar__2
+mdb> break_print -f -e -n -b1 HeadVar__2
1: + stop interface pred breakpoints.qperm/2-0 (nondet)
HeadVar__1 (flat, nowarn), HeadVar__2 (flat, nowarn)
mdb> continue
@@ -240,9 +240,9 @@
[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
+mdb> break_print -b0 none
0: + stop interface func breakpoints.a.testmod.test_in_a/0-0 (det)
-mdb> break_print 0 *
+mdb> break_print -b0 *
0: + stop interface func breakpoints.a.testmod.test_in_a/0-0 (det)
all (flat)
mdb> continue
Index: tests/debugger/breakpoints.exp2
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/breakpoints.exp2,v
retrieving revision 1.12
diff -u -b -r1.12 breakpoints.exp2
--- tests/debugger/breakpoints.exp2 8 Jan 2007 09:13:11 -0000 1.12
+++ tests/debugger/breakpoints.exp2 12 Jan 2007 15:40:21 -0000
@@ -98,7 +98,7 @@
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
+mdb> break_print -v -n -b1 HeadVar__1 HeadVar__2
1: + stop interface pred breakpoints.qperm/2-0 (nondet)
HeadVar__1 (verbose, nowarn), HeadVar__2 (verbose, nowarn)
mdb> continue
@@ -112,11 +112,11 @@
1-3
2-[|]/2
-mdb> break_print 1 none
+mdb> break_print -b1 none
1: + stop interface pred breakpoints.qperm/2-0 (nondet)
mdb> format_param -p depth 10
mdb> format_param -p size 20
-mdb> break_print -p -n 1 HeadVar__1 HeadVar__2
+mdb> break_print -p -n -b1 HeadVar__1 HeadVar__2
1: + stop interface pred breakpoints.qperm/2-0 (nondet)
HeadVar__1 (pretty, nowarn), HeadVar__2 (pretty, nowarn)
mdb> continue
@@ -131,12 +131,12 @@
[2, 3, 4, 5]
HeadVar__2
[2, 3, 4, 5]
-mdb> break_print 1 none
+mdb> break_print -b1 none
1: + stop interface pred breakpoints.qperm/2-0 (nondet)
-mdb> break_print -f -n 1 HeadVar__1
+mdb> break_print -f -n -b1 HeadVar__1
1: + stop interface pred breakpoints.qperm/2-0 (nondet)
HeadVar__1 (flat, nowarn)
-mdb> break_print -f -e -n 1 HeadVar__2
+mdb> break_print -f -e -n -b1 HeadVar__2
1: + stop interface pred breakpoints.qperm/2-0 (nondet)
HeadVar__1 (flat, nowarn), HeadVar__2 (flat, nowarn)
mdb> continue
@@ -248,9 +248,9 @@
[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
+mdb> break_print -b0 none
0: + stop interface func breakpoints.a.testmod.test_in_a/0-0 (det)
-mdb> break_print 0 *
+mdb> break_print -b0 *
0: + stop interface func breakpoints.a.testmod.test_in_a/0-0 (det)
all (flat)
mdb> continue
Index: tests/debugger/breakpoints.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/breakpoints.inp,v
retrieving revision 1.9
diff -u -b -r1.9 breakpoints.inp
--- tests/debugger/breakpoints.inp 4 Apr 2006 07:37:16 -0000 1.9
+++ tests/debugger/breakpoints.inp 18 Jan 2007 04:30:49 -0000
@@ -27,18 +27,18 @@
break info
disable 3
break nodiag
-break_print -v -n 1 HeadVar__1 HeadVar__2
+break_print -v -n -b1 HeadVar__1 HeadVar__2
continue
-break_print 1 none
+break_print -b1 none
format_param -p depth 10
format_param -p size 20
-break_print -p -n 1 HeadVar__1 HeadVar__2
+break_print -p -n -b1 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
+break_print -b1 none
+break_print -f -n -b1 HeadVar__1
+break_print -f -e -n -b1 HeadVar__2
continue
continue
finish
@@ -73,7 +73,7 @@
break -O -P -p HeadVar__1 test_in_b
break info
continue
-break_print 0 none
-break_print 0 *
+break_print -b0 none
+break_print -b0 *
continue
continue
Index: tests/debugger/browser_test.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/browser_test.exp,v
retrieving revision 1.27
diff -u -b -r1.27 browser_test.exp
--- tests/debugger/browser_test.exp 18 Aug 2006 07:19:48 -0000 1.27
+++ tests/debugger/browser_test.exp 18 Jan 2007 11:56:19 -0000
@@ -171,14 +171,14 @@
mdb> print *
Data (arg 1) big(big/3, 3, big/3)
mdb> print Data/1
- Data (arg 1) big(big(small, 1, small), 2, small)
+ Data (arg 1)^1 big(big(small, 1, small), 2, small)
mdb> format_param -f depth 3
mdb> print 1
Data (arg 1) big(big(big(small, 1, small), 2, small), 3, big(big(small, 4, big/3), 6, small))
mdb> print Data/1/2
- Data (arg 1) 2
+ Data (arg 1)/1/2 2
mdb> print 1^1^2^3
-mdb: the path 3 does not exist.
+mdb: the path 3 does not exist in variable 1.
mdb> retry
E2: C2 CALL pred browser_test.big_data/1-0 (det) browser_test.m:37 (browser_test.m:20)
mdb> break list_data
Index: tests/debugger/field_names.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/field_names.exp,v
retrieving revision 1.7
diff -u -b -r1.7 field_names.exp
--- tests/debugger/field_names.exp 5 Oct 2005 06:34:24 -0000 1.7
+++ tests/debugger/field_names.exp 18 Jan 2007 10:55:45 -0000
@@ -13,27 +13,27 @@
mdb> p 5^1x
mdb: bad component selector.
mdb> p 5^1^x
-mdb: the path x does not exist.
+mdb: the path x does not exist in variable 5.
mdb> p 5^x
-mdb: the path x does not exist.
+mdb: the path x does not exist in variable 5.
mdb> p 5^1
- HeadVar__5 41
+ HeadVar__5^1 41
mdb> p 5^2
- HeadVar__5 42
+ HeadVar__5^2 42
mdb> p 5^3
- HeadVar__5 43
+ HeadVar__5^3 43
mdb> p 5^4
- HeadVar__5 44
+ HeadVar__5^4 44
mdb> p 5^t1a
- HeadVar__5 41
+ HeadVar__5^t1a 41
mdb> p 5^t1b
- HeadVar__5 42
+ HeadVar__5^t1b 42
mdb> p 5^t1c
-mdb: the path t1c does not exist.
+mdb: the path t1c does not exist in variable 5.
mdb> p 5^t1d
- HeadVar__5 44
+ HeadVar__5^t1d 44
mdb> p 5^t1e
-mdb: the path t1e does not exist.
+mdb: the path t1e does not exist in variable 5.
mdb> browse 5
browser> ^1x
error: in subdir 1: there is no subterm x
@@ -71,19 +71,19 @@
mdb> p 4
HeadVar__4 t1f2(51, 52, 53)
mdb> p 4^1
- HeadVar__4 51
+ HeadVar__4^1 51
mdb> p 4^2
- HeadVar__4 52
+ HeadVar__4^2 52
mdb> p 4^3
- HeadVar__4 53
+ HeadVar__4^3 53
mdb> p 4^t1a
-mdb: the path t1a does not exist.
+mdb: the path t1a does not exist in variable 4.
mdb> p 4^t1e
- HeadVar__4 51
+ HeadVar__4^t1e 51
mdb> p 4^t1f
-mdb: the path t1f does not exist.
+mdb: the path t1f does not exist in variable 4.
mdb> p 4^t1g
- HeadVar__4 53
+ HeadVar__4^t1g 53
mdb> browse 4
browser> ^t1a
error: there is no subterm t1a
@@ -103,55 +103,55 @@
mdb> p 5
HeadVar__5 t2f(0.600000000000000, 61, t1f1(41, 42, 43, 44), t1f2(51, 52, 53))
mdb> p 5^1
- HeadVar__5 0.600000000000000
+ HeadVar__5^1 0.600000000000000
mdb> p 5^2
- HeadVar__5 61
+ HeadVar__5^2 61
mdb> p 5^3
- HeadVar__5 t1f1(41, 42, 43, 44)
+ HeadVar__5^3 t1f1(41, 42, 43, 44)
mdb> p 5^3^t1a
- HeadVar__5 41
+ HeadVar__5^3^t1a 41
mdb> p 5^3^t1b
- HeadVar__5 42
+ HeadVar__5^3^t1b 42
mdb> p 5^3^t1c
-mdb: the path t1c does not exist.
+mdb: the path t1c does not exist in variable 5.
mdb> p 5^3^t1d
- HeadVar__5 44
+ HeadVar__5^3^t1d 44
mdb> p 5^3^t1e
-mdb: the path t1e does not exist.
+mdb: the path t1e does not exist in variable 5.
mdb> p 5^4
- HeadVar__5 t1f2(51, 52, 53)
+ HeadVar__5^4 t1f2(51, 52, 53)
mdb> p 5^4^t1a
-mdb: the path t1a does not exist.
+mdb: the path t1a does not exist in variable 5.
mdb> p 5^4^t1e
- HeadVar__5 51
+ HeadVar__5^4^t1e 51
mdb> p 5^4^t1f
-mdb: the path t1f does not exist.
+mdb: the path t1f does not exist in variable 5.
mdb> p 5^4^t1g
- HeadVar__5 53
+ HeadVar__5^4^t1g 53
mdb> p 5^t2a
- HeadVar__5 0.600000000000000
+ HeadVar__5^t2a 0.600000000000000
mdb> p 5^t2b
- HeadVar__5 t1f1(41, 42, 43, 44)
+ HeadVar__5^t2b t1f1(41, 42, 43, 44)
mdb> p 5^t2b^t1a
- HeadVar__5 41
+ HeadVar__5^t2b^t1a 41
mdb> p 5^t2b^t1b
- HeadVar__5 42
+ HeadVar__5^t2b^t1b 42
mdb> p 5^t2b^t1c
-mdb: the path t1c does not exist.
+mdb: the path t1c does not exist in variable 5.
mdb> p 5^t2b^t1d
- HeadVar__5 44
+ HeadVar__5^t2b^t1d 44
mdb> p 5^t2b^t1e
-mdb: the path t1e does not exist.
+mdb: the path t1e does not exist in variable 5.
mdb> p 5^t2c
- HeadVar__5 t1f2(51, 52, 53)
+ HeadVar__5^t2c t1f2(51, 52, 53)
mdb> p 5^t2c^t1a
-mdb: the path t1a does not exist.
+mdb: the path t1a does not exist in variable 5.
mdb> p 5^t2c^t1e
- HeadVar__5 51
+ HeadVar__5^t2c^t1e 51
mdb> p 5^t2c^t1f
-mdb: the path t1f does not exist.
+mdb: the path t1f does not exist in variable 5.
mdb> p 5^t2c^t1g
- HeadVar__5 53
+ HeadVar__5^t2c^t1g 53
mdb> browse 5
browser> ^3^t1a
browser> p
@@ -178,63 +178,63 @@
mdb> p 4
HeadVar__4 t3f(t1f2(51, 52, 53), 72, "xyzzy", t1f1(41, 42, 43, 44))
mdb> p 4^1
- HeadVar__4 t1f2(51, 52, 53)
+ HeadVar__4^1 t1f2(51, 52, 53)
mdb> p 4^1^1
- HeadVar__4 51
+ HeadVar__4^1^1 51
mdb> p 4^1^t1a
-mdb: the path t1a does not exist.
+mdb: the path t1a does not exist in variable 4.
mdb> p 4^1^t1e
- HeadVar__4 51
+ HeadVar__4^1^t1e 51
mdb> p 4^1^t1g
- HeadVar__4 53
+ HeadVar__4^1^t1g 53
mdb> p 4^2
- HeadVar__4 72
+ HeadVar__4^2 72
mdb> p 4^3
- HeadVar__4 "xyzzy"
+ HeadVar__4^3 "xyzzy"
mdb> p 4^3^1
-mdb: the path 1 does not exist.
+mdb: the path 1 does not exist in variable 4.
mdb> p 4^3^t1a
-mdb: the path t1a does not exist.
+mdb: the path t1a does not exist in variable 4.
mdb> p 4^4
- HeadVar__4 t1f1(41, 42, 43, 44)
+ HeadVar__4^4 t1f1(41, 42, 43, 44)
mdb> p 4^4^t1a
- HeadVar__4 41
+ HeadVar__4^4^t1a 41
mdb> p 4^4^t1b
- HeadVar__4 42
+ HeadVar__4^4^t1b 42
mdb> p 4^4^t1c
-mdb: the path t1c does not exist.
+mdb: the path t1c does not exist in variable 4.
mdb> p 4^4^t1d
- HeadVar__4 44
+ HeadVar__4^4^t1d 44
mdb> p 4^4^t1e
-mdb: the path t1e does not exist.
+mdb: the path t1e does not exist in variable 4.
mdb> p 4^t3a
- HeadVar__4 t1f2(51, 52, 53)
+ HeadVar__4^t3a t1f2(51, 52, 53)
mdb> p 4^t3a^1
- HeadVar__4 51
+ HeadVar__4^t3a^1 51
mdb> p 4^t3a^t1a
-mdb: the path t1a does not exist.
+mdb: the path t1a does not exist in variable 4.
mdb> p 4^t3a^t1e
- HeadVar__4 51
+ HeadVar__4^t3a^t1e 51
mdb> p 4^t3a^t1g
- HeadVar__4 53
+ HeadVar__4^t3a^t1g 53
mdb> p 4^t3b
- HeadVar__4 72
+ HeadVar__4^t3b 72
mdb> p 4^t3c
- HeadVar__4 "xyzzy"
+ HeadVar__4^t3c "xyzzy"
mdb> p 4^t3d
- HeadVar__4 t1f1(41, 42, 43, 44)
+ HeadVar__4^t3d t1f1(41, 42, 43, 44)
mdb> p 4^t3d^t1a
- HeadVar__4 41
+ HeadVar__4^t3d^t1a 41
mdb> p 4^t3d^t1b
- HeadVar__4 42
+ HeadVar__4^t3d^t1b 42
mdb> p 4^t3d^t1c
-mdb: the path t1c does not exist.
+mdb: the path t1c does not exist in variable 4.
mdb> p 4^t3d^t1d
- HeadVar__4 44
+ HeadVar__4^t3d^t1d 44
mdb> p 4^t3d^t1e
-mdb: the path t1e does not exist.
+mdb: the path t1e does not exist in variable 4.
mdb> p 4^t3e^t1a
-mdb: the path t3e^t1a does not exist.
+mdb: the path t3e^t1a does not exist in variable 4.
mdb> step
10: 6 2 CALL pred field_names.make_t4/2-0 (det)
mdb> finish
@@ -242,53 +242,53 @@
mdb> p 2
A(1) (arg 2) t2f(0.600000000000000, 61, t1f1(41, 42, 43, 44), t1f2(51, 52, 53))
mdb> p 2^1
- A(1) (arg 2) 0.600000000000000
+ A(1) (arg 2)^1 0.600000000000000
mdb> p 2^2
- A(1) (arg 2) 61
+ A(1) (arg 2)^2 61
mdb> p 2^3^t1a
- A(1) (arg 2) 41
+ A(1) (arg 2)^3^t1a 41
mdb> p 2^3^t1b
- A(1) (arg 2) 42
+ A(1) (arg 2)^3^t1b 42
mdb> p 2^3^t1c
-mdb: the path t1c does not exist.
+mdb: the path t1c does not exist in variable 2.
mdb> p 2^3^t1d
- A(1) (arg 2) 44
+ A(1) (arg 2)^3^t1d 44
mdb> p 2^3^t1e
-mdb: the path t1e does not exist.
+mdb: the path t1e does not exist in variable 2.
mdb> p 2^4
- A(1) (arg 2) t1f2(51, 52, 53)
+ A(1) (arg 2)^4 t1f2(51, 52, 53)
mdb> p 2^4^t1a
-mdb: the path t1a does not exist.
+mdb: the path t1a does not exist in variable 2.
mdb> p 2^4^t1e
- A(1) (arg 2) 51
+ A(1) (arg 2)^4^t1e 51
mdb> p 2^4^t1f
-mdb: the path t1f does not exist.
+mdb: the path t1f does not exist in variable 2.
mdb> p 2^4^t1g
- A(1) (arg 2) 53
+ A(1) (arg 2)^4^t1g 53
mdb> p 2^t2a
- A(1) (arg 2) 0.600000000000000
+ A(1) (arg 2)^t2a 0.600000000000000
mdb> p 2^t2b
- A(1) (arg 2) t1f1(41, 42, 43, 44)
+ A(1) (arg 2)^t2b t1f1(41, 42, 43, 44)
mdb> p 2^t2b^t1a
- A(1) (arg 2) 41
+ A(1) (arg 2)^t2b^t1a 41
mdb> p 2^t2b^t1b
- A(1) (arg 2) 42
+ A(1) (arg 2)^t2b^t1b 42
mdb> p 2^t2b^t1c
-mdb: the path t1c does not exist.
+mdb: the path t1c does not exist in variable 2.
mdb> p 2^t2b^t1d
- A(1) (arg 2) 44
+ A(1) (arg 2)^t2b^t1d 44
mdb> p 2^t2b^t1e
-mdb: the path t1e does not exist.
+mdb: the path t1e does not exist in variable 2.
mdb> p 2^t2c
- A(1) (arg 2) t1f2(51, 52, 53)
+ A(1) (arg 2)^t2c t1f2(51, 52, 53)
mdb> p 2^t2c^t1a
-mdb: the path t1a does not exist.
+mdb: the path t1a does not exist in variable 2.
mdb> p 2^t2c^t1e
- A(1) (arg 2) 51
+ A(1) (arg 2)^t2c^t1e 51
mdb> p 2^t2c^t1f
-mdb: the path t1f does not exist.
+mdb: the path t1f does not exist in variable 2.
mdb> p 2^t2c^t1g
- A(1) (arg 2) 53
+ A(1) (arg 2)^t2c^t1g 53
mdb> step
12: 7 2 CALL pred field_names.make_t5/2-0 (det)
mdb> finish
@@ -296,19 +296,19 @@
mdb> p 2
HeadVar__2 t5f(t1f1(41, 42, 43, 44))
mdb> p 2/1
- HeadVar__2 t1f1(41, 42, 43, 44)
+ HeadVar__2^1 t1f1(41, 42, 43, 44)
mdb> p 2/1/1
- HeadVar__2 41
+ HeadVar__2/1/1 41
mdb> p 2/1/t1a
- HeadVar__2 41
+ HeadVar__2/1/t1a 41
mdb> p 2/t5a
- HeadVar__2 t1f1(41, 42, 43, 44)
+ HeadVar__2^t5a t1f1(41, 42, 43, 44)
mdb> p 2/t5a/1
- HeadVar__2 41
+ HeadVar__2/t5a/1 41
mdb> p 2/t5a/t1a
- HeadVar__2 41
+ HeadVar__2/t5a/t1a 41
mdb> p 2/t6a
-mdb: the path t6a does not exist.
+mdb: the path t6a does not exist in variable 2.
mdb> step
14: 8 2 CALL pred field_names.make_t6/2-0 (det)
mdb> finish
@@ -316,11 +316,11 @@
mdb> p 2
HeadVar__2 t6f(0.900000000000000)
mdb> p 2/1
- HeadVar__2 0.900000000000000
+ HeadVar__2^1 0.900000000000000
mdb> p 2/t5a
-mdb: the path t5a does not exist.
+mdb: the path t5a does not exist in variable 2.
mdb> p 2/t6a
-mdb: the path t6a does not exist.
+mdb: the path t6a does not exist in variable 2.
mdb> browse 2
browser> p
t6f(0.900000000000000)
Index: tests/debugger/queens.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/queens.exp,v
retrieving revision 1.33
diff -u -b -r1.33 queens.exp
--- tests/debugger/queens.exp 6 Jan 2007 10:56:26 -0000 1.33
+++ tests/debugger/queens.exp 18 Jan 2007 08:44:01 -0000
@@ -233,6 +233,9 @@
0: + stop interface pred queens.print_list/3-0 (det)
mdb> break qdelete
1: + stop interface pred queens.qdelete/3-0 (nondet)
+mdb> break_print HeadVar__2^2
+ 1: + stop interface pred queens.qdelete/3-0 (nondet)
+ HeadVar__2^2 (flat)
mdb> continue -a
E35: C8 EXIT queens.m:36 (from queens.m:40)
pred queens.qperm/2-0 (nondet)
@@ -272,9 +275,11 @@
pred queens.qperm/2-0 (nondet)
E53: C13 REDO queens.m:45 (from queens.m:38)
pred queens.qdelete/3-0 (nondet)
+ HeadVar__2^2 []
mdb> break info
0: + stop interface pred queens.print_list/3-0 (det)
1: + stop interface pred queens.qdelete/3-0 (nondet)
+ HeadVar__2^2 (flat)
mdb> enable *
0: + stop interface pred queens.print_list/3-0 (det)
1: + stop interface pred queens.qdelete/3-0 (nondet)
@@ -283,10 +288,13 @@
pred queens.qdelete/3-0 (nondet) c2;d2;
E55: C17 CALL queens.m:45 (from queens.m:47)
pred queens.qdelete/3-0 (nondet)
+mdb: the path 2 does not exist in variable HeadVar__2.
E56: C17 FAIL queens.m:45 (from queens.m:47)
pred queens.qdelete/3-0 (nondet)
+mdb: the path 2 does not exist in variable HeadVar__2.
E57: C13 FAIL queens.m:45 (from queens.m:38)
pred queens.qdelete/3-0 (nondet)
+ HeadVar__2^2 []
E58: C12 FAIL queens.m:36 (from queens.m:40)
pred queens.qperm/2-0 (nondet)
mdb> disable 1
Index: tests/debugger/queens.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/queens.inp,v
retrieving revision 1.15
diff -u -b -r1.15 queens.inp
--- tests/debugger/queens.inp 11 Jul 2005 07:30:28 -0000 1.15
+++ tests/debugger/queens.inp 18 Jan 2007 08:11:45 -0000
@@ -76,6 +76,7 @@
register --quiet
break print_list
break qdelete
+break_print HeadVar__2^2
continue -a
break info
enable *
Index: tests/debugger/user_event.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/user_event.exp,v
retrieving revision 1.3
diff -u -b -r1.3 user_event.exp
--- tests/debugger/user_event.exp 6 Jan 2007 10:56:26 -0000 1.3
+++ tests/debugger/user_event.exp 12 Jan 2007 12:54:35 -0000
@@ -2,6 +2,15 @@
mdb> echo on
Command echo enabled.
mdb> register --quiet
+mdb> break user_event nonexistent_event_name
+There is no user event named `nonexistent_event_name'.
+mdb> break user_event nonexistent_set_name nodiag_fail
+There is no user event set named `nonexistent_set_name'.
+mdb> break user_event nodiag_fail
+ 0: + stop user_event nodiag_fail
+mdb> break_print -b0 !arg_b
+ 0: + stop user_event nodiag_fail
+ !arg_b (flat)
mdb> user
E2: C2 USER <safe_test> pred user_event.queen/2-0 (nondet) c3; user_event.m:32
mdb> print *
@@ -16,6 +25,7 @@
browser> quit
mdb> user
E3: C3 USER <nodiag_fail> pred user_event.nodiag/3-0 (semidet) s2-2;c6;t;c2; user_event.m:64
+ arg_b (attr 1, B) 1
mdb> vars
1 test_failed (attr 0)
2 arg_b (attr 1, B)
@@ -48,5 +58,12 @@
mdb> print *
test_list (attr 0, Out) [1, 2, 3, 5, 4]
Data (arg 1) [1, 2, 3, 4, 5]
+mdb> condition -b0 !arg_b = 1
+ 0: + stop user_event nodiag_fail
+ !arg_b = 1
+ !arg_b (flat)
mdb> continue
+ E5: C4 USER <nodiag_fail> pred user_event.nodiag/3-0 (semidet) s2-2;c6;t;c2; user_event.m:64
+ arg_b (attr 1, B) 1
+mdb> continue -S
[1, 3, 5, 2, 4]
Index: tests/debugger/user_event.inp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/debugger/user_event.inp,v
retrieving revision 1.1
diff -u -b -r1.1 user_event.inp
--- tests/debugger/user_event.inp 24 Nov 2006 03:48:23 -0000 1.1
+++ tests/debugger/user_event.inp 12 Jan 2007 04:49:16 -0000
@@ -1,5 +1,9 @@
echo on
register --quiet
+break user_event nonexistent_event_name
+break user_event nonexistent_set_name nodiag_fail
+break user_event nodiag_fail
+break_print -b0 !arg_b
user
print *
browse !test_list
@@ -13,4 +17,6 @@
print !arg_b
user
print *
+condition -b0 !arg_b = 1
continue
+continue -S
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/mercury_trace.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace.c,v
retrieving revision 1.104
diff -u -b -r1.104 mercury_trace.c
--- trace/mercury_trace.c 8 Jan 2007 09:15:22 -0000 1.104
+++ trace/mercury_trace.c 11 Jan 2007 18:46:33 -0000
@@ -559,6 +559,7 @@
MR_SpyAction action; /* ignored */
MR_SpyPrintList print_list;
+ print_list = NULL;
(void) MR_event_matches_spy_point(layout, port, &action,
&print_list);
jumpaddr = MR_trace_event_internal(cmd, interactive,
Index: trace/mercury_trace_cmd_breakpoint.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_cmd_breakpoint.c,v
retrieving revision 1.2
diff -u -b -r1.2 mercury_trace_cmd_breakpoint.c
--- trace/mercury_trace_cmd_breakpoint.c 29 Nov 2006 05:18:34 -0000 1.2
+++ trace/mercury_trace_cmd_breakpoint.c 18 Jan 2007 07:11:09 -0000
@@ -37,9 +37,11 @@
MR_MULTIMATCH_ASK, MR_MULTIMATCH_ALL, MR_MULTIMATCH_ONE
} MR_MultiMatch;
+static const char *MR_parse_spy_print(MR_BrowseFormat format, MR_bool warn,
+ char *word, MR_SpyPrint *sp_ptr);
static MR_SpyPrintList
- MR_add_to_print_list_end(MR_BrowseFormat format,
- char *word, MR_bool warn, MR_SpyPrintList print_list);
+ MR_add_to_print_list_end(MR_SpyPrint sp,
+ MR_SpyPrintList print_list);
static void MR_maybe_print_spy_point(int slot, const char *problem);
static MR_bool MR_parse_source_locn(char *word, const char **file,
int *line);
@@ -55,9 +57,9 @@
static MR_bool MR_trace_options_ignore_count(
MR_SpyIgnore_When *ignore_when,
int *ignore_count, char ***words, int *word_count);
-static MR_bool MR_trace_options_break_print(MR_BrowseFormat *format,
- MR_bool *at_start, MR_bool *warn, char ***words,
- int *word_count);
+static MR_bool MR_trace_options_break_print(int *break_num,
+ MR_BrowseFormat *format, MR_bool *at_start,
+ MR_bool *warn, char ***words, int *word_count);
static MR_bool MR_trace_options_register(MR_bool *verbose, char ***words,
int *word_count);
@@ -68,7 +70,7 @@
MR_EventInfo *event_info, MR_Code **jumpaddr)
{
const MR_LabelLayout *layout;
- MR_ProcSpec spec;
+ MR_ProcSpec proc_spec;
MR_SpyWhen when;
MR_SpyAction action;
MR_MultiMatch multi_match;
@@ -88,7 +90,7 @@
count = 0;
for (i = 0; i < MR_spy_point_next; i++) {
- if (MR_spy_points[i]->spy_exists) {
+ if (MR_spy_points[i]->MR_spy_exists) {
MR_print_spy_point(MR_mdb_out, i, MR_TRUE);
count++;
}
@@ -116,6 +118,160 @@
&words, &word_count))
{
; /* the usage message has already been printed */
+ } else if (word_count >= 2 && MR_streq(words[1], "user_event")) {
+ const MR_UserEventSpec *user_event_spec;
+ const char *user_event_set;
+ const char *user_event_name;
+ int slot;
+ int set;
+ int spec;
+ MR_bool found_event_set;
+ MR_bool found_event_name;
+
+ if (word_count == 2) {
+ user_event_set = NULL;
+ user_event_name = NULL;
+ } else if (word_count == 3) {
+ user_event_set = NULL;
+ user_event_name = words[2];
+ } else if (word_count == 4) {
+ user_event_set = words[2];
+ user_event_name = words[3];
+ } else {
+ MR_trace_usage_cur_cmd();
+ return KEEP_INTERACTING;
+ }
+
+ MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
+
+ if (user_event_name != NULL) {
+ found_event_set = MR_FALSE;
+ found_event_name = MR_FALSE;
+ for (set = 0; set < MR_trace_event_set_next; set++) {
+ if (user_event_set == NULL ||
+ MR_streq(user_event_set,
+ MR_trace_event_sets[set].MR_tes_name))
+ {
+ if (user_event_set != NULL) {
+ found_event_set = MR_TRUE;
+ }
+
+ for (spec = 0;
+ spec < MR_trace_event_sets[set].MR_tes_num_specs;
+ spec++)
+ {
+ if (MR_trace_event_sets[set].MR_tes_specs == NULL) {
+ /*
+ ** We couldn't parse the event set specification
+ ** in the module. The error message has already
+ ** been printed, so just ignore the event set.
+ */
+ continue;
+ }
+
+ user_event_spec =
+ &MR_trace_event_sets[set].MR_tes_specs[spec];
+ if (MR_streq(user_event_name,
+ user_event_spec->MR_ues_event_name))
+ {
+ found_event_name = MR_TRUE;
+ }
+ }
+ }
+ }
+
+ if (user_event_set != NULL && ! found_event_set) {
+ fprintf(MR_mdb_out,
+ "There is no user event set named `%s'.\n",
+ user_event_set);
+ return KEEP_INTERACTING;
+ }
+
+ if (! found_event_name) {
+ if (user_event_set == NULL) {
+ fprintf(MR_mdb_out,
+ "There is no user event named `%s'.\n",
+ user_event_name);
+ } else {
+ fprintf(MR_mdb_out,
+ "There is no user event named `%s' "
+ "in event set `%s'.\n",
+ user_event_set, user_event_name);
+ }
+
+ return KEEP_INTERACTING;
+ }
+ }
+
+ if (ignore_count > 0 && ignore_when == MR_SPY_IGNORE_ENTRY) {
+ fprintf(MR_mdb_out, "That breakpoint "
+ "would never become enabled.\n");
+ return KEEP_INTERACTING;
+ } else if (ignore_count > 0 &&
+ ignore_when == MR_SPY_IGNORE_INTERFACE)
+ {
+ fprintf(MR_mdb_out, "That breakpoint "
+ "would never become enabled.\n");
+ return KEEP_INTERACTING;
+ }
+
+ MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
+ slot = MR_add_user_event_spy_point(action, ignore_when, ignore_count,
+ user_event_set, user_event_name, print_list, &problem);
+ MR_maybe_print_spy_point(slot, problem);
+ } else if (word_count >= 2 && MR_streq(words[1], "user_event_set")) {
+ const MR_UserEventSpec *user_event_spec;
+ const char *user_event_set;
+ int slot;
+ int set;
+ int spec;
+ MR_bool found_event_set;
+
+ if (word_count == 2) {
+ user_event_set = NULL;
+ } else if (word_count == 3) {
+ user_event_set = words[2];
+ } else {
+ MR_trace_usage_cur_cmd();
+ return KEEP_INTERACTING;
+ }
+
+ MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
+
+ if (user_event_set != NULL) {
+ found_event_set = MR_FALSE;
+ for (set = 0; set < MR_trace_event_set_next; set++) {
+ if (MR_streq(user_event_set,
+ MR_trace_event_sets[set].MR_tes_name))
+ {
+ found_event_set = MR_TRUE;
+ }
+ }
+
+ if (! found_event_set) {
+ fprintf(MR_mdb_out,
+ "There is no user event set named `%s'.\n",
+ user_event_set);
+ return KEEP_INTERACTING;
+ }
+ }
+
+ if (ignore_count > 0 && ignore_when == MR_SPY_IGNORE_ENTRY) {
+ fprintf(MR_mdb_out, "That breakpoint "
+ "would never become enabled.\n");
+ return KEEP_INTERACTING;
+ } else if (ignore_count > 0 &&
+ ignore_when == MR_SPY_IGNORE_INTERFACE)
+ {
+ fprintf(MR_mdb_out, "That breakpoint "
+ "would never become enabled.\n");
+ return KEEP_INTERACTING;
+ }
+
+ MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
+ slot = MR_add_user_event_spy_point(action, ignore_when, ignore_count,
+ user_event_set, NULL, print_list, &problem);
+ MR_maybe_print_spy_point(slot, problem);
} else if (word_count == 2 && MR_streq(words[1], "here")) {
int slot;
MR_TracePort port;
@@ -140,27 +296,27 @@
slot = MR_add_proc_spy_point(MR_SPY_SPECIFIC, action, ignore_when,
ignore_count, 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)) {
+ } else if (word_count == 2 && MR_parse_proc_spec(words[1], &proc_spec)) {
MR_MatchesInfo matches;
int slot;
MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);
- matches = MR_search_for_matching_procedures(&spec);
+ matches = MR_search_for_matching_procedures(&proc_spec);
if (matches.match_proc_next == 0) {
fflush(MR_mdb_out);
fprintf(MR_mdb_err, "mdb: there is no such procedure.\n");
} else if (matches.match_proc_next == 1) {
slot = MR_add_proc_spy_point(when, action, ignore_when,
- ignore_count, matches.match_procs[0], NULL, print_list,
- &problem);
+ ignore_count, matches.match_procs[0], NULL,
+ print_list, &problem);
MR_maybe_print_spy_point(slot, problem);
} else if (multi_match == MR_MULTIMATCH_ALL) {
int i;
for (i = 0; i < matches.match_proc_next; i++) {
slot = MR_add_proc_spy_point(when, action, ignore_when,
- ignore_count, matches.match_procs[i], NULL, print_list,
- &problem);
+ ignore_count, matches.match_procs[i], NULL,
+ print_list, &problem);
MR_maybe_print_spy_point(slot, problem);
}
} else {
@@ -191,8 +347,8 @@
} else if (MR_streq(line2, "*")) {
for (i = 0; i < matches.match_proc_next; i++) {
slot = MR_add_proc_spy_point(when, action, ignore_when,
- ignore_count, matches.match_procs[i], NULL, print_list,
- &problem);
+ ignore_count, matches.match_procs[i], NULL,
+ print_list, &problem);
MR_maybe_print_spy_point(slot, problem);
}
@@ -200,8 +356,8 @@
} else if (MR_trace_is_natural_number(line2, &i)) {
if (0 <= i && i < matches.match_proc_next) {
slot = MR_add_proc_spy_point(when, action, ignore_when,
- ignore_count, matches.match_procs[i], NULL, print_list,
- &problem);
+ ignore_count, matches.match_procs[i], NULL,
+ print_list, &problem);
MR_maybe_print_spy_point(slot, problem);
} else {
fprintf(MR_mdb_out, "no such match\n");
@@ -281,13 +437,11 @@
return KEEP_INTERACTING;
}
- if (! MR_spy_points[break_num]->spy_exists) {
+ if (! MR_spy_points[break_num]->MR_spy_exists) {
fprintf(MR_mdb_err, "Breakpoint %d has been deleted.\n", break_num);
return KEEP_INTERACTING;
}
- cond = MR_malloc(sizeof(MR_SpyCond));
-
what_str = MR_malloc(strlen(words[1]) + 1);
strcpy(what_str, words[1]);
@@ -329,23 +483,34 @@
return KEEP_INTERACTING;
}
- if (MR_spy_points[break_num]->spy_cond != NULL) {
- MR_delete_cterm(MR_spy_points[break_num]->spy_cond->cond_term);
- MR_free(MR_spy_points[break_num]->spy_cond->cond_what_string);
- MR_free(MR_spy_points[break_num]->spy_cond->cond_term_string);
- MR_free(MR_spy_points[break_num]->spy_cond);
- }
-
- cond->cond_var_spec = var_spec;
- cond->cond_path = path;
- cond->cond_test = test;
- cond->cond_term = term;
- cond->cond_term_string = term_str;
- cond->cond_what_string = what_str;
- cond->cond_require_var = require_var;
- cond->cond_require_path = require_path;
+ if (MR_spy_points[break_num]->MR_spy_cond != NULL) {
+ MR_delete_cterm(MR_spy_points[break_num]->MR_spy_cond->MR_cond_term);
+ MR_free(MR_spy_points[break_num]->MR_spy_cond->MR_cond_what_string);
+ MR_free(MR_spy_points[break_num]->MR_spy_cond->MR_cond_term_string);
+ MR_free(MR_spy_points[break_num]->MR_spy_cond);
+ }
+
+ if (MR_spy_points[break_num]->MR_spy_when == MR_SPY_USER_EVENT_SET) {
+ /*
+ ** If the breakpoint is matched by all events in an event set (or
+ ** possibly all events in all event sets), then it doesn't make sense
+ ** to insist on any given variable name existing at the matching event.
+ */
+ require_var = MR_FALSE;
+ require_path = MR_FALSE;
+ }
+
+ cond = MR_malloc(sizeof(MR_SpyCond));
+ cond->MR_cond_var_spec = var_spec;
+ cond->MR_cond_path = path;
+ cond->MR_cond_test = test;
+ cond->MR_cond_term = term;
+ cond->MR_cond_term_string = term_str;
+ cond->MR_cond_what_string = what_str;
+ cond->MR_cond_require_var = require_var;
+ cond->MR_cond_require_path = require_path;
- MR_spy_points[break_num]->spy_cond = cond;
+ MR_spy_points[break_num]->MR_spy_cond = cond;
MR_print_spy_point(MR_mdb_out, break_num, MR_TRUE);
return KEEP_INTERACTING;
@@ -367,7 +532,9 @@
{
; /* the usage message has already been printed */
} else if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
- if (0 <= n && n < MR_spy_point_next && MR_spy_points[n]->spy_exists) {
+ if (0 <= n && n < MR_spy_point_next &&
+ MR_spy_points[n]->MR_spy_exists)
+ {
problem = MR_ignore_spy_point(n, ignore_when, ignore_count);
MR_maybe_print_spy_point(n, problem);
} else {
@@ -380,7 +547,7 @@
count = 0;
for (i = 0; i < MR_spy_point_next; i++) {
- if (MR_spy_points[i]->spy_exists) {
+ if (MR_spy_points[i]->MR_spy_exists) {
problem = MR_ignore_spy_point(n, ignore_when, ignore_count);
MR_maybe_print_spy_point(n, problem);
count++;
@@ -393,7 +560,7 @@
} else if (word_count == 1) {
if (0 <= MR_most_recent_spy_point
&& MR_most_recent_spy_point < MR_spy_point_next
- && MR_spy_points[MR_most_recent_spy_point]->spy_exists)
+ && MR_spy_points[MR_most_recent_spy_point]->MR_spy_exists)
{
n = MR_most_recent_spy_point;
problem = MR_ignore_spy_point(n, ignore_when, ignore_count);
@@ -413,40 +580,62 @@
MR_trace_cmd_break_print(char **words, int word_count, MR_TraceCmdInfo *cmd,
MR_EventInfo *event_info, MR_Code **jumpaddr)
{
- int n;
+ int break_num;
int i;
MR_BrowseFormat format;
MR_bool at_start;
MR_bool warn;
MR_SpyPrintList print_list;
+ MR_SpyPrint sp;
+ const char *problem;
+ MR_bool any_problem;
- if (! MR_trace_options_break_print(&format, &at_start, &warn,
+ if (! MR_trace_options_break_print(&break_num, &format, &at_start, &warn,
&words, &word_count))
{
; /* 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)
+ } else if (word_count > 1) {
+ if (break_num < 0) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: no break point exists.\n");
+ } else if (! (0 <= break_num && break_num < MR_spy_point_next
+ && MR_spy_points[break_num]->MR_spy_exists))
{
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: break point #%d does not exist.\n",
+ break_num);
+ } else {
+ if (word_count == 2 && MR_streq(words[1], "none")) {
+ MR_clear_spy_point_print_list(break_num);
+ MR_print_spy_point(MR_mdb_out, break_num, MR_TRUE);
+ } else {
print_list = NULL;
- for (i = 2; i < word_count; i++) {
- print_list = MR_add_to_print_list_end(format, words[i], warn,
- print_list);
+ any_problem = MR_FALSE;
+ for (i = 1; i < word_count; i++) {
+ problem = MR_parse_spy_print(format, warn, words[i], &sp);
+ if (problem != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: cannot parse `%s'\n",
+ words[i]);
+ any_problem = MR_TRUE;
+ } else {
+ print_list =
+ MR_add_to_print_list_end(sp, print_list);
+ }
}
+ if (! any_problem) {
if (at_start) {
- MR_add_spy_point_print_list_start(n, print_list);
+ MR_add_spy_point_print_list_start(break_num,
+ print_list);
} else {
- MR_add_spy_point_print_list_end(n, print_list);
+ MR_add_spy_point_print_list_end(break_num,
+ 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);
+ MR_print_spy_point(MR_mdb_out, break_num, MR_TRUE);
+ }
+ }
}
} else {
MR_trace_usage_cur_cmd();
@@ -462,8 +651,10 @@
int n;
if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
- if (0 <= n && n < MR_spy_point_next && MR_spy_points[n]->spy_exists) {
- MR_spy_points[n]->spy_enabled = MR_TRUE;
+ if (0 <= n && n < MR_spy_point_next &&
+ MR_spy_points[n]->MR_spy_exists)
+ {
+ MR_spy_points[n]->MR_spy_enabled = MR_TRUE;
MR_print_spy_point(MR_mdb_out, n, MR_FALSE);
} else {
fflush(MR_mdb_out);
@@ -475,8 +666,8 @@
count = 0;
for (i = 0; i < MR_spy_point_next; i++) {
- if (MR_spy_points[i]->spy_exists) {
- MR_spy_points[i]->spy_enabled = MR_TRUE;
+ if (MR_spy_points[i]->MR_spy_exists) {
+ MR_spy_points[i]->MR_spy_enabled = MR_TRUE;
MR_print_spy_point(MR_mdb_out, i, MR_FALSE);
count++;
}
@@ -488,9 +679,9 @@
} else if (word_count == 1) {
if (0 <= MR_most_recent_spy_point
&& MR_most_recent_spy_point < MR_spy_point_next
- && MR_spy_points[MR_most_recent_spy_point]->spy_exists)
+ && MR_spy_points[MR_most_recent_spy_point]->MR_spy_exists)
{
- MR_spy_points[MR_most_recent_spy_point]->spy_enabled = MR_TRUE;
+ MR_spy_points[MR_most_recent_spy_point]->MR_spy_enabled = MR_TRUE;
MR_print_spy_point(MR_mdb_out, MR_most_recent_spy_point, MR_FALSE);
} else {
fflush(MR_mdb_out);
@@ -510,8 +701,10 @@
int n;
if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
- if (0 <= n && n < MR_spy_point_next && MR_spy_points[n]->spy_exists) {
- MR_spy_points[n]->spy_enabled = MR_FALSE;
+ if (0 <= n && n < MR_spy_point_next &&
+ MR_spy_points[n]->MR_spy_exists)
+ {
+ MR_spy_points[n]->MR_spy_enabled = MR_FALSE;
MR_print_spy_point(MR_mdb_out, n, MR_FALSE);
} else {
fflush(MR_mdb_out);
@@ -523,8 +716,8 @@
count = 0;
for (i = 0; i < MR_spy_point_next; i++) {
- if (MR_spy_points[i]->spy_exists) {
- MR_spy_points[i]->spy_enabled = MR_FALSE;
+ if (MR_spy_points[i]->MR_spy_exists) {
+ MR_spy_points[i]->MR_spy_enabled = MR_FALSE;
MR_print_spy_point(MR_mdb_out, i, MR_FALSE);
count++;
}
@@ -537,9 +730,9 @@
} else if (word_count == 1) {
if (0 <= MR_most_recent_spy_point
&& MR_most_recent_spy_point < MR_spy_point_next
- && MR_spy_points[MR_most_recent_spy_point]->spy_exists)
+ && MR_spy_points[MR_most_recent_spy_point]->MR_spy_exists)
{
- MR_spy_points[MR_most_recent_spy_point]->spy_enabled = MR_FALSE;
+ MR_spy_points[MR_most_recent_spy_point]->MR_spy_enabled = MR_FALSE;
MR_print_spy_point(MR_mdb_out, MR_most_recent_spy_point, MR_FALSE);
} else {
fflush(MR_mdb_out);
@@ -559,10 +752,12 @@
int n;
if (word_count == 2 && MR_trace_is_natural_number(words[1], &n)) {
- if (0 <= n && n < MR_spy_point_next && MR_spy_points[n]->spy_exists) {
- MR_spy_points[n]->spy_exists = MR_FALSE;
+ if (0 <= n && n < MR_spy_point_next &&
+ MR_spy_points[n]->MR_spy_exists)
+ {
+ MR_spy_points[n]->MR_spy_exists = MR_FALSE;
MR_print_spy_point(MR_mdb_out, n, MR_FALSE);
- MR_spy_points[n]->spy_exists = MR_TRUE;
+ MR_spy_points[n]->MR_spy_exists = MR_TRUE;
MR_delete_spy_point(n);
} else {
fflush(MR_mdb_out);
@@ -574,10 +769,10 @@
count = 0;
for (i = 0; i < MR_spy_point_next; i++) {
- if (MR_spy_points[i]->spy_exists) {
- MR_spy_points[i]->spy_exists = MR_FALSE;
+ if (MR_spy_points[i]->MR_spy_exists) {
+ MR_spy_points[i]->MR_spy_exists = MR_FALSE;
MR_print_spy_point(MR_mdb_out, i, MR_FALSE);
- MR_spy_points[i]->spy_exists = MR_TRUE;
+ MR_spy_points[i]->MR_spy_exists = MR_TRUE;
MR_delete_spy_point(i);
count++;
}
@@ -590,14 +785,14 @@
} else if (word_count == 1) {
if (0 <= MR_most_recent_spy_point
&& MR_most_recent_spy_point < MR_spy_point_next
- && MR_spy_points[MR_most_recent_spy_point]->spy_exists)
+ && MR_spy_points[MR_most_recent_spy_point]->MR_spy_exists)
{
int slot;
slot = MR_most_recent_spy_point;
- MR_spy_points[slot]->spy_exists = MR_FALSE;
+ MR_spy_points[slot]->MR_spy_exists = MR_FALSE;
MR_print_spy_point(MR_mdb_out, slot, MR_FALSE);
- MR_spy_points[slot]->spy_exists = MR_TRUE;
+ MR_spy_points[slot]->MR_spy_exists = MR_TRUE;
MR_delete_spy_point(slot);
} else {
fflush(MR_mdb_out);
@@ -659,42 +854,70 @@
/****************************************************************************/
-static MR_SpyPrintList
-MR_add_to_print_list_end(MR_BrowseFormat format, char *word, MR_bool warn,
- MR_SpyPrintList print_list)
+static const char *
+MR_parse_spy_print(MR_BrowseFormat format, MR_bool warn, char *word,
+ MR_SpyPrint *sp_ptr)
{
- MR_SpyPrintList list;
- MR_SpyPrintList new_list;
- MR_SpyPrint new_node;
+ MR_SpyPrint sp;
+ const char *problem;
+
+ word = MR_copy_string(word);
+
+ problem = NULL;
+ sp = MR_malloc(sizeof(struct MR_SpyPrint_Struct));
+ sp->MR_p_format = format;
+ sp->MR_p_warn = warn;
+ sp->MR_p_word_copy = word;
- new_node = MR_malloc(sizeof(struct MR_SpyPrint_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;
+ sp->MR_p_what = MR_SPY_PRINT_ALL;
+ /* The other fields are initialized to dummies. */
+ sp->MR_p_var_spec.MR_var_spec_kind = MR_VAR_SPEC_NAME;
+ sp->MR_p_var_spec.MR_var_spec_number = -1;
+ sp->MR_p_var_spec.MR_var_spec_name = NULL;
+ sp->MR_p_path = NULL;
} else if (MR_streq(word, "goal")) {
- new_node->p_what = MR_SPY_PRINT_GOAL;
- new_node->p_name = NULL;
+ sp->MR_p_what = MR_SPY_PRINT_GOAL;
+ /* The other fields are initialized to dummies. */
+ sp->MR_p_var_spec.MR_var_spec_kind = MR_VAR_SPEC_NAME;
+ sp->MR_p_var_spec.MR_var_spec_number = -1;
+ sp->MR_p_var_spec.MR_var_spec_name = NULL;
+ sp->MR_p_path = NULL;
} else {
- new_node->p_what = MR_SPY_PRINT_ONE;
- new_node->p_name = MR_copy_string(word);
+ sp->MR_p_what = MR_SPY_PRINT_ONE;
+ problem = MR_trace_parse_var_path(word,
+ &sp->MR_p_var_spec, &sp->MR_p_path);
}
+ if (problem == NULL) {
+ *sp_ptr = sp;
+ } else {
+ *sp_ptr = NULL;
+ }
+
+ return problem;
+}
+
+static MR_SpyPrintList
+MR_add_to_print_list_end(MR_SpyPrint sp, MR_SpyPrintList print_list)
+{
+ MR_SpyPrintList list;
+ MR_SpyPrintList new_list;
+
new_list = MR_malloc(sizeof(struct MR_SpyPrintList_Struct));
- new_list->pl_cur = new_node;
- new_list->pl_next = NULL;
+ new_list->MR_pl_cur = sp;
+ new_list->MR_pl_next = NULL;
list = print_list;
if (list == NULL) {
return new_list;
}
- while (list->pl_next != NULL) {
- list = list->pl_next;
+ while (list->MR_pl_next != NULL) {
+ list = list->MR_pl_next;
}
- list->pl_next = new_list;
+ list->MR_pl_next = new_list;
return print_list;
}
@@ -737,7 +960,7 @@
{ "-A", "-E", "-I", "-O", "-P", "-S", "-a", "-e", "-i",
"--all", "--entry", "--ignore-entry", "--ignore-interface",
"--interface", "--print", "--select-all", "--select-one",
- "--stop", "here", "info", NULL };
+ "--stop", "here", "info", "user_event", NULL };
const char *const MR_trace_ignore_cmd_args[] =
{ "-E", "-I", "--ignore-entry", "--ignore-interface", NULL };
@@ -749,6 +972,7 @@
{ "all", MR_no_argument, NULL, 'a' },
{ "entry", MR_no_argument, NULL, 'e' },
{ "interface", MR_no_argument, NULL, 'i' },
+ { "ignore", MR_required_argument, NULL, 'X' },
{ "ignore-entry", MR_required_argument, NULL, 'E' },
{ "ignore-interface", MR_required_argument, NULL, 'I' },
{ "print-list", MR_required_argument, NULL, 'p' },
@@ -767,13 +991,14 @@
MR_SpyPrintList *print_list, char ***words, int *word_count)
{
int c;
- MR_SpyPrint node;
+ MR_SpyPrint sp;
MR_SpyPrintList list;
MR_bool warn;
+ const char *problem;
warn = MR_TRUE;
MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "AE:I:OPSaeinp:",
+ while ((c = MR_getopt_long(*word_count, *words, "AE:I:OPSX:aeinp:",
MR_trace_when_action_multi_ignore_opts, NULL)) != EOF)
{
switch (c) {
@@ -795,8 +1020,15 @@
break;
case 'p':
- *print_list = MR_add_to_print_list_end(MR_BROWSE_FORMAT_FLAT,
- MR_optarg, warn, *print_list);
+ problem = MR_parse_spy_print(MR_BROWSE_FORMAT_FLAT, warn,
+ MR_optarg, &sp);
+ if (problem != NULL) {
+ fflush(MR_mdb_out);
+ fprintf(MR_mdb_err, "mdb: cannot parse `%s'\n", MR_optarg);
+ return MR_FALSE;
+ }
+
+ *print_list = MR_add_to_print_list_end(sp, *print_list);
break;
case 'E':
@@ -815,6 +1047,14 @@
*ignore_when = MR_SPY_IGNORE_INTERFACE;
break;
+ case 'X':
+ if (! MR_trace_is_natural_number(MR_optarg, ignore_count)) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+ *ignore_when = MR_SPY_IGNORE_ALL;
+ break;
+
case 'A':
*multi_match = MR_MULTIMATCH_ALL;
break;
@@ -844,7 +1084,7 @@
static struct MR_option MR_trace_condition_opts[] =
{
- { "break-num", MR_required_argument, NULL, 'n' },
+ { "break-num", MR_required_argument, NULL, 'b' },
{ "dont-require-var", MR_no_argument, NULL, 'v' },
{ "dont-require-path", MR_no_argument, NULL, 'p' },
{ NULL, MR_no_argument, NULL, 0 }
@@ -858,12 +1098,12 @@
int n;
MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "n:vp",
+ while ((c = MR_getopt_long(*word_count, *words, "b:vp",
MR_trace_condition_opts, NULL)) != EOF)
{
switch (c) {
- case 'n':
+ case 'b':
if (! MR_trace_is_natural_number(MR_optarg, &n)) {
MR_trace_usage_cur_cmd();
return MR_FALSE;
@@ -898,6 +1138,7 @@
static struct MR_option MR_trace_ignore_count_opts[] =
{
+ { "ignore", MR_required_argument, NULL, 'X' },
{ "ignore-entry", MR_required_argument, NULL, 'E' },
{ "ignore-interface", MR_required_argument, NULL, 'I' },
{ NULL, MR_no_argument, NULL, 0 }
@@ -910,7 +1151,7 @@
int c;
MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "E:I:",
+ while ((c = MR_getopt_long(*word_count, *words, "E:I:X:",
MR_trace_ignore_count_opts, NULL)) != EOF)
{
switch (c) {
@@ -931,6 +1172,14 @@
*ignore_when = MR_SPY_IGNORE_INTERFACE;
break;
+ case 'X':
+ if (! MR_trace_is_natural_number(MR_optarg, ignore_count)) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+ *ignore_when = MR_SPY_IGNORE_ALL;
+ break;
+
default:
MR_trace_usage_cur_cmd();
return MR_FALSE;
@@ -944,6 +1193,7 @@
static struct MR_option MR_trace_break_print_opts[] =
{
+ { "break-num", MR_required_argument, NULL, 'b' },
{ "end", MR_no_argument, NULL, 'e' },
{ "no-warn", MR_no_argument, NULL, 'n' },
{ "flat", MR_no_argument, NULL, 'f' },
@@ -954,20 +1204,30 @@
};
static MR_bool
-MR_trace_options_break_print(MR_BrowseFormat *format, MR_bool *at_start,
- MR_bool *warn, char ***words, int *word_count)
+MR_trace_options_break_print(int *break_num, MR_BrowseFormat *format,
+ MR_bool *at_start, MR_bool *warn, char ***words, int *word_count)
{
int c;
+ int n;
+ *break_num = MR_most_recent_spy_point;
*format = MR_BROWSE_FORMAT_FLAT;
*at_start = MR_TRUE;
*warn = MR_TRUE;
MR_optind = 0;
- while ((c = MR_getopt_long(*word_count, *words, "enfrvp",
+ while ((c = MR_getopt_long(*word_count, *words, "b:enfrvp",
MR_trace_break_print_opts, NULL)) != EOF)
{
switch (c) {
+ case 'b':
+ if (! MR_trace_is_natural_number(MR_optarg, &n)) {
+ MR_trace_usage_cur_cmd();
+ return MR_FALSE;
+ }
+ *break_num = n;
+ break;
+
case 'e':
*at_start = MR_FALSE;
break;
Index: trace/mercury_trace_cmd_misc.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_cmd_misc.c,v
retrieving revision 1.3
diff -u -b -r1.3 mercury_trace_cmd_misc.c
--- trace/mercury_trace_cmd_misc.c 29 Nov 2006 05:18:36 -0000 1.3
+++ trace/mercury_trace_cmd_misc.c 12 Jan 2007 11:18:24 -0000
@@ -164,6 +164,8 @@
case MR_SPY_LINENO:
case MR_SPY_SPECIFIC:
+ case MR_SPY_USER_EVENT:
+ case MR_SPY_USER_EVENT_SET:
MR_fatal_error("save cmd: invalid default scope");
}
Index: trace/mercury_trace_internal.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_internal.c,v
retrieving revision 1.232
diff -u -b -r1.232 mercury_trace_internal.c
--- trace/mercury_trace_internal.c 3 Jan 2007 05:17:21 -0000 1.232
+++ trace/mercury_trace_internal.c 18 Jan 2007 10:17:28 -0000
@@ -358,25 +358,6 @@
MR_io_tabling_start = MR_IO_ACTION_MAX;
MR_io_tabling_end = MR_IO_ACTION_MAX;
- for (i = 0; i < MR_trace_event_set_next; i++) {
- if (! MR_trace_event_sets[i].MR_tes_is_consistent) {
- fprintf(MR_mdb_out,
- "The executable's modules were compiled with "
- "inconsistent definitions of user event set %s.\n",
- MR_trace_event_sets[i].MR_tes_name);
- } else {
- MR_trace_event_sets[i].MR_tes_event_set =
- MR_read_event_set("no input file",
- MR_trace_event_sets[i].MR_tes_desc);
- if (MR_trace_event_sets[i].MR_tes_event_set == NULL) {
- fprintf(MR_mdb_out,
- "Internal error: could not parse "
- "the specification of event set %s.\n",
- MR_trace_event_sets[i].MR_tes_name);
- }
- }
- }
-
MR_trace_internal_initialized = MR_TRUE;
}
}
@@ -808,37 +789,38 @@
{
MR_SpyPrint node;
const char *problem;
- char *after_problem;
+ MR_VarSpec *after_var_spec;
int count;
count = 0;
- for (; print_list != NULL; print_list = print_list->pl_next) {
+ for (; print_list != NULL; print_list = print_list->MR_pl_next) {
count++;
- node = print_list->pl_cur;
- after_problem = NULL;
+ node = print_list->MR_pl_cur;
+ after_var_spec = NULL;
- switch (node->p_what) {
+ switch (node->MR_p_what) {
case MR_SPY_PRINT_ALL:
problem = MR_trace_browse_all(MR_mdb_out,
- MR_trace_browse_internal, node->p_format);
+ MR_trace_browse_internal, node->MR_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);
+ node->MR_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);
+ problem = MR_trace_browse_one_path(MR_mdb_out, MR_TRUE,
+ node->MR_p_var_spec, node->MR_p_path,
+ MR_trace_browse_internal, MR_BROWSE_CALLER_PRINT,
+ node->MR_p_format, MR_FALSE);
if (problem != NULL &&
MR_streq(problem, "there is no such variable"))
{
- if (node->p_warn) {
+ if (node->MR_p_warn) {
problem = "there is no variable named";
- after_problem = node->p_name;
+ after_var_spec = &node->MR_p_var_spec;
} else {
problem = NULL;
}
@@ -847,15 +829,16 @@
break;
default:
- MR_fatal_error("invalid node->p_what");
+ MR_fatal_error("invalid node->MR_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);
+ if (after_var_spec != NULL) {
+ fprintf(MR_mdb_err, " ");
+ MR_print_var_spec(MR_mdb_err, after_var_spec);
}
fprintf(MR_mdb_err, ".\n");
}
@@ -1388,7 +1371,7 @@
list = print_list;
len = 0;
- for (; list != NULL; list = list->pl_next) {
+ for (; list != NULL; list = list->MR_pl_next) {
len++;
}
Index: trace/mercury_trace_spy.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_spy.c,v
retrieving revision 1.29
diff -u -b -r1.29 mercury_trace_spy.c
--- trace/mercury_trace_spy.c 29 Nov 2006 05:18:40 -0000 1.29
+++ trace/mercury_trace_spy.c 18 Jan 2007 08:08:14 -0000
@@ -44,6 +44,8 @@
"entry",
"specific",
"linenumber",
+ "user_event",
+ "user_event_set",
};
/*
@@ -70,8 +72,8 @@
*/
typedef struct {
- const MR_ProcLayout *spy_proc;
- MR_SpyPoint *spy_points;
+ const MR_ProcLayout *MR_sp_proc;
+ MR_SpyPoint *MR_sp_points;
} MR_SpiedProc;
static MR_SpiedProc *MR_spied_procs;
@@ -89,8 +91,8 @@
*/
typedef struct {
- const MR_LabelLayout *spy_label;
- int spy_point_num;
+ const MR_LabelLayout *MR_sl_label;
+ int MR_sl_point_num;
} MR_SpiedLabel;
static MR_SpiedLabel *MR_spied_labels;
@@ -100,6 +102,54 @@
/* The initial size of the spied labels table. */
#define MR_INIT_SPIED_LABELS 10
+/*
+** The table of spied on user event names, with one entry per user event
+** name that is currently being spied on, ordered on the event name,
+** and with counters saying which is the next free slot and how many slots
+** are allocated.
+**
+** All the MR_SPY_USER_EVENT breakpoints are listed in MR_spied_user_events,
+** whether or not the breakpoint requires a specific event set as well as a
+** specific name.
+*/
+
+typedef struct {
+ const char *MR_sue_user_event_name;
+ MR_SpyPoint *MR_sue_points;
+} MR_SpiedUserEvent;
+
+static MR_SpiedUserEvent *MR_spied_user_events;
+static int MR_spied_user_event_next = 0;
+static int MR_spied_user_event_max = 0;
+
+/* The initial size of the spied user events table. */
+#define MR_INIT_SPIED_USER_EVENTS 10
+
+/*
+** The table of spied on user event set names, with one entry per user event
+** set name that is currently being spied on, ordered on the event set name,
+** and with counters saying which is the next free slot and how many slots
+** are allocated.
+**
+** Only the MR_SPY_USER_EVENT_SET breakpoints that specify an event set
+** are listed in MR_spied_user_event_sets. The ones that do not specify
+** an event set are all listed in MR_spied_universal_user_events.
+*/
+
+typedef struct {
+ const char *MR_sues_user_event_set;
+ MR_SpyPoint *MR_sues_points;
+} MR_SpiedUserEventSet;
+
+static MR_SpiedUserEventSet *MR_spied_user_event_sets;
+static int MR_spied_user_event_set_next = 0;
+static int MR_spied_user_event_set_max = 0;
+
+/* The initial size of the spied user event sets table. */
+#define MR_INIT_SPIED_USER_EVENT_SETS 10
+
+static MR_SpyPoint *MR_spied_universal_user_events;
+
/**************************************************************************/
static int MR_compare_addr(const void *address1,
@@ -107,16 +157,23 @@
static int MR_search_spy_table_for_proc(const MR_ProcLayout *entry);
static int MR_search_spy_table_for_label(
const MR_LabelLayout *label);
+static int MR_search_spy_table_for_user_event_name(
+ const char *user_event_name);
+static int MR_search_spy_table_for_user_event_set(
+ const char *user_event_set);
static MR_bool MR_spy_cond_is_true(MR_SpyPoint *point,
const MR_LabelLayout *label);
+static int MR_add_spy_point(MR_bool reuse, MR_SpyPoint *point);
static void MR_add_line_spy_point_callback(
const MR_LabelLayout *label, int spy_point_num);
static int MR_compare_spied_labels(const void *, const void *);
static void MR_delete_spy_print_list(MR_SpyPrintList print_list);
static void MR_update_enabled_action(MR_SpyPoint *point,
- MR_TracePort port, MR_SpyAction *action_ptr,
- MR_bool *enabled_ptr);
+ const MR_LabelLayout *layout, MR_TracePort port,
+ MR_bool *enabled_ptr, MR_SpyAction *action_ptr,
+ MR_SpyPrintList *print_listr_ptr);
static const char *MR_ignore_when_to_string(MR_SpyIgnore_When ignore_when);
+static void MR_print_spy_print_what(FILE *fp, MR_SpyPrint sp);
/*
** Compare two addresses, and return an integer which is <0, 0, or >0
@@ -144,7 +201,7 @@
}
/*
-** Return the index of the entry in MR_spied_procs whose spy_proc field
+** Return the index of the entry in MR_spied_procs whose MR_sp_proc field
** is entry, or a negative number if absent.
*/
@@ -155,7 +212,7 @@
MR_bool found;
MR_bsearch(MR_spied_proc_next, slot, found,
- MR_compare_addr(MR_spied_procs[slot].spy_proc, entry));
+ MR_compare_addr(MR_spied_procs[slot].MR_sp_proc, entry));
if (found) {
return slot;
} else {
@@ -164,7 +221,7 @@
}
/*
-** Return the index of the entry in MR_spied_labels whose spy_label field
+** Return the index of the entry in MR_spied_labels whose MR_sl_label field
** is label, or a negative number if absent.
*/
@@ -175,7 +232,51 @@
MR_bool found;
MR_bsearch(MR_spied_label_next, slot, found,
- MR_compare_addr(MR_spied_labels[slot].spy_label, label));
+ MR_compare_addr(MR_spied_labels[slot].MR_sl_label, label));
+ if (found) {
+ return slot;
+ } else {
+ return -1;
+ }
+}
+
+/*
+** Return the index of the entry in MR_spied_user_events whose
+** MR_sue_user_event_name field is user_event_name, or a negative number
+** if absent.
+*/
+
+static int
+MR_search_spy_table_for_user_event_name(const char *user_event_name)
+{
+ int slot;
+ MR_bool found;
+
+ MR_bsearch(MR_spied_user_event_next, slot, found,
+ strcmp(MR_spied_user_events[slot].MR_sue_user_event_name,
+ user_event_name));
+ if (found) {
+ return slot;
+ } else {
+ return -1;
+ }
+}
+
+/*
+** Return the index of the entry in MR_spied_user_event_sets whose
+** MR_sues_user_event_set field is user_event_set, or a negative number
+** if absent.
+*/
+
+static int
+MR_search_spy_table_for_user_event_set(const char *user_event_set)
+{
+ int slot;
+ MR_bool found;
+
+ MR_bsearch(MR_spied_user_event_set_next, slot, found,
+ strcmp(MR_spied_user_event_sets[slot].MR_sues_user_event_set,
+ user_event_set));
if (found) {
return slot;
} else {
@@ -186,35 +287,36 @@
MR_bool
MR_event_matches_spy_point(const MR_LabelLayout *layout,
MR_TracePort port, MR_SpyAction *action_ptr,
- MR_SpyPrintList *print_list)
+ MR_SpyPrintList *print_list_ptr)
{
int slot;
MR_bool enabled;
MR_SpyPoint *point;
MR_SpyAction action;
+ MR_SpyPrintList print_list;
const MR_LabelLayout *parent;
+ const MR_UserEvent *user_event;
+ const MR_UserEventSpec *user_event_spec;
+ const char *user_event_set;
+ const char *user_event_name;
const char *problem;
MR_Word *base_sp;
MR_Word *base_curfr;
enabled = MR_FALSE;
action = MR_SPY_PRINT;
- *print_list = NULL;
+ 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];
- if (point->spy_when != MR_SPY_LINENO) {
+ point = MR_spy_points[MR_spied_labels[slot].MR_sl_point_num];
+ if (point->MR_spy_when != MR_SPY_LINENO) {
MR_fatal_error("non-lineno spy point in spied labels array");
}
- if (MR_spy_cond_is_true(point, layout)) {
- MR_update_enabled_action(point, port, &action, &enabled);
- if (*print_list == NULL) {
- *print_list = point->spy_print_list;
- }
- }
+ MR_update_enabled_action(point, layout, port,
+ &enabled, &action, &print_list);
}
if (MR_port_is_interface(port)) {
@@ -226,48 +328,100 @@
if (parent != NULL && 0 <=
(slot = MR_search_spy_table_for_label(parent)))
{
- point = MR_spy_points[MR_spied_labels[slot].spy_point_num];
- if (point->spy_when != MR_SPY_LINENO) {
+ point = MR_spy_points[MR_spied_labels[slot].MR_sl_point_num];
+ if (point->MR_spy_when != MR_SPY_LINENO) {
MR_fatal_error("non-lineno spy point in "
"spied labels array");
}
- if (MR_spy_cond_is_true(point, layout)) {
- MR_update_enabled_action(point, port, &action, &enabled);
- if (*print_list == NULL) {
- *print_list = point->spy_print_list;
+ MR_update_enabled_action(point, layout, port,
+ &enabled, &action, &print_list);
+ }
+ }
+ }
+
+ user_event = layout->MR_sll_user_event;
+ if (user_event != NULL) {
+ user_event_spec = &MR_user_event_spec(layout);
+ user_event_name = user_event_spec->MR_ues_event_name;
+ user_event_set = MR_user_event_set_name(layout);
+
+ /*
+ ** Check for breakpoints that specify an event name, and possibly
+ ** and event set.
+ */
+
+ slot = MR_search_spy_table_for_user_event_name(user_event_name);
+ if (slot >= 0) {
+ for (point = MR_spied_user_events[slot].MR_sue_points;
+ point != NULL; point = point->MR_spy_next)
+ {
+ if (point->MR_spy_when != MR_SPY_USER_EVENT) {
+ MR_fatal_error("non-named-user-event spy point "
+ "in named user event array");
+ }
+
+ if (point->MR_spy_user_event_set == NULL ||
+ MR_streq(user_event_set, point->MR_spy_user_event_set))
+ {
+ MR_update_enabled_action(point, layout, port,
+ &enabled, &action, &print_list);
}
}
}
+
+ /*
+ ** Check for breakpoints that specify just an event set.
+ */
+
+ slot = MR_search_spy_table_for_user_event_set(user_event_set);
+ if (slot >= 0) {
+ for (point = MR_spied_user_event_sets[slot].MR_sues_points;
+ point != NULL; point = point->MR_spy_next)
+ {
+ if (point->MR_spy_when != MR_SPY_USER_EVENT_SET) {
+ MR_fatal_error("non-named-user-event spy point "
+ "in named user event array");
+ }
+
+ MR_update_enabled_action(point, layout, port,
+ &enabled, &action, &print_list);
+ }
+ }
+
+ /*
+ ** Check for breakpoints that specify neither event name nor event set.
+ */
+
+ for (point = MR_spied_universal_user_events; point != NULL;
+ point = point->MR_spy_next)
+ {
+ if (point->MR_spy_when != MR_SPY_USER_EVENT_SET) {
+ MR_fatal_error("non-unnamed-user-event spy point "
+ "in unnamed user event list");
+ }
+
+ MR_update_enabled_action(point, layout, port,
+ &enabled, &action, &print_list);
}
}
slot = MR_search_spy_table_for_proc(layout->MR_sll_entry);
if (slot >= 0) {
- for (point = MR_spied_procs[slot].spy_points; point != NULL;
- point = point->spy_next)
+ for (point = MR_spied_procs[slot].MR_sp_points; point != NULL;
+ point = point->MR_spy_next)
{
- switch (point->spy_when) {
+ switch (point->MR_spy_when) {
case MR_SPY_ALL:
- if (MR_spy_cond_is_true(point, layout)) {
- MR_update_enabled_action(point, port, &action,
- &enabled);
- if (*print_list == NULL) {
- *print_list = point->spy_print_list;
- }
- }
+ MR_update_enabled_action(point, layout, port,
+ &enabled, &action, &print_list);
break;
case MR_SPY_ENTRY:
if (MR_port_is_entry(port)) {
- if (MR_spy_cond_is_true(point, layout)) {
- MR_update_enabled_action(point, port, &action,
- &enabled);
- if (*print_list == NULL) {
- *print_list = point->spy_print_list;
- }
- }
+ MR_update_enabled_action(point, layout, port,
+ &enabled, &action, &print_list);
} else {
continue;
}
@@ -276,13 +430,8 @@
case MR_SPY_INTERFACE:
if (MR_port_is_interface(port)) {
- if (MR_spy_cond_is_true(point, layout)) {
- MR_update_enabled_action(point, port, &action,
- &enabled);
- if (*print_list == NULL) {
- *print_list = point->spy_print_list;
- }
- }
+ MR_update_enabled_action(point, layout, port,
+ &enabled, &action, &print_list);
} else {
continue;
}
@@ -290,14 +439,9 @@
break;
case MR_SPY_SPECIFIC:
- if (layout == point->spy_label) {
- if (MR_spy_cond_is_true(point, layout)) {
- MR_update_enabled_action(point, port, &action,
- &enabled);
- if (*print_list == NULL) {
- *print_list = point->spy_print_list;
- }
- }
+ if (layout == point->MR_spy_label) {
+ MR_update_enabled_action(point, layout, port,
+ &enabled, &action, &print_list);
} else {
continue;
}
@@ -306,6 +450,17 @@
case MR_SPY_LINENO:
MR_fatal_error("lineno spy point in spied procs array");
+ break;
+
+ case MR_SPY_USER_EVENT:
+ MR_fatal_error("user_event spy point "
+ "in spied procs array");
+ break;
+
+ case MR_SPY_USER_EVENT_SET:
+ MR_fatal_error("user_event_set spy point "
+ "in spied procs array");
+ break;
default:
MR_fatal_error("bad spy point when in "
@@ -316,6 +471,7 @@
if (enabled) {
*action_ptr = action;
+ *print_list_ptr = print_list;
return MR_TRUE;
} else {
return MR_FALSE;
@@ -323,33 +479,39 @@
}
static void
-MR_update_enabled_action(MR_SpyPoint *point, MR_TracePort port,
- MR_SpyAction *action_ptr, MR_bool *enabled_ptr)
+MR_update_enabled_action(MR_SpyPoint *point, const MR_LabelLayout *layout,
+ MR_TracePort port, MR_bool *enabled_ptr, MR_SpyAction *action_ptr,
+ MR_SpyPrintList *print_list_ptr)
{
- if (point->spy_enabled) {
- if (point->spy_ignore_count == 0) {
+ if (point->MR_spy_enabled && MR_spy_cond_is_true(point, layout)) {
+ if (point->MR_spy_ignore_count == 0) {
*enabled_ptr = MR_TRUE;
- *action_ptr = MR_max(*action_ptr, point->spy_action);
+ *action_ptr = MR_max(*action_ptr, point->MR_spy_action);
+ if (*print_list_ptr == NULL) {
+ *print_list_ptr = point->MR_spy_print_list;
}
-
- if (point->spy_ignore_count > 0) {
- switch (point->spy_ignore_when) {
+ } else if (point->MR_spy_ignore_count > 0) {
+ switch (point->MR_spy_ignore_when) {
case MR_SPY_DONT_IGNORE:
break;
case MR_SPY_IGNORE_ENTRY:
if (port == MR_PORT_CALL) {
- --point->spy_ignore_count;
+ --point->MR_spy_ignore_count;
}
break;
case MR_SPY_IGNORE_INTERFACE:
if (MR_port_is_interface(port)) {
- --point->spy_ignore_count;
+ --point->MR_spy_ignore_count;
}
break;
+ case MR_SPY_IGNORE_ALL:
+ --point->MR_spy_ignore_count;
+ break;
+
default:
MR_fatal_error("MR_update_enabled_action: "
"invalid ignore_when");
@@ -381,13 +543,13 @@
MR_bool retval;
MR_SpyCond *cond;
- if (point->spy_cond == NULL) {
+ if (point->MR_spy_cond == NULL) {
return MR_TRUE;
}
MR_restore_transient_registers();
- cond = point->spy_cond;
+ cond = point->MR_spy_cond;
/*
** From this point, returning should be done by setting both
@@ -404,10 +566,10 @@
MR_trace_init_point_vars(label_layout, saved_regs,
(MR_TracePort) label_layout->MR_sll_port, MR_FALSE);
- problem = MR_lookup_unambiguous_var_spec(cond->cond_var_spec,
+ problem = MR_lookup_unambiguous_var_spec(cond->MR_cond_var_spec,
&type_info, &value, &name);
if (problem != NULL) {
- if (cond->cond_require_var) {
+ if (cond->MR_cond_require_var) {
MR_spy_point_cond_problem = problem;
retval = MR_TRUE;
} else {
@@ -419,11 +581,11 @@
}
value_ptr = &value;
- bad_path = MR_select_specified_subterm(cond->cond_path,
+ bad_path = MR_select_specified_subterm(cond->MR_cond_path,
type_info, value_ptr, &sub_type_info, &sub_value_ptr);
if (bad_path != NULL) {
- if (cond->cond_require_var) {
+ if (cond->MR_cond_require_var) {
MR_spy_point_cond_problem = MR_trace_bad_path(bad_path);
retval = MR_TRUE;
} else {
@@ -442,7 +604,7 @@
MR_trace_func_enabled = MR_FALSE;
MR_TRACE_CALL_MERCURY(
ML_BROWSE_match_with_cterm((MR_Word) sub_type_info, *sub_value_ptr,
- cond->cond_term, &match);
+ cond->MR_cond_term, &match);
);
MR_trace_func_enabled = saved_trace_func_enabled;
@@ -450,7 +612,7 @@
fprintf(stdout, "%d\n", match);
#endif
- switch (cond->cond_test) {
+ switch (cond->MR_cond_test) {
case MR_SPY_TEST_EQUAL:
MR_spy_point_cond_problem = NULL;
if (match != 0) {
@@ -487,6 +649,33 @@
static const char *incompatible =
"Ignore count is not compatible with break point specification";
+static int
+MR_add_spy_point(MR_bool reuse, MR_SpyPoint *point)
+{
+ int i;
+ int point_slot;
+
+ if (reuse) {
+ /* Try to reuse an existing slot in the MR_spy_points array. */
+ for (i = 0; i < MR_spy_point_next; i++) {
+ if (! MR_spy_points[i]->MR_spy_exists) {
+ MR_most_recent_spy_point = i;
+ MR_spy_points[i] = point;
+ return i;
+ }
+ }
+ }
+
+ /* Allocate a new slot. */
+ MR_ensure_room_for_next(MR_spy_point, MR_SpyPoint *, MR_INIT_SPY_POINTS);
+ point_slot = MR_spy_point_next;
+ MR_spy_points[point_slot] = point;
+ MR_spy_point_next++;
+
+ MR_most_recent_spy_point = point_slot;
+ return point_slot;
+}
+
int
MR_add_proc_spy_point(MR_SpyWhen when, MR_SpyAction action,
MR_SpyIgnore_When ignore_when, int ignore_count,
@@ -494,53 +683,42 @@
MR_SpyPrintList print_list, const char **problem)
{
MR_SpyPoint *point;
- int point_slot;
int proc_slot;
- int i;
*problem = NULL;
+ /* Insert the spy point at the head of the list for the proc. */
+ point = MR_NEW(MR_SpyPoint);
+ point->MR_spy_when = when;
+ point->MR_spy_exists = MR_TRUE;
+ point->MR_spy_enabled = MR_TRUE;
+ point->MR_spy_action = action;
+ point->MR_spy_ignore_when = ignore_when;
+ point->MR_spy_ignore_count = ignore_count;
+ point->MR_spy_cond = NULL;
+ point->MR_spy_print_list = print_list;
+ point->MR_spy_proc = entry;
+ point->MR_spy_label = label;
+ point->MR_spy_filename = NULL;
+ point->MR_spy_linenumber = 0;
+ point->MR_spy_user_event_set = NULL;
+ point->MR_spy_user_event_name = NULL;
+
proc_slot = MR_search_spy_table_for_proc(entry);
if (proc_slot < 0) {
MR_ensure_room_for_next(MR_spied_proc, MR_SpiedProc,
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_spied_procs[proc_slot].spy_proc = entry;
- MR_spied_procs[proc_slot].spy_points = NULL;
+ MR_compare_addr(MR_spied_procs[proc_slot].MR_sp_proc, entry));
+ MR_spied_procs[proc_slot].MR_sp_proc = entry;
+ MR_spied_procs[proc_slot].MR_sp_points = NULL;
}
- /* Insert the spy point at the head of the list for the proc. */
- point = MR_NEW(MR_SpyPoint);
- point->spy_when = when;
- point->spy_exists = MR_TRUE;
- point->spy_enabled = MR_TRUE;
- point->spy_action = action;
- point->spy_ignore_when = ignore_when;
- point->spy_ignore_count = ignore_count;
- point->spy_cond = NULL;
- point->spy_print_list = print_list;
- point->spy_proc = entry;
- point->spy_label = label;
- point->spy_next = MR_spied_procs[proc_slot].spy_points;
- MR_spied_procs[proc_slot].spy_points = point;
+ point->MR_spy_next = MR_spied_procs[proc_slot].MR_sp_points;
+ MR_spied_procs[proc_slot].MR_sp_points = point;
- for (i = 0; i < MR_spy_point_next; i++) {
- if (! MR_spy_points[i]->spy_exists) {
- MR_most_recent_spy_point = i;
- MR_spy_points[i] = point;
- return i;
- }
- }
-
- MR_ensure_room_for_next(MR_spy_point, MR_SpyPoint *, MR_INIT_SPY_POINTS);
- point_slot = MR_spy_point_next;
- MR_spy_points[point_slot] = point;
- MR_spy_point_next++;
-
- MR_most_recent_spy_point = point_slot;
- return point_slot;
+ return MR_add_spy_point(MR_TRUE, point);
}
/* 1024 characters should be big enough ... */
@@ -604,23 +782,20 @@
MR_compare_spied_labels);
point = MR_NEW(MR_SpyPoint);
- point->spy_when = MR_SPY_LINENO;
- point->spy_exists = MR_TRUE;
- point->spy_enabled = MR_TRUE;
- point->spy_action = action;
- point->spy_ignore_when = ignore_when;
- point->spy_ignore_count = ignore_count;
- point->spy_cond = NULL;
- point->spy_print_list = print_list;
- point->spy_filename = filename;
- point->spy_linenumber = linenumber;
+ point->MR_spy_when = MR_SPY_LINENO;
+ point->MR_spy_exists = MR_TRUE;
+ point->MR_spy_enabled = MR_TRUE;
+ point->MR_spy_action = action;
+ point->MR_spy_ignore_when = ignore_when;
+ point->MR_spy_ignore_count = ignore_count;
+ point->MR_spy_cond = NULL;
+ point->MR_spy_print_list = print_list;
+ point->MR_spy_filename = filename;
+ point->MR_spy_linenumber = linenumber;
+ point->MR_spy_user_event_set = NULL;
+ point->MR_spy_user_event_name = NULL;
- MR_ensure_room_for_next(MR_spy_point, MR_SpyPoint *, MR_INIT_SPY_POINTS);
- MR_spy_points[point_slot] = point;
- MR_spy_point_next++;
-
- MR_most_recent_spy_point = point_slot;
- return point_slot;
+ return MR_add_spy_point(MR_FALSE, point);
}
static void
@@ -631,8 +806,8 @@
MR_ensure_room_for_next(MR_spied_label, MR_SpiedLabel,
MR_INIT_SPIED_LABELS);
spied_label_slot = MR_spied_label_next;
- MR_spied_labels[spied_label_slot].spy_label = label;
- MR_spied_labels[spied_label_slot].spy_point_num = spy_point_num;
+ MR_spied_labels[spied_label_slot].MR_sl_label = label;
+ MR_spied_labels[spied_label_slot].MR_sl_point_num = spy_point_num;
MR_spied_label_next++;
}
@@ -645,8 +820,91 @@
label1 = (const MR_SpiedLabel *) l1;
label2 = (const MR_SpiedLabel *) l2;
- return (int) ((MR_Integer) label1->spy_label
- - (MR_Integer) label2->spy_label);
+ return (int) ((MR_Integer) label1->MR_sl_label
+ - (MR_Integer) label2->MR_sl_label);
+}
+
+int
+MR_add_user_event_spy_point(MR_SpyAction action,
+ MR_SpyIgnore_When ignore_when, int ignore_count,
+ const char *user_event_set, const char *user_event_name,
+ MR_SpyPrintList print_list, const char **problem)
+{
+ MR_SpyPoint *point;
+ int name_slot;
+ int set_slot;
+ int point_slot;
+ int i;
+
+ *problem = NULL;
+
+ if (user_event_set != NULL) {
+ user_event_set = strdup(user_event_set);
+ }
+
+ if (user_event_name != NULL) {
+ user_event_name = strdup(user_event_name);
+ }
+
+ point = MR_NEW(MR_SpyPoint);
+ point->MR_spy_exists = MR_TRUE;
+ point->MR_spy_enabled = MR_TRUE;
+ point->MR_spy_action = action;
+ point->MR_spy_ignore_when = ignore_when;
+ point->MR_spy_ignore_count = ignore_count;
+ point->MR_spy_cond = NULL;
+ point->MR_spy_print_list = print_list;
+ point->MR_spy_proc = NULL;
+ point->MR_spy_label = NULL;
+ point->MR_spy_user_event_set = user_event_set;
+ point->MR_spy_user_event_name = user_event_name;
+
+ if (user_event_name == NULL) {
+ point->MR_spy_when = MR_SPY_USER_EVENT_SET;
+
+ if (user_event_set == NULL) {
+ point->MR_spy_next = MR_spied_universal_user_events;
+ MR_spied_universal_user_events = point;
+ } else {
+ set_slot = MR_search_spy_table_for_user_event_set(user_event_set);
+ if (set_slot < 0) {
+ MR_ensure_room_for_next(MR_spied_user_event_set,
+ MR_SpiedUserEventSet, MR_INIT_SPIED_USER_EVENT_SETS);
+ MR_prepare_insert_into_sorted(MR_spied_user_event_sets,
+ MR_spied_user_event_set_next, set_slot,
+ strcmp(MR_spied_user_event_sets[set_slot].
+ MR_sues_user_event_set, user_event_set));
+ MR_spied_user_event_sets[set_slot].MR_sues_user_event_set =
+ user_event_set;
+ MR_spied_user_event_sets[set_slot].MR_sues_points = NULL;
+ }
+
+ point->MR_spy_next =
+ MR_spied_user_event_sets[set_slot].MR_sues_points;
+ MR_spied_user_event_sets[set_slot].MR_sues_points = point;
+ }
+ } else {
+ point->MR_spy_when = MR_SPY_USER_EVENT;
+
+ name_slot = MR_search_spy_table_for_user_event_name(user_event_name);
+ if (name_slot < 0) {
+ MR_ensure_room_for_next(MR_spied_user_event,
+ MR_SpiedUserEvent, MR_INIT_SPIED_USER_EVENTS);
+ MR_prepare_insert_into_sorted(MR_spied_user_events,
+ MR_spied_user_event_next, name_slot,
+ strcmp(MR_spied_user_events[name_slot].
+ MR_sue_user_event_name, user_event_name));
+ MR_spied_user_events[name_slot].MR_sue_user_event_name =
+ user_event_name;
+ MR_spied_user_events[name_slot].MR_sue_points = NULL;
+ }
+
+ point->MR_spy_next =
+ MR_spied_user_events[name_slot].MR_sue_points;
+ MR_spied_user_events[name_slot].MR_sue_points = point;
+ }
+
+ return MR_add_spy_point(MR_TRUE, point);
}
void
@@ -660,13 +918,13 @@
}
/* find the last node in print_list */
- while (list->pl_next != NULL) {
- list = list->pl_next;
+ while (list->MR_pl_next != NULL) {
+ list = list->MR_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;
+ list->MR_pl_next = MR_spy_points[point_slot]->MR_spy_print_list;
+ MR_spy_points[point_slot]->MR_spy_print_list = print_list;
}
void
@@ -674,33 +932,33 @@
{
MR_SpyPrintList list;
- list = MR_spy_points[point_slot]->spy_print_list;
+ list = MR_spy_points[point_slot]->MR_spy_print_list;
if (list == NULL) {
- MR_spy_points[point_slot]->spy_print_list = print_list;
+ MR_spy_points[point_slot]->MR_spy_print_list = print_list;
return;
}
/* find the last node in print_list */
- while (list->pl_next != NULL) {
- list = list->pl_next;
+ while (list->MR_pl_next != NULL) {
+ list = list->MR_pl_next;
}
/* add the print_list at the end of the existing spy_print_list */
- list->pl_next = print_list;
+ list->MR_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;
+ MR_delete_spy_print_list(MR_spy_points[point_slot]->MR_spy_print_list);
+ MR_spy_points[point_slot]->MR_spy_print_list = NULL;
}
const char *
MR_ignore_spy_point(int point_slot, MR_SpyIgnore_When ignore_when,
int ignore_count)
{
- switch (MR_spy_points[point_slot]->spy_when) {
+ switch (MR_spy_points[point_slot]->MR_spy_when) {
case MR_SPY_ENTRY:
case MR_SPY_INTERFACE:
case MR_SPY_ALL:
@@ -716,8 +974,8 @@
break;
}
- MR_spy_points[point_slot]->spy_ignore_when = ignore_when;
- MR_spy_points[point_slot]->spy_ignore_count = ignore_count;
+ MR_spy_points[point_slot]->MR_spy_ignore_when = ignore_when;
+ MR_spy_points[point_slot]->MR_spy_ignore_count = ignore_count;
return NULL;
}
@@ -728,13 +986,13 @@
return;
}
- MR_delete_spy_print_list(print_list->pl_next);
+ MR_delete_spy_print_list(print_list->MR_pl_next);
- if (print_list->pl_cur->p_name != NULL) {
- MR_free(print_list->pl_cur->p_name);
+ if (print_list->MR_pl_cur->MR_p_word_copy != NULL) {
+ MR_free(print_list->MR_pl_cur->MR_p_word_copy);
}
- MR_free(print_list->pl_cur);
+ MR_free(print_list->MR_pl_cur);
MR_free(print_list);
}
@@ -754,29 +1012,29 @@
MR_most_recent_spy_point = -1;
}
- if (! MR_spy_points[point_table_slot]->spy_exists) {
+ if (! MR_spy_points[point_table_slot]->MR_spy_exists) {
return;
}
- MR_spy_points[point_table_slot]->spy_exists = MR_FALSE;
+ MR_spy_points[point_table_slot]->MR_spy_exists = MR_FALSE;
- MR_delete_spy_print_list(point->spy_print_list);
+ MR_delete_spy_print_list(point->MR_spy_print_list);
/* in case it gets deleted again */
- point->spy_print_list = NULL;
+ point->MR_spy_print_list = NULL;
- if (point->spy_cond != NULL) {
- MR_delete_cterm(point->spy_cond->cond_term);
- MR_free(point->spy_cond->cond_what_string);
- MR_free(point->spy_cond->cond_term_string);
- MR_free(point->spy_cond);
+ if (point->MR_spy_cond != NULL) {
+ MR_delete_cterm(point->MR_spy_cond->MR_cond_term);
+ MR_free(point->MR_spy_cond->MR_cond_what_string);
+ MR_free(point->MR_spy_cond->MR_cond_term_string);
+ MR_free(point->MR_spy_cond);
/* in case it gets deleted again */
- point->spy_cond = NULL;
+ point->MR_spy_cond = NULL;
}
- if (point->spy_when == MR_SPY_LINENO) {
+ if (point->MR_spy_when == MR_SPY_LINENO) {
/* Release the storage acquired by MR_copy_string. */
- MR_free(point->spy_filename);
+ MR_free(point->MR_spy_filename);
/*
** Remove the spy point from the spied label table list.
@@ -784,11 +1042,11 @@
label_slot = 0;
for (i = 0; i < MR_spied_label_next; i++) {
- 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 =
- MR_spied_labels[i].spy_point_num;
+ if (MR_spied_labels[i].MR_sl_point_num != point_table_slot) {
+ MR_spied_labels[label_slot].MR_sl_label =
+ MR_spied_labels[i].MR_sl_label;
+ MR_spied_labels[label_slot].MR_sl_point_num =
+ MR_spied_labels[i].MR_sl_point_num;
label_slot++;
}
}
@@ -800,23 +1058,23 @@
** for its proc.
*/
- proc_table_slot = MR_search_spy_table_for_proc(point->spy_proc);
+ proc_table_slot = MR_search_spy_table_for_proc(point->MR_spy_proc);
if (proc_table_slot < 0) {
MR_fatal_error("deleted spy point was not indexed by proc addr");
}
- cur_addr = &MR_spied_procs[proc_table_slot].spy_points;
- cur = MR_spied_procs[proc_table_slot].spy_points;
+ cur_addr = &MR_spied_procs[proc_table_slot].MR_sp_points;
+ cur = MR_spied_procs[proc_table_slot].MR_sp_points;
while (cur != NULL && cur != point) {
- cur_addr = &cur->spy_next;
- cur = cur->spy_next;
+ cur_addr = &cur->MR_spy_next;
+ cur = cur->MR_spy_next;
}
if (cur == NULL) {
MR_fatal_error("deleted spy point was not on proc index list");
}
- *cur_addr = point->spy_next;
+ *cur_addr = point->MR_spy_next;
}
}
@@ -829,38 +1087,67 @@
point = MR_spy_points[spy_point_num];
fprintf(fp, "%2d: %1s %-5s %9s ",
spy_point_num,
- point->spy_exists ?
- (point->spy_enabled ? "+" : "-") :
- (point->spy_enabled ? "E" : "D"),
- 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);
+ point->MR_spy_exists ?
+ (point->MR_spy_enabled ? "+" : "-") :
+ (point->MR_spy_enabled ? "E" : "D"),
+ MR_spy_action_string(point->MR_spy_action),
+ MR_spy_when_names[point->MR_spy_when]);
+
+ switch (point->MR_spy_when) {
+ case MR_SPY_ALL:
+ case MR_SPY_INTERFACE:
+ case MR_SPY_ENTRY:
+ case MR_SPY_SPECIFIC:
+ MR_print_proc_id(fp, point->MR_spy_proc);
+ break;
+
+ case MR_SPY_LINENO:
+ fprintf(fp, "%s:%d",
+ point->MR_spy_filename, point->MR_spy_linenumber);
+ break;
+
+ case MR_SPY_USER_EVENT:
+ /* MR_spy_when_names has already printed "user_event". */
+ if (point->MR_spy_user_event_set != NULL) {
+ fprintf(fp, "%s %s",
+ point->MR_spy_user_event_set,
+ point->MR_spy_user_event_name);
} else {
- MR_print_proc_id(fp, point->spy_proc);
+ fprintf(fp, "%s",
+ point->MR_spy_user_event_name);
}
+ break;
- if (point->spy_ignore_count > 1) {
+ case MR_SPY_USER_EVENT_SET:
+ /* MR_spy_when_names has already printed "user_event_set". */
+ if (point->MR_spy_user_event_set != NULL) {
+ fprintf(fp, "%s",
+ point->MR_spy_user_event_set);
+ }
+ break;
+ }
+
+ if (point->MR_spy_ignore_count > 1) {
fprintf(fp, "\n%12s(ignore next %d %s events)\n",
- "", point->spy_ignore_count,
- MR_ignore_when_to_string(point->spy_ignore_when));
- } else if (point->spy_ignore_count > 0) {
+ "", point->MR_spy_ignore_count,
+ MR_ignore_when_to_string(point->MR_spy_ignore_when));
+ } else if (point->MR_spy_ignore_count > 0) {
fprintf(fp, "\n%12s(ignore next %s event)\n",
- "", MR_ignore_when_to_string(point->spy_ignore_when));
+ "", MR_ignore_when_to_string(point->MR_spy_ignore_when));
} else {
fprintf(fp, "\n");
}
- if (point->spy_cond != NULL) {
- cond = point->spy_cond;
+ if (point->MR_spy_cond != NULL) {
+ cond = point->MR_spy_cond;
fprintf(fp, "%12s", "");
- if (! cond->cond_require_var) {
+ if (! cond->MR_cond_require_var) {
fprintf(fp, "-v ");
}
- if (! cond->cond_require_path) {
+ if (! cond->MR_cond_require_path) {
fprintf(fp, "-p ");
}
@@ -868,34 +1155,19 @@
fprintf(fp, "\n");
}
- if (verbose && point->spy_print_list != NULL) {
+ if (verbose && point->MR_spy_print_list != NULL) {
MR_SpyPrintList list;
MR_SpyPrint node;
fprintf(fp, "%12s", "");
- for (list = point->spy_print_list; list != NULL; list = list->pl_next)
+ for (list = point->MR_spy_print_list; list != NULL;
+ list = list->MR_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;
- }
+ node = list->MR_pl_cur;
+ MR_print_spy_print_what(fp, node);
fprintf(fp, " (");
- switch (node->p_format) {
+ switch (node->MR_p_format) {
case MR_BROWSE_FORMAT_FLAT:
fprintf(fp, "flat");
break;
@@ -917,17 +1189,17 @@
break;
default:
- MR_fatal_error("invalid node->p_format");
+ MR_fatal_error("invalid node->MR_p_format");
break;
}
- if (! node->p_warn) {
+ if (! node->MR_p_warn) {
fprintf(fp, ", nowarn");
}
fprintf(fp, ")");
- if (list->pl_next == NULL) {
+ if (list->MR_pl_next == NULL) {
fprintf(fp, "\n");
} else {
fprintf(fp, ", ");
@@ -939,25 +1211,29 @@
void
MR_print_spy_cond(FILE *fp, MR_SpyCond *cond)
{
- switch (cond->cond_var_spec.MR_var_spec_kind) {
+ switch (cond->MR_cond_var_spec.MR_var_spec_kind) {
case MR_VAR_SPEC_NUMBER:
- fprintf(fp, "%d", cond->cond_var_spec.MR_var_spec_number);
+ fprintf(fp, "%d", cond->MR_cond_var_spec.MR_var_spec_number);
break;
case MR_VAR_SPEC_NAME:
- fprintf(fp, "%s", cond->cond_var_spec.MR_var_spec_name);
+ fprintf(fp, "%s", cond->MR_cond_var_spec.MR_var_spec_name);
break;
- default:
- MR_fatal_error("MR_print_spy_point: invalid cond_what");
+ case MR_VAR_SPEC_HELD_NAME:
+ fprintf(fp, "$%s", cond->MR_cond_var_spec.MR_var_spec_name);
+ break;
+
+ case MR_VAR_SPEC_ATTRIBUTE:
+ fprintf(fp, "!%s", cond->MR_cond_var_spec.MR_var_spec_name);
break;
}
- if (cond->cond_path != NULL) {
- fprintf(fp, " ^%s", cond->cond_path);
+ if (cond->MR_cond_path != NULL) {
+ fprintf(fp, " ^%s", cond->MR_cond_path);
}
- switch (cond->cond_test) {
+ switch (cond->MR_cond_test) {
case MR_SPY_TEST_EQUAL:
fprintf(fp, " = ");
break;
@@ -971,7 +1247,7 @@
break;
}
- MR_print_cterm(fp, cond->cond_term);
+ MR_print_cterm(fp, cond->MR_cond_term);
}
static const char *
@@ -998,13 +1274,13 @@
spy_point_num = 0;
for (i = 0; i < MR_spy_point_next; i++) {
- if (! MR_spy_points[i]->spy_exists) {
+ if (! MR_spy_points[i]->MR_spy_exists) {
continue;
}
point = MR_spy_points[i];
- switch (point->spy_action) {
+ switch (point->MR_spy_action) {
case MR_SPY_STOP:
fprintf(fp, "break ");
break;
@@ -1018,14 +1294,14 @@
return MR_TRUE;
}
- if (point->spy_ignore_count > 0) {
- switch (point->spy_ignore_when) {
+ if (point->MR_spy_ignore_count > 0) {
+ switch (point->MR_spy_ignore_when) {
case MR_SPY_IGNORE_INTERFACE:
- fprintf(fp, " -I%d", point->spy_ignore_count);
+ fprintf(fp, " -I%d", point->MR_spy_ignore_count);
break;
case MR_SPY_IGNORE_ENTRY:
- fprintf(fp, " -E%d", point->spy_ignore_count);
+ fprintf(fp, " -E%d", point->MR_spy_ignore_count);
break;
default:
@@ -1033,26 +1309,26 @@
}
}
- switch (point->spy_when) {
+ switch (point->MR_spy_when) {
case MR_SPY_LINENO:
- fprintf(fp, "%s:%d\n", point->spy_filename,
- point->spy_linenumber);
+ fprintf(fp, "%s:%d\n",
+ point->MR_spy_filename, point->MR_spy_linenumber);
break;
case MR_SPY_ALL:
fprintf(fp, "-a ");
- MR_print_proc_spec(fp, point->spy_proc);
+ MR_print_proc_spec(fp, point->MR_spy_proc);
fprintf(fp, "\n");
break;
case MR_SPY_INTERFACE:
- MR_print_proc_spec(fp, point->spy_proc);
+ MR_print_proc_spec(fp, point->MR_spy_proc);
fprintf(fp, "\n");
break;
case MR_SPY_ENTRY:
fprintf(fp, "-e ");
- MR_print_proc_spec(fp, point->spy_proc);
+ MR_print_proc_spec(fp, point->MR_spy_proc);
fprintf(fp, "\n");
break;
@@ -1066,21 +1342,21 @@
return MR_TRUE;
}
- if (point->spy_cond != NULL) {
+ if (point->MR_spy_cond != NULL) {
MR_SpyCond *cond;
- cond = point->spy_cond;
+ cond = point->MR_spy_cond;
fprintf(fp, "condition ");
- if (!cond->cond_require_var) {
+ if (!cond->MR_cond_require_var) {
fprintf(fp, "-v "); /* also implies -p */
- } else if (!cond->cond_require_path) {
+ } else if (!cond->MR_cond_require_path) {
fprintf(fp, "-p ");
}
- fprintf(fp, "%s ", cond->cond_what_string);
+ fprintf(fp, "%s ", cond->MR_cond_what_string);
- switch (cond->cond_test) {
+ switch (cond->MR_cond_test) {
case MR_SPY_TEST_EQUAL:
fprintf(fp, "= ");
break;
@@ -1094,27 +1370,27 @@
break;
}
- fprintf(fp, "%s\n", cond->cond_term_string);
+ fprintf(fp, "%s\n", cond->MR_cond_term_string);
}
- if (!point->spy_enabled) {
+ if (!point->MR_spy_enabled) {
fprintf(fp, "disable\n");
}
- if (point->spy_print_list != NULL) {
+ if (point->MR_spy_print_list != NULL) {
MR_SpyPrintList list;
MR_SpyPrint node;
- list = point->spy_print_list;
- for (; list != NULL; list = list->pl_next) {
- node = list->pl_cur;
+ list = point->MR_spy_print_list;
+ for (; list != NULL; list = list->MR_pl_next) {
+ node = list->MR_pl_cur;
fprintf(fp, "break_print -e");
- if (! node->p_warn) {
+ if (! node->MR_p_warn) {
fprintf(fp, " -n");
}
- switch (node->p_format) {
+ switch (node->MR_p_format) {
case MR_BROWSE_FORMAT_FLAT:
fprintf(fp, " -f");
break;
@@ -1136,34 +1412,39 @@
break;
default:
- MR_fatal_error("invalid node->p_format");
+ MR_fatal_error("invalid node->MR_p_format");
break;
}
- switch (node->p_what) {
+ fprintf(fp, " ");
+ MR_print_spy_print_what(fp, node);
+ fprintf(fp, "\n");
+ }
+ }
+
+ spy_point_num++;
+ }
+
+ return MR_FALSE;
+}
+
+static void
+MR_print_spy_print_what(FILE *fp, MR_SpyPrint sp)
+{
+ switch (sp->MR_p_what) {
case MR_SPY_PRINT_GOAL:
- fprintf(fp, " goal");
+ fprintf(fp, "goal");
break;
case MR_SPY_PRINT_ALL:
- fprintf(fp, " 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, "\n");
- }
+ MR_print_var_spec(fp, &sp->MR_p_var_spec);
+ if (sp->MR_p_path != NULL) {
+ fprintf(fp, "^%s", sp->MR_p_path);
}
-
- spy_point_num++;
+ break;
}
-
- return MR_FALSE;
}
Index: trace/mercury_trace_spy.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_spy.h,v
retrieving revision 1.13
diff -u -b -r1.13 mercury_trace_spy.h
--- trace/mercury_trace_spy.h 29 Nov 2006 05:18:41 -0000 1.13
+++ trace/mercury_trace_spy.h 18 Jan 2007 07:10:56 -0000
@@ -36,13 +36,16 @@
MR_SPY_INTERFACE,
MR_SPY_ENTRY,
MR_SPY_SPECIFIC,
- MR_SPY_LINENO
+ MR_SPY_LINENO,
+ MR_SPY_USER_EVENT,
+ MR_SPY_USER_EVENT_SET
} MR_SpyWhen;
typedef enum {
MR_SPY_DONT_IGNORE,
MR_SPY_IGNORE_INTERFACE,
- MR_SPY_IGNORE_ENTRY
+ MR_SPY_IGNORE_ENTRY,
+ MR_SPY_IGNORE_ALL
} MR_SpyIgnore_When;
extern const char *MR_spy_when_names[];
@@ -61,44 +64,48 @@
} MR_SpyPrintWhat;
struct MR_SpyPrint_Struct {
- MR_BrowseFormat p_format;
- MR_SpyPrintWhat p_what;
- char *p_name; /* if MR_SPY_PRINT_ONE */
- MR_bool p_warn;
+ MR_BrowseFormat MR_p_format;
+ MR_SpyPrintWhat MR_p_what;
+ char *MR_p_word_copy;
+ MR_VarSpec MR_p_var_spec; /* if MR_SPY_PRINT_ONE */
+ char *MR_p_path; /* if MR_SPY_PRINT_ONE */
+ MR_bool MR_p_warn;
};
struct MR_SpyPrintList_Struct {
- MR_SpyPrint pl_cur;
- MR_SpyPrintList pl_next;
+ MR_SpyPrint MR_pl_cur;
+ MR_SpyPrintList MR_pl_next;
};
typedef struct MR_SpyPoint_Struct MR_SpyPoint;
typedef struct {
- MR_VarSpec cond_var_spec;
- char *cond_path;
- MR_SpyTest cond_test;
- MR_CTerm cond_term;
- MR_bool cond_require_var;
- MR_bool cond_require_path;
- char *cond_what_string;
- char *cond_term_string;
+ MR_VarSpec MR_cond_var_spec;
+ char *MR_cond_path;
+ MR_SpyTest MR_cond_test;
+ MR_CTerm MR_cond_term;
+ MR_bool MR_cond_require_var;
+ MR_bool MR_cond_require_path;
+ char *MR_cond_what_string;
+ char *MR_cond_term_string;
} MR_SpyCond;
struct MR_SpyPoint_Struct {
- MR_bool spy_exists; /* MR_FALSE if deleted */
- MR_bool spy_enabled;
- MR_SpyWhen spy_when;
- MR_SpyAction spy_action;
- MR_SpyIgnore_When spy_ignore_when;
- int spy_ignore_count;
- MR_SpyCond *spy_cond;
- MR_SpyPrintList spy_print_list;
- const MR_ProcLayout *spy_proc; /* if not LINENO */
- const MR_LabelLayout *spy_label; /* if SPECIFIC */
- char *spy_filename; /* if LINENO */
- int spy_linenumber; /* if LINENO */
- MR_SpyPoint *spy_next; /* if not LINENO */
+ MR_bool MR_spy_exists; /* MR_FALSE if deleted */
+ MR_bool MR_spy_enabled;
+ MR_SpyWhen MR_spy_when;
+ MR_SpyAction MR_spy_action;
+ MR_SpyIgnore_When MR_spy_ignore_when;
+ int MR_spy_ignore_count;
+ MR_SpyCond *MR_spy_cond;
+ MR_SpyPrintList MR_spy_print_list;
+ const MR_ProcLayout *MR_spy_proc; /* if not LINENO */
+ const MR_LabelLayout *MR_spy_label; /* if SPECIFIC */
+ char *MR_spy_filename; /* if LINENO */
+ int MR_spy_linenumber; /* if LINENO */
+ const char *MR_spy_user_event_set; /* if USER_EVENT or SET */
+ const char *MR_spy_user_event_name;/* if USER_EVENT */
+ MR_SpyPoint *MR_spy_next; /* if not LINENO */
};
/*
@@ -128,9 +135,9 @@
MR_SpyPrintList *print_list);
/*
-** Add a new spy point on a procedure (as opposed to on a line number)
-** to the table. If this cannot be done, return a negative number and set
-** *problem to point to an error message.
+** Add a new spy point on a procedure (as opposed to on a line number or
+** user event) to the table. If this cannot be done, return a negative number
+** and set *problem to point to an error message.
*/
extern int MR_add_proc_spy_point(MR_SpyWhen when,
@@ -140,9 +147,9 @@
MR_SpyPrintList print_list, const char **problem);
/*
-** Add a new spy point on a line number (as opposed to on a procedure)
-** to the table. If this cannot be done, return a negative number and set
-** *problem to point to an error message.
+** Add a new spy point on a line number (as opposed to on a procedure or user
+** event) to the table. If this cannot be done, return a negative number
+** and set *problem to point to an error message.
*/
extern int MR_add_line_spy_point(MR_SpyAction action,
@@ -151,6 +158,18 @@
MR_SpyPrintList print_list, const char **problem);
/*
+** Add a new spy point on a user event (as opposed to on a procedure or
+** line number) to the table. If this cannot be done, return a negative number
+** and set *problem to point to an error message.
+*/
+
+extern int MR_add_user_event_spy_point(MR_SpyAction action,
+ MR_SpyIgnore_When ignore_when, int ignore_count,
+ const char *user_event_set,
+ const char *user_event_name,
+ MR_SpyPrintList 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.
*/
Index: trace/mercury_trace_tables.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_tables.c,v
retrieving revision 1.48
diff -u -b -r1.48 mercury_trace_tables.c
--- trace/mercury_trace_tables.c 10 Jan 2007 07:55:49 -0000 1.48
+++ trace/mercury_trace_tables.c 11 Jan 2007 16:54:35 -0000
@@ -173,7 +173,6 @@
if (MR_search_module_info_by_name(module->MR_ml_name) == NULL) {
MR_insert_module_info(module);
- if (module->MR_ml_version_number >= MR_LAYOUT_VERSION__EVENTSETNAME) {
if (module->MR_ml_user_event_set_desc != NULL) {
int i;
MR_bool found;
@@ -182,6 +181,7 @@
event_set_name = module->MR_ml_user_event_set_name;
+ found = MR_FALSE;
for (i = 0; i < MR_trace_event_set_next; i++) {
if (MR_streq(MR_trace_event_sets[i].MR_tes_name,
event_set_name))
@@ -191,6 +191,11 @@
module->MR_ml_user_event_set_desc))
{
trace_event_set->MR_tes_is_consistent = MR_FALSE;
+ fprintf(MR_mdb_out,
+ "The executable's modules were compiled with "
+ "inconsistent definitions of "
+ "user event set `%s'.\n",
+ event_set_name);
}
found = MR_TRUE;
@@ -203,13 +208,26 @@
MR_TraceEventSet, MR_INIT_EVENT_SET_TABLE_SIZE);
trace_event_set =
&MR_trace_event_sets[MR_trace_event_set_next];
+ MR_trace_event_set_next++;
+
trace_event_set->MR_tes_name = event_set_name;
trace_event_set->MR_tes_desc =
module->MR_ml_user_event_set_desc;
trace_event_set->MR_tes_is_consistent = MR_TRUE;
+ trace_event_set->MR_tes_num_specs =
+ module->MR_ml_num_user_event_specs;
trace_event_set->MR_tes_specs =
module->MR_ml_user_event_specs;
- MR_trace_event_set_next++;
+ trace_event_set->MR_tes_event_set =
+ MR_read_event_set("no input file",
+ trace_event_set->MR_tes_desc);
+
+ if (trace_event_set->MR_tes_event_set == NULL) {
+ fprintf(MR_mdb_out,
+ "Internal error: could not parse "
+ "the specification of event set `%s'.\n",
+ event_set_name);
+ }
if (MR_trace_event_sets_max_num_attr <
module->MR_ml_user_event_max_num_attr)
@@ -221,7 +239,6 @@
}
}
}
- }
}
static const MR_ModuleLayout *
Index: trace/mercury_trace_tables.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_tables.h,v
retrieving revision 1.28
diff -u -b -r1.28 mercury_trace_tables.h
--- trace/mercury_trace_tables.h 14 Dec 2006 04:36:04 -0000 1.28
+++ trace/mercury_trace_tables.h 11 Jan 2007 15:02:30 -0000
@@ -67,7 +67,7 @@
MR_bool MR_tes_is_consistent;
MR_EventSet MR_tes_event_set;
int MR_tes_num_specs;
- MR_UserEventSpec *MR_tes_specs;
+ const MR_UserEventSpec *MR_tes_specs;
} MR_TraceEventSet;
extern MR_TraceEventSet *MR_trace_event_sets;
Index: trace/mercury_trace_vars.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_vars.c,v
retrieving revision 1.76
diff -u -b -r1.76 mercury_trace_vars.c
--- trace/mercury_trace_vars.c 11 Jan 2007 03:41:51 -0000 1.76
+++ trace/mercury_trace_vars.c 18 Jan 2007 10:59:58 -0000
@@ -184,11 +184,6 @@
const MR_ProgVarDetails *var2);
static int MR_compare_slots_on_headvar_num(const void *p1,
const void *p2);
-static const char *MR_trace_browse_one_path(FILE *out,
- MR_bool print_var_name, MR_VarSpec var_spec,
- char *path, MR_Browser browser,
- MR_BrowseCallerType caller,
- MR_BrowseFormat format, MR_bool must_be_unique);
static char *MR_trace_browse_var(FILE *out, MR_bool print_var_name,
MR_TypeInfo type_info, MR_Word value,
const char *name, char *path,
@@ -1123,6 +1118,28 @@
}
}
+void
+MR_print_var_spec(FILE *fp, MR_VarSpec *var_spec)
+{
+ switch (var_spec->MR_var_spec_kind) {
+ case MR_VAR_SPEC_NUMBER:
+ fprintf(fp, "%d", var_spec->MR_var_spec_number);
+ break;
+
+ case MR_VAR_SPEC_NAME:
+ fprintf(fp, "%s", var_spec->MR_var_spec_name);
+ break;
+
+ case MR_VAR_SPEC_HELD_NAME:
+ fprintf(fp, "$%s", var_spec->MR_var_spec_name);
+ break;
+
+ case MR_VAR_SPEC_ATTRIBUTE:
+ fprintf(fp, "!%s", var_spec->MR_var_spec_name);
+ break;
+ }
+}
+
static int
MR_compare_slots_on_headvar_num(const void *p1, const void *p2)
{
@@ -1408,7 +1425,7 @@
return NULL;
}
-static const char *
+const char *
MR_trace_browse_one_path(FILE *out, MR_bool print_var_name,
MR_VarSpec var_spec, char *path, MR_Browser browser,
MR_BrowseCallerType caller, MR_BrowseFormat format,
@@ -1432,7 +1449,7 @@
bad_path = MR_trace_browse_var(out, print_var_name, type_info, value,
name, path, browser, caller, format);
if (bad_path != NULL) {
- return MR_trace_bad_path(bad_path);
+ return MR_trace_bad_path_in_var(&var_spec, bad_path);
}
} else {
int success_count;
@@ -1540,22 +1557,89 @@
#define BAD_PATH_MSG_PREFIX "the path "
#define BAD_PATH_MSG_SUFFIX " does not exist"
+static char MR_trace_bad_path_buffer[BAD_PATH_BUFFER_SIZE];
+
const char *
MR_trace_bad_path(const char *path)
{
- static char buffer[BAD_PATH_BUFFER_SIZE];
-
if (strlen(BAD_PATH_MSG_PREFIX) + strlen(path) +
strlen(BAD_PATH_MSG_SUFFIX) < BAD_PATH_BUFFER_SIZE)
{
- sprintf(buffer, "%s%s%s", BAD_PATH_MSG_PREFIX, path,
+ sprintf(MR_trace_bad_path_buffer, "%s%s%s", BAD_PATH_MSG_PREFIX, path,
BAD_PATH_MSG_SUFFIX);
- return buffer;
+ return MR_trace_bad_path_buffer;
} else {
return "the given path does not exist";
}
}
+#define BAD_VAR_PATH_BUFFER_SIZE 128
+#define BAD_VAR_PATH_MSG_MIDDLE " in variable "
+
+static char MR_trace_bad_path_in_var_buffer[BAD_VAR_PATH_BUFFER_SIZE];
+
+const char *
+MR_trace_bad_path_in_var(MR_VarSpec *var_spec, const char *path)
+{
+ const char *path_msg;
+ int suffix_len;
+
+ path_msg = MR_trace_bad_path(path);
+ suffix_len = 0;
+ switch (var_spec->MR_var_spec_kind) {
+ case MR_VAR_SPEC_NUMBER:
+ /* This should be ample. */
+ suffix_len = 20;
+ break;
+
+ case MR_VAR_SPEC_NAME:
+ suffix_len = strlen(var_spec->MR_var_spec_name);
+ break;
+
+ case MR_VAR_SPEC_HELD_NAME:
+ suffix_len = strlen(var_spec->MR_var_spec_name) + 1;
+ break;
+
+ case MR_VAR_SPEC_ATTRIBUTE:
+ suffix_len = strlen(var_spec->MR_var_spec_name) + 1;
+ break;
+ }
+
+ if (strlen(path_msg) + strlen(BAD_VAR_PATH_MSG_MIDDLE) + suffix_len
+ < BAD_PATH_BUFFER_SIZE)
+ {
+ switch (var_spec->MR_var_spec_kind) {
+ case MR_VAR_SPEC_NUMBER:
+ sprintf(MR_trace_bad_path_in_var_buffer, "%s%s%d",
+ path_msg, BAD_VAR_PATH_MSG_MIDDLE,
+ var_spec->MR_var_spec_number);
+ break;
+
+ case MR_VAR_SPEC_NAME:
+ sprintf(MR_trace_bad_path_in_var_buffer, "%s%s%s",
+ path_msg, BAD_VAR_PATH_MSG_MIDDLE,
+ var_spec->MR_var_spec_name);
+ break;
+
+ case MR_VAR_SPEC_HELD_NAME:
+ sprintf(MR_trace_bad_path_in_var_buffer, "%s%s$%s",
+ path_msg, BAD_VAR_PATH_MSG_MIDDLE,
+ var_spec->MR_var_spec_name);
+ break;
+
+ case MR_VAR_SPEC_ATTRIBUTE:
+ sprintf(MR_trace_bad_path_in_var_buffer, "%s%s!%s",
+ path_msg, BAD_VAR_PATH_MSG_MIDDLE,
+ var_spec->MR_var_spec_name);
+ break;
+ }
+
+ return MR_trace_bad_path_in_var_buffer;
+ } else {
+ return path_msg;
+ }
+}
+
const char *
MR_trace_browse_all(FILE *out, MR_Browser browser, MR_BrowseFormat format)
{
@@ -1741,6 +1825,21 @@
fprintf(out, "%7s", "");
fprintf(out, "%s", name);
len = strlen(name);
+
+ if (path != NULL) {
+ char sep;
+
+ /* Try to conform to the separator used in the path. */
+ if (strchr(path, '/') != NULL && strchr(path, '^') == NULL) {
+ sep = '/';
+ } else {
+ sep = '^';
+ }
+
+ fprintf(out, "%c%s", sep, path);
+ len += 1 + strlen(path);
+ }
+
while (len < MR_TRACE_PADDED_VAR_NAME_LENGTH) {
fputc(' ', out);
len++;
Index: trace/mercury_trace_vars.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/trace/mercury_trace_vars.h,v
retrieving revision 1.32
diff -u -b -r1.32 mercury_trace_vars.h
--- trace/mercury_trace_vars.h 29 Nov 2006 05:18:42 -0000 1.32
+++ trace/mercury_trace_vars.h 18 Jan 2007 08:34:33 -0000
@@ -89,6 +89,12 @@
MR_VarSpec *var_spec);
/*
+** Print the given MR_VarSpec.
+*/
+
+extern void MR_print_var_spec(FILE *fp, MR_VarSpec *var_spec);
+
+/*
** These functions are documented near the top of this file.
*/
@@ -241,6 +247,13 @@
MR_BrowseCallerType caller, MR_BrowseFormat format,
MR_bool must_be_unique);
+
+extern const char *MR_trace_browse_one_path(FILE *out,
+ MR_bool print_var_name, MR_VarSpec var_spec,
+ char *path, MR_Browser browser,
+ MR_BrowseCallerType caller, MR_BrowseFormat format,
+ MR_bool must_be_unique);
+
/*
** Print the list of the names and values of all variables live at the current
** point. The variables names are printed directly to the given file, but
@@ -293,11 +306,25 @@
/*
** Given an invalid path specification, return an error message for that error.
+**
+** The returned string is valid only until the next call to MR_trace_bad_path
+** or MR_trace_bad_path_in_var.
*/
extern const char *MR_trace_bad_path(const char *path);
/*
+** Given a path specification that does not exist within the specified
+** variable, return an error message for that error.
+**
+** The returned string is valid only until the next call to MR_trace_bad_path
+** or MR_trace_bad_path_in_var.
+*/
+
+extern const char *MR_trace_bad_path_in_var(MR_VarSpec *var_spec,
+ const char *path);
+
+/*
** Print the size of the specified variable(s) to the specified file.
** Return a non-NULL error message if this is not possible.
*/
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