To: vim_dev@googlegroups.com Subject: Patch 8.1.0309 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.0309 Problem: Profiling does not show a count for condition lines. (Daniel Hahler) Solution: Count lines when not skipping. (Ozaki Kiichi, closes #2499) Files: src/ex_docmd.c, src/testdir/test_profile.vim *** ../vim-8.1.0308/src/ex_docmd.c 2018-08-21 15:12:10.839801647 +0200 --- src/ex_docmd.c 2018-08-21 17:40:31.920546399 +0200 *************** *** 1766,1782 **** ea.skip = (if_level > 0); #endif #ifdef FEAT_EVAL # ifdef FEAT_PROFILE ! /* Count this line for profiling if ea.skip is FALSE. */ ! if (do_profiling == PROF_YES && !ea.skip) { ! if (getline_equal(fgetline, cookie, get_func_line)) ! func_line_exec(getline_cookie(fgetline, cookie)); ! else if (getline_equal(fgetline, cookie, getsourceline)) ! script_line_exec(); } ! #endif /* May go to debug mode. If this happens and the ">quit" debug command is * used, throw an interrupt exception and skip the next command. */ --- 1766,1816 ---- ea.skip = (if_level > 0); #endif + /* + * 3. Skip over the range to find the command. Let "p" point to after it. + * + * We need the command to know what kind of range it uses. + */ + cmd = ea.cmd; + ea.cmd = skip_range(ea.cmd, NULL); + if (*ea.cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL) + ea.cmd = skipwhite(ea.cmd + 1); + p = find_command(&ea, NULL); + #ifdef FEAT_EVAL # ifdef FEAT_PROFILE ! // Count this line for profiling if skip is TRUE. ! if (do_profiling == PROF_YES ! && (!ea.skip || cstack->cs_idx == 0 || (cstack->cs_idx > 0 ! && (cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE)))) { ! int skip = did_emsg || got_int || did_throw; ! ! if (ea.cmdidx == CMD_catch) ! skip = !skip && !(cstack->cs_idx >= 0 ! && (cstack->cs_flags[cstack->cs_idx] & CSF_THROWN) ! && !(cstack->cs_flags[cstack->cs_idx] & CSF_CAUGHT)); ! else if (ea.cmdidx == CMD_else || ea.cmdidx == CMD_elseif) ! skip = skip || !(cstack->cs_idx >= 0 ! && !(cstack->cs_flags[cstack->cs_idx] ! & (CSF_ACTIVE | CSF_TRUE))); ! else if (ea.cmdidx == CMD_finally) ! skip = FALSE; ! else if (ea.cmdidx != CMD_endif ! && ea.cmdidx != CMD_endfor ! && ea.cmdidx != CMD_endtry ! && ea.cmdidx != CMD_endwhile) ! skip = ea.skip; ! ! if (!skip) ! { ! if (getline_equal(fgetline, cookie, get_func_line)) ! func_line_exec(getline_cookie(fgetline, cookie)); ! else if (getline_equal(fgetline, cookie, getsourceline)) ! script_line_exec(); ! } } ! # endif /* May go to debug mode. If this happens and the ">quit" debug command is * used, throw an interrupt exception and skip the next command. */ *************** *** 1789,1805 **** #endif /* - * 3. Skip over the range to find the command. Let "p" point to after it. - * - * We need the command to know what kind of range it uses. - */ - cmd = ea.cmd; - ea.cmd = skip_range(ea.cmd, NULL); - if (*ea.cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL) - ea.cmd = skipwhite(ea.cmd + 1); - p = find_command(&ea, NULL); - - /* * 4. parse a range specifier of the form: addr [,addr] [;addr] .. * * where 'addr' is: --- 1823,1828 ---- *** ../vim-8.1.0308/src/testdir/test_profile.vim 2018-06-30 21:18:10.486300954 +0200 --- src/testdir/test_profile.vim 2018-08-21 17:35:04.318354275 +0200 *************** *** 67,73 **** call assert_match('^\s*1\s\+.*\slet l:count = 100$', lines[13]) call assert_match('^\s*101\s\+.*\swhile l:count > 0$', lines[14]) call assert_match('^\s*100\s\+.*\s let l:count = l:count - 1$', lines[15]) ! call assert_match('^\s*100\s\+.*\sendwhile$', lines[16]) call assert_equal('', lines[17]) call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[18]) call assert_equal('count total (s) self (s) function', lines[19]) --- 67,73 ---- call assert_match('^\s*1\s\+.*\slet l:count = 100$', lines[13]) call assert_match('^\s*101\s\+.*\swhile l:count > 0$', lines[14]) call assert_match('^\s*100\s\+.*\s let l:count = l:count - 1$', lines[15]) ! call assert_match('^\s*101\s\+.*\sendwhile$', lines[16]) call assert_equal('', lines[17]) call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[18]) call assert_equal('count total (s) self (s) function', lines[19]) *************** *** 84,89 **** --- 84,310 ---- call delete('Xprofile_func.log') endfunc + func Test_profile_func_with_ifelse() + let lines = [ + \ "func! Foo1()", + \ " if 1", + \ " let x = 0", + \ " elseif 1", + \ " let x = 1", + \ " else", + \ " let x = 2", + \ " endif", + \ "endfunc", + \ "func! Foo2()", + \ " if 0", + \ " let x = 0", + \ " elseif 1", + \ " let x = 1", + \ " else", + \ " let x = 2", + \ " endif", + \ "endfunc", + \ "func! Foo3()", + \ " if 0", + \ " let x = 0", + \ " elseif 0", + \ " let x = 1", + \ " else", + \ " let x = 2", + \ " endif", + \ "endfunc", + \ "call Foo1()", + \ "call Foo2()", + \ "call Foo3()", + \ ] + + call writefile(lines, 'Xprofile_func.vim') + call system(v:progpath + \ . ' -es -u NONE -U NONE -i NONE --noplugin' + \ . ' -c "profile start Xprofile_func.log"' + \ . ' -c "profile func Foo*"' + \ . ' -c "so Xprofile_func.vim"' + \ . ' -c "qall!"') + call assert_equal(0, v:shell_error) + + let lines = readfile('Xprofile_func.log') + + " - Foo1() should pass 'if' block. + " - Foo2() should pass 'elseif' block. + " - Foo3() should pass 'else' block. + call assert_equal(54, len(lines)) + + call assert_equal('FUNCTION Foo1()', lines[0]) + call assert_equal('Called 1 time', lines[1]) + call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2]) + call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3]) + call assert_equal('', lines[4]) + call assert_equal('count total (s) self (s)', lines[5]) + call assert_match('^\s*1\s\+.*\sif 1$', lines[6]) + call assert_match('^\s*1\s\+.*\s let x = 0$', lines[7]) + call assert_match( '^\s\+elseif 1$', lines[8]) + call assert_match( '^\s\+let x = 1$', lines[9]) + call assert_match( '^\s\+else$', lines[10]) + call assert_match( '^\s\+let x = 2$', lines[11]) + call assert_match('^\s*1\s\+.*\sendif$', lines[12]) + call assert_equal('', lines[13]) + call assert_equal('FUNCTION Foo2()', lines[14]) + call assert_equal('Called 1 time', lines[15]) + call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[16]) + call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[17]) + call assert_equal('', lines[18]) + call assert_equal('count total (s) self (s)', lines[19]) + call assert_match('^\s*1\s\+.*\sif 0$', lines[20]) + call assert_match( '^\s\+let x = 0$', lines[21]) + call assert_match('^\s*1\s\+.*\selseif 1$', lines[22]) + call assert_match('^\s*1\s\+.*\s let x = 1$', lines[23]) + call assert_match( '^\s\+else$', lines[24]) + call assert_match( '^\s\+let x = 2$', lines[25]) + call assert_match('^\s*1\s\+.*\sendif$', lines[26]) + call assert_equal('', lines[27]) + call assert_equal('FUNCTION Foo3()', lines[28]) + call assert_equal('Called 1 time', lines[29]) + call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[30]) + call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[31]) + call assert_equal('', lines[32]) + call assert_equal('count total (s) self (s)', lines[33]) + call assert_match('^\s*1\s\+.*\sif 0$', lines[34]) + call assert_match( '^\s\+let x = 0$', lines[35]) + call assert_match('^\s*1\s\+.*\selseif 0$', lines[36]) + call assert_match( '^\s\+let x = 1$', lines[37]) + call assert_match('^\s*1\s\+.*\selse$', lines[38]) + call assert_match('^\s*1\s\+.*\s let x = 2$', lines[39]) + call assert_match('^\s*1\s\+.*\sendif$', lines[40]) + call assert_equal('', lines[41]) + call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[42]) + call assert_equal('count total (s) self (s) function', lines[43]) + call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[44]) + call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[45]) + call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[46]) + call assert_equal('', lines[47]) + call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[48]) + call assert_equal('count total (s) self (s) function', lines[49]) + call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[50]) + call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[51]) + call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[52]) + call assert_equal('', lines[53]) + + call delete('Xprofile_func.vim') + call delete('Xprofile_func.log') + endfunc + + func Test_profile_func_with_trycatch() + let lines = [ + \ "func! Foo1()", + \ " try", + \ " let x = 0", + \ " catch", + \ " let x = 1", + \ " finally", + \ " let x = 2", + \ " endtry", + \ "endfunc", + \ "func! Foo2()", + \ " try", + \ " throw 0", + \ " catch", + \ " let x = 1", + \ " finally", + \ " let x = 2", + \ " endtry", + \ "endfunc", + \ "func! Foo3()", + \ " try", + \ " throw 0", + \ " catch", + \ " throw 1", + \ " finally", + \ " let x = 2", + \ " endtry", + \ "endfunc", + \ "call Foo1()", + \ "call Foo2()", + \ "try", + \ " call Foo3()", + \ "catch", + \ "endtry", + \ ] + + call writefile(lines, 'Xprofile_func.vim') + call system(v:progpath + \ . ' -es -u NONE -U NONE -i NONE --noplugin' + \ . ' -c "profile start Xprofile_func.log"' + \ . ' -c "profile func Foo*"' + \ . ' -c "so Xprofile_func.vim"' + \ . ' -c "qall!"') + call assert_equal(0, v:shell_error) + + let lines = readfile('Xprofile_func.log') + + " - Foo1() should pass 'try' 'finally' blocks. + " - Foo2() should pass 'catch' 'finally' blocks. + " - Foo3() should not pass 'endtry'. + call assert_equal(54, len(lines)) + + call assert_equal('FUNCTION Foo1()', lines[0]) + call assert_equal('Called 1 time', lines[1]) + call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[2]) + call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3]) + call assert_equal('', lines[4]) + call assert_equal('count total (s) self (s)', lines[5]) + call assert_match('^\s*1\s\+.*\stry$', lines[6]) + call assert_match('^\s*1\s\+.*\s let x = 0$', lines[7]) + call assert_match( '^\s\+catch$', lines[8]) + call assert_match( '^\s\+let x = 1$', lines[9]) + call assert_match('^\s*1\s\+.*\sfinally$', lines[10]) + call assert_match('^\s*1\s\+.*\s let x = 2$', lines[11]) + call assert_match('^\s*1\s\+.*\sendtry$', lines[12]) + call assert_equal('', lines[13]) + call assert_equal('FUNCTION Foo2()', lines[14]) + call assert_equal('Called 1 time', lines[15]) + call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[16]) + call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[17]) + call assert_equal('', lines[18]) + call assert_equal('count total (s) self (s)', lines[19]) + call assert_match('^\s*1\s\+.*\stry$', lines[20]) + call assert_match('^\s*1\s\+.*\s throw 0$', lines[21]) + call assert_match('^\s*1\s\+.*\scatch$', lines[22]) + call assert_match('^\s*1\s\+.*\s let x = 1$', lines[23]) + call assert_match('^\s*1\s\+.*\sfinally$', lines[24]) + call assert_match('^\s*1\s\+.*\s let x = 2$', lines[25]) + call assert_match('^\s*1\s\+.*\sendtry$', lines[26]) + call assert_equal('', lines[27]) + call assert_equal('FUNCTION Foo3()', lines[28]) + call assert_equal('Called 1 time', lines[29]) + call assert_match('^Total time:\s\+\d\+\.\d\+$', lines[30]) + call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[31]) + call assert_equal('', lines[32]) + call assert_equal('count total (s) self (s)', lines[33]) + call assert_match('^\s*1\s\+.*\stry$', lines[34]) + call assert_match('^\s*1\s\+.*\s throw 0$', lines[35]) + call assert_match('^\s*1\s\+.*\scatch$', lines[36]) + call assert_match('^\s*1\s\+.*\s throw 1$', lines[37]) + call assert_match('^\s*1\s\+.*\sfinally$', lines[38]) + call assert_match('^\s*1\s\+.*\s let x = 2$', lines[39]) + call assert_match( '^\s\+endtry$', lines[40]) + call assert_equal('', lines[41]) + call assert_equal('FUNCTIONS SORTED ON TOTAL TIME', lines[42]) + call assert_equal('count total (s) self (s) function', lines[43]) + call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[44]) + call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[45]) + call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[46]) + call assert_equal('', lines[47]) + call assert_equal('FUNCTIONS SORTED ON SELF TIME', lines[48]) + call assert_equal('count total (s) self (s) function', lines[49]) + call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[50]) + call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[51]) + call assert_match('^\s*1\s\+\d\+\.\d\+\s\+Foo.()$', lines[52]) + call assert_equal('', lines[53]) + + call delete('Xprofile_func.vim') + call delete('Xprofile_func.log') + endfunc + func Test_profile_file() let lines = [ \ 'func! Foo()', *************** *** 123,129 **** call assert_equal(' " a comment', lines[9]) " if self and total are equal we only get one number call assert_match('^\s*20\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[10]) ! call assert_match('^\s*20\s\+\d\+\.\d\+\s\+endfor$', lines[11]) " if self and total are equal we only get one number call assert_match('^\s*2\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[12]) call assert_equal('', lines[13]) --- 344,350 ---- call assert_equal(' " a comment', lines[9]) " if self and total are equal we only get one number call assert_match('^\s*20\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[10]) ! call assert_match('^\s*22\s\+\d\+\.\d\+\s\+endfor$', lines[11]) " if self and total are equal we only get one number call assert_match('^\s*2\s\+\(\d\+\.\d\+\s\+\)\=\d\+\.\d\+\s\+call Foo()$', lines[12]) call assert_equal('', lines[13]) *** ../vim-8.1.0308/src/version.c 2018-08-21 17:07:40.155188638 +0200 --- src/version.c 2018-08-21 17:48:43.353706395 +0200 *************** *** 796,797 **** --- 796,799 ---- { /* Add new patch number below this line */ + /**/ + 309, /**/ -- ARTHUR: ... and I am your king .... OLD WOMAN: Ooooh! I didn't know we had a king. I thought we were an autonomous collective ... "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 ///