Patch 8.1.1625
Problem:    Script line numbers are not exactly right.
Solution:   Handle heredoc and continuation lines better. (Ozaki Kiichi,
            closes #4611, closes #4511)
Files:      src/ex_cmds2.c, src/proto/ex_cmds2.pro,
            src/testdir/test_vimscript.vim, src/userfunc.c


*** ../vim-8.1.1624/src/ex_cmds2.c      2019-06-25 06:27:57.537385321 +0200
--- src/ex_cmds2.c      2019-07-04 14:44:06.668255705 +0200
***************
*** 3269,3288 ****
   */
  struct source_cookie
  {
!     FILE      *fp;            /* opened file for sourcing */
!     char_u      *nextline;      /* if not NULL: line that was read ahead */
!     int               finished;       /* ":finish" used */
  #ifdef USE_CRNL
!     int               fileformat;     /* EOL_UNKNOWN, EOL_UNIX or EOL_DOS */
!     int               error;          /* TRUE if LF found after CR-LF */
  #endif
  #ifdef FEAT_EVAL
!     linenr_T  breakpoint;     /* next line with breakpoint or zero */
!     char_u    *fname;         /* name of sourced file */
!     int               dbg_tick;       /* debug_tick when breakpoint was set */
!     int               level;          /* top nesting level of sourced file */
  #endif
!     vimconv_T conv;           /* type of conversion */
  };
  
  #ifdef FEAT_EVAL
--- 3269,3289 ----
   */
  struct source_cookie
  {
!     FILE      *fp;            // opened file for sourcing
!     char_u    *nextline;      // if not NULL: line that was read ahead
!     linenr_T  sourcing_lnum;  // line number of the source file
!     int               finished;       // ":finish" used
  #ifdef USE_CRNL
!     int               fileformat;     // EOL_UNKNOWN, EOL_UNIX or EOL_DOS
!     int               error;          // TRUE if LF found after CR-LF
  #endif
  #ifdef FEAT_EVAL
!     linenr_T  breakpoint;     // next line with breakpoint or zero
!     char_u    *fname;         // name of sourced file
!     int               dbg_tick;       // debug_tick when breakpoint was set
!     int               level;          // top nesting level of sourced file
  #endif
!     vimconv_T conv;           // type of conversion
  };
  
  #ifdef FEAT_EVAL
***************
*** 3346,3352 ****
  }
  #endif
  
- 
  /*
   * do_source: Read the file "fname" and execute its lines as EX commands.
   *
--- 3347,3352 ----
***************
*** 3495,3500 ****
--- 3495,3501 ----
  #endif
  
      cookie.nextline = NULL;
+     cookie.sourcing_lnum = 0;
      cookie.finished = FALSE;
  
  #ifdef FEAT_EVAL
***************
*** 3790,3795 ****
--- 3791,3804 ----
  
  #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.
   * Called by do_cmdline() when it's called from do_source().
***************
*** 3816,3821 ****
--- 3825,3834 ----
        script_line_end();
  # 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
       * one now.
***************
*** 3828,3834 ****
      {
        line = sp->nextline;
        sp->nextline = NULL;
!       ++sourcing_lnum;
      }
  #ifdef FEAT_PROFILE
      if (line != NULL && do_profiling == PROF_YES)
--- 3841,3847 ----
      {
        line = sp->nextline;
        sp->nextline = NULL;
!       ++sp->sourcing_lnum;
      }
  #ifdef FEAT_PROFILE
      if (line != NULL && do_profiling == PROF_YES)
***************
*** 3840,3846 ****
      if (line != NULL && do_concat && vim_strchr(p_cpo, CPO_CONCAT) == NULL)
      {
        /* compensate for the one line read-ahead */
!       --sourcing_lnum;
  
        // Get the next line and concatenate it when it starts with a
        // backslash. We always need to read the next line, keep it in
