1
0
forked from aniani/vim

patch 8.1.1625: script line numbers are not exactly right

Problem:    Script line numbers are not exactly right.
Solution:   Handle heredoc and continuation lines better. (Ozaki Kiichi,
            closes #4611, closes #4511)
This commit is contained in:
Bram Moolenaar
2019-07-04 14:57:12 +02:00
parent 0d702028fe
commit bc2cfe4672
5 changed files with 110 additions and 20 deletions

View File

@@ -3269,20 +3269,21 @@ cmd_source(char_u *fname, exarg_T *eap)
*/ */
struct source_cookie struct source_cookie
{ {
FILE *fp; /* opened file for sourcing */ FILE *fp; // opened file for sourcing
char_u *nextline; /* if not NULL: line that was read ahead */ char_u *nextline; // if not NULL: line that was read ahead
int finished; /* ":finish" used */ linenr_T sourcing_lnum; // line number of the source file
int finished; // ":finish" used
#ifdef USE_CRNL #ifdef USE_CRNL
int fileformat; /* EOL_UNKNOWN, EOL_UNIX or EOL_DOS */ int fileformat; // EOL_UNKNOWN, EOL_UNIX or EOL_DOS
int error; /* TRUE if LF found after CR-LF */ int error; // TRUE if LF found after CR-LF
#endif #endif
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
linenr_T breakpoint; /* next line with breakpoint or zero */ linenr_T breakpoint; // next line with breakpoint or zero
char_u *fname; /* name of sourced file */ char_u *fname; // name of sourced file
int dbg_tick; /* debug_tick when breakpoint was set */ int dbg_tick; // debug_tick when breakpoint was set
int level; /* top nesting level of sourced file */ int level; // top nesting level of sourced file
#endif #endif
vimconv_T conv; /* type of conversion */ vimconv_T conv; // type of conversion
}; };
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
@@ -3346,7 +3347,6 @@ fopen_noinh_readbin(char *filename)
} }
#endif #endif
/* /*
* do_source: Read the file "fname" and execute its lines as EX commands. * do_source: Read the file "fname" and execute its lines as EX commands.
* *
@@ -3495,6 +3495,7 @@ do_source(
#endif #endif
cookie.nextline = NULL; cookie.nextline = NULL;
cookie.sourcing_lnum = 0;
cookie.finished = FALSE; cookie.finished = FALSE;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
@@ -3790,6 +3791,14 @@ free_scriptnames(void)
#endif #endif
linenr_T
get_sourced_lnum(char_u *(*fgetline)(int, void *, int, int), void *cookie)
{
return fgetline == getsourceline
? ((struct source_cookie *)cookie)->sourcing_lnum
: sourcing_lnum;
}
/* /*
* Get one full line from a sourced file. * Get one full line from a sourced file.
* Called by do_cmdline() when it's called from do_source(). * Called by do_cmdline() when it's called from do_source().
@@ -3816,6 +3825,10 @@ getsourceline(int c UNUSED, void *cookie, int indent UNUSED, int do_concat)
script_line_end(); script_line_end();
# endif # endif
#endif #endif
// Set the current sourcing line number.
sourcing_lnum = sp->sourcing_lnum + 1;
/* /*
* Get current line. If there is a read-ahead line, use it, otherwise get * Get current line. If there is a read-ahead line, use it, otherwise get
* one now. * one now.
@@ -3828,7 +3841,7 @@ getsourceline(int c UNUSED, void *cookie, int indent UNUSED, int do_concat)
{ {
line = sp->nextline; line = sp->nextline;
sp->nextline = NULL; sp->nextline = NULL;
++sourcing_lnum; ++sp->sourcing_lnum;
} }
#ifdef FEAT_PROFILE #ifdef FEAT_PROFILE
if (line != NULL && do_profiling == PROF_YES) if (line != NULL && do_profiling == PROF_YES)
@@ -3840,7 +3853,7 @@ getsourceline(int c UNUSED, void *cookie, int indent UNUSED, int do_concat)
if (line != NULL && do_concat && vim_strchr(p_cpo, CPO_CONCAT) == NULL) if (line != NULL && do_concat && vim_strchr(p_cpo, CPO_CONCAT) == NULL)
{ {
/* compensate for the one line read-ahead */ /* compensate for the one line read-ahead */
--sourcing_lnum; --sp->sourcing_lnum;
// Get the next line and concatenate it when it starts with a // Get the next line and concatenate it when it starts with a
// backslash. We always need to read the next line, keep it in // backslash. We always need to read the next line, keep it in
@@ -3931,7 +3944,7 @@ get_one_sourceline(struct source_cookie *sp)
/* /*
* Loop until there is a finished line (or end-of-file). * Loop until there is a finished line (or end-of-file).
*/ */
sourcing_lnum++; ++sp->sourcing_lnum;
for (;;) for (;;)
{ {
/* make room to read at least 120 (more) characters */ /* make room to read at least 120 (more) characters */
@@ -4001,7 +4014,7 @@ get_one_sourceline(struct source_cookie *sp)
; ;
if ((len & 1) != (c & 1)) /* escaped NL, read more */ if ((len & 1) != (c & 1)) /* escaped NL, read more */
{ {
sourcing_lnum++; ++sp->sourcing_lnum;
continue; continue;
} }

View File

@@ -81,6 +81,7 @@ void ex_scriptnames(exarg_T *eap);
void scriptnames_slash_adjust(void); void scriptnames_slash_adjust(void);
char_u *get_scriptname(scid_T id); char_u *get_scriptname(scid_T id);
void free_scriptnames(void); void free_scriptnames(void);
linenr_T get_sourced_lnum(char_u *(*fgetline)(int, void *, int, int), void *cookie);
char_u *getsourceline(int c, void *cookie, int indent, int do_concat); char_u *getsourceline(int c, void *cookie, int indent, int do_concat);
void script_line_start(void); void script_line_start(void);
void script_line_exec(void); void script_line_exec(void);

View File

@@ -1676,6 +1676,76 @@ func Test_funccall_garbage_collect()
delfunc Func delfunc Func
endfunc endfunc
func Test_function_defined_line()
if has('gui_running')
" Can't catch the output of gvim.
return
endif
let lines =<< trim [CODE]
" F1
func F1()
" F2
func F2()
"
"
"
return
endfunc
" F3
execute "func F3()\n\n\n\nreturn\nendfunc"
" F4
execute "func F4()\n
\\n
\\n
\\n
\return\n
\endfunc"
endfunc
" F5
execute "func F5()\n\n\n\nreturn\nendfunc"
" F6
execute "func F6()\n
\\n
\\n
\\n
\return\n
\endfunc"
call F1()
verbose func F1
verbose func F2
verbose func F3
verbose func F4
verbose func F5
verbose func F6
qall!
[CODE]
call writefile(lines, 'Xtest.vim')
let res = system(v:progpath .. ' --clean -es -X -S Xtest.vim')
call assert_equal(0, v:shell_error)
let m = matchstr(res, 'function F1()[^[:print:]]*[[:print:]]*')
call assert_match(' line 2$', m)
let m = matchstr(res, 'function F2()[^[:print:]]*[[:print:]]*')
call assert_match(' line 4$', m)
let m = matchstr(res, 'function F3()[^[:print:]]*[[:print:]]*')
call assert_match(' line 11$', m)
let m = matchstr(res, 'function F4()[^[:print:]]*[[:print:]]*')
call assert_match(' line 13$', m)
let m = matchstr(res, 'function F5()[^[:print:]]*[[:print:]]*')
call assert_match(' line 21$', m)
let m = matchstr(res, 'function F6()[^[:print:]]*[[:print:]]*')
call assert_match(' line 23$', m)
call delete('Xtest.vim')
endfunc
"------------------------------------------------------------------------------- "-------------------------------------------------------------------------------
" Modelines {{{1 " Modelines {{{1
" vim: ts=8 sw=4 tw=80 fdm=marker " vim: ts=8 sw=4 tw=80 fdm=marker

View File

@@ -2008,7 +2008,8 @@ ex_function(exarg_T *eap)
int todo; int todo;
hashitem_T *hi; hashitem_T *hi;
int do_concat = TRUE; int do_concat = TRUE;
int sourcing_lnum_off; linenr_T sourcing_lnum_off;
linenr_T sourcing_lnum_top;
/* /*
* ":function" without argument: list functions. * ":function" without argument: list functions.
@@ -2275,6 +2276,9 @@ ex_function(exarg_T *eap)
cmdline_row = msg_row; cmdline_row = msg_row;
} }
// Save the starting line number.
sourcing_lnum_top = sourcing_lnum;
indent = 2; indent = 2;
nesting = 0; nesting = 0;
for (;;) for (;;)
@@ -2285,7 +2289,6 @@ ex_function(exarg_T *eap)
saved_wait_return = FALSE; saved_wait_return = FALSE;
} }
need_wait_return = FALSE; need_wait_return = FALSE;
sourcing_lnum_off = sourcing_lnum;
if (line_arg != NULL) if (line_arg != NULL)
{ {
@@ -2318,8 +2321,9 @@ ex_function(exarg_T *eap)
} }
/* Detect line continuation: sourcing_lnum increased more than one. */ /* Detect line continuation: sourcing_lnum increased more than one. */
if (sourcing_lnum > sourcing_lnum_off + 1) sourcing_lnum_off = get_sourced_lnum(eap->getline, eap->cookie);
sourcing_lnum_off = sourcing_lnum - sourcing_lnum_off - 1; if (sourcing_lnum < sourcing_lnum_off)
sourcing_lnum_off -= sourcing_lnum;
else else
sourcing_lnum_off = 0; sourcing_lnum_off = 0;
@@ -2670,7 +2674,7 @@ ex_function(exarg_T *eap)
fp->uf_flags = flags; fp->uf_flags = flags;
fp->uf_calls = 0; fp->uf_calls = 0;
fp->uf_script_ctx = current_sctx; fp->uf_script_ctx = current_sctx;
fp->uf_script_ctx.sc_lnum += sourcing_lnum - newlines.ga_len - 1; fp->uf_script_ctx.sc_lnum += sourcing_lnum_top;
goto ret_free; goto ret_free;
erret: erret:

View File

@@ -777,6 +777,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1625,
/**/ /**/
1624, 1624,
/**/ /**/