diff options
Diffstat (limited to 'data/vim/patches/8.1.1195')
-rw-r--r-- | data/vim/patches/8.1.1195 | 2445 |
1 files changed, 2445 insertions, 0 deletions
diff --git a/data/vim/patches/8.1.1195 b/data/vim/patches/8.1.1195 new file mode 100644 index 000000000..68b696239 --- /dev/null +++ b/data/vim/patches/8.1.1195 @@ -0,0 +1,2445 @@ +To: vim_dev@googlegroups.com +Subject: Patch 8.1.1195 +Fcc: outbox +From: Bram Moolenaar <Bram@moolenaar.net> +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +------------ + +Patch 8.1.1195 +Problem: Vim script debugger functionality needs cleanup. +Solution: Move debugger code to a separate file. Add more tests. (Yegappan + Lakshmanan, closes #4285) +Files: Filelist, src/Make_bc5.mak, src/Make_cyg_ming.mak, + src/Make_dice.mak, src/Make_ivc.mak, src/Make_manx.mak, + src/Make_morph.mak, src/Make_mvc.mak, src/Make_sas.mak, + src/Make_vms.mms, src/Makefile, src/debugger.c, src/ex_cmds2.c, + src/proto.h, src/proto/debugger.pro, src/proto/ex_cmds2.pro + + +*** ../vim-8.1.1194/Filelist 2019-04-11 13:09:57.786699880 +0200 +--- Filelist 2019-04-21 11:18:57.688977840 +0200 +*************** +*** 23,28 **** +--- 23,29 ---- + src/charset.c \ + src/crypt.c \ + src/crypt_zip.c \ ++ src/debugger.c \ + src/dict.c \ + src/diff.c \ + src/digraph.c \ +*************** +*** 156,161 **** +--- 157,163 ---- + src/proto/charset.pro \ + src/proto/crypt.pro \ + src/proto/crypt_zip.pro \ ++ src/proto/debugger.pro \ + src/proto/dict.pro \ + src/proto/diff.pro \ + src/proto/digraph.pro \ +*** ../vim-8.1.1194/src/Make_bc5.mak 2019-03-30 13:53:26.166425144 +0100 +--- src/Make_bc5.mak 2019-04-21 11:18:57.688977840 +0200 +*************** +*** 516,521 **** +--- 516,522 ---- + $(OBJDIR)\charset.obj \ + $(OBJDIR)\crypt.obj \ + $(OBJDIR)\crypt_zip.obj \ ++ $(OBJDIR)\debugger.obj \ + $(OBJDIR)\dict.obj \ + $(OBJDIR)\diff.obj \ + $(OBJDIR)\digraph.obj \ +*** ../vim-8.1.1194/src/Make_cyg_ming.mak 2019-04-03 20:30:56.081017564 +0200 +--- src/Make_cyg_ming.mak 2019-04-21 11:18:57.688977840 +0200 +*************** +*** 703,708 **** +--- 703,709 ---- + $(OUTDIR)/charset.o \ + $(OUTDIR)/crypt.o \ + $(OUTDIR)/crypt_zip.o \ ++ $(OUTDIR)/debugger.o \ + $(OUTDIR)/dict.o \ + $(OUTDIR)/diff.o \ + $(OUTDIR)/digraph.o \ +*** ../vim-8.1.1194/src/Make_dice.mak 2019-03-30 13:53:26.166425144 +0100 +--- src/Make_dice.mak 2019-04-21 11:18:57.688977840 +0200 +*************** +*** 33,38 **** +--- 33,39 ---- + charset.c \ + crypt.c \ + crypt_zip.c \ ++ debugger.c \ + dict.c \ + diff.c \ + digraph.c \ +*************** +*** 93,98 **** +--- 94,100 ---- + o/charset.o \ + o/crypt.o \ + o/crypt_zip.o \ ++ o/debugger.o \ + o/dict.o \ + o/diff.o \ + o/digraph.o \ +*************** +*** 179,184 **** +--- 181,188 ---- + + o/crypt_zip.o: crypt_zip.c $(SYMS) + ++ o/debugger.o: debugger.c $(SYMS) ++ + o/dict.o: dict.c $(SYMS) + + o/diff.o: diff.c $(SYMS) +*** ../vim-8.1.1194/src/Make_ivc.mak 2019-03-30 13:53:26.166425144 +0100 +--- src/Make_ivc.mak 2019-04-21 11:18:57.688977840 +0200 +*************** +*** 217,222 **** +--- 217,223 ---- + "$(INTDIR)/charset.obj" \ + "$(INTDIR)/crypt.obj" \ + "$(INTDIR)/crypt_zip.obj" \ ++ "$(INTDIR)/debugger.obj" \ + "$(INTDIR)/dict.obj" \ + "$(INTDIR)/diff.obj" \ + "$(INTDIR)/digraph.obj" \ +*************** +*** 369,374 **** +--- 370,379 ---- + # End Source File + # Begin Source File + ++ SOURCE=.\debugger.c ++ # End Source File ++ # Begin Source File ++ + SOURCE=.\dict.c + # End Source File + # Begin Source File +*** ../vim-8.1.1194/src/Make_manx.mak 2019-03-30 13:53:26.166425144 +0100 +--- src/Make_manx.mak 2019-04-21 11:18:57.688977840 +0200 +*************** +*** 43,48 **** +--- 43,49 ---- + charset.c \ + crypt.c \ + crypt_zip.c \ ++ debugger.c \ + dict.c \ + diff.c \ + digraph.c \ +*************** +*** 105,110 **** +--- 106,112 ---- + obj/charset.o \ + obj/crypt.o \ + obj/crypt_zip.o \ ++ obj/debugger.o \ + obj/dict.o \ + obj/diff.o \ + obj/digraph.o \ +*************** +*** 165,170 **** +--- 167,173 ---- + proto/charset.pro \ + proto/crypt.pro \ + proto/crypt_zip.pro \ ++ proto/debugger.pro \ + proto/dict.pro \ + proto/diff.pro \ + proto/digraph.pro \ +*************** +*** 283,288 **** +--- 286,294 ---- + obj/crypt_zip.o: crypt_zip.c + $(CCSYM) $@ crypt_zip.c + ++ obj/debugger.o: debugger.c ++ $(CCSYM) $@ debugger.c ++ + obj/dict.o: dict.c + $(CCSYM) $@ dict.c + +*** ../vim-8.1.1194/src/Make_morph.mak 2019-03-30 13:53:26.166425144 +0100 +--- src/Make_morph.mak 2019-04-21 11:18:57.688977840 +0200 +*************** +*** 31,36 **** +--- 31,37 ---- + charset.c \ + crypt.c \ + crypt_zip.c \ ++ debugger.c \ + dict.c \ + diff.c \ + digraph.c \ +*** ../vim-8.1.1194/src/Make_mvc.mak 2019-04-04 20:31:59.094873282 +0200 +--- src/Make_mvc.mak 2019-04-21 11:18:57.688977840 +0200 +*************** +*** 711,716 **** +--- 711,717 ---- + $(OUTDIR)\charset.obj \ + $(OUTDIR)\crypt.obj \ + $(OUTDIR)\crypt_zip.obj \ ++ $(OUTDIR)\debugger.obj \ + $(OUTDIR)\dict.obj \ + $(OUTDIR)\diff.obj \ + $(OUTDIR)\digraph.obj \ +*************** +*** 1367,1372 **** +--- 1368,1375 ---- + + $(OUTDIR)/crypt_zip.obj: $(OUTDIR) crypt_zip.c $(INCL) + ++ $(OUTDIR)/debugger.obj: $(OUTDIR) debugger.c $(INCL) ++ + $(OUTDIR)/dict.obj: $(OUTDIR) dict.c $(INCL) + + $(OUTDIR)/diff.obj: $(OUTDIR) diff.c $(INCL) +*************** +*** 1638,1643 **** +--- 1641,1647 ---- + proto/charset.pro \ + proto/crypt.pro \ + proto/crypt_zip.pro \ ++ proto/debugger.pro \ + proto/dict.pro \ + proto/diff.pro \ + proto/digraph.pro \ +*** ../vim-8.1.1194/src/Make_sas.mak 2019-03-30 13:53:26.166425144 +0100 +--- src/Make_sas.mak 2019-04-21 11:18:57.688977840 +0200 +*************** +*** 96,101 **** +--- 96,102 ---- + charset.c \ + crypt.c \ + crypt_zip.c \ ++ debugger.c \ + dict.c \ + diff.c \ + digraph.c \ +*************** +*** 157,162 **** +--- 158,164 ---- + charset.o \ + crypt.o \ + crypt_zip.o \ ++ debugger.o \ + dict.o \ + diff.o \ + digraph.o \ +*************** +*** 218,223 **** +--- 220,226 ---- + proto/charset.pro \ + proto/crypt.pro \ + proto/crypt_zip.pro \ ++ proto/debugger.pro \ + proto/dict.pro \ + proto/diff.pro \ + proto/digraph.pro \ +*************** +*** 340,345 **** +--- 343,350 ---- + proto/crypt.pro: crypt.c + crypt_zip.o: crypt_zip.c + proto/crypt_zip.pro: crypt_zip.c ++ debugger.o: debugger.c ++ proto/debugger.pro: debugger.c + dict.o: dict.c + proto/dict.pro: dict.c + diff.o: diff.c +*** ../vim-8.1.1194/src/Make_vms.mms 2019-03-30 13:53:26.166425144 +0100 +--- src/Make_vms.mms 2019-04-21 11:18:57.688977840 +0200 +*************** +*** 308,337 **** + $(PERL_LIB) $(PYTHON_LIB) $(TCL_LIB) $(RUBY_LIB) + + SRC = arabic.c autocmd.c beval.c blob.c blowfish.c buffer.c charset.c \ +! crypt.c crypt_zip.c dict.c diff.c digraph.c edit.c eval.c evalfunc.c \ +! ex_cmds.c ex_cmds2.c ex_docmd.c ex_eval.c ex_getln.c if_cscope.c \ +! if_xcmdsrv.c fileio.c findfile.c fold.c getchar.c hardcopy.c \ +! hashtab.c indent.c insexpand.c json.c list.c main.c mark.c menu.c \ +! mbyte.c memfile.c memline.c message.c misc1.c misc2.c move.c normal.c \ +! ops.c option.c popupmnu.c quickfix.c regexp.c search.c sha256.c sign.c \ +! spell.c spellfile.c syntax.c tag.c term.c termlib.c textprop.c ui.c \ +! undo.c userfunc.c version.c screen.c window.c os_unix.c os_vms.c \ +! pathdef.c + $(GUI_SRC) $(PERL_SRC) $(PYTHON_SRC) $(TCL_SRC) \ + $(RUBY_SRC) $(HANGULIN_SRC) $(MZSCH_SRC) $(XDIFF_SRC) + + OBJ = arabic.obj autocmd.obj beval.obj blob.obj blowfish.obj buffer.obj \ +! charset.obj crypt.obj crypt_zip.obj dict.obj diff.obj digraph.obj \ +! edit.obj eval.obj evalfunc.obj ex_cmds.obj ex_cmds2.obj ex_docmd.obj \ +! ex_eval.obj ex_getln.obj if_cscope.obj if_xcmdsrv.obj \ + fileio.obj findfile.obj fold.obj getchar.obj hardcopy.obj hashtab.obj \ + indent.obj insexpand.obj json.obj list.obj main.obj mark.obj \ + menu.obj memfile.obj memline.obj message.obj misc1.obj misc2.obj \ + move.obj mbyte.obj normal.obj ops.obj option.obj popupmnu.obj \ + quickfix.obj regexp.obj search.obj sha256.obj sign.obj spell.obj \ + spellfile.obj syntax.obj tag.obj term.obj termlib.obj textprop.obj \ +! ui.obj undo.obj userfunc.obj screen.obj version.obj window.obj \ +! os_unix.obj os_vms.obj pathdef.obj if_mzsch.obj \ + $(GUI_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(TCL_OBJ) \ + $(RUBY_OBJ) $(HANGULIN_OBJ) $(MZSCH_OBJ) $(XDIFF_OBJ) + +--- 308,337 ---- + $(PERL_LIB) $(PYTHON_LIB) $(TCL_LIB) $(RUBY_LIB) + + SRC = arabic.c autocmd.c beval.c blob.c blowfish.c buffer.c charset.c \ +! crypt.c crypt_zip.c debugger.c dict.c diff.c digraph.c edit.c eval.c \ +! evalfunc.c ex_cmds.c ex_cmds2.c ex_docmd.c ex_eval.c ex_getln.c \ +! if_cscope.c if_xcmdsrv.c fileio.c findfile.c fold.c getchar.c \ +! hardcopy.c hashtab.c indent.c insexpand.c json.c list.c main.c mark.c \ +! menu.c mbyte.c memfile.c memline.c message.c misc1.c misc2.c move.c \ +! normal.c ops.c option.c popupmnu.c quickfix.c regexp.c search.c \ +! sha256.c sign.c spell.c spellfile.c syntax.c tag.c term.c termlib.c \ +! textprop.c ui.c undo.c userfunc.c version.c screen.c window.c \ +! os_unix.c os_vms.c pathdef.c \ + $(GUI_SRC) $(PERL_SRC) $(PYTHON_SRC) $(TCL_SRC) \ + $(RUBY_SRC) $(HANGULIN_SRC) $(MZSCH_SRC) $(XDIFF_SRC) + + OBJ = arabic.obj autocmd.obj beval.obj blob.obj blowfish.obj buffer.obj \ +! charset.obj crypt.obj crypt_zip.obj debugger.obj dict.obj diff.obj \ +! digraph.obj edit.obj eval.obj evalfunc.obj ex_cmds.obj ex_cmds2.obj \ +! ex_docmd.obj ex_eval.obj ex_getln.obj if_cscope.obj if_xcmdsrv.obj \ + fileio.obj findfile.obj fold.obj getchar.obj hardcopy.obj hashtab.obj \ + indent.obj insexpand.obj json.obj list.obj main.obj mark.obj \ + menu.obj memfile.obj memline.obj message.obj misc1.obj misc2.obj \ + move.obj mbyte.obj normal.obj ops.obj option.obj popupmnu.obj \ + quickfix.obj regexp.obj search.obj sha256.obj sign.obj spell.obj \ + spellfile.obj syntax.obj tag.obj term.obj termlib.obj textprop.obj \ +! ui.obj undo.obj userfunc.obj screen.obj version.obj \ +! window.obj os_unix.obj os_vms.obj pathdef.obj if_mzsch.obj \ + $(GUI_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(TCL_OBJ) \ + $(RUBY_OBJ) $(HANGULIN_OBJ) $(MZSCH_OBJ) $(XDIFF_OBJ) + +*************** +*** 522,527 **** +--- 522,531 ---- + ascii.h keymap.h term.h macros.h option.h structs.h \ + regexp.h gui.h beval.h [.proto]gui_beval.pro alloc.h ex_cmds.h spell.h \ + proto.h globals.h ++ debugger.obj : debugger.c vim.h [.auto]config.h feature.h os_unix.h \ ++ ascii.h keymap.h term.h macros.h structs.h regexp.h \ ++ gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ ++ globals.h + dict.obj : dict.c vim.h [.auto]config.h feature.h os_unix.h \ + ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \ + beval.h [.proto]gui_beval.pro alloc.h ex_cmds.h spell.h proto.h \ +*** ../vim-8.1.1194/src/Makefile 2019-04-17 16:59:12.575688584 +0200 +--- src/Makefile 2019-04-21 11:18:57.688977840 +0200 +*************** +*** 1579,1584 **** +--- 1579,1585 ---- + charset.c \ + crypt.c \ + crypt_zip.c \ ++ debugger.c \ + dict.c \ + diff.c \ + digraph.c \ +*************** +*** 1693,1698 **** +--- 1694,1700 ---- + objects/blowfish.o \ + objects/crypt.o \ + objects/crypt_zip.o \ ++ objects/debugger.o \ + objects/dict.o \ + objects/diff.o \ + objects/digraph.o \ +*************** +*** 1820,1825 **** +--- 1822,1828 ---- + charset.pro \ + crypt.pro \ + crypt_zip.pro \ ++ debugger.pro \ + dict.pro \ + diff.pro \ + digraph.pro \ +*************** +*** 2963,2968 **** +--- 2966,2974 ---- + objects/crypt_zip.o: crypt_zip.c + $(CCC) -o $@ crypt_zip.c + ++ objects/debugger.o: debugger.c ++ $(CCC) -o $@ debugger.c ++ + objects/dict.o: dict.c + $(CCC) -o $@ dict.c + +*************** +*** 3425,3430 **** +--- 3431,3439 ---- + os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ + proto.h globals.h ++ objects/debugger.o: debugger.c vim.h protodef.h auto/config.h feature.h os_unix.h \ ++ os_mac.h ascii.h keymap.h term.h macros.h option.h beval.h structs.h \ ++ regexp.h gui.h alloc.h ex_cmds.h spell.h proto.h globals.h + objects/dict.o: dict.c vim.h protodef.h auto/config.h feature.h os_unix.h \ + auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ +*** ../vim-8.1.1194/src/debugger.c 2019-04-21 11:33:08.863781264 +0200 +--- src/debugger.c 2019-04-21 11:18:57.688977840 +0200 +*************** +*** 0 **** +--- 1,990 ---- ++ /* vi:set ts=8 sts=4 sw=4 noet: ++ * ++ * VIM - Vi IMproved by Bram Moolenaar ++ * ++ * Do ":help uganda" in Vim to read copying and usage conditions. ++ * Do ":help credits" in Vim to see a list of people who contributed. ++ * See README.txt for an overview of the Vim source code. ++ */ ++ ++ /* ++ * debugger.c: Vim script debugger functions ++ */ ++ ++ #include "vim.h" ++ ++ #if defined(FEAT_EVAL) || defined(PROTO) ++ static int debug_greedy = FALSE; /* batch mode debugging: don't save ++ and restore typeahead. */ ++ static void do_setdebugtracelevel(char_u *arg); ++ static void do_checkbacktracelevel(void); ++ static void do_showbacktrace(char_u *cmd); ++ ++ static char_u *debug_oldval = NULL; /* old and newval for debug expressions */ ++ static char_u *debug_newval = NULL; ++ static int debug_expr = 0; /* use debug_expr */ ++ ++ int ++ has_watchexpr(void) ++ { ++ return debug_expr; ++ } ++ ++ /* ++ * do_debug(): Debug mode. ++ * Repeatedly get Ex commands, until told to continue normal execution. ++ */ ++ void ++ do_debug(char_u *cmd) ++ { ++ int save_msg_scroll = msg_scroll; ++ int save_State = State; ++ int save_did_emsg = did_emsg; ++ int save_cmd_silent = cmd_silent; ++ int save_msg_silent = msg_silent; ++ int save_emsg_silent = emsg_silent; ++ int save_redir_off = redir_off; ++ tasave_T typeaheadbuf; ++ int typeahead_saved = FALSE; ++ int save_ignore_script = 0; ++ int save_ex_normal_busy; ++ int n; ++ char_u *cmdline = NULL; ++ char_u *p; ++ char *tail = NULL; ++ static int last_cmd = 0; ++ #define CMD_CONT 1 ++ #define CMD_NEXT 2 ++ #define CMD_STEP 3 ++ #define CMD_FINISH 4 ++ #define CMD_QUIT 5 ++ #define CMD_INTERRUPT 6 ++ #define CMD_BACKTRACE 7 ++ #define CMD_FRAME 8 ++ #define CMD_UP 9 ++ #define CMD_DOWN 10 ++ ++ #ifdef ALWAYS_USE_GUI ++ /* Can't do this when there is no terminal for input/output. */ ++ if (!gui.in_use) ++ { ++ /* Break as soon as possible. */ ++ debug_break_level = 9999; ++ return; ++ } ++ #endif ++ ++ /* Make sure we are in raw mode and start termcap mode. Might have side ++ * effects... */ ++ settmode(TMODE_RAW); ++ starttermcap(); ++ ++ ++RedrawingDisabled; /* don't redisplay the window */ ++ ++no_wait_return; /* don't wait for return */ ++ did_emsg = FALSE; /* don't use error from debugged stuff */ ++ cmd_silent = FALSE; /* display commands */ ++ msg_silent = FALSE; /* display messages */ ++ emsg_silent = FALSE; /* display error messages */ ++ redir_off = TRUE; /* don't redirect debug commands */ ++ ++ State = NORMAL; ++ debug_mode = TRUE; ++ ++ if (!debug_did_msg) ++ msg(_("Entering Debug mode. Type \"cont\" to continue.")); ++ if (debug_oldval != NULL) ++ { ++ smsg(_("Oldval = \"%s\""), debug_oldval); ++ vim_free(debug_oldval); ++ debug_oldval = NULL; ++ } ++ if (debug_newval != NULL) ++ { ++ smsg(_("Newval = \"%s\""), debug_newval); ++ vim_free(debug_newval); ++ debug_newval = NULL; ++ } ++ if (sourcing_name != NULL) ++ msg((char *)sourcing_name); ++ if (sourcing_lnum != 0) ++ smsg(_("line %ld: %s"), (long)sourcing_lnum, cmd); ++ else ++ smsg(_("cmd: %s"), cmd); ++ /* ++ * Repeat getting a command and executing it. ++ */ ++ for (;;) ++ { ++ msg_scroll = TRUE; ++ need_wait_return = FALSE; ++ ++ /* Save the current typeahead buffer and replace it with an empty one. ++ * This makes sure we get input from the user here and don't interfere ++ * with the commands being executed. Reset "ex_normal_busy" to avoid ++ * the side effects of using ":normal". Save the stuff buffer and make ++ * it empty. Set ignore_script to avoid reading from script input. */ ++ save_ex_normal_busy = ex_normal_busy; ++ ex_normal_busy = 0; ++ if (!debug_greedy) ++ { ++ save_typeahead(&typeaheadbuf); ++ typeahead_saved = TRUE; ++ save_ignore_script = ignore_script; ++ ignore_script = TRUE; ++ } ++ ++ vim_free(cmdline); ++ cmdline = getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL); ++ ++ if (typeahead_saved) ++ { ++ restore_typeahead(&typeaheadbuf); ++ ignore_script = save_ignore_script; ++ } ++ ex_normal_busy = save_ex_normal_busy; ++ ++ cmdline_row = msg_row; ++ msg_starthere(); ++ if (cmdline != NULL) ++ { ++ /* If this is a debug command, set "last_cmd". ++ * If not, reset "last_cmd". ++ * For a blank line use previous command. */ ++ p = skipwhite(cmdline); ++ if (*p != NUL) ++ { ++ switch (*p) ++ { ++ case 'c': last_cmd = CMD_CONT; ++ tail = "ont"; ++ break; ++ case 'n': last_cmd = CMD_NEXT; ++ tail = "ext"; ++ break; ++ case 's': last_cmd = CMD_STEP; ++ tail = "tep"; ++ break; ++ case 'f': ++ last_cmd = 0; ++ if (p[1] == 'r') ++ { ++ last_cmd = CMD_FRAME; ++ tail = "rame"; ++ } ++ else ++ { ++ last_cmd = CMD_FINISH; ++ tail = "inish"; ++ } ++ break; ++ case 'q': last_cmd = CMD_QUIT; ++ tail = "uit"; ++ break; ++ case 'i': last_cmd = CMD_INTERRUPT; ++ tail = "nterrupt"; ++ break; ++ case 'b': last_cmd = CMD_BACKTRACE; ++ if (p[1] == 't') ++ tail = "t"; ++ else ++ tail = "acktrace"; ++ break; ++ case 'w': last_cmd = CMD_BACKTRACE; ++ tail = "here"; ++ break; ++ case 'u': last_cmd = CMD_UP; ++ tail = "p"; ++ break; ++ case 'd': last_cmd = CMD_DOWN; ++ tail = "own"; ++ break; ++ default: last_cmd = 0; ++ } ++ if (last_cmd != 0) ++ { ++ /* Check that the tail matches. */ ++ ++p; ++ while (*p != NUL && *p == *tail) ++ { ++ ++p; ++ ++tail; ++ } ++ if (ASCII_ISALPHA(*p) && last_cmd != CMD_FRAME) ++ last_cmd = 0; ++ } ++ } ++ ++ if (last_cmd != 0) ++ { ++ /* Execute debug command: decided where to break next and ++ * return. */ ++ switch (last_cmd) ++ { ++ case CMD_CONT: ++ debug_break_level = -1; ++ break; ++ case CMD_NEXT: ++ debug_break_level = ex_nesting_level; ++ break; ++ case CMD_STEP: ++ debug_break_level = 9999; ++ break; ++ case CMD_FINISH: ++ debug_break_level = ex_nesting_level - 1; ++ break; ++ case CMD_QUIT: ++ got_int = TRUE; ++ debug_break_level = -1; ++ break; ++ case CMD_INTERRUPT: ++ got_int = TRUE; ++ debug_break_level = 9999; ++ /* Do not repeat ">interrupt" cmd, continue stepping. */ ++ last_cmd = CMD_STEP; ++ break; ++ case CMD_BACKTRACE: ++ do_showbacktrace(cmd); ++ continue; ++ case CMD_FRAME: ++ if (*p == NUL) ++ { ++ do_showbacktrace(cmd); ++ } ++ else ++ { ++ p = skipwhite(p); ++ do_setdebugtracelevel(p); ++ } ++ continue; ++ case CMD_UP: ++ debug_backtrace_level++; ++ do_checkbacktracelevel(); ++ continue; ++ case CMD_DOWN: ++ debug_backtrace_level--; ++ do_checkbacktracelevel(); ++ continue; ++ } ++ /* Going out reset backtrace_level */ ++ debug_backtrace_level = 0; ++ break; ++ } ++ ++ /* don't debug this command */ ++ n = debug_break_level; ++ debug_break_level = -1; ++ (void)do_cmdline(cmdline, getexline, NULL, ++ DOCMD_VERBOSE|DOCMD_EXCRESET); ++ debug_break_level = n; ++ } ++ lines_left = Rows - 1; ++ } ++ vim_free(cmdline); ++ ++ --RedrawingDisabled; ++ --no_wait_return; ++ redraw_all_later(NOT_VALID); ++ need_wait_return = FALSE; ++ msg_scroll = save_msg_scroll; ++ lines_left = Rows - 1; ++ State = save_State; ++ debug_mode = FALSE; ++ did_emsg = save_did_emsg; ++ cmd_silent = save_cmd_silent; ++ msg_silent = save_msg_silent; ++ emsg_silent = save_emsg_silent; ++ redir_off = save_redir_off; ++ ++ /* Only print the message again when typing a command before coming back ++ * here. */ ++ debug_did_msg = TRUE; ++ } ++ ++ static int ++ get_maxbacktrace_level(void) ++ { ++ char *p, *q; ++ int maxbacktrace = 0; ++ ++ if (sourcing_name != NULL) ++ { ++ p = (char *)sourcing_name; ++ while ((q = strstr(p, "..")) != NULL) ++ { ++ p = q + 2; ++ maxbacktrace++; ++ } ++ } ++ return maxbacktrace; ++ } ++ ++ static void ++ do_setdebugtracelevel(char_u *arg) ++ { ++ int level; ++ ++ level = atoi((char *)arg); ++ if (*arg == '+' || level < 0) ++ debug_backtrace_level += level; ++ else ++ debug_backtrace_level = level; ++ ++ do_checkbacktracelevel(); ++ } ++ ++ static void ++ do_checkbacktracelevel(void) ++ { ++ if (debug_backtrace_level < 0) ++ { ++ debug_backtrace_level = 0; ++ msg(_("frame is zero")); ++ } ++ else ++ { ++ int max = get_maxbacktrace_level(); ++ ++ if (debug_backtrace_level > max) ++ { ++ debug_backtrace_level = max; ++ smsg(_("frame at highest level: %d"), max); ++ } ++ } ++ } ++ ++ static void ++ do_showbacktrace(char_u *cmd) ++ { ++ char *cur; ++ char *next; ++ int i = 0; ++ int max = get_maxbacktrace_level(); ++ ++ if (sourcing_name != NULL) ++ { ++ cur = (char *)sourcing_name; ++ while (!got_int) ++ { ++ next = strstr(cur, ".."); ++ if (next != NULL) ++ *next = NUL; ++ if (i == max - debug_backtrace_level) ++ smsg("->%d %s", max - i, cur); ++ else ++ smsg(" %d %s", max - i, cur); ++ ++i; ++ if (next == NULL) ++ break; ++ *next = '.'; ++ cur = next + 2; ++ } ++ } ++ if (sourcing_lnum != 0) ++ smsg(_("line %ld: %s"), (long)sourcing_lnum, cmd); ++ else ++ smsg(_("cmd: %s"), cmd); ++ } ++ ++ /* ++ * ":debug". ++ */ ++ void ++ ex_debug(exarg_T *eap) ++ { ++ int debug_break_level_save = debug_break_level; ++ ++ debug_break_level = 9999; ++ do_cmdline_cmd(eap->arg); ++ debug_break_level = debug_break_level_save; ++ } ++ ++ static char_u *debug_breakpoint_name = NULL; ++ static linenr_T debug_breakpoint_lnum; ++ ++ /* ++ * When debugging or a breakpoint is set on a skipped command, no debug prompt ++ * is shown by do_one_cmd(). This situation is indicated by debug_skipped, and ++ * debug_skipped_name is then set to the source name in the breakpoint case. If ++ * a skipped command decides itself that a debug prompt should be displayed, it ++ * can do so by calling dbg_check_skipped(). ++ */ ++ static int debug_skipped; ++ static char_u *debug_skipped_name; ++ ++ /* ++ * Go to debug mode when a breakpoint was encountered or "ex_nesting_level" is ++ * at or below the break level. But only when the line is actually ++ * executed. Return TRUE and set breakpoint_name for skipped commands that ++ * decide to execute something themselves. ++ * Called from do_one_cmd() before executing a command. ++ */ ++ void ++ dbg_check_breakpoint(exarg_T *eap) ++ { ++ char_u *p; ++ ++ debug_skipped = FALSE; ++ if (debug_breakpoint_name != NULL) ++ { ++ if (!eap->skip) ++ { ++ /* replace K_SNR with "<SNR>" */ ++ if (debug_breakpoint_name[0] == K_SPECIAL ++ && debug_breakpoint_name[1] == KS_EXTRA ++ && debug_breakpoint_name[2] == (int)KE_SNR) ++ p = (char_u *)"<SNR>"; ++ else ++ p = (char_u *)""; ++ smsg(_("Breakpoint in \"%s%s\" line %ld"), ++ p, ++ debug_breakpoint_name + (*p == NUL ? 0 : 3), ++ (long)debug_breakpoint_lnum); ++ debug_breakpoint_name = NULL; ++ do_debug(eap->cmd); ++ } ++ else ++ { ++ debug_skipped = TRUE; ++ debug_skipped_name = debug_breakpoint_name; ++ debug_breakpoint_name = NULL; ++ } ++ } ++ else if (ex_nesting_level <= debug_break_level) ++ { ++ if (!eap->skip) ++ do_debug(eap->cmd); ++ else ++ { ++ debug_skipped = TRUE; ++ debug_skipped_name = NULL; ++ } ++ } ++ } ++ ++ /* ++ * Go to debug mode if skipped by dbg_check_breakpoint() because eap->skip was ++ * set. Return TRUE when the debug mode is entered this time. ++ */ ++ int ++ dbg_check_skipped(exarg_T *eap) ++ { ++ int prev_got_int; ++ ++ if (debug_skipped) ++ { ++ /* ++ * Save the value of got_int and reset it. We don't want a previous ++ * interruption cause flushing the input buffer. ++ */ ++ prev_got_int = got_int; ++ got_int = FALSE; ++ debug_breakpoint_name = debug_skipped_name; ++ /* eap->skip is TRUE */ ++ eap->skip = FALSE; ++ (void)dbg_check_breakpoint(eap); ++ eap->skip = TRUE; ++ got_int |= prev_got_int; ++ return TRUE; ++ } ++ 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, 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 */ ++ #ifdef FEAT_EVAL ++ typval_T *dbg_val; /* last result of watchexpression */ ++ #endif ++ 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]) ++ static int last_breakp = 0; /* nr of last defined breakpoint */ ++ ++ #ifdef FEAT_PROFILE ++ /* Profiling uses file and func names similar to breakpoints. */ ++ static garray_T prof_ga = {0, 0, sizeof(struct debuggy), 4, NULL}; ++ #endif ++ #define DBG_FUNC 1 ++ #define DBG_FILE 2 ++ #define DBG_EXPR 3 ++ ++ static linenr_T debuggy_find(int file,char_u *fname, linenr_T after, garray_T *gap, int *fp); ++ ++ /* ++ * 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. ++ * Returns FAIL for failure. ++ */ ++ static int ++ dbg_parsearg( ++ char_u *arg, ++ garray_T *gap) /* either &dbg_breakp or &prof_ga */ ++ { ++ char_u *p = arg; ++ char_u *q; ++ struct debuggy *bp; ++ int here = FALSE; ++ ++ if (ga_grow(gap, 1) == FAIL) ++ return FAIL; ++ bp = &DEBUGGY(gap, gap->ga_len); ++ ++ /* Find "func" or "file". */ ++ if (STRNCMP(p, "func", 4) == 0) ++ bp->dbg_type = DBG_FUNC; ++ else if (STRNCMP(p, "file", 4) == 0) ++ bp->dbg_type = DBG_FILE; ++ else if ( ++ #ifdef FEAT_PROFILE ++ gap != &prof_ga && ++ #endif ++ STRNCMP(p, "here", 4) == 0) ++ { ++ if (curbuf->b_ffname == NULL) ++ { ++ emsg(_(e_noname)); ++ return FAIL; ++ } ++ bp->dbg_type = DBG_FILE; ++ here = TRUE; ++ } ++ else if ( ++ #ifdef FEAT_PROFILE ++ gap != &prof_ga && ++ #endif ++ STRNCMP(p, "expr", 4) == 0) ++ bp->dbg_type = DBG_EXPR; ++ else ++ { ++ semsg(_(e_invarg2), p); ++ return FAIL; ++ } ++ p = skipwhite(p + 4); ++ ++ /* Find optional line number. */ ++ if (here) ++ bp->dbg_lnum = curwin->w_cursor.lnum; ++ else if ( ++ #ifdef FEAT_PROFILE ++ gap != &prof_ga && ++ #endif ++ VIM_ISDIGIT(*p)) ++ { ++ bp->dbg_lnum = getdigits(&p); ++ p = skipwhite(p); ++ } ++ else ++ bp->dbg_lnum = 0; ++ ++ /* Find the function or file name. Don't accept a function name with (). */ ++ if ((!here && *p == NUL) ++ || (here && *p != NUL) ++ || (bp->dbg_type == DBG_FUNC && strstr((char *)p, "()") != NULL)) ++ { ++ semsg(_(e_invarg2), arg); ++ return FAIL; ++ } ++ ++ if (bp->dbg_type == DBG_FUNC) ++ 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); ++ if (bp->dbg_name != NULL) ++ bp->dbg_val = eval_expr(bp->dbg_name, NULL); ++ } ++ 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 ++ * "~/dir". */ ++ q = expand_env_save(p); ++ if (q == NULL) ++ return FAIL; ++ p = expand_env_save(q); ++ vim_free(q); ++ if (p == NULL) ++ return FAIL; ++ if (*p != '*') ++ { ++ bp->dbg_name = fix_fname(p); ++ vim_free(p); ++ } ++ else ++ bp->dbg_name = p; ++ } ++ ++ if (bp->dbg_name == NULL) ++ return FAIL; ++ return OK; ++ } ++ ++ /* ++ * ":breakadd". Also used for ":profile". ++ */ ++ void ++ ex_breakadd(exarg_T *eap) ++ { ++ struct debuggy *bp; ++ char_u *pat; ++ garray_T *gap; ++ ++ gap = &dbg_breakp; ++ #ifdef FEAT_PROFILE ++ if (eap->cmdidx == CMD_profile) ++ gap = &prof_ga; ++ #endif ++ ++ if (dbg_parsearg(eap->arg, gap) == OK) ++ { ++ bp = &DEBUGGY(gap, gap->ga_len); ++ bp->dbg_forceit = eap->forceit; ++ ++ if (bp->dbg_type != DBG_EXPR) ++ { ++ 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); ++ vim_free(pat); ++ } ++ if (pat == NULL || bp->dbg_prog == NULL) ++ vim_free(bp->dbg_name); ++ else ++ { ++ if (bp->dbg_lnum == 0) /* default line number is 1 */ ++ bp->dbg_lnum = 1; ++ #ifdef FEAT_PROFILE ++ if (eap->cmdidx != CMD_profile) ++ #endif ++ { ++ DEBUGGY(gap, gap->ga_len).dbg_nr = ++last_breakp; ++ ++debug_tick; ++ } ++ ++gap->ga_len; ++ } ++ } ++ else ++ { ++ /* DBG_EXPR */ ++ DEBUGGY(gap, gap->ga_len++).dbg_nr = ++last_breakp; ++ ++debug_tick; ++ } ++ } ++ } ++ ++ /* ++ * ":debuggreedy". ++ */ ++ void ++ ex_debuggreedy(exarg_T *eap) ++ { ++ if (eap->addr_count == 0 || eap->line2 != 0) ++ debug_greedy = TRUE; ++ else ++ debug_greedy = FALSE; ++ } ++ ++ /* ++ * ":breakdel" and ":profdel". ++ */ ++ void ++ ex_breakdel(exarg_T *eap) ++ { ++ struct debuggy *bp, *bpi; ++ int nr; ++ int todel = -1; ++ int del_all = FALSE; ++ int i; ++ linenr_T best_lnum = 0; ++ garray_T *gap; ++ ++ gap = &dbg_breakp; ++ if (eap->cmdidx == CMD_profdel) ++ { ++ #ifdef FEAT_PROFILE ++ gap = &prof_ga; ++ #else ++ ex_ni(eap); ++ return; ++ #endif ++ } ++ ++ if (vim_isdigit(*eap->arg)) ++ { ++ /* ":breakdel {nr}" */ ++ nr = atol((char *)eap->arg); ++ for (i = 0; i < gap->ga_len; ++i) ++ if (DEBUGGY(gap, i).dbg_nr == nr) ++ { ++ todel = i; ++ break; ++ } ++ } ++ else if (*eap->arg == '*') ++ { ++ todel = 0; ++ del_all = TRUE; ++ } ++ else ++ { ++ /* ":breakdel {func|file|expr} [lnum] {name}" */ ++ if (dbg_parsearg(eap->arg, gap) == FAIL) ++ return; ++ bp = &DEBUGGY(gap, gap->ga_len); ++ for (i = 0; i < gap->ga_len; ++i) ++ { ++ 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 ++ || (bp->dbg_lnum == 0 ++ && (best_lnum == 0 ++ || bpi->dbg_lnum < best_lnum)))) ++ { ++ todel = i; ++ best_lnum = bpi->dbg_lnum; ++ } ++ } ++ vim_free(bp->dbg_name); ++ } ++ ++ if (todel < 0) ++ semsg(_("E161: Breakpoint not found: %s"), eap->arg); ++ else ++ { ++ while (gap->ga_len > 0) ++ { ++ vim_free(DEBUGGY(gap, todel).dbg_name); ++ #ifdef FEAT_EVAL ++ if (DEBUGGY(gap, todel).dbg_type == DBG_EXPR ++ && DEBUGGY(gap, todel).dbg_val != NULL) ++ free_tv(DEBUGGY(gap, todel).dbg_val); ++ #endif ++ vim_regfree(DEBUGGY(gap, todel).dbg_prog); ++ --gap->ga_len; ++ if (todel < gap->ga_len) ++ mch_memmove(&DEBUGGY(gap, todel), &DEBUGGY(gap, todel + 1), ++ (gap->ga_len - todel) * sizeof(struct debuggy)); ++ #ifdef FEAT_PROFILE ++ if (eap->cmdidx == CMD_breakdel) ++ #endif ++ ++debug_tick; ++ if (!del_all) ++ break; ++ } ++ ++ /* If all breakpoints were removed clear the array. */ ++ if (gap->ga_len == 0) ++ ga_clear(gap); ++ } ++ } ++ ++ /* ++ * ":breaklist". ++ */ ++ void ++ ex_breaklist(exarg_T *eap UNUSED) ++ { ++ struct debuggy *bp; ++ int i; ++ ++ if (dbg_breakp.ga_len == 0) ++ msg(_("No breakpoints defined")); ++ else ++ for (i = 0; i < dbg_breakp.ga_len; ++i) ++ { ++ bp = &BREAKP(i); ++ if (bp->dbg_type == DBG_FILE) ++ home_replace(NULL, bp->dbg_name, NameBuff, MAXPATHL, TRUE); ++ if (bp->dbg_type != DBG_EXPR) ++ smsg(_("%3d %s %s line %ld"), ++ bp->dbg_nr, ++ bp->dbg_type == DBG_FUNC ? "func" : "file", ++ bp->dbg_type == DBG_FUNC ? bp->dbg_name : NameBuff, ++ (long)bp->dbg_lnum); ++ else ++ smsg(_("%3d expr %s"), ++ bp->dbg_nr, bp->dbg_name); ++ } ++ } ++ ++ /* ++ * Find a breakpoint for a function or sourced file. ++ * Returns line number at which to break; zero when no matching breakpoint. ++ */ ++ linenr_T ++ dbg_find_breakpoint( ++ int file, /* TRUE for a file, FALSE for a function */ ++ char_u *fname, /* file or function name */ ++ linenr_T after) /* after this line number */ ++ { ++ return debuggy_find(file, fname, after, &dbg_breakp, NULL); ++ } ++ ++ #if defined(FEAT_PROFILE) || defined(PROTO) ++ /* ++ * Return TRUE if profiling is on for a function or sourced file. ++ */ ++ int ++ has_profiling( ++ int file, /* TRUE for a file, FALSE for a function */ ++ char_u *fname, /* file or function name */ ++ int *fp) /* return: forceit */ ++ { ++ return (debuggy_find(file, fname, (linenr_T)0, &prof_ga, fp) ++ != (linenr_T)0); ++ } ++ #endif ++ ++ /* ++ * Common code for dbg_find_breakpoint() and has_profiling(). ++ */ ++ static linenr_T ++ debuggy_find( ++ int file, /* TRUE for a file, FALSE for a function */ ++ char_u *fname, /* file or function name */ ++ linenr_T after, /* after this line number */ ++ garray_T *gap, /* either &dbg_breakp or &prof_ga */ ++ int *fp) /* if not NULL: return forceit */ ++ { ++ struct debuggy *bp; ++ int i; ++ linenr_T lnum = 0; ++ char_u *name = fname; ++ int prev_got_int; ++ ++ /* Return quickly when there are no breakpoints. */ ++ if (gap->ga_len == 0) ++ return (linenr_T)0; ++ ++ /* Replace K_SNR in function name with "<SNR>". */ ++ if (!file && fname[0] == K_SPECIAL) ++ { ++ name = alloc((unsigned)STRLEN(fname) + 3); ++ if (name == NULL) ++ name = fname; ++ else ++ { ++ STRCPY(name, "<SNR>"); ++ STRCPY(name + 5, fname + 3); ++ } ++ } ++ ++ for (i = 0; i < gap->ga_len; ++i) ++ { ++ /* Skip entries that are not useful or are for a line that is beyond ++ * an already found breakpoint. */ ++ bp = &DEBUGGY(gap, i); ++ if (((bp->dbg_type == DBG_FILE) == file && ++ bp->dbg_type != DBG_EXPR && ( ++ #ifdef FEAT_PROFILE ++ gap == &prof_ga || ++ #endif ++ (bp->dbg_lnum > after && (lnum == 0 || bp->dbg_lnum < lnum))))) ++ { ++ /* ++ * Save the value of got_int and reset it. We don't want a ++ * previous interruption cancel matching, only hitting CTRL-C ++ * 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)) ++ { ++ lnum = bp->dbg_lnum; ++ if (fp != NULL) ++ *fp = bp->dbg_forceit; ++ } ++ got_int |= prev_got_int; ++ } ++ #ifdef FEAT_EVAL ++ else if (bp->dbg_type == DBG_EXPR) ++ { ++ typval_T *tv; ++ int line = FALSE; ++ ++ prev_got_int = got_int; ++ got_int = FALSE; ++ ++ tv = eval_expr(bp->dbg_name, NULL); ++ 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 ++ { ++ if (typval_compare(tv, bp->dbg_val, TYPE_EQUAL, ++ TRUE, FALSE) == OK ++ && tv->vval.v_number == FALSE) ++ { ++ typval_T *v; ++ ++ line = TRUE; ++ debug_oldval = typval_tostring(bp->dbg_val); ++ /* Need to evaluate again, typval_compare() overwrites ++ * "tv". */ ++ v = eval_expr(bp->dbg_name, NULL); ++ debug_newval = typval_tostring(v); ++ free_tv(bp->dbg_val); ++ bp->dbg_val = v; ++ } ++ free_tv(tv); ++ } ++ } ++ else if (bp->dbg_val != NULL) ++ { ++ debug_oldval = typval_tostring(bp->dbg_val); ++ debug_newval = typval_tostring(NULL); ++ free_tv(bp->dbg_val); ++ bp->dbg_val = NULL; ++ line = TRUE; ++ } ++ ++ if (line) ++ { ++ lnum = after > 0 ? after : 1; ++ break; ++ } ++ ++ got_int |= prev_got_int; ++ } ++ #endif ++ } ++ if (name != fname) ++ vim_free(name); ++ ++ return lnum; ++ } ++ ++ /* ++ * Called when a breakpoint was encountered. ++ */ ++ void ++ dbg_breakpoint(char_u *name, linenr_T lnum) ++ { ++ /* We need to check if this line is actually executed in do_one_cmd() */ ++ debug_breakpoint_name = name; ++ debug_breakpoint_lnum = lnum; ++ } ++ #endif +*** ../vim-8.1.1194/src/ex_cmds2.c 2019-04-20 14:39:42.796386124 +0200 +--- src/ex_cmds2.c 2019-04-21 11:18:57.688977840 +0200 +*************** +*** 66,1046 **** + #endif + + #if defined(FEAT_EVAL) || defined(PROTO) +- static int debug_greedy = FALSE; /* batch mode debugging: don't save +- and restore typeahead. */ +- static void do_setdebugtracelevel(char_u *arg); +- static void do_checkbacktracelevel(void); +- static void do_showbacktrace(char_u *cmd); +- +- static char_u *debug_oldval = NULL; /* old and newval for debug expressions */ +- static char_u *debug_newval = NULL; +- static int debug_expr = 0; /* use debug_expr */ +- +- int +- has_watchexpr(void) +- { +- return debug_expr; +- } +- +- /* +- * do_debug(): Debug mode. +- * Repeatedly get Ex commands, until told to continue normal execution. +- */ +- void +- do_debug(char_u *cmd) +- { +- int save_msg_scroll = msg_scroll; +- int save_State = State; +- int save_did_emsg = did_emsg; +- int save_cmd_silent = cmd_silent; +- int save_msg_silent = msg_silent; +- int save_emsg_silent = emsg_silent; +- int save_redir_off = redir_off; +- tasave_T typeaheadbuf; +- int typeahead_saved = FALSE; +- int save_ignore_script = 0; +- int save_ex_normal_busy; +- int n; +- char_u *cmdline = NULL; +- char_u *p; +- char *tail = NULL; +- static int last_cmd = 0; +- #define CMD_CONT 1 +- #define CMD_NEXT 2 +- #define CMD_STEP 3 +- #define CMD_FINISH 4 +- #define CMD_QUIT 5 +- #define CMD_INTERRUPT 6 +- #define CMD_BACKTRACE 7 +- #define CMD_FRAME 8 +- #define CMD_UP 9 +- #define CMD_DOWN 10 +- +- #ifdef ALWAYS_USE_GUI +- /* Can't do this when there is no terminal for input/output. */ +- if (!gui.in_use) +- { +- /* Break as soon as possible. */ +- debug_break_level = 9999; +- return; +- } +- #endif +- +- /* Make sure we are in raw mode and start termcap mode. Might have side +- * effects... */ +- settmode(TMODE_RAW); +- starttermcap(); +- +- ++RedrawingDisabled; /* don't redisplay the window */ +- ++no_wait_return; /* don't wait for return */ +- did_emsg = FALSE; /* don't use error from debugged stuff */ +- cmd_silent = FALSE; /* display commands */ +- msg_silent = FALSE; /* display messages */ +- emsg_silent = FALSE; /* display error messages */ +- redir_off = TRUE; /* don't redirect debug commands */ +- +- State = NORMAL; +- debug_mode = TRUE; +- +- if (!debug_did_msg) +- msg(_("Entering Debug mode. Type \"cont\" to continue.")); +- if (debug_oldval != NULL) +- { +- smsg(_("Oldval = \"%s\""), debug_oldval); +- vim_free(debug_oldval); +- debug_oldval = NULL; +- } +- if (debug_newval != NULL) +- { +- smsg(_("Newval = \"%s\""), debug_newval); +- vim_free(debug_newval); +- debug_newval = NULL; +- } +- if (sourcing_name != NULL) +- msg((char *)sourcing_name); +- if (sourcing_lnum != 0) +- smsg(_("line %ld: %s"), (long)sourcing_lnum, cmd); +- else +- smsg(_("cmd: %s"), cmd); +- /* +- * Repeat getting a command and executing it. +- */ +- for (;;) +- { +- msg_scroll = TRUE; +- need_wait_return = FALSE; +- +- /* Save the current typeahead buffer and replace it with an empty one. +- * This makes sure we get input from the user here and don't interfere +- * with the commands being executed. Reset "ex_normal_busy" to avoid +- * the side effects of using ":normal". Save the stuff buffer and make +- * it empty. Set ignore_script to avoid reading from script input. */ +- save_ex_normal_busy = ex_normal_busy; +- ex_normal_busy = 0; +- if (!debug_greedy) +- { +- save_typeahead(&typeaheadbuf); +- typeahead_saved = TRUE; +- save_ignore_script = ignore_script; +- ignore_script = TRUE; +- } +- +- vim_free(cmdline); +- cmdline = getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL); +- +- if (typeahead_saved) +- { +- restore_typeahead(&typeaheadbuf); +- ignore_script = save_ignore_script; +- } +- ex_normal_busy = save_ex_normal_busy; +- +- cmdline_row = msg_row; +- msg_starthere(); +- if (cmdline != NULL) +- { +- /* If this is a debug command, set "last_cmd". +- * If not, reset "last_cmd". +- * For a blank line use previous command. */ +- p = skipwhite(cmdline); +- if (*p != NUL) +- { +- switch (*p) +- { +- case 'c': last_cmd = CMD_CONT; +- tail = "ont"; +- break; +- case 'n': last_cmd = CMD_NEXT; +- tail = "ext"; +- break; +- case 's': last_cmd = CMD_STEP; +- tail = "tep"; +- break; +- case 'f': +- last_cmd = 0; +- if (p[1] == 'r') +- { +- last_cmd = CMD_FRAME; +- tail = "rame"; +- } +- else +- { +- last_cmd = CMD_FINISH; +- tail = "inish"; +- } +- break; +- case 'q': last_cmd = CMD_QUIT; +- tail = "uit"; +- break; +- case 'i': last_cmd = CMD_INTERRUPT; +- tail = "nterrupt"; +- break; +- case 'b': last_cmd = CMD_BACKTRACE; +- if (p[1] == 't') +- tail = "t"; +- else +- tail = "acktrace"; +- break; +- case 'w': last_cmd = CMD_BACKTRACE; +- tail = "here"; +- break; +- case 'u': last_cmd = CMD_UP; +- tail = "p"; +- break; +- case 'd': last_cmd = CMD_DOWN; +- tail = "own"; +- break; +- default: last_cmd = 0; +- } +- if (last_cmd != 0) +- { +- /* Check that the tail matches. */ +- ++p; +- while (*p != NUL && *p == *tail) +- { +- ++p; +- ++tail; +- } +- if (ASCII_ISALPHA(*p) && last_cmd != CMD_FRAME) +- last_cmd = 0; +- } +- } +- +- if (last_cmd != 0) +- { +- /* Execute debug command: decided where to break next and +- * return. */ +- switch (last_cmd) +- { +- case CMD_CONT: +- debug_break_level = -1; +- break; +- case CMD_NEXT: +- debug_break_level = ex_nesting_level; +- break; +- case CMD_STEP: +- debug_break_level = 9999; +- break; +- case CMD_FINISH: +- debug_break_level = ex_nesting_level - 1; +- break; +- case CMD_QUIT: +- got_int = TRUE; +- debug_break_level = -1; +- break; +- case CMD_INTERRUPT: +- got_int = TRUE; +- debug_break_level = 9999; +- /* Do not repeat ">interrupt" cmd, continue stepping. */ +- last_cmd = CMD_STEP; +- break; +- case CMD_BACKTRACE: +- do_showbacktrace(cmd); +- continue; +- case CMD_FRAME: +- if (*p == NUL) +- { +- do_showbacktrace(cmd); +- } +- else +- { +- p = skipwhite(p); +- do_setdebugtracelevel(p); +- } +- continue; +- case CMD_UP: +- debug_backtrace_level++; +- do_checkbacktracelevel(); +- continue; +- case CMD_DOWN: +- debug_backtrace_level--; +- do_checkbacktracelevel(); +- continue; +- } +- /* Going out reset backtrace_level */ +- debug_backtrace_level = 0; +- break; +- } +- +- /* don't debug this command */ +- n = debug_break_level; +- debug_break_level = -1; +- (void)do_cmdline(cmdline, getexline, NULL, +- DOCMD_VERBOSE|DOCMD_EXCRESET); +- debug_break_level = n; +- } +- lines_left = Rows - 1; +- } +- vim_free(cmdline); +- +- --RedrawingDisabled; +- --no_wait_return; +- redraw_all_later(NOT_VALID); +- need_wait_return = FALSE; +- msg_scroll = save_msg_scroll; +- lines_left = Rows - 1; +- State = save_State; +- debug_mode = FALSE; +- did_emsg = save_did_emsg; +- cmd_silent = save_cmd_silent; +- msg_silent = save_msg_silent; +- emsg_silent = save_emsg_silent; +- redir_off = save_redir_off; +- +- /* Only print the message again when typing a command before coming back +- * here. */ +- debug_did_msg = TRUE; +- } +- +- static int +- get_maxbacktrace_level(void) +- { +- char *p, *q; +- int maxbacktrace = 0; +- +- if (sourcing_name != NULL) +- { +- p = (char *)sourcing_name; +- while ((q = strstr(p, "..")) != NULL) +- { +- p = q + 2; +- maxbacktrace++; +- } +- } +- return maxbacktrace; +- } +- +- static void +- do_setdebugtracelevel(char_u *arg) +- { +- int level; +- +- level = atoi((char *)arg); +- if (*arg == '+' || level < 0) +- debug_backtrace_level += level; +- else +- debug_backtrace_level = level; +- +- do_checkbacktracelevel(); +- } +- +- static void +- do_checkbacktracelevel(void) +- { +- if (debug_backtrace_level < 0) +- { +- debug_backtrace_level = 0; +- msg(_("frame is zero")); +- } +- else +- { +- int max = get_maxbacktrace_level(); +- +- if (debug_backtrace_level > max) +- { +- debug_backtrace_level = max; +- smsg(_("frame at highest level: %d"), max); +- } +- } +- } +- +- static void +- do_showbacktrace(char_u *cmd) +- { +- char *cur; +- char *next; +- int i = 0; +- int max = get_maxbacktrace_level(); +- +- if (sourcing_name != NULL) +- { +- cur = (char *)sourcing_name; +- while (!got_int) +- { +- next = strstr(cur, ".."); +- if (next != NULL) +- *next = NUL; +- if (i == max - debug_backtrace_level) +- smsg("->%d %s", max - i, cur); +- else +- smsg(" %d %s", max - i, cur); +- ++i; +- if (next == NULL) +- break; +- *next = '.'; +- cur = next + 2; +- } +- } +- if (sourcing_lnum != 0) +- smsg(_("line %ld: %s"), (long)sourcing_lnum, cmd); +- else +- smsg(_("cmd: %s"), cmd); +- } +- +- /* +- * ":debug". +- */ +- void +- ex_debug(exarg_T *eap) +- { +- int debug_break_level_save = debug_break_level; +- +- debug_break_level = 9999; +- do_cmdline_cmd(eap->arg); +- debug_break_level = debug_break_level_save; +- } +- +- static char_u *debug_breakpoint_name = NULL; +- static linenr_T debug_breakpoint_lnum; +- +- /* +- * When debugging or a breakpoint is set on a skipped command, no debug prompt +- * is shown by do_one_cmd(). This situation is indicated by debug_skipped, and +- * debug_skipped_name is then set to the source name in the breakpoint case. If +- * a skipped command decides itself that a debug prompt should be displayed, it +- * can do so by calling dbg_check_skipped(). +- */ +- static int debug_skipped; +- static char_u *debug_skipped_name; +- +- /* +- * Go to debug mode when a breakpoint was encountered or "ex_nesting_level" is +- * at or below the break level. But only when the line is actually +- * executed. Return TRUE and set breakpoint_name for skipped commands that +- * decide to execute something themselves. +- * Called from do_one_cmd() before executing a command. +- */ +- void +- dbg_check_breakpoint(exarg_T *eap) +- { +- char_u *p; +- +- debug_skipped = FALSE; +- if (debug_breakpoint_name != NULL) +- { +- if (!eap->skip) +- { +- /* replace K_SNR with "<SNR>" */ +- if (debug_breakpoint_name[0] == K_SPECIAL +- && debug_breakpoint_name[1] == KS_EXTRA +- && debug_breakpoint_name[2] == (int)KE_SNR) +- p = (char_u *)"<SNR>"; +- else +- p = (char_u *)""; +- smsg(_("Breakpoint in \"%s%s\" line %ld"), +- p, +- debug_breakpoint_name + (*p == NUL ? 0 : 3), +- (long)debug_breakpoint_lnum); +- debug_breakpoint_name = NULL; +- do_debug(eap->cmd); +- } +- else +- { +- debug_skipped = TRUE; +- debug_skipped_name = debug_breakpoint_name; +- debug_breakpoint_name = NULL; +- } +- } +- else if (ex_nesting_level <= debug_break_level) +- { +- if (!eap->skip) +- do_debug(eap->cmd); +- else +- { +- debug_skipped = TRUE; +- debug_skipped_name = NULL; +- } +- } +- } +- +- /* +- * Go to debug mode if skipped by dbg_check_breakpoint() because eap->skip was +- * set. Return TRUE when the debug mode is entered this time. +- */ +- int +- dbg_check_skipped(exarg_T *eap) +- { +- int prev_got_int; +- +- if (debug_skipped) +- { +- /* +- * Save the value of got_int and reset it. We don't want a previous +- * interruption cause flushing the input buffer. +- */ +- prev_got_int = got_int; +- got_int = FALSE; +- debug_breakpoint_name = debug_skipped_name; +- /* eap->skip is TRUE */ +- eap->skip = FALSE; +- (void)dbg_check_breakpoint(eap); +- eap->skip = TRUE; +- got_int |= prev_got_int; +- return TRUE; +- } +- 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, 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 */ +- #ifdef FEAT_EVAL +- typval_T *dbg_val; /* last result of watchexpression */ +- #endif +- 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]) +- static int last_breakp = 0; /* nr of last defined breakpoint */ +- +- #ifdef FEAT_PROFILE +- /* Profiling uses file and func names similar to breakpoints. */ +- static garray_T prof_ga = {0, 0, sizeof(struct debuggy), 4, NULL}; +- #endif +- #define DBG_FUNC 1 +- #define DBG_FILE 2 +- #define DBG_EXPR 3 +- +- static linenr_T debuggy_find(int file,char_u *fname, linenr_T after, garray_T *gap, int *fp); +- +- /* +- * 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. +- * Returns FAIL for failure. +- */ +- static int +- dbg_parsearg( +- char_u *arg, +- garray_T *gap) /* either &dbg_breakp or &prof_ga */ +- { +- char_u *p = arg; +- char_u *q; +- struct debuggy *bp; +- int here = FALSE; +- +- if (ga_grow(gap, 1) == FAIL) +- return FAIL; +- bp = &DEBUGGY(gap, gap->ga_len); +- +- /* Find "func" or "file". */ +- if (STRNCMP(p, "func", 4) == 0) +- bp->dbg_type = DBG_FUNC; +- else if (STRNCMP(p, "file", 4) == 0) +- bp->dbg_type = DBG_FILE; +- else if ( +- #ifdef FEAT_PROFILE +- gap != &prof_ga && +- #endif +- STRNCMP(p, "here", 4) == 0) +- { +- if (curbuf->b_ffname == NULL) +- { +- emsg(_(e_noname)); +- return FAIL; +- } +- bp->dbg_type = DBG_FILE; +- here = TRUE; +- } +- else if ( +- #ifdef FEAT_PROFILE +- gap != &prof_ga && +- #endif +- STRNCMP(p, "expr", 4) == 0) +- bp->dbg_type = DBG_EXPR; +- else +- { +- semsg(_(e_invarg2), p); +- return FAIL; +- } +- p = skipwhite(p + 4); +- +- /* Find optional line number. */ +- if (here) +- bp->dbg_lnum = curwin->w_cursor.lnum; +- else if ( +- #ifdef FEAT_PROFILE +- gap != &prof_ga && +- #endif +- VIM_ISDIGIT(*p)) +- { +- bp->dbg_lnum = getdigits(&p); +- p = skipwhite(p); +- } +- else +- bp->dbg_lnum = 0; +- +- /* Find the function or file name. Don't accept a function name with (). */ +- if ((!here && *p == NUL) +- || (here && *p != NUL) +- || (bp->dbg_type == DBG_FUNC && strstr((char *)p, "()") != NULL)) +- { +- semsg(_(e_invarg2), arg); +- return FAIL; +- } +- +- if (bp->dbg_type == DBG_FUNC) +- 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); +- if (bp->dbg_name != NULL) +- bp->dbg_val = eval_expr(bp->dbg_name, NULL); +- } +- 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 +- * "~/dir". */ +- q = expand_env_save(p); +- if (q == NULL) +- return FAIL; +- p = expand_env_save(q); +- vim_free(q); +- if (p == NULL) +- return FAIL; +- if (*p != '*') +- { +- bp->dbg_name = fix_fname(p); +- vim_free(p); +- } +- else +- bp->dbg_name = p; +- } +- +- if (bp->dbg_name == NULL) +- return FAIL; +- return OK; +- } +- +- /* +- * ":breakadd". Also used for ":profile". +- */ +- void +- ex_breakadd(exarg_T *eap) +- { +- struct debuggy *bp; +- char_u *pat; +- garray_T *gap; +- +- gap = &dbg_breakp; +- #ifdef FEAT_PROFILE +- if (eap->cmdidx == CMD_profile) +- gap = &prof_ga; +- #endif +- +- if (dbg_parsearg(eap->arg, gap) == OK) +- { +- bp = &DEBUGGY(gap, gap->ga_len); +- bp->dbg_forceit = eap->forceit; +- +- if (bp->dbg_type != DBG_EXPR) +- { +- 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); +- vim_free(pat); +- } +- if (pat == NULL || bp->dbg_prog == NULL) +- vim_free(bp->dbg_name); +- else +- { +- if (bp->dbg_lnum == 0) /* default line number is 1 */ +- bp->dbg_lnum = 1; +- #ifdef FEAT_PROFILE +- if (eap->cmdidx != CMD_profile) +- #endif +- { +- DEBUGGY(gap, gap->ga_len).dbg_nr = ++last_breakp; +- ++debug_tick; +- } +- ++gap->ga_len; +- } +- } +- else +- { +- /* DBG_EXPR */ +- DEBUGGY(gap, gap->ga_len++).dbg_nr = ++last_breakp; +- ++debug_tick; +- } +- } +- } +- +- /* +- * ":debuggreedy". +- */ +- void +- ex_debuggreedy(exarg_T *eap) +- { +- if (eap->addr_count == 0 || eap->line2 != 0) +- debug_greedy = TRUE; +- else +- debug_greedy = FALSE; +- } +- +- /* +- * ":breakdel" and ":profdel". +- */ +- void +- ex_breakdel(exarg_T *eap) +- { +- struct debuggy *bp, *bpi; +- int nr; +- int todel = -1; +- int del_all = FALSE; +- int i; +- linenr_T best_lnum = 0; +- garray_T *gap; +- +- gap = &dbg_breakp; +- if (eap->cmdidx == CMD_profdel) +- { +- #ifdef FEAT_PROFILE +- gap = &prof_ga; +- #else +- ex_ni(eap); +- return; +- #endif +- } +- +- if (vim_isdigit(*eap->arg)) +- { +- /* ":breakdel {nr}" */ +- nr = atol((char *)eap->arg); +- for (i = 0; i < gap->ga_len; ++i) +- if (DEBUGGY(gap, i).dbg_nr == nr) +- { +- todel = i; +- break; +- } +- } +- else if (*eap->arg == '*') +- { +- todel = 0; +- del_all = TRUE; +- } +- else +- { +- /* ":breakdel {func|file|expr} [lnum] {name}" */ +- if (dbg_parsearg(eap->arg, gap) == FAIL) +- return; +- bp = &DEBUGGY(gap, gap->ga_len); +- for (i = 0; i < gap->ga_len; ++i) +- { +- 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 +- || (bp->dbg_lnum == 0 +- && (best_lnum == 0 +- || bpi->dbg_lnum < best_lnum)))) +- { +- todel = i; +- best_lnum = bpi->dbg_lnum; +- } +- } +- vim_free(bp->dbg_name); +- } +- +- if (todel < 0) +- semsg(_("E161: Breakpoint not found: %s"), eap->arg); +- else +- { +- while (gap->ga_len > 0) +- { +- vim_free(DEBUGGY(gap, todel).dbg_name); +- #ifdef FEAT_EVAL +- if (DEBUGGY(gap, todel).dbg_type == DBG_EXPR +- && DEBUGGY(gap, todel).dbg_val != NULL) +- free_tv(DEBUGGY(gap, todel).dbg_val); +- #endif +- vim_regfree(DEBUGGY(gap, todel).dbg_prog); +- --gap->ga_len; +- if (todel < gap->ga_len) +- mch_memmove(&DEBUGGY(gap, todel), &DEBUGGY(gap, todel + 1), +- (gap->ga_len - todel) * sizeof(struct debuggy)); +- #ifdef FEAT_PROFILE +- if (eap->cmdidx == CMD_breakdel) +- #endif +- ++debug_tick; +- if (!del_all) +- break; +- } +- +- /* If all breakpoints were removed clear the array. */ +- if (gap->ga_len == 0) +- ga_clear(gap); +- } +- } +- +- /* +- * ":breaklist". +- */ +- void +- ex_breaklist(exarg_T *eap UNUSED) +- { +- struct debuggy *bp; +- int i; +- +- if (dbg_breakp.ga_len == 0) +- msg(_("No breakpoints defined")); +- else +- for (i = 0; i < dbg_breakp.ga_len; ++i) +- { +- bp = &BREAKP(i); +- if (bp->dbg_type == DBG_FILE) +- home_replace(NULL, bp->dbg_name, NameBuff, MAXPATHL, TRUE); +- if (bp->dbg_type != DBG_EXPR) +- smsg(_("%3d %s %s line %ld"), +- bp->dbg_nr, +- bp->dbg_type == DBG_FUNC ? "func" : "file", +- bp->dbg_type == DBG_FUNC ? bp->dbg_name : NameBuff, +- (long)bp->dbg_lnum); +- else +- smsg(_("%3d expr %s"), +- bp->dbg_nr, bp->dbg_name); +- } +- } +- +- /* +- * Find a breakpoint for a function or sourced file. +- * Returns line number at which to break; zero when no matching breakpoint. +- */ +- linenr_T +- dbg_find_breakpoint( +- int file, /* TRUE for a file, FALSE for a function */ +- char_u *fname, /* file or function name */ +- linenr_T after) /* after this line number */ +- { +- return debuggy_find(file, fname, after, &dbg_breakp, NULL); +- } +- +- #if defined(FEAT_PROFILE) || defined(PROTO) +- /* +- * Return TRUE if profiling is on for a function or sourced file. +- */ +- int +- has_profiling( +- int file, /* TRUE for a file, FALSE for a function */ +- char_u *fname, /* file or function name */ +- int *fp) /* return: forceit */ +- { +- return (debuggy_find(file, fname, (linenr_T)0, &prof_ga, fp) +- != (linenr_T)0); +- } +- #endif +- +- /* +- * Common code for dbg_find_breakpoint() and has_profiling(). +- */ +- static linenr_T +- debuggy_find( +- int file, /* TRUE for a file, FALSE for a function */ +- char_u *fname, /* file or function name */ +- linenr_T after, /* after this line number */ +- garray_T *gap, /* either &dbg_breakp or &prof_ga */ +- int *fp) /* if not NULL: return forceit */ +- { +- struct debuggy *bp; +- int i; +- linenr_T lnum = 0; +- char_u *name = fname; +- int prev_got_int; +- +- /* Return quickly when there are no breakpoints. */ +- if (gap->ga_len == 0) +- return (linenr_T)0; +- +- /* Replace K_SNR in function name with "<SNR>". */ +- if (!file && fname[0] == K_SPECIAL) +- { +- name = alloc((unsigned)STRLEN(fname) + 3); +- if (name == NULL) +- name = fname; +- else +- { +- STRCPY(name, "<SNR>"); +- STRCPY(name + 5, fname + 3); +- } +- } +- +- for (i = 0; i < gap->ga_len; ++i) +- { +- /* Skip entries that are not useful or are for a line that is beyond +- * an already found breakpoint. */ +- bp = &DEBUGGY(gap, i); +- if (((bp->dbg_type == DBG_FILE) == file && +- bp->dbg_type != DBG_EXPR && ( +- #ifdef FEAT_PROFILE +- gap == &prof_ga || +- #endif +- (bp->dbg_lnum > after && (lnum == 0 || bp->dbg_lnum < lnum))))) +- { +- /* +- * Save the value of got_int and reset it. We don't want a +- * previous interruption cancel matching, only hitting CTRL-C +- * 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)) +- { +- lnum = bp->dbg_lnum; +- if (fp != NULL) +- *fp = bp->dbg_forceit; +- } +- got_int |= prev_got_int; +- } +- #ifdef FEAT_EVAL +- else if (bp->dbg_type == DBG_EXPR) +- { +- typval_T *tv; +- int line = FALSE; +- +- prev_got_int = got_int; +- got_int = FALSE; +- +- tv = eval_expr(bp->dbg_name, NULL); +- 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 +- { +- if (typval_compare(tv, bp->dbg_val, TYPE_EQUAL, +- TRUE, FALSE) == OK +- && tv->vval.v_number == FALSE) +- { +- typval_T *v; +- +- line = TRUE; +- debug_oldval = typval_tostring(bp->dbg_val); +- /* Need to evaluate again, typval_compare() overwrites +- * "tv". */ +- v = eval_expr(bp->dbg_name, NULL); +- debug_newval = typval_tostring(v); +- free_tv(bp->dbg_val); +- bp->dbg_val = v; +- } +- free_tv(tv); +- } +- } +- else if (bp->dbg_val != NULL) +- { +- debug_oldval = typval_tostring(bp->dbg_val); +- debug_newval = typval_tostring(NULL); +- free_tv(bp->dbg_val); +- bp->dbg_val = NULL; +- line = TRUE; +- } +- +- if (line) +- { +- lnum = after > 0 ? after : 1; +- break; +- } +- +- got_int |= prev_got_int; +- } +- #endif +- } +- if (name != fname) +- vim_free(name); +- +- return lnum; +- } +- +- /* +- * Called when a breakpoint was encountered. +- */ +- void +- dbg_breakpoint(char_u *name, linenr_T lnum) +- { +- /* We need to check if this line is actually executed in do_one_cmd() */ +- debug_breakpoint_name = name; +- debug_breakpoint_lnum = lnum; +- } +- +- + # if defined(FEAT_PROFILE) || defined(FEAT_RELTIME) || defined(PROTO) + /* + * Store the current time in "tm". +--- 66,71 ---- +*** ../vim-8.1.1194/src/proto.h 2019-03-30 13:53:26.174425093 +0100 +--- src/proto.h 2019-04-21 11:18:57.688977840 +0200 +*************** +*** 68,73 **** +--- 68,74 ---- + # ifdef FEAT_CSCOPE + # include "if_cscope.pro" + # endif ++ # include "debugger.pro" + # include "dict.pro" + # include "diff.pro" + # include "digraph.pro" +*** ../vim-8.1.1194/src/proto/debugger.pro 2019-04-21 11:33:08.875781192 +0200 +--- src/proto/debugger.pro 2019-04-21 11:18:57.688977840 +0200 +*************** +*** 0 **** +--- 1,14 ---- ++ /* debugger.c */ ++ int has_watchexpr(void); ++ void do_debug(char_u *cmd); ++ void ex_debug(exarg_T *eap); ++ void dbg_check_breakpoint(exarg_T *eap); ++ int dbg_check_skipped(exarg_T *eap); ++ void ex_breakadd(exarg_T *eap); ++ void ex_debuggreedy(exarg_T *eap); ++ void ex_breakdel(exarg_T *eap); ++ void ex_breaklist(exarg_T *eap); ++ linenr_T dbg_find_breakpoint(int file, char_u *fname, linenr_T after); ++ int has_profiling(int file, char_u *fname, int *fp); ++ void dbg_breakpoint(char_u *name, linenr_T lnum); ++ /* vim: set ft=c : */ +*** ../vim-8.1.1194/src/proto/ex_cmds2.pro 2019-04-04 18:15:05.770857065 +0200 +--- src/proto/ex_cmds2.pro 2019-04-21 11:18:57.688977840 +0200 +*************** +*** 1,16 **** + /* ex_cmds2.c */ +- int has_watchexpr(void); +- void do_debug(char_u *cmd); +- void ex_debug(exarg_T *eap); +- void dbg_check_breakpoint(exarg_T *eap); +- int dbg_check_skipped(exarg_T *eap); +- void ex_breakadd(exarg_T *eap); +- void ex_debuggreedy(exarg_T *eap); +- void ex_breakdel(exarg_T *eap); +- void ex_breaklist(exarg_T *eap); +- linenr_T dbg_find_breakpoint(int file, char_u *fname, linenr_T after); +- int has_profiling(int file, char_u *fname, int *fp); +- void dbg_breakpoint(char_u *name, linenr_T lnum); + void profile_start(proftime_T *tm); + void profile_end(proftime_T *tm); + void profile_sub(proftime_T *tm, proftime_T *tm2); +--- 1,4 ---- +*** ../vim-8.1.1194/src/version.c 2019-04-21 00:00:07.946354820 +0200 +--- src/version.c 2019-04-21 11:20:15.084493742 +0200 +*************** +*** 773,774 **** +--- 773,776 ---- + { /* Add new patch number below this line */ ++ /**/ ++ 1195, + /**/ + +-- +FATHER: Make sure the Prince doesn't leave this room until I come and + get him. +FIRST GUARD: Not ... to leave the room ... even if you come and get him. +FATHER: No. Until I come and get him. +SECOND GUARD: Hic. + "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD + + /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ +/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ +\\\ an exciting new programming language -- http://www.Zimbu.org /// + \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |