Patch 8.2.2332
Problem:    Vim9: missing :endif not reported when using :windo.
Solution:   Pass a getline function to do_cmdline(). (closes #7650)
Files:      src/vim9execute.c, src/structs.h, src/scriptfile.c,
            src/testdir/test_vim9_cmd.vim


*** ../vim-8.2.2331/src/vim9execute.c   2021-01-10 23:58:25.432466870 +0100
--- src/vim9execute.c   2021-01-11 22:14:39.627831890 +0100
***************
*** 1382,1390 ****
            // execute Ex command line
            case ISN_EXEC:
                {
                    SOURCING_LNUM = iptr->isn_lnum;
!                   do_cmdline_cmd(iptr->isn_arg.string);
!                   if (did_emsg)
                        goto on_error;
                }
                break;
--- 1382,1399 ----
            // execute Ex command line
            case ISN_EXEC:
                {
+                   source_cookie_T cookie;
+ 
                    SOURCING_LNUM = iptr->isn_lnum;
!                   // Pass getsourceline to get an error for a missing ":end"
!                   // command.
!                   CLEAR_FIELD(cookie);
!                   cookie.sourcing_lnum = iptr->isn_lnum - 1;
!                   if (do_cmdline(iptr->isn_arg.string,
!                               getsourceline, &cookie,
!                                  DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_KEYTYPED)
!                                                                       == FAIL
!                               || did_emsg)
                        goto on_error;
                }
                break;
*** ../vim-8.2.2331/src/structs.h       2021-01-11 21:20:05.669652000 +0100
--- src/structs.h       2021-01-11 22:01:43.434252983 +0100
***************
*** 4300,4305 ****
--- 4300,4331 ----
      int               sa_wrapped;     // search wrapped around
  } searchit_arg_T;
  
+ /*
+  * Cookie used by getsourceline().
+  */
+ /*
+  * Cookie used to store info for each sourced file.
+  * It is shared between do_source() and getsourceline().
+  * This is passed to do_cmdline().
+  */
+ typedef struct {
+     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
+ } source_cookie_T;
+ 
  
  #define WRITEBUFSIZE  8192    // size of normal write buffer
  
*** ../vim-8.2.2331/src/scriptfile.c    2020-12-29 11:14:58.444606193 +0100
--- src/scriptfile.c    2021-01-11 22:08:22.428976195 +0100
***************
*** 1019,1048 ****
  /*
   * ":source" and associated commands.
   */
