aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/debugger.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-11-30 20:35:25 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-11-30 20:35:25 +0000
commit1b7b916b7631ddf73c38e3a0070d64e4636cb2f3 (patch)
treecd08258054db80bb9a11b1061bb091c70b76926a /src/nvim/debugger.c
parenteaa89c11d0f8aefbb512de769c6c82f61a8baca3 (diff)
parent4a8bf24ac690004aedf5540fa440e788459e5e34 (diff)
downloadrneovim-1b7b916b7631ddf73c38e3a0070d64e4636cb2f3.tar.gz
rneovim-1b7b916b7631ddf73c38e3a0070d64e4636cb2f3.tar.bz2
rneovim-1b7b916b7631ddf73c38e3a0070d64e4636cb2f3.zip
Merge remote-tracking branch 'upstream/master' into aucmd_textputpostaucmd_textputpost
Diffstat (limited to 'src/nvim/debugger.c')
-rw-r--r--src/nvim/debugger.c96
1 files changed, 54 insertions, 42 deletions
diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c
index f7e70a78ce..a343c1ad6b 100644
--- a/src/nvim/debugger.c
+++ b/src/nvim/debugger.c
@@ -1,6 +1,3 @@
-// This is an open source non-commercial project. Dear PVS-Studio, please check
-// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-
/// @file debugger.c
///
/// Vim script debugger functions
@@ -10,33 +7,33 @@
#include <stdlib.h>
#include <string.h>
-#include "nvim/ascii.h"
-#include "nvim/buffer_defs.h"
+#include "nvim/ascii_defs.h"
#include "nvim/charset.h"
+#include "nvim/cmdexpand_defs.h"
#include "nvim/debugger.h"
#include "nvim/drawscreen.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
-#include "nvim/eval/typval_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
+#include "nvim/func_attr.h"
#include "nvim/garray.h"
#include "nvim/getchar.h"
#include "nvim/gettext.h"
#include "nvim/globals.h"
#include "nvim/keycodes.h"
-#include "nvim/macros.h"
+#include "nvim/macros_defs.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/os/os.h"
#include "nvim/path.h"
-#include "nvim/pos.h"
+#include "nvim/pos_defs.h"
#include "nvim/regexp.h"
#include "nvim/runtime.h"
-#include "nvim/types.h"
-#include "nvim/vim.h"
+#include "nvim/state_defs.h"
+#include "nvim/vim_defs.h"
/// batch mode debugging: don't save and restore typeahead.
static bool debug_greedy = false;
@@ -75,7 +72,6 @@ void do_debug(char *cmd)
tasave_T typeaheadbuf;
bool typeahead_saved = false;
int save_ignore_script = 0;
- int n;
char *cmdline = NULL;
char *p;
char *tail = NULL;
@@ -103,31 +99,31 @@ void do_debug(char *cmd)
debug_mode = true;
if (!debug_did_msg) {
- msg(_("Entering Debug mode. Type \"cont\" to continue."));
+ msg(_("Entering Debug mode. Type \"cont\" to continue."), 0);
}
if (debug_oldval != NULL) {
- smsg(_("Oldval = \"%s\""), debug_oldval);
+ smsg(0, _("Oldval = \"%s\""), debug_oldval);
xfree(debug_oldval);
debug_oldval = NULL;
}
if (debug_newval != NULL) {
- smsg(_("Newval = \"%s\""), debug_newval);
+ smsg(0, _("Newval = \"%s\""), debug_newval);
xfree(debug_newval);
debug_newval = NULL;
}
char *sname = estack_sfile(ESTACK_NONE);
if (sname != NULL) {
- msg(sname);
+ msg(sname, 0);
}
xfree(sname);
if (SOURCING_LNUM != 0) {
- smsg(_("line %" PRId64 ": %s"), (int64_t)SOURCING_LNUM, cmd);
+ smsg(0, _("line %" PRId64 ": %s"), (int64_t)SOURCING_LNUM, cmd);
} else {
- smsg(_("cmd: %s"), cmd);
+ smsg(0, _("cmd: %s"), cmd);
}
// Repeat getting a command and executing it.
- for (;;) {
+ while (true) {
msg_scroll = true;
need_wait_return = false;
@@ -146,7 +142,7 @@ void do_debug(char *cmd)
}
// don't debug any function call, e.g. from an expression mapping
- n = debug_break_level;
+ int n = debug_break_level;
debug_break_level = -1;
xfree(cmdline);
@@ -236,7 +232,7 @@ void do_debug(char *cmd)
}
if (last_cmd != 0) {
- // Execute debug command: decided where to break next and return.
+ // Execute debug command: decide where to break next and return.
switch (last_cmd) {
case CMD_CONT:
debug_break_level = -1;
@@ -346,14 +342,14 @@ static void do_checkbacktracelevel(void)
{
if (debug_backtrace_level < 0) {
debug_backtrace_level = 0;
- msg(_("frame is zero"));
+ msg(_("frame is zero"), 0);
} else {
char *sname = estack_sfile(ESTACK_NONE);
int max = get_maxbacktrace_level(sname);
if (debug_backtrace_level > max) {
debug_backtrace_level = max;
- smsg(_("frame at highest level: %d"), max);
+ smsg(0, _("frame at highest level: %d"), max);
}
xfree(sname);
}
@@ -372,9 +368,9 @@ static void do_showbacktrace(char *cmd)
*next = NUL;
}
if (i == max - debug_backtrace_level) {
- smsg("->%d %s", max - i, cur);
+ smsg(0, "->%d %s", max - i, cur);
} else {
- smsg(" %d %s", max - i, cur);
+ smsg(0, " %d %s", max - i, cur);
}
i++;
if (next == NULL) {
@@ -387,9 +383,9 @@ static void do_showbacktrace(char *cmd)
}
if (SOURCING_LNUM != 0) {
- smsg(_("line %" PRId64 ": %s"), (int64_t)SOURCING_LNUM, cmd);
+ smsg(0, _("line %" PRId64 ": %s"), (int64_t)SOURCING_LNUM, cmd);
} else {
- smsg(_("cmd: %s"), cmd);
+ smsg(0, _("cmd: %s"), cmd);
}
}
@@ -433,7 +429,7 @@ void dbg_check_breakpoint(exarg_T *eap)
} else {
p = "";
}
- smsg(_("Breakpoint in \"%s%s\" line %" PRId64),
+ smsg(0, _("Breakpoint in \"%s%s\" line %" PRId64),
p,
debug_breakpoint_name + (*p == NUL ? 0 : 3),
(int64_t)debug_breakpoint_lnum);
@@ -481,6 +477,7 @@ 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])
static int last_breakp = 0; // nr of last defined breakpoint
+static bool has_expr_breakpoint = false;
// Profiling uses file and func names similar to breakpoints.
static garray_T prof_ga = { 0, 0, sizeof(struct debuggy), 4, NULL };
@@ -495,7 +492,7 @@ static typval_T *eval_expr_no_emsg(struct debuggy *const bp)
{
// Disable error messages, a bad expression would make Vim unusable.
emsg_off++;
- typval_T *const tv = eval_expr(bp->dbg_name);
+ typval_T *const tv = eval_expr(bp->dbg_name, NULL);
emsg_off--;
return tv;
}
@@ -510,7 +507,6 @@ static typval_T *eval_expr_no_emsg(struct debuggy *const bp)
static int dbg_parsearg(char *arg, garray_T *gap)
{
char *p = arg;
- char *q;
bool here = false;
ga_grow(gap, 1);
@@ -556,7 +552,7 @@ static int dbg_parsearg(char *arg, garray_T *gap)
}
if (bp->dbg_type == DBG_FUNC) {
- bp->dbg_name = xstrdup(p);
+ bp->dbg_name = xstrdup(strncmp(p, "g:", 2) == 0 ? p + 2 : p);
} else if (here) {
bp->dbg_name = xstrdup(curbuf->b_ffname);
} else if (bp->dbg_type == DBG_EXPR) {
@@ -566,7 +562,7 @@ static int dbg_parsearg(char *arg, garray_T *gap)
// 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
// "~/dir".
- q = expand_env_save(p);
+ char *q = expand_env_save(p);
if (q == NULL) {
return FAIL;
}
@@ -626,6 +622,9 @@ void ex_breakadd(exarg_T *eap)
// DBG_EXPR
DEBUGGY(gap, gap->ga_len++).dbg_nr = ++last_breakp;
debug_tick++;
+ if (gap == &dbg_breakp) {
+ has_expr_breakpoint = true;
+ }
}
}
@@ -639,10 +638,20 @@ void ex_debuggreedy(exarg_T *eap)
}
}
+static void update_has_expr_breakpoint(void)
+{
+ has_expr_breakpoint = false;
+ for (int i = 0; i < dbg_breakp.ga_len; i++) {
+ if (BREAKP(i).dbg_type == DBG_EXPR) {
+ has_expr_breakpoint = true;
+ break;
+ }
+ }
+}
+
/// ":breakdel" and ":profdel".
void ex_breakdel(exarg_T *eap)
{
- struct debuggy *bp, *bpi;
int todel = -1;
bool del_all = false;
linenr_T best_lnum = 0;
@@ -669,9 +678,9 @@ void ex_breakdel(exarg_T *eap)
if (dbg_parsearg(eap->arg, gap) == FAIL) {
return;
}
- bp = &DEBUGGY(gap, gap->ga_len);
+ struct debuggy *bp = &DEBUGGY(gap, gap->ga_len);
for (int i = 0; i < gap->ga_len; i++) {
- bpi = &DEBUGGY(gap, i);
+ struct debuggy *bpi = &DEBUGGY(gap, i);
if (bp->dbg_type == bpi->dbg_type
&& strcmp(bp->dbg_name, bpi->dbg_name) == 0
&& (bp->dbg_lnum == bpi->dbg_lnum
@@ -714,29 +723,32 @@ void ex_breakdel(exarg_T *eap)
if (GA_EMPTY(gap)) {
ga_clear(gap);
}
+ if (gap == &dbg_breakp) {
+ update_has_expr_breakpoint();
+ }
}
/// ":breaklist".
void ex_breaklist(exarg_T *eap)
{
if (GA_EMPTY(&dbg_breakp)) {
- msg(_("No breakpoints defined"));
+ msg(_("No breakpoints defined"), 0);
return;
}
for (int i = 0; i < dbg_breakp.ga_len; i++) {
struct debuggy *bp = &BREAKP(i);
if (bp->dbg_type == DBG_FILE) {
- home_replace(NULL, bp->dbg_name, (char *)NameBuff, MAXPATHL, true);
+ home_replace(NULL, bp->dbg_name, NameBuff, MAXPATHL, true);
}
if (bp->dbg_type != DBG_EXPR) {
- smsg(_("%3d %s %s line %" PRId64),
+ smsg(0, _("%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);
+ smsg(0, _("%3d expr %s"), bp->dbg_nr, bp->dbg_name);
}
}
}
@@ -759,8 +771,8 @@ linenr_T dbg_find_breakpoint(bool file, char *fname, linenr_T after)
/// @returns true if profiling is on for a function or sourced file.
bool has_profiling(bool file, char *fname, bool *fp)
{
- return debuggy_find(file, fname, (linenr_T)0, &prof_ga, fp)
- != (linenr_T)0;
+ return debuggy_find(file, fname, 0, &prof_ga, fp)
+ != 0;
}
/// Common code for dbg_find_breakpoint() and has_profiling().
@@ -779,7 +791,7 @@ static linenr_T debuggy_find(bool file, char *fname, linenr_T after, garray_T *g
// Return quickly when there are no breakpoints.
if (GA_EMPTY(gap)) {
- return (linenr_T)0;
+ return 0;
}
// Replace K_SNR in function name with "<SNR>".
@@ -802,7 +814,7 @@ static linenr_T debuggy_find(bool file, char *fname, linenr_T after, garray_T *g
// while matching should abort it.
prev_got_int = got_int;
got_int = false;
- if (vim_regexec_prog(&bp->dbg_prog, false, name, (colnr_T)0)) {
+ if (vim_regexec_prog(&bp->dbg_prog, false, name, 0)) {
lnum = bp->dbg_lnum;
if (fp != NULL) {
*fp = bp->dbg_forceit;