Files
mercury/trace/mercury_trace_spy.h
Zoltan Somogyi 672582375c Make an mdb error message more informative.
trace/mercury_trace_internal.c:
    Whe printing the "there is no such variable" message at
    conditional break points, print the name of the variable.
    The original message can be misread to mean that there
    is nothing at *the selected path*; the new one cannot.

trace/mercury_trace_spy.c:
trace/mercury_trace_spy.h:
    Add a mechanism to enable the above change.

tests/debugger/cond.exp:
    Expect the updated error message.
2025-06-12 10:16:50 +02:00

205 lines
7.7 KiB
C

// vim: ts=4 sw=4 expandtab ft=c
// Copyright (C) 1998-2001, 2005-2007 The University of Melbourne.
// Copyright (C) 2016, 2018, 2025 The Mercury team.
// This file is distributed under the terms specified in COPYING.LIB.
// This file contains the declarations of the types and functions that
// the internal and external debuggers can use to manipulate spy points.
//
// Main author: Zoltan Somogyi.
#ifndef MERCURY_TRACE_SPY_H
#define MERCURY_TRACE_SPY_H
#include "mercury_stack_layout.h" // for MR_ProcLayout etc
#include "mercury_trace_term.h" // for MR_CTerm
#include "mercury_trace_base.h" // for MR_TracePort etc
#include "mercury_trace_browse.h" // for MR_BrowseFormat
#include "mercury_trace_vars.h" // for MR_VarSpec
#include "mercury_trace.h" // for MR_IgnoreCount
typedef enum {
MR_SPY_PRINT, MR_SPY_STOP
} MR_SpyAction;
#define MR_spy_action_string(a) ((a == MR_SPY_STOP) ? "stop" : \
(a == MR_SPY_PRINT) ? "print" : \
"unknown spy action")
typedef enum {
MR_SPY_ALL,
MR_SPY_INTERFACE,
MR_SPY_ENTRY,
MR_SPY_SPECIFIC,
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_ALL
} MR_SpyIgnore_When;
extern const char *MR_spy_when_names[];
typedef struct MR_SpyPrint_Struct *MR_SpyPrint;
typedef struct MR_SpyPrintList_Struct *MR_SpyPrintList;
typedef enum {
MR_SPY_TEST_EQUAL, MR_SPY_TEST_NOT_EQUAL
} MR_SpyTest;
typedef enum {
MR_SPY_PRINT_GOAL,
MR_SPY_PRINT_ALL,
MR_SPY_PRINT_ONE,
} MR_SpyPrintWhat;
struct MR_SpyPrint_Struct {
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 MR_pl_cur;
MR_SpyPrintList MR_pl_next;
};
typedef struct MR_SpyPoint_Struct MR_SpyPoint;
typedef struct {
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;
} MR_SpyCond;
struct MR_SpyPoint_Struct {
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;
MR_IgnoreCount 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
};
// The table of spy points, with counters saying which is the next free slot
// and how many slots are allocated.
extern MR_SpyPoint **MR_spy_points;
extern int MR_spy_point_next;
extern int MR_spy_point_max;
extern int MR_most_recent_spy_point;
extern MR_SpyCond *MR_spy_point_cond_bad;
extern const char *MR_spy_point_cond_problem;
// Check whether the event described by the given label layout and port
// matches any spy points. If yes, return MR_TRUE, set *action to say what
// action should be executed for the spy point, and set print_list to the
// variable print list of the first matching spy point.
extern MR_bool MR_event_matches_spy_point(
const MR_LabelLayout *layout, MR_TracePort port,
MR_SpyAction *action,
MR_SpyPrintList *print_list);
// 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,
MR_SpyAction action, MR_SpyIgnore_When ignore_when,
MR_IgnoreCount ignore_count,
const MR_ProcLayout *entry,
const MR_LabelLayout *label,
MR_SpyPrintList print_list, const char **problem);
// 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,
MR_SpyIgnore_When ignore_when,
MR_IgnoreCount ignore_count,
const char *filename, int linenumber,
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,
MR_IgnoreCount 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.
extern void MR_add_spy_point_print_list_start(int point_slot,
MR_SpyPrintList print_list);
extern void MR_add_spy_point_print_list_end(int point_slot,
MR_SpyPrintList print_list);
// Empty the set of things to be printed at the spy point.
extern void MR_clear_spy_point_print_list(int point_slot);
// Apply the given ignore specification to the given spy point.
// If the ignore specification is not appropriate for the spy point,
// return a non-NULL problem report.
extern const char *MR_ignore_spy_point(int point_slot,
MR_SpyIgnore_When ignore_when,
MR_IgnoreCount ignore_count);
// Delete a spy point from the table.
extern void MR_delete_spy_point(int point_table_slot);
// Print the spy point with the given number in a nice format for humans to
// read to the given file.
extern void MR_print_spy_point(FILE *fp, int i, MR_bool verbose);
// Print the given spy point condition in a user-friendly manner.
// If the condition involves a named variable, set *name to point to that name.
// Otherwise, set it to NULL.
extern void MR_print_spy_cond(FILE *fp, MR_SpyCond *cond,
const char **name);
// Print the set of current spy points (including those that are currently
// disabled) to fp in a format that, when sourced by mdb, recreates those
// spy points. Any internal errors encountered while trying to do this
// should be reported to err_fp. Return MR_TRUE iff the debugger's data
// structures are inconsistent, and the spy points could not be saved.
extern MR_bool MR_save_spy_points(FILE *fp, FILE *err_fp);
#endif // not MERCURY_TRACE_SPY_H