diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/debugger.c | 57 | ||||
-rw-r--r-- | src/nvim/testdir/test_debugger.vim | 7 |
2 files changed, 43 insertions, 21 deletions
diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c index d5b86f3d51..778facb0f5 100644 --- a/src/nvim/debugger.c +++ b/src/nvim/debugger.c @@ -27,6 +27,19 @@ static bool debug_greedy = false; static char *debug_oldval = NULL; // old and newval for debug expressions static char *debug_newval = NULL; +/// The list of breakpoints: dbg_breakp. +/// This is a grow-array of structs. +struct debuggy { + int dbg_nr; ///< breakpoint number + 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 +}; + #ifdef INCLUDE_GENERATED_DECLARATIONS # include "debugger.c.generated.h" #endif @@ -429,19 +442,6 @@ bool dbg_check_skipped(exarg_T *eap) return false; } -/// The list of breakpoints: dbg_breakp. -/// This is a grow-array of structs. -struct debuggy { - int dbg_nr; ///< breakpoint number - 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 }; #define BREAKP(idx) (((struct debuggy *)dbg_breakp.ga_data)[idx]) #define DEBUGGY(gap, idx) (((struct debuggy *)gap->ga_data)[idx]) @@ -453,6 +453,26 @@ static garray_T prof_ga = { 0, 0, sizeof(struct debuggy), 4, NULL }; #define DBG_FILE 2 #define DBG_EXPR 3 +/// Evaluate the "bp->dbg_name" expression and return the result. +/// Restore the got_int and called_emsg flags. +static typval_T *eval_expr_restore(struct debuggy *const bp) + FUNC_ATTR_NONNULL_ALL +{ + const int prev_called_emsg = called_emsg; + const int prev_did_emsg = did_emsg; + + got_int = false; + typval_T *const tv = eval_expr(bp->dbg_name); + + // Evaluating the expression should not result in breaking the sequence of + // commands. + got_int = false; + called_emsg = prev_called_emsg; + did_emsg = prev_did_emsg; + + return tv; +} + /// Parse the arguments of ":profile", ":breakadd" or ":breakdel" and put them /// in the entry just after the last one in dbg_breakp. Note that "dbg_name" /// is allocated. @@ -515,7 +535,7 @@ static int dbg_parsearg(char_u *arg, garray_T *gap) 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); + bp->dbg_val = eval_expr_restore(bp); } 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 @@ -771,10 +791,7 @@ debuggy_find( } 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); + typval_T *const tv = eval_expr_restore(bp); if (tv != NULL) { if (bp->dbg_val == NULL) { debug_oldval = typval_tostring(NULL); @@ -787,7 +804,7 @@ debuggy_find( line = true; debug_oldval = typval_tostring(bp->dbg_val); // Need to evaluate again, typval_compare() overwrites "tv". - typval_T *v = eval_expr(bp->dbg_name); + typval_T *const v = eval_expr_restore(bp); debug_newval = typval_tostring(v); tv_free(bp->dbg_val); bp->dbg_val = v; @@ -806,8 +823,6 @@ debuggy_find( lnum = after > 0 ? after : 1; break; } - - got_int |= prev_got_int; } } if (name != fname) { diff --git a/src/nvim/testdir/test_debugger.vim b/src/nvim/testdir/test_debugger.vim index d1464e9d3b..c6d6a90275 100644 --- a/src/nvim/testdir/test_debugger.vim +++ b/src/nvim/testdir/test_debugger.vim @@ -314,9 +314,12 @@ func Test_Debugger() call RunDbgCmd(buf, 'enew! | only!') call StopVimInTerminal(buf) +endfunc +func Test_Debugger_breakadd() " Tests for :breakadd file and :breakadd here " Breakpoints should be set before sourcing the file + CheckRunVimInTerminal let lines =<< trim END let var1 = 10 @@ -337,6 +340,10 @@ func Test_Debugger() call StopVimInTerminal(buf) call delete('Xtest.vim') + %bw! + + call assert_fails('breakadd here', 'E32:') + call assert_fails('breakadd file Xtest.vim /\)/', 'E55:') endfunc func Test_Backtrace_Through_Source() |