1 /* vi:set ts=8 sts=4 sw=4 noet: 2 * 3 * VIM - Vi IMproved by Bram Moolenaar 4 * 5 * Do ":help uganda" in Vim to read copying and usage conditions. 6 * Do ":help credits" in Vim to see a list of people who contributed. 7 * See README.txt for an overview of the Vim source code. 8 */ 9 10 /* 11 * debugger.c: Vim script debugger functions 12 */ 13 14 #include "vim.h" 15 16 #if defined(FEAT_EVAL) || defined(PROTO) 17 static int debug_greedy = FALSE; // batch mode debugging: don't save 18 // and restore typeahead. 19 static void do_setdebugtracelevel(char_u *arg); 20 static void do_checkbacktracelevel(void); 21 static void do_showbacktrace(char_u *cmd); 22 23 static char_u *debug_oldval = NULL; // old and newval for debug expressions 24 static char_u *debug_newval = NULL; 25 static int debug_expr = 0; // use debug_expr 26 27 int 28 has_watchexpr(void) 29 { 30 return debug_expr; 31 } 32 33 /* 34 * do_debug(): Debug mode. 35 * Repeatedly get Ex commands, until told to continue normal execution. 36 */ 37 void 38 do_debug(char_u *cmd) 39 { 40 int save_msg_scroll = msg_scroll; 41 int save_State = State; 42 int save_did_emsg = did_emsg; 43 int save_cmd_silent = cmd_silent; 44 int save_msg_silent = msg_silent; 45 int save_emsg_silent = emsg_silent; 46 int save_redir_off = redir_off; 47 tasave_T typeaheadbuf; 48 int typeahead_saved = FALSE; 49 int save_ignore_script = 0; 50 int save_ex_normal_busy; 51 int n; 52 char_u *cmdline = NULL; 53 char_u *p; 54 char *tail = NULL; 55 static int last_cmd = 0; 56 #define CMD_CONT 1 57 #define CMD_NEXT 2 58 #define CMD_STEP 3 59 #define CMD_FINISH 4 60 #define CMD_QUIT 5 61 #define CMD_INTERRUPT 6 62 #define CMD_BACKTRACE 7 63 #define CMD_FRAME 8 64 #define CMD_UP 9 65 #define CMD_DOWN 10 66 67 #ifdef ALWAYS_USE_GUI 68 // Can't do this when there is no terminal for input/output. 69 if (!gui.in_use) 70 { 71 // Break as soon as possible. 72 debug_break_level = 9999; 73 return; 74 } 75 #endif 76 77 // Make sure we are in raw mode and start termcap mode. Might have side 78 // effects... 79 settmode(TMODE_RAW); 80 starttermcap(); 81 82 ++RedrawingDisabled; // don't redisplay the window 83 ++no_wait_return; // don't wait for return 84 did_emsg = FALSE; // don't use error from debugged stuff 85 cmd_silent = FALSE; // display commands 86 msg_silent = FALSE; // display messages 87 emsg_silent = FALSE; // display error messages 88 redir_off = TRUE; // don't redirect debug commands 89 90 State = NORMAL; 91 debug_mode = TRUE; 92 93 if (!debug_did_msg) 94 msg(_("Entering Debug mode. Type \"cont\" to continue.")); 95 if (debug_oldval != NULL) 96 { 97 smsg(_("Oldval = \"%s\""), debug_oldval); 98 vim_free(debug_oldval); 99 debug_oldval = NULL; 100 } 101 if (debug_newval != NULL) 102 { 103 smsg(_("Newval = \"%s\""), debug_newval); 104 vim_free(debug_newval); 105 debug_newval = NULL; 106 } 107 if (sourcing_name != NULL) 108 msg((char *)sourcing_name); 109 if (sourcing_lnum != 0) 110 smsg(_("line %ld: %s"), (long)sourcing_lnum, cmd); 111 else 112 smsg(_("cmd: %s"), cmd); 113 114 // Repeat getting a command and executing it. 115 for (;;) 116 { 117 msg_scroll = TRUE; 118 need_wait_return = FALSE; 119 120 // Save the current typeahead buffer and replace it with an empty one. 121 // This makes sure we get input from the user here and don't interfere 122 // with the commands being executed. Reset "ex_normal_busy" to avoid 123 // the side effects of using ":normal". Save the stuff buffer and make 124 // it empty. Set ignore_script to avoid reading from script input. 125 save_ex_normal_busy = ex_normal_busy; 126 ex_normal_busy = 0; 127 if (!debug_greedy) 128 { 129 save_typeahead(&typeaheadbuf); 130 typeahead_saved = TRUE; 131 save_ignore_script = ignore_script; 132 ignore_script = TRUE; 133 } 134 135 vim_free(cmdline); 136 cmdline = getcmdline_prompt('>', NULL, 0, EXPAND_NOTHING, NULL); 137 138 if (typeahead_saved) 139 { 140 restore_typeahead(&typeaheadbuf); 141 ignore_script = save_ignore_script; 142 } 143 ex_normal_busy = save_ex_normal_busy; 144 145 cmdline_row = msg_row; 146 msg_starthere(); 147 if (cmdline != NULL) 148 { 149 // If this is a debug command, set "last_cmd". 150 // If not, reset "last_cmd". 151 // For a blank line use previous command. 152 p = skipwhite(cmdline); 153 if (*p != NUL) 154 { 155 switch (*p) 156 { 157 case 'c': last_cmd = CMD_CONT; 158 tail = "ont"; 159 break; 160 case 'n': last_cmd = CMD_NEXT; 161 tail = "ext"; 162 break; 163 case 's': last_cmd = CMD_STEP; 164 tail = "tep"; 165 break; 166 case 'f': 167 last_cmd = 0; 168 if (p[1] == 'r') 169 { 170 last_cmd = CMD_FRAME; 171 tail = "rame"; 172 } 173 else 174 { 175 last_cmd = CMD_FINISH; 176 tail = "inish"; 177 } 178 break; 179 case 'q': last_cmd = CMD_QUIT; 180 tail = "uit"; 181 break; 182 case 'i': last_cmd = CMD_INTERRUPT; 183 tail = "nterrupt"; 184 break; 185 case 'b': last_cmd = CMD_BACKTRACE; 186 if (p[1] == 't') 187 tail = "t"; 188 else 189 tail = "acktrace"; 190 break; 191 case 'w': last_cmd = CMD_BACKTRACE; 192 tail = "here"; 193 break; 194 case 'u': last_cmd = CMD_UP; 195 tail = "p"; 196 break; 197 case 'd': last_cmd = CMD_DOWN; 198 tail = "own"; 199 break; 200 default: last_cmd = 0; 201 } 202 if (last_cmd != 0) 203 { 204 // Check that the tail matches. 205 ++p; 206 while (*p != NUL && *p == *tail) 207 { 208 ++p; 209 ++tail; 210 } 211 if (ASCII_ISALPHA(*p) && last_cmd != CMD_FRAME) 212 last_cmd = 0; 213 } 214 } 215 216 if (last_cmd != 0) 217 { 218 // Execute debug command: decided where to break next and 219 // return. 220 switch (last_cmd) 221 { 222 case CMD_CONT: 223 debug_break_level = -1; 224 break; 225 case CMD_NEXT: 226 debug_break_level = ex_nesting_level; 227 break; 228 case CMD_STEP: 229 debug_break_level = 9999; 230 break; 231 case CMD_FINISH: 232 debug_break_level = ex_nesting_level - 1; 233 break; 234 case CMD_QUIT: 235 got_int = TRUE; 236 debug_break_level = -1; 237 break; 238 case CMD_INTERRUPT: 239 got_int = TRUE; 240 debug_break_level = 9999; 241 // Do not repeat ">interrupt" cmd, continue stepping. 242 last_cmd = CMD_STEP; 243 break; 244 case CMD_BACKTRACE: 245 do_showbacktrace(cmd); 246 continue; 247 case CMD_FRAME: 248 if (*p == NUL) 249 { 250 do_showbacktrace(cmd); 251 } 252 else 253 { 254 p = skipwhite(p); 255 do_setdebugtracelevel(p); 256 } 257 continue; 258 case CMD_UP: 259 debug_backtrace_level++; 260 do_checkbacktracelevel(); 261 continue; 262 case CMD_DOWN: 263 debug_backtrace_level--; 264 do_checkbacktracelevel(); 265 continue; 266 } 267 // Going out reset backtrace_level 268 debug_backtrace_level = 0; 269 break; 270 } 271 272 // don't debug this command 273 n = debug_break_level; 274 debug_break_level = -1; 275 (void)do_cmdline(cmdline, getexline, NULL, 276 DOCMD_VERBOSE|DOCMD_EXCRESET); 277 debug_break_level = n; 278 } 279 lines_left = Rows - 1; 280 } 281 vim_free(cmdline); 282 283 --RedrawingDisabled; 284 --no_wait_return; 285 redraw_all_later(NOT_VALID); 286 need_wait_return = FALSE; 287 msg_scroll = save_msg_scroll; 288 lines_left = Rows - 1; 289 State = save_State; 290 debug_mode = FALSE; 291 did_emsg = save_did_emsg; 292 cmd_silent = save_cmd_silent; 293 msg_silent = save_msg_silent; 294 emsg_silent = save_emsg_silent; 295 redir_off = save_redir_off; 296 297 // Only print the message again when typing a command before coming back 298 // here. 299 debug_did_msg = TRUE; 300 } 301 302 static int 303 get_maxbacktrace_level(void) 304 { 305 char *p, *q; 306 int maxbacktrace = 0; 307 308 if (sourcing_name != NULL) 309 { 310 p = (char *)sourcing_name; 311 while ((q = strstr(p, "..")) != NULL) 312 { 313 p = q + 2; 314 maxbacktrace++; 315 } 316 } 317 return maxbacktrace; 318 } 319 320 static void 321 do_setdebugtracelevel(char_u *arg) 322 { 323 int level; 324 325 level = atoi((char *)arg); 326 if (*arg == '+' || level < 0) 327 debug_backtrace_level += level; 328 else 329 debug_backtrace_level = level; 330 331 do_checkbacktracelevel(); 332 } 333 334 static void 335 do_checkbacktracelevel(void) 336 { 337 if (debug_backtrace_level < 0) 338 { 339 debug_backtrace_level = 0; 340 msg(_("frame is zero")); 341 } 342 else 343 { 344 int max = get_maxbacktrace_level(); 345 346 if (debug_backtrace_level > max) 347 { 348 debug_backtrace_level = max; 349 smsg(_("frame at highest level: %d"), max); 350 } 351 } 352 } 353 354 static void 355 do_showbacktrace(char_u *cmd) 356 { 357 char *cur; 358 char *next; 359 int i = 0; 360 int max = get_maxbacktrace_level(); 361 362 if (sourcing_name != NULL) 363 { 364 cur = (char *)sourcing_name; 365 while (!got_int) 366 { 367 next = strstr(cur, ".."); 368 if (next != NULL) 369 *next = NUL; 370 if (i == max - debug_backtrace_level) 371 smsg("->%d %s", max - i, cur); 372 else 373 smsg(" %d %s", max - i, cur); 374 ++i; 375 if (next == NULL) 376 break; 377 *next = '.'; 378 cur = next + 2; 379 } 380 } 381 if (sourcing_lnum != 0) 382 smsg(_("line %ld: %s"), (long)sourcing_lnum, cmd); 383 else 384 smsg(_("cmd: %s"), cmd); 385 } 386 387 /* 388 * ":debug". 389 */ 390 void 391 ex_debug(exarg_T *eap) 392 { 393 int debug_break_level_save = debug_break_level; 394 395 debug_break_level = 9999; 396 do_cmdline_cmd(eap->arg); 397 debug_break_level = debug_break_level_save; 398 } 399 400 static char_u *debug_breakpoint_name = NULL; 401 static linenr_T debug_breakpoint_lnum; 402 403 /* 404 * When debugging or a breakpoint is set on a skipped command, no debug prompt 405 * is shown by do_one_cmd(). This situation is indicated by debug_skipped, and 406 * debug_skipped_name is then set to the source name in the breakpoint case. If 407 * a skipped command decides itself that a debug prompt should be displayed, it 408 * can do so by calling dbg_check_skipped(). 409 */ 410 static int debug_skipped; 411 static char_u *debug_skipped_name; 412 413 /* 414 * Go to debug mode when a breakpoint was encountered or "ex_nesting_level" is 415 * at or below the break level. But only when the line is actually 416 * executed. Return TRUE and set breakpoint_name for skipped commands that 417 * decide to execute something themselves. 418 * Called from do_one_cmd() before executing a command. 419 */ 420 void 421 dbg_check_breakpoint(exarg_T *eap) 422 { 423 char_u *p; 424 425 debug_skipped = FALSE; 426 if (debug_breakpoint_name != NULL) 427 { 428 if (!eap->skip) 429 { 430 // replace K_SNR with "<SNR>" 431 if (debug_breakpoint_name[0] == K_SPECIAL 432 && debug_breakpoint_name[1] == KS_EXTRA 433 && debug_breakpoint_name[2] == (int)KE_SNR) 434 p = (char_u *)"<SNR>"; 435 else 436 p = (char_u *)""; 437 smsg(_("Breakpoint in \"%s%s\" line %ld"), 438 p, 439 debug_breakpoint_name + (*p == NUL ? 0 : 3), 440 (long)debug_breakpoint_lnum); 441 debug_breakpoint_name = NULL; 442 do_debug(eap->cmd); 443 } 444 else 445 { 446 debug_skipped = TRUE; 447 debug_skipped_name = debug_breakpoint_name; 448 debug_breakpoint_name = NULL; 449 } 450 } 451 else if (ex_nesting_level <= debug_break_level) 452 { 453 if (!eap->skip) 454 do_debug(eap->cmd); 455 else 456 { 457 debug_skipped = TRUE; 458 debug_skipped_name = NULL; 459 } 460 } 461 } 462 463 /* 464 * Go to debug mode if skipped by dbg_check_breakpoint() because eap->skip was 465 * set. Return TRUE when the debug mode is entered this time. 466 */ 467 int 468 dbg_check_skipped(exarg_T *eap) 469 { 470 int prev_got_int; 471 472 if (debug_skipped) 473 { 474 // Save the value of got_int and reset it. We don't want a previous 475 // interruption cause flushing the input buffer. 476 prev_got_int = got_int; 477 got_int = FALSE; 478 debug_breakpoint_name = debug_skipped_name; 479 // eap->skip is TRUE 480 eap->skip = FALSE; 481 (void)dbg_check_breakpoint(eap); 482 eap->skip = TRUE; 483 got_int |= prev_got_int; 484 return TRUE; 485 } 486 return FALSE; 487 } 488 489 /* 490 * The list of breakpoints: dbg_breakp. 491 * This is a grow-array of structs. 492 */ 493 struct debuggy 494 { 495 int dbg_nr; // breakpoint number 496 int dbg_type; // DBG_FUNC, DBG_FILE or DBG_EXPR 497 char_u *dbg_name; // function, expression or file name 498 regprog_T *dbg_prog; // regexp program 499 linenr_T dbg_lnum; // line number in function or file 500 int dbg_forceit; // ! used 501 #ifdef FEAT_EVAL 502 typval_T *dbg_val; // last result of watchexpression 503 #endif 504 int dbg_level; // stored nested level for expr 505 }; 506 507 static garray_T dbg_breakp = {0, 0, sizeof(struct debuggy), 4, NULL}; 508 #define BREAKP(idx) (((struct debuggy *)dbg_breakp.ga_data)[idx]) 509 #define DEBUGGY(gap, idx) (((struct debuggy *)gap->ga_data)[idx]) 510 static int last_breakp = 0; // nr of last defined breakpoint 511 512 #ifdef FEAT_PROFILE 513 // Profiling uses file and func names similar to breakpoints. 514 static garray_T prof_ga = {0, 0, sizeof(struct debuggy), 4, NULL}; 515 #endif 516 #define DBG_FUNC 1 517 #define DBG_FILE 2 518 #define DBG_EXPR 3 519 520 static linenr_T debuggy_find(int file,char_u *fname, linenr_T after, garray_T *gap, int *fp); 521 522 /* 523 * Parse the arguments of ":profile", ":breakadd" or ":breakdel" and put them 524 * in the entry just after the last one in dbg_breakp. Note that "dbg_name" 525 * is allocated. 526 * Returns FAIL for failure. 527 */ 528 static int 529 dbg_parsearg( 530 char_u *arg, 531 garray_T *gap) // either &dbg_breakp or &prof_ga 532 { 533 char_u *p = arg; 534 char_u *q; 535 struct debuggy *bp; 536 int here = FALSE; 537 538 if (ga_grow(gap, 1) == FAIL) 539 return FAIL; 540 bp = &DEBUGGY(gap, gap->ga_len); 541 542 // Find "func" or "file". 543 if (STRNCMP(p, "func", 4) == 0) 544 bp->dbg_type = DBG_FUNC; 545 else if (STRNCMP(p, "file", 4) == 0) 546 bp->dbg_type = DBG_FILE; 547 else if ( 548 #ifdef FEAT_PROFILE 549 gap != &prof_ga && 550 #endif 551 STRNCMP(p, "here", 4) == 0) 552 { 553 if (curbuf->b_ffname == NULL) 554 { 555 emsg(_(e_noname)); 556 return FAIL; 557 } 558 bp->dbg_type = DBG_FILE; 559 here = TRUE; 560 } 561 else if ( 562 #ifdef FEAT_PROFILE 563 gap != &prof_ga && 564 #endif 565 STRNCMP(p, "expr", 4) == 0) 566 bp->dbg_type = DBG_EXPR; 567 else 568 { 569 semsg(_(e_invarg2), p); 570 return FAIL; 571 } 572 p = skipwhite(p + 4); 573 574 // Find optional line number. 575 if (here) 576 bp->dbg_lnum = curwin->w_cursor.lnum; 577 else if ( 578 #ifdef FEAT_PROFILE 579 gap != &prof_ga && 580 #endif 581 VIM_ISDIGIT(*p)) 582 { 583 bp->dbg_lnum = getdigits(&p); 584 p = skipwhite(p); 585 } 586 else 587 bp->dbg_lnum = 0; 588 589 // Find the function or file name. Don't accept a function name with (). 590 if ((!here && *p == NUL) 591 || (here && *p != NUL) 592 || (bp->dbg_type == DBG_FUNC && strstr((char *)p, "()") != NULL)) 593 { 594 semsg(_(e_invarg2), arg); 595 return FAIL; 596 } 597 598 if (bp->dbg_type == DBG_FUNC) 599 bp->dbg_name = vim_strsave(p); 600 else if (here) 601 bp->dbg_name = vim_strsave(curbuf->b_ffname); 602 else if (bp->dbg_type == DBG_EXPR) 603 { 604 bp->dbg_name = vim_strsave(p); 605 if (bp->dbg_name != NULL) 606 bp->dbg_val = eval_expr(bp->dbg_name, NULL); 607 } 608 else 609 { 610 // Expand the file name in the same way as do_source(). This means 611 // doing it twice, so that $DIR/file gets expanded when $DIR is 612 // "~/dir". 613 q = expand_env_save(p); 614 if (q == NULL) 615 return FAIL; 616 p = expand_env_save(q); 617 vim_free(q); 618 if (p == NULL) 619 return FAIL; 620 if (*p != '*') 621 { 622 bp->dbg_name = fix_fname(p); 623 vim_free(p); 624 } 625 else 626 bp->dbg_name = p; 627 } 628 629 if (bp->dbg_name == NULL) 630 return FAIL; 631 return OK; 632 } 633 634 /* 635 * ":breakadd". Also used for ":profile". 636 */ 637 void 638 ex_breakadd(exarg_T *eap) 639 { 640 struct debuggy *bp; 641 char_u *pat; 642 garray_T *gap; 643 644 gap = &dbg_breakp; 645 #ifdef FEAT_PROFILE 646 if (eap->cmdidx == CMD_profile) 647 gap = &prof_ga; 648 #endif 649 650 if (dbg_parsearg(eap->arg, gap) == OK) 651 { 652 bp = &DEBUGGY(gap, gap->ga_len); 653 bp->dbg_forceit = eap->forceit; 654 655 if (bp->dbg_type != DBG_EXPR) 656 { 657 pat = file_pat_to_reg_pat(bp->dbg_name, NULL, NULL, FALSE); 658 if (pat != NULL) 659 { 660 bp->dbg_prog = vim_regcomp(pat, RE_MAGIC + RE_STRING); 661 vim_free(pat); 662 } 663 if (pat == NULL || bp->dbg_prog == NULL) 664 vim_free(bp->dbg_name); 665 else 666 { 667 if (bp->dbg_lnum == 0) // default line number is 1 668 bp->dbg_lnum = 1; 669 #ifdef FEAT_PROFILE 670 if (eap->cmdidx != CMD_profile) 671 #endif 672 { 673 DEBUGGY(gap, gap->ga_len).dbg_nr = ++last_breakp; 674 ++debug_tick; 675 } 676 ++gap->ga_len; 677 } 678 } 679 else 680 { 681 // DBG_EXPR 682 DEBUGGY(gap, gap->ga_len++).dbg_nr = ++last_breakp; 683 ++debug_tick; 684 } 685 } 686 } 687 688 /* 689 * ":debuggreedy". 690 */ 691 void 692 ex_debuggreedy(exarg_T *eap) 693 { 694 if (eap->addr_count == 0 || eap->line2 != 0) 695 debug_greedy = TRUE; 696 else 697 debug_greedy = FALSE; 698 } 699 700 /* 701 * ":breakdel" and ":profdel". 702 */ 703 void 704 ex_breakdel(exarg_T *eap) 705 { 706 struct debuggy *bp, *bpi; 707 int nr; 708 int todel = -1; 709 int del_all = FALSE; 710 int i; 711 linenr_T best_lnum = 0; 712 garray_T *gap; 713 714 gap = &dbg_breakp; 715 if (eap->cmdidx == CMD_profdel) 716 { 717 #ifdef FEAT_PROFILE 718 gap = &prof_ga; 719 #else 720 ex_ni(eap); 721 return; 722 #endif 723 } 724 725 if (vim_isdigit(*eap->arg)) 726 { 727 // ":breakdel {nr}" 728 nr = atol((char *)eap->arg); 729 for (i = 0; i < gap->ga_len; ++i) 730 if (DEBUGGY(gap, i).dbg_nr == nr) 731 { 732 todel = i; 733 break; 734 } 735 } 736 else if (*eap->arg == '*') 737 { 738 todel = 0; 739 del_all = TRUE; 740 } 741 else 742 { 743 // ":breakdel {func|file|expr} [lnum] {name}" 744 if (dbg_parsearg(eap->arg, gap) == FAIL) 745 return; 746 bp = &DEBUGGY(gap, gap->ga_len); 747 for (i = 0; i < gap->ga_len; ++i) 748 { 749 bpi = &DEBUGGY(gap, i); 750 if (bp->dbg_type == bpi->dbg_type 751 && STRCMP(bp->dbg_name, bpi->dbg_name) == 0 752 && (bp->dbg_lnum == bpi->dbg_lnum 753 || (bp->dbg_lnum == 0 754 && (best_lnum == 0 755 || bpi->dbg_lnum < best_lnum)))) 756 { 757 todel = i; 758 best_lnum = bpi->dbg_lnum; 759 } 760 } 761 vim_free(bp->dbg_name); 762 } 763 764 if (todel < 0) 765 semsg(_("E161: Breakpoint not found: %s"), eap->arg); 766 else 767 { 768 while (gap->ga_len > 0) 769 { 770 vim_free(DEBUGGY(gap, todel).dbg_name); 771 #ifdef FEAT_EVAL 772 if (DEBUGGY(gap, todel).dbg_type == DBG_EXPR 773 && DEBUGGY(gap, todel).dbg_val != NULL) 774 free_tv(DEBUGGY(gap, todel).dbg_val); 775 #endif 776 vim_regfree(DEBUGGY(gap, todel).dbg_prog); 777 --gap->ga_len; 778 if (todel < gap->ga_len) 779 mch_memmove(&DEBUGGY(gap, todel), &DEBUGGY(gap, todel + 1), 780 (gap->ga_len - todel) * sizeof(struct debuggy)); 781 #ifdef FEAT_PROFILE 782 if (eap->cmdidx == CMD_breakdel) 783 #endif 784 ++debug_tick; 785 if (!del_all) 786 break; 787 } 788 789 // If all breakpoints were removed clear the array. 790 if (gap->ga_len == 0) 791 ga_clear(gap); 792 } 793 } 794 795 /* 796 * ":breaklist". 797 */ 798 void 799 ex_breaklist(exarg_T *eap UNUSED) 800 { 801 struct debuggy *bp; 802 int i; 803 804 if (dbg_breakp.ga_len == 0) 805 msg(_("No breakpoints defined")); 806 else 807 for (i = 0; i < dbg_breakp.ga_len; ++i) 808 { 809 bp = &BREAKP(i); 810 if (bp->dbg_type == DBG_FILE) 811 home_replace(NULL, bp->dbg_name, NameBuff, MAXPATHL, TRUE); 812 if (bp->dbg_type != DBG_EXPR) 813 smsg(_("%3d %s %s line %ld"), 814 bp->dbg_nr, 815 bp->dbg_type == DBG_FUNC ? "func" : "file", 816 bp->dbg_type == DBG_FUNC ? bp->dbg_name : NameBuff, 817 (long)bp->dbg_lnum); 818 else 819 smsg(_("%3d expr %s"), 820 bp->dbg_nr, bp->dbg_name); 821 } 822 } 823 824 /* 825 * Find a breakpoint for a function or sourced file. 826 * Returns line number at which to break; zero when no matching breakpoint. 827 */ 828 linenr_T 829 dbg_find_breakpoint( 830 int file, // TRUE for a file, FALSE for a function 831 char_u *fname, // file or function name 832 linenr_T after) // after this line number 833 { 834 return debuggy_find(file, fname, after, &dbg_breakp, NULL); 835 } 836 837 #if defined(FEAT_PROFILE) || defined(PROTO) 838 /* 839 * Return TRUE if profiling is on for a function or sourced file. 840 */ 841 int 842 has_profiling( 843 int file, // TRUE for a file, FALSE for a function 844 char_u *fname, // file or function name 845 int *fp) // return: forceit 846 { 847 return (debuggy_find(file, fname, (linenr_T)0, &prof_ga, fp) 848 != (linenr_T)0); 849 } 850 #endif 851 852 /* 853 * Common code for dbg_find_breakpoint() and has_profiling(). 854 */ 855 static linenr_T 856 debuggy_find( 857 int file, // TRUE for a file, FALSE for a function 858 char_u *fname, // file or function name 859 linenr_T after, // after this line number 860 garray_T *gap, // either &dbg_breakp or &prof_ga 861 int *fp) // if not NULL: return forceit 862 { 863 struct debuggy *bp; 864 int i; 865 linenr_T lnum = 0; 866 char_u *name = fname; 867 int prev_got_int; 868 869 // Return quickly when there are no breakpoints. 870 if (gap->ga_len == 0) 871 return (linenr_T)0; 872 873 // Replace K_SNR in function name with "<SNR>". 874 if (!file && fname[0] == K_SPECIAL) 875 { 876 name = alloc(STRLEN(fname) + 3); 877 if (name == NULL) 878 name = fname; 879 else 880 { 881 STRCPY(name, "<SNR>"); 882 STRCPY(name + 5, fname + 3); 883 } 884 } 885 886 for (i = 0; i < gap->ga_len; ++i) 887 { 888 // Skip entries that are not useful or are for a line that is beyond 889 // an already found breakpoint. 890 bp = &DEBUGGY(gap, i); 891 if (((bp->dbg_type == DBG_FILE) == file && 892 bp->dbg_type != DBG_EXPR && ( 893 #ifdef FEAT_PROFILE 894 gap == &prof_ga || 895 #endif 896 (bp->dbg_lnum > after && (lnum == 0 || bp->dbg_lnum < lnum))))) 897 { 898 // Save the value of got_int and reset it. We don't want a 899 // previous interruption cancel matching, only hitting CTRL-C 900 // while matching should abort it. 901 prev_got_int = got_int; 902 got_int = FALSE; 903 if (vim_regexec_prog(&bp->dbg_prog, FALSE, name, (colnr_T)0)) 904 { 905 lnum = bp->dbg_lnum; 906 if (fp != NULL) 907 *fp = bp->dbg_forceit; 908 } 909 got_int |= prev_got_int; 910 } 911 #ifdef FEAT_EVAL 912 else if (bp->dbg_type == DBG_EXPR) 913 { 914 typval_T *tv; 915 int line = FALSE; 916 917 prev_got_int = got_int; 918 got_int = FALSE; 919 920 tv = eval_expr(bp->dbg_name, NULL); 921 if (tv != NULL) 922 { 923 if (bp->dbg_val == NULL) 924 { 925 debug_oldval = typval_tostring(NULL); 926 bp->dbg_val = tv; 927 debug_newval = typval_tostring(bp->dbg_val); 928 line = TRUE; 929 } 930 else 931 { 932 if (typval_compare(tv, bp->dbg_val, TYPE_EQUAL, 933 TRUE, FALSE) == OK 934 && tv->vval.v_number == FALSE) 935 { 936 typval_T *v; 937 938 line = TRUE; 939 debug_oldval = typval_tostring(bp->dbg_val); 940 // Need to evaluate again, typval_compare() overwrites 941 // "tv". 942 v = eval_expr(bp->dbg_name, NULL); 943 debug_newval = typval_tostring(v); 944 free_tv(bp->dbg_val); 945 bp->dbg_val = v; 946 } 947 free_tv(tv); 948 } 949 } 950 else if (bp->dbg_val != NULL) 951 { 952 debug_oldval = typval_tostring(bp->dbg_val); 953 debug_newval = typval_tostring(NULL); 954 free_tv(bp->dbg_val); 955 bp->dbg_val = NULL; 956 line = TRUE; 957 } 958 959 if (line) 960 { 961 lnum = after > 0 ? after : 1; 962 break; 963 } 964 965 got_int |= prev_got_int; 966 } 967 #endif 968 } 969 if (name != fname) 970 vim_free(name); 971 972 return lnum; 973 } 974 975 /* 976 * Called when a breakpoint was encountered. 977 */ 978 void 979 dbg_breakpoint(char_u *name, linenr_T lnum) 980 { 981 // We need to check if this line is actually executed in do_one_cmd() 982 debug_breakpoint_name = name; 983 debug_breakpoint_lnum = lnum; 984 } 985 #endif 986