--- 3853,3859 ----
      if (line != NULL && do_concat && vim_strchr(p_cpo, CPO_CONCAT) == NULL)
      {
        /* compensate for the one line read-ahead */
!       --sp->sourcing_lnum;
  
        // Get the next line and concatenate it when it starts with a
        // backslash. We always need to read the next line, keep it in
***************
*** 3931,3937 ****
      /*
       * Loop until there is a finished line (or end-of-file).
       */
!     sourcing_lnum++;
      for (;;)
      {
        /* make room to read at least 120 (more) characters */
--- 3944,3950 ----
      /*
       * Loop until there is a finished line (or end-of-file).
       */
!     ++sp->sourcing_lnum;
      for (;;)
      {
        /* make room to read at least 120 (more) characters */
***************
*** 4001,4007 ****
                ;
            if ((len & 1) != (c & 1))   /* escaped NL, read more */
            {
!               sourcing_lnum++;
                continue;
            }
  
--- 4014,4020 ----
                ;
            if ((len & 1) != (c & 1))   /* escaped NL, read more */
            {
!               ++sp->sourcing_lnum;
                continue;
            }
  
*** ../vim-8.1.1624/src/proto/ex_cmds2.pro      2019-06-25 04:12:12.312665250 
+0200
--- src/proto/ex_cmds2.pro      2019-07-04 14:44:22.440165162 +0200
***************
*** 81,86 ****
--- 81,87 ----
  void scriptnames_slash_adjust(void);
  char_u *get_scriptname(scid_T id);
  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);
  void script_line_start(void);
  void script_line_exec(void);
*** ../vim-8.1.1624/src/testdir/test_vimscript.vim      2019-06-25 
06:27:57.537385321 +0200
--- src/testdir/test_vimscript.vim      2019-07-04 14:40:09.613616459 +0200
***************
*** 1676,1681 ****
--- 1676,1751 ----
      delfunc Func
  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
  " vim: ts=8 sw=4 tw=80 fdm=marker
*** ../vim-8.1.1624/src/userfunc.c      2019-06-25 04:12:12.312665250 +0200
--- src/userfunc.c      2019-07-04 14:40:09.613616459 +0200
***************
*** 2008,2014 ****
      int               todo;
      hashitem_T        *hi;
      int               do_concat = TRUE;
!     int               sourcing_lnum_off;
  
      /*
       * ":function" without argument: list functions.
--- 2008,2015 ----
      int               todo;
      hashitem_T        *hi;
      int               do_concat = TRUE;
!     linenr_T  sourcing_lnum_off;
!     linenr_T  sourcing_lnum_top;
  
      /*
       * ":function" without argument: list functions.
***************
*** 2275,2280 ****
--- 2276,2284 ----
        cmdline_row = msg_row;
      }
  
+     // Save the starting line number.
+     sourcing_lnum_top = sourcing_lnum;
+ 
      indent = 2;
      nesting = 0;
      for (;;)
***************
*** 2285,2291 ****
            saved_wait_return = FALSE;
        }
        need_wait_return = FALSE;
-       sourcing_lnum_off = sourcing_lnum;
  
        if (line_arg != NULL)
        {
--- 2289,2294 ----
***************
*** 2318,2325 ****
        }
  
        /* Detect line continuation: sourcing_lnum increased more than one. */
!       if (sourcing_lnum > sourcing_lnum_off + 1)
!           sourcing_lnum_off = sourcing_lnum - sourcing_lnum_off - 1;
        else
            sourcing_lnum_off = 0;
  
--- 2321,2329 ----
        }
  
        /* Detect line continuation: sourcing_lnum increased more than one. */
!       sourcing_lnum_off = get_sourced_lnum(eap->getline, eap->cookie);
!       if (sourcing_lnum < sourcing_lnum_off)
!           sourcing_lnum_off -= sourcing_lnum;
        else
            sourcing_lnum_off = 0;
  
***************
*** 2670,2676 ****
      fp->uf_flags = flags;
      fp->uf_calls = 0;
      fp->uf_script_ctx = current_sctx;
!     fp->uf_script_ctx.sc_lnum += sourcing_lnum - newlines.ga_len - 1;
      goto ret_free;
  
  erret:
--- 2674,2680 ----
      fp->uf_flags = flags;
      fp->uf_calls = 0;
      fp->uf_script_ctx = current_sctx;
!     fp->uf_script_ctx.sc_lnum += sourcing_lnum_top;
      goto ret_free;
  
  erret:
*** ../vim-8.1.1624/src/version.c       2019-07-04 14:20:38.180325318 +0200
--- src/version.c       2019-07-04 14:41:39.325101527 +0200
***************
*** 779,780 ****
--- 779,782 ----
  {   /* Add new patch number below this line */
+ /**/
+     1625,
  /**/

-- 
Q:  Why do ducks have flat feet?
A:  To stamp out forest fires.

Q:  Why do elephants have flat feet?
A:  To stamp out flaming ducks.

 /// Bram Moolenaar -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/201907041257.x64CvRC6007630%40masaka.moolenaar.net.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui