mirror of
https://github.com/neovim/neovim.git
synced 2025-09-28 22:18:33 +00:00
vim-patch:8.0.1505: debugger can't break on a condition
Problem: Debugger can't break on a condition. (Charles Campbell) Solution: Add ":breakadd expr". (Christian Brabandt, closes vim/vim#859)c6f9f739d3
Do not port "has_watchexpr()" to avoid dead code. "has_watchexpr()" always returns 0 because "debug_expr" is always 0. Restore "eval_expr()" as a wrapper to allocate "typval_T" for "eval0()". Remove it in later patches. Include "typval_compare()" changes from patch v8.1.0958, partially ported in8b60368c1b
. Close https://github.com/neovim/neovim/pull/12373 N/A patches for version.c: vim-patch:8.2.2720: GTK menu tooltip moves the cursor Problem: GTK menu tooltip moves the cursor. Solution: Position the cursor after displaying the tooltip. Do not show the tooltip when editing the command line.01ac0a1f66
This commit is contained in:
@@ -120,6 +120,9 @@ struct source_cookie {
|
||||
/// batch mode debugging: don't save and restore typeahead.
|
||||
static bool debug_greedy = false;
|
||||
|
||||
static char *debug_oldval = NULL; // old and newval for debug expressions
|
||||
static char *debug_newval = NULL;
|
||||
|
||||
/// Debug mode. Repeatedly get Ex commands, until told to continue normal
|
||||
/// execution.
|
||||
void do_debug(char_u *cmd)
|
||||
@@ -166,6 +169,16 @@ void do_debug(char_u *cmd)
|
||||
if (!debug_did_msg) {
|
||||
MSG(_("Entering Debug mode. Type \"cont\" to continue."));
|
||||
}
|
||||
if (debug_oldval != NULL) {
|
||||
smsg(_("Oldval = \"%s\""), debug_oldval);
|
||||
xfree(debug_oldval);
|
||||
debug_oldval = NULL;
|
||||
}
|
||||
if (debug_newval != NULL) {
|
||||
smsg(_("Newval = \"%s\""), debug_newval);
|
||||
xfree(debug_newval);
|
||||
debug_newval = NULL;
|
||||
}
|
||||
if (sourcing_name != NULL) {
|
||||
msg(sourcing_name);
|
||||
}
|
||||
@@ -174,7 +187,6 @@ void do_debug(char_u *cmd)
|
||||
} else {
|
||||
smsg(_("cmd: %s"), cmd);
|
||||
}
|
||||
|
||||
// Repeat getting a command and executing it.
|
||||
for (;; ) {
|
||||
msg_scroll = true;
|
||||
@@ -514,11 +526,13 @@ bool dbg_check_skipped(exarg_T *eap)
|
||||
/// This is a grow-array of structs.
|
||||
struct debuggy {
|
||||
int dbg_nr; ///< breakpoint number
|
||||
int dbg_type; ///< DBG_FUNC or DBG_FILE
|
||||
char_u *dbg_name; ///< function or file name
|
||||
int dbg_type; ///< DBG_FUNC or DBG_FILE or DBG_EXPR
|
||||
char_u *dbg_name; ///< function, expression or file name
|
||||
regprog_T *dbg_prog; ///< regexp program
|
||||
linenr_T dbg_lnum; ///< line number in function or file
|
||||
int dbg_forceit; ///< ! used
|
||||
typval_T *dbg_val; ///< last result of watchexpression
|
||||
int dbg_level; ///< stored nested level for expr
|
||||
};
|
||||
|
||||
static garray_T dbg_breakp = { 0, 0, sizeof(struct debuggy), 4, NULL };
|
||||
@@ -530,6 +544,7 @@ static int last_breakp = 0; // nr of last defined breakpoint
|
||||
static garray_T prof_ga = { 0, 0, sizeof(struct debuggy), 4, NULL };
|
||||
#define DBG_FUNC 1
|
||||
#define DBG_FILE 2
|
||||
#define DBG_EXPR 3
|
||||
|
||||
|
||||
/// Parse the arguments of ":profile", ":breakadd" or ":breakdel" and put them
|
||||
@@ -562,6 +577,8 @@ static int dbg_parsearg(char_u *arg, garray_T *gap)
|
||||
}
|
||||
bp->dbg_type = DBG_FILE;
|
||||
here = true;
|
||||
} else if (gap != &prof_ga && STRNCMP(p, "expr", 4) == 0) {
|
||||
bp->dbg_type = DBG_EXPR;
|
||||
} else {
|
||||
EMSG2(_(e_invarg2), p);
|
||||
return FAIL;
|
||||
@@ -590,6 +607,9 @@ static int dbg_parsearg(char_u *arg, garray_T *gap)
|
||||
bp->dbg_name = vim_strsave(p);
|
||||
} else if (here) {
|
||||
bp->dbg_name = vim_strsave(curbuf->b_ffname);
|
||||
} else if (bp->dbg_type == DBG_EXPR) {
|
||||
bp->dbg_name = vim_strsave(p);
|
||||
bp->dbg_val = eval_expr(bp->dbg_name);
|
||||
} else {
|
||||
// Expand the file name in the same way as do_source(). This means
|
||||
// doing it twice, so that $DIR/file gets expanded when $DIR is
|
||||
@@ -621,7 +641,6 @@ static int dbg_parsearg(char_u *arg, garray_T *gap)
|
||||
void ex_breakadd(exarg_T *eap)
|
||||
{
|
||||
struct debuggy *bp;
|
||||
char_u *pat;
|
||||
garray_T *gap;
|
||||
|
||||
gap = &dbg_breakp;
|
||||
@@ -633,22 +652,28 @@ void ex_breakadd(exarg_T *eap)
|
||||
bp = &DEBUGGY(gap, gap->ga_len);
|
||||
bp->dbg_forceit = eap->forceit;
|
||||
|
||||
pat = file_pat_to_reg_pat(bp->dbg_name, NULL, NULL, false);
|
||||
if (pat != NULL) {
|
||||
bp->dbg_prog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
|
||||
xfree(pat);
|
||||
}
|
||||
if (pat == NULL || bp->dbg_prog == NULL) {
|
||||
xfree(bp->dbg_name);
|
||||
if (bp->dbg_type != DBG_EXPR) {
|
||||
char_u *pat = file_pat_to_reg_pat(bp->dbg_name, NULL, NULL, false);
|
||||
if (pat != NULL) {
|
||||
bp->dbg_prog = vim_regcomp(pat, RE_MAGIC + RE_STRING);
|
||||
xfree(pat);
|
||||
}
|
||||
if (pat == NULL || bp->dbg_prog == NULL) {
|
||||
xfree(bp->dbg_name);
|
||||
} else {
|
||||
if (bp->dbg_lnum == 0) { // default line number is 1
|
||||
bp->dbg_lnum = 1;
|
||||
}
|
||||
if (eap->cmdidx != CMD_profile) {
|
||||
DEBUGGY(gap, gap->ga_len).dbg_nr = ++last_breakp;
|
||||
debug_tick++;
|
||||
}
|
||||
gap->ga_len++;
|
||||
}
|
||||
} else {
|
||||
if (bp->dbg_lnum == 0) { // default line number is 1
|
||||
bp->dbg_lnum = 1;
|
||||
}
|
||||
if (eap->cmdidx != CMD_profile) {
|
||||
DEBUGGY(gap, gap->ga_len).dbg_nr = ++last_breakp;
|
||||
debug_tick++;
|
||||
}
|
||||
gap->ga_len++;
|
||||
// DBG_EXPR
|
||||
DEBUGGY(gap, gap->ga_len++).dbg_nr = ++last_breakp;
|
||||
debug_tick++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -691,7 +716,7 @@ void ex_breakdel(exarg_T *eap)
|
||||
todel = 0;
|
||||
del_all = true;
|
||||
} else {
|
||||
// ":breakdel {func|file} [lnum] {name}"
|
||||
// ":breakdel {func|file|expr} [lnum] {name}"
|
||||
if (dbg_parsearg(eap->arg, gap) == FAIL) {
|
||||
return;
|
||||
}
|
||||
@@ -716,6 +741,10 @@ void ex_breakdel(exarg_T *eap)
|
||||
} else {
|
||||
while (!GA_EMPTY(gap)) {
|
||||
xfree(DEBUGGY(gap, todel).dbg_name);
|
||||
if (DEBUGGY(gap, todel).dbg_type == DBG_EXPR
|
||||
&& DEBUGGY(gap, todel).dbg_val != NULL) {
|
||||
tv_free(DEBUGGY(gap, todel).dbg_val);
|
||||
}
|
||||
vim_regfree(DEBUGGY(gap, todel).dbg_prog);
|
||||
gap->ga_len--;
|
||||
if (todel < gap->ga_len) {
|
||||
@@ -750,11 +779,15 @@ void ex_breaklist(exarg_T *eap)
|
||||
if (bp->dbg_type == DBG_FILE) {
|
||||
home_replace(NULL, bp->dbg_name, NameBuff, MAXPATHL, true);
|
||||
}
|
||||
smsg(_("%3d %s %s line %" PRId64),
|
||||
bp->dbg_nr,
|
||||
bp->dbg_type == DBG_FUNC ? "func" : "file",
|
||||
bp->dbg_type == DBG_FUNC ? bp->dbg_name : NameBuff,
|
||||
(int64_t)bp->dbg_lnum);
|
||||
if (bp->dbg_type != DBG_EXPR) {
|
||||
smsg(_("%3d %s %s line %" PRId64),
|
||||
bp->dbg_nr,
|
||||
bp->dbg_type == DBG_FUNC ? "func" : "file",
|
||||
bp->dbg_type == DBG_FUNC ? bp->dbg_name : NameBuff,
|
||||
(int64_t)bp->dbg_lnum);
|
||||
} else {
|
||||
smsg(_("%3d expr %s"), bp->dbg_nr, bp->dbg_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -814,6 +847,7 @@ debuggy_find(
|
||||
// an already found breakpoint.
|
||||
bp = &DEBUGGY(gap, i);
|
||||
if ((bp->dbg_type == DBG_FILE) == file
|
||||
&& bp->dbg_type != DBG_EXPR
|
||||
&& (gap == &prof_ga
|
||||
|| (bp->dbg_lnum > after && (lnum == 0 || bp->dbg_lnum < lnum)))) {
|
||||
// Save the value of got_int and reset it. We don't want a
|
||||
@@ -827,6 +861,49 @@ debuggy_find(
|
||||
*fp = bp->dbg_forceit;
|
||||
}
|
||||
}
|
||||
got_int |= prev_got_int;
|
||||
} else if (bp->dbg_type == DBG_EXPR) {
|
||||
bool line = false;
|
||||
|
||||
prev_got_int = got_int;
|
||||
got_int = false;
|
||||
|
||||
typval_T *tv = eval_expr(bp->dbg_name);
|
||||
if (tv != NULL) {
|
||||
if (bp->dbg_val == NULL) {
|
||||
debug_oldval = typval_tostring(NULL);
|
||||
bp->dbg_val = tv;
|
||||
debug_newval = typval_tostring(bp->dbg_val);
|
||||
line = true;
|
||||
} else {
|
||||
typval_T val3;
|
||||
|
||||
if (typval_copy(bp->dbg_val, &val3) == OK) {
|
||||
if (typval_compare(tv, &val3, TYPE_EQUAL, true, false, true) == OK
|
||||
&& tv->vval.v_number == false) {
|
||||
line = true;
|
||||
debug_oldval = typval_tostring(bp->dbg_val);
|
||||
typval_T *v = eval_expr(bp->dbg_name);
|
||||
debug_newval = typval_tostring(v);
|
||||
tv_free(bp->dbg_val);
|
||||
bp->dbg_val = v;
|
||||
}
|
||||
}
|
||||
tv_free(tv);
|
||||
}
|
||||
} else if (bp->dbg_val != NULL) {
|
||||
debug_oldval = typval_tostring(bp->dbg_val);
|
||||
debug_newval = typval_tostring(NULL);
|
||||
tv_free(bp->dbg_val);
|
||||
bp->dbg_val = NULL;
|
||||
line = true;
|
||||
}
|
||||
|
||||
if (line) {
|
||||
lnum = after > 0 ? after : 1;
|
||||
break;
|
||||
}
|
||||
|
||||
got_int |= prev_got_int;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user