vim-patch:8.0.1207

Problem:    Profiling skips the first and last script line.
Solution:   Check for BOM after setting script ID. (Lemonboy, closes vim/vim#2103,
            closes vim/vim#2112) Add a test. List the trailing script lines.

67435d9983
This commit is contained in:
Justin M. Keyes 2017-10-29 17:26:49 +01:00
parent 45296b331f
commit 1e2ae942f3
2 changed files with 61 additions and 22 deletions

View File

@ -1068,7 +1068,7 @@ static void profile_init(scriptitem_T *si)
si->sn_pr_nest = 0; si->sn_pr_nest = 0;
} }
/// save time when starting to invoke another script or function. /// Save time when starting to invoke another script or function.
void script_prof_save( void script_prof_save(
proftime_T *tm // place to store wait time proftime_T *tm // place to store wait time
) )
@ -1141,12 +1141,14 @@ static void script_dump_profile(FILE *fd)
if (sfd == NULL) { if (sfd == NULL) {
fprintf(fd, "Cannot open file!\n"); fprintf(fd, "Cannot open file!\n");
} else { } else {
for (int i = 0; i < si->sn_prl_ga.ga_len; i++) { // Keep going till the end of file, so that trailing
// continuation lines are listed.
for (int i = 0; ; i++) {
if (vim_fgets(IObuff, IOSIZE, sfd)) { if (vim_fgets(IObuff, IOSIZE, sfd)) {
break; break;
} }
pp = &PRL_ITEM(si, i); if (i < si->sn_prl_ga.ga_len
if (pp->snp_count > 0) { && (pp = &PRL_ITEM(si, i))->snp_count > 0) {
fprintf(fd, "%5d ", pp->snp_count); fprintf(fd, "%5d ", pp->snp_count);
if (profile_equal(pp->sn_prl_total, pp->sn_prl_self)) { if (profile_equal(pp->sn_prl_total, pp->sn_prl_self)) {
fprintf(fd, " "); fprintf(fd, " ");
@ -2871,22 +2873,6 @@ int do_source(char_u *fname, int check_other, int is_vimrc)
save_sourcing_lnum = sourcing_lnum; save_sourcing_lnum = sourcing_lnum;
sourcing_lnum = 0; sourcing_lnum = 0;
cookie.conv.vc_type = CONV_NONE; // no conversion
// Read the first line so we can check for a UTF-8 BOM.
firstline = getsourceline(0, (void *)&cookie, 0);
if (firstline != NULL && STRLEN(firstline) >= 3 && firstline[0] == 0xef
&& firstline[1] == 0xbb && firstline[2] == 0xbf) {
// Found BOM; setup conversion, skip over BOM and recode the line.
convert_setup(&cookie.conv, (char_u *)"utf-8", p_enc);
p = string_convert(&cookie.conv, firstline + 3, NULL);
if (p == NULL) {
p = vim_strsave(firstline + 3);
}
xfree(firstline);
firstline = p;
}
// start measuring script load time if --startuptime was passed and // start measuring script load time if --startuptime was passed and
// time_fd was successfully opened afterwards. // time_fd was successfully opened afterwards.
proftime_T rel_time; proftime_T rel_time;
@ -2959,6 +2945,22 @@ int do_source(char_u *fname, int check_other, int is_vimrc)
} }
} }
cookie.conv.vc_type = CONV_NONE; // no conversion
// Read the first line so we can check for a UTF-8 BOM.
firstline = getsourceline(0, (void *)&cookie, 0);
if (firstline != NULL && STRLEN(firstline) >= 3 && firstline[0] == 0xef
&& firstline[1] == 0xbb && firstline[2] == 0xbf) {
// Found BOM; setup conversion, skip over BOM and recode the line.
convert_setup(&cookie.conv, (char_u *)"utf-8", p_enc);
p = string_convert(&cookie.conv, firstline + 3, NULL);
if (p == NULL) {
p = vim_strsave(firstline + 3);
}
xfree(firstline);
firstline = p;
}
// Call do_cmdline, which will call getsourceline() to get the lines. // Call do_cmdline, which will call getsourceline() to get the lines.
do_cmdline(firstline, getsourceline, (void *)&cookie, do_cmdline(firstline, getsourceline, (void *)&cookie,
DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_REPEAT); DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_REPEAT);
@ -3281,7 +3283,8 @@ void script_line_start(void)
if (si->sn_prof_on && sourcing_lnum >= 1) { if (si->sn_prof_on && sourcing_lnum >= 1) {
// Grow the array before starting the timer, so that the time spent // Grow the array before starting the timer, so that the time spent
// here isn't counted. // here isn't counted.
ga_grow(&si->sn_prl_ga, (int)(sourcing_lnum - si->sn_prl_ga.ga_len)); (void)ga_grow(&si->sn_prl_ga,
(int)(sourcing_lnum - si->sn_prl_ga.ga_len));
si->sn_prl_idx = sourcing_lnum - 1; si->sn_prl_idx = sourcing_lnum - 1;
while (si->sn_prl_ga.ga_len <= si->sn_prl_idx while (si->sn_prl_ga.ga_len <= si->sn_prl_idx
&& si->sn_prl_ga.ga_len < si->sn_prl_ga.ga_maxlen) { && si->sn_prl_ga.ga_len < si->sn_prl_ga.ga_maxlen) {

View File

@ -115,7 +115,7 @@ func Test_profile_file()
call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3]) call assert_match('^ Self time:\s\+\d\+\.\d\+$', lines[3])
call assert_equal('', lines[4]) call assert_equal('', lines[4])
call assert_equal('count total (s) self (s)', lines[5]) call assert_equal('count total (s) self (s)', lines[5])
call assert_equal(' func! Foo()', lines[6]) call assert_match(' 2 0.\d\+ func! Foo()', lines[6])
call assert_equal(' endfunc', lines[7]) call assert_equal(' endfunc', lines[7])
" Loop iterates 10 times. Since script runs twice, body executes 20 times. " Loop iterates 10 times. Since script runs twice, body executes 20 times.
" First line of loop executes one more time than body to detect end of loop. " First line of loop executes one more time than body to detect end of loop.
@ -132,6 +132,42 @@ func Test_profile_file()
call delete('Xprofile_file.log') call delete('Xprofile_file.log')
endfunc endfunc
func Test_profile_file_with_cont()
let lines = [
\ 'echo "hello',
\ ' \ world"',
\ 'echo "foo ',
\ ' \bar"',
\ ]
call writefile(lines, 'Xprofile_file.vim')
call system(v:progpath
\ . ' -es -u NONE -U NONE -i NONE --noplugin'
\ . ' -c "profile start Xprofile_file.log"'
\ . ' -c "profile file Xprofile_file.vim"'
\ . ' -c "so Xprofile_file.vim"'
\ . ' -c "qall!"')
call assert_equal(0, v:shell_error)
let lines = readfile('Xprofile_file.log')
call assert_equal(11, len(lines))
call assert_match('^SCRIPT .*Xprofile_file.vim$', lines[0])
call assert_equal('Sourced 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(' 1 0.\d\+ echo "hello', lines[6])
call assert_equal(' \ world"', lines[7])
call assert_match(' 1 0.\d\+ echo "foo ', lines[8])
call assert_equal(' \bar"', lines[9])
call assert_equal('', lines[10])
call delete('Xprofile_file.vim')
call delete('Xprofile_file.log')
endfunc
func Test_profile_completion() func Test_profile_completion()
call feedkeys(":profile \<C-A>\<C-B>\"\<CR>", 'tx') call feedkeys(":profile \<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"profile continue dump file func pause start stop', @:) call assert_equal('"profile continue dump file func pause start stop', @:)