- /*
-  * Structure used to store info for each sourced file.
-  * It is shared between do_source() and getsourceline().
-  * This is required, because it needs to be handed to do_cmdline() and
-  * sourcing can be done recursively.
-  */
- 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
  /*
--- 1019,1024 ----
***************
*** 1051,1057 ****
      linenr_T *
  source_breakpoint(void *cookie)
  {
!     return &((struct source_cookie *)cookie)->breakpoint;
  }
  
  /*
--- 1027,1033 ----
      linenr_T *
  source_breakpoint(void *cookie)
  {
!     return &((source_cookie_T *)cookie)->breakpoint;
  }
  
  /*
***************
*** 1060,1066 ****
      int *
  source_dbg_tick(void *cookie)
  {
!     return &((struct source_cookie *)cookie)->dbg_tick;
  }
  
  /*
--- 1036,1042 ----
      int *
  source_dbg_tick(void *cookie)
  {
!     return &((source_cookie_T *)cookie)->dbg_tick;
  }
  
  /*
***************
*** 1069,1075 ****
      int
  source_level(void *cookie)
  {
!     return ((struct source_cookie *)cookie)->level;
  }
  
  /*
--- 1045,1051 ----
      int
  source_level(void *cookie)
  {
!     return ((source_cookie_T *)cookie)->level;
  }
  
  /*
***************
*** 1079,1085 ****
      char_u *
  source_nextline(void *cookie)
  {
!     return ((struct source_cookie *)cookie)->nextline;
  }
  #endif
  
--- 1055,1061 ----
      char_u *
  source_nextline(void *cookie)
  {
!     return ((source_cookie_T *)cookie)->nextline;
  }
  #endif
  
***************
*** 1130,1136 ****
      int               is_vimrc,           // DOSO_ value
      int               *ret_sid UNUSED)
  {
!     struct source_cookie    cookie;
      char_u                *p;
      char_u                *fname_exp;
      char_u                *firstline = NULL;
--- 1106,1112 ----
      int               is_vimrc,           // DOSO_ value
      int               *ret_sid UNUSED)
  {
!     source_cookie_T       cookie;
      char_u                *p;
      char_u                *fname_exp;
      char_u                *firstline = NULL;
***************
*** 1613,1624 ****
        void *cookie)
  {
      return fgetline == getsourceline
!                       ? ((struct source_cookie *)cookie)->sourcing_lnum
                        : SOURCING_LNUM;
  }
  
      static char_u *
! get_one_sourceline(struct source_cookie *sp)
  {
      garray_T          ga;
      int                       len;
--- 1589,1600 ----
        void *cookie)
  {
      return fgetline == getsourceline
!                       ? ((source_cookie_T *)cookie)->sourcing_lnum
                        : SOURCING_LNUM;
  }
  
      static char_u *
! get_one_sourceline(source_cookie_T *sp)
  {
      garray_T          ga;
      int                       len;
***************
*** 1736,1742 ****
        int indent UNUSED,
        getline_opt_T options)
  {
!     struct source_cookie *sp = (struct source_cookie *)cookie;
      char_u            *line;
      char_u            *p;
      int                       do_vim9_all = in_vim9script()
--- 1712,1718 ----
        int indent UNUSED,
        getline_opt_T options)
  {
!     source_cookie_T   *sp = (source_cookie_T *)cookie;
      char_u            *line;
      char_u            *p;
      int                       do_vim9_all = in_vim9script()
***************
*** 1761,1768 ****
      SOURCING_LNUM = sp->sourcing_lnum + 1;
  
      // Get current line.  If there is a read-ahead line, use it, otherwise get
!     // one now.
!     if (sp->finished)
        line = NULL;
      else if (sp->nextline == NULL)
        line = get_one_sourceline(sp);
--- 1737,1744 ----
      SOURCING_LNUM = sp->sourcing_lnum + 1;
  
      // Get current line.  If there is a read-ahead line, use it, otherwise get
!     // one now.  "fp" is NULL if actually using a string.
!     if (sp->finished || sp->fp == NULL)
        line = NULL;
      else if (sp->nextline == NULL)
        line = get_one_sourceline(sp);
***************
*** 1880,1887 ****
      void
  ex_scriptencoding(exarg_T *eap)
  {
!     struct source_cookie      *sp;
!     char_u                    *name;
  
      if (!getline_equal(eap->getline, eap->cookie, getsourceline))
      {
--- 1856,1863 ----
      void
  ex_scriptencoding(exarg_T *eap)
  {
!     source_cookie_T   *sp;
!     char_u            *name;
  
      if (!getline_equal(eap->getline, eap->cookie, getsourceline))
      {
***************
*** 1899,1905 ****
        name = eap->arg;
  
      // Setup for conversion from the specified encoding to 'encoding'.
!     sp = (struct source_cookie *)getline_cookie(eap->getline, eap->cookie);
      convert_setup(&sp->conv, name, p_enc);
  
      if (name != eap->arg)
--- 1875,1881 ----
        name = eap->arg;
  
      // Setup for conversion from the specified encoding to 'encoding'.
!     sp = (source_cookie_T *)getline_cookie(eap->getline, eap->cookie);
      convert_setup(&sp->conv, name, p_enc);
  
      if (name != eap->arg)
***************
*** 1963,1969 ****
      int               idx;
  
      if (reanimate)
!       ((struct source_cookie *)getline_cookie(eap->getline,
                                              eap->cookie))->finished = FALSE;
  
      // Cleanup (and inactivate) conditionals, but stop when a try conditional
--- 1939,1945 ----
      int               idx;
  
      if (reanimate)
!       ((source_cookie_T *)getline_cookie(eap->getline,
                                              eap->cookie))->finished = FALSE;
  
      // Cleanup (and inactivate) conditionals, but stop when a try conditional
***************
*** 1977,1983 ****
        report_make_pending(CSTP_FINISH, NULL);
      }
      else
!       ((struct source_cookie *)getline_cookie(eap->getline,
                                               eap->cookie))->finished = TRUE;
  }
  
--- 1953,1959 ----
        report_make_pending(CSTP_FINISH, NULL);
      }
      else
!       ((source_cookie_T *)getline_cookie(eap->getline,
                                               eap->cookie))->finished = TRUE;
  }
  
***************
*** 1993,1999 ****
      void      *cookie)
  {
      return (getline_equal(fgetline, cookie, getsourceline)
!           && ((struct source_cookie *)getline_cookie(
                                                fgetline, cookie))->finished);
  }
  
--- 1969,1975 ----
      void      *cookie)
  {
      return (getline_equal(fgetline, cookie, getsourceline)
!           && ((source_cookie_T *)getline_cookie(
                                                fgetline, cookie))->finished);
  }
  
*** ../vim-8.2.2331/src/testdir/test_vim9_cmd.vim       2021-01-08 
20:40:41.958161849 +0100
--- src/testdir/test_vim9_cmd.vim       2021-01-11 22:13:24.756056001 +0100
***************
*** 921,924 ****
--- 921,931 ----
    close
  enddef
  
+ def Test_windo_missing_endif()
+   var lines =<< trim END
+       windo if 1
+   END
+   CheckDefExecFailure(lines, 'E171:', 1)
+ enddef
+ 
  " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
*** ../vim-8.2.2331/src/version.c       2021-01-11 21:20:05.669652000 +0100
--- src/version.c       2021-01-11 22:15:29.095684422 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2332,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
129. You cancel your newspaper subscription.

 /// 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/202101112118.10BLIug8754842%40masaka.moolenaar.net.

Raspunde prin e-mail lui