Patch 8.1.0266
Problem:    Parsing Ex address range is not a separate function.
Solution:   Refactor do_one_cmd() to separate address parsing.
Files:      src/ex_docmd.c, src/proto/ex_docmd.pro


*** ../vim-8.1.0265/src/ex_docmd.c      2018-08-07 22:30:26.670240840 +0200
--- src/ex_docmd.c      2018-08-10 23:08:38.139696671 +0200
***************
*** 1719,1725 ****
      cmdmod_T          save_cmdmod;
      int                       ni;                     /* set when Not 
Implemented */
      char_u            *cmd;
-     int                       address_count = 1;
  
      vim_memset(&ea, 0, sizeof(ea));
      ea.line1 = 1;
--- 1719,1724 ----
***************
*** 2045,2212 ****
            get_wincmd_addr_type(skipwhite(p), &ea);
      }
  
-     /* repeat for all ',' or ';' separated addresses */
      ea.cmd = cmd;
!     for (;;)
!     {
!       ea.line1 = ea.line2;
!       switch (ea.addr_type)
!       {
!           case ADDR_LINES:
!               /* default is current line number */
!               ea.line2 = curwin->w_cursor.lnum;
!               break;
!           case ADDR_WINDOWS:
!               ea.line2 = CURRENT_WIN_NR;
!               break;
!           case ADDR_ARGUMENTS:
!               ea.line2 = curwin->w_arg_idx + 1;
!               if (ea.line2 > ARGCOUNT)
!                   ea.line2 = ARGCOUNT;
!               break;
!           case ADDR_LOADED_BUFFERS:
!           case ADDR_BUFFERS:
!               ea.line2 = curbuf->b_fnum;
!               break;
!           case ADDR_TABS:
!               ea.line2 = CURRENT_TAB_NR;
!               break;
!           case ADDR_TABS_RELATIVE:
!               ea.line2 = 1;
!               break;
! #ifdef FEAT_QUICKFIX
!           case ADDR_QUICKFIX:
!               ea.line2 = qf_get_cur_valid_idx(&ea);
!               break;
! #endif
!       }
!       ea.cmd = skipwhite(ea.cmd);
!       lnum = get_address(&ea, &ea.cmd, ea.addr_type, ea.skip,
!                                         ea.addr_count == 0, address_count++);
!       if (ea.cmd == NULL)                 /* error detected */
!           goto doend;
!       if (lnum == MAXLNUM)
!       {
!           if (*ea.cmd == '%')             /* '%' - all lines */
!           {
!               ++ea.cmd;
!               switch (ea.addr_type)
!               {
!                   case ADDR_LINES:
!                       ea.line1 = 1;
!                       ea.line2 = curbuf->b_ml.ml_line_count;
!                       break;
!                   case ADDR_LOADED_BUFFERS:
!                       {
!                           buf_T       *buf = firstbuf;
! 
!                           while (buf->b_next != NULL
!                                                 && buf->b_ml.ml_mfp == NULL)
!                               buf = buf->b_next;
!                           ea.line1 = buf->b_fnum;
!                           buf = lastbuf;
!                           while (buf->b_prev != NULL
!                                                 && buf->b_ml.ml_mfp == NULL)
!                               buf = buf->b_prev;
!                           ea.line2 = buf->b_fnum;
!                           break;
!                       }
!                   case ADDR_BUFFERS:
!                       ea.line1 = firstbuf->b_fnum;
!                       ea.line2 = lastbuf->b_fnum;
!                       break;
!                   case ADDR_WINDOWS:
!                   case ADDR_TABS:
!                       if (IS_USER_CMDIDX(ea.cmdidx))
!                       {
!                           ea.line1 = 1;
!                           ea.line2 = ea.addr_type == ADDR_WINDOWS
!                                                 ? LAST_WIN_NR : LAST_TAB_NR;
!                       }
!                       else
!                       {
!                           /* there is no Vim command which uses '%' and
!                            * ADDR_WINDOWS or ADDR_TABS */
!                           errormsg = (char_u *)_(e_invrange);
!                           goto doend;
!                       }
!                       break;
!                   case ADDR_TABS_RELATIVE:
!                       errormsg = (char_u *)_(e_invrange);
!                       goto doend;
!                       break;
!                   case ADDR_ARGUMENTS:
!                       if (ARGCOUNT == 0)
!                           ea.line1 = ea.line2 = 0;
!                       else
!                       {
!                           ea.line1 = 1;
!                           ea.line2 = ARGCOUNT;
!                       }
!                       break;
! #ifdef FEAT_QUICKFIX
!                   case ADDR_QUICKFIX:
!                       ea.line1 = 1;
!                       ea.line2 = qf_get_size(&ea);
!                       if (ea.line2 == 0)
!                           ea.line2 = 1;
!                       break;
! #endif
!               }
!               ++ea.addr_count;
!           }
!                                           /* '*' - visual area */
!           else if (*ea.cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL)
!           {
!               pos_T       *fp;
! 
!               if (ea.addr_type != ADDR_LINES)
!               {
!                   errormsg = (char_u *)_(e_invrange);
!                   goto doend;
!               }
! 
!               ++ea.cmd;
!               if (!ea.skip)
!               {
!                   fp = getmark('<', FALSE);
!                   if (check_mark(fp) == FAIL)
!                       goto doend;
!                   ea.line1 = fp->lnum;
!                   fp = getmark('>', FALSE);
!                   if (check_mark(fp) == FAIL)
!                       goto doend;
!                   ea.line2 = fp->lnum;
!                   ++ea.addr_count;
!               }
!           }
!       }
!       else
!           ea.line2 = lnum;
!       ea.addr_count++;
! 
!       if (*ea.cmd == ';')
!       {
!           if (!ea.skip)
!           {
!               curwin->w_cursor.lnum = ea.line2;
!               /* don't leave the cursor on an illegal line or column */
!               check_cursor();
!           }
!       }
!       else if (*ea.cmd != ',')
!           break;
!       ++ea.cmd;
!     }
! 
!     /* One address given: set start and end lines */
!     if (ea.addr_count == 1)
!     {
!       ea.line1 = ea.line2;
!           /* ... but only implicit: really no address given */
!       if (lnum == MAXLNUM)
!           ea.addr_count = 0;
!     }
  
  /*
   * 5. Parse the command.
--- 2044,2052 ----
            get_wincmd_addr_type(skipwhite(p), &ea);
      }
  
      ea.cmd = cmd;
!     if (parse_cmd_address(&ea, &errormsg) == FAIL)
!       goto doend;
  
  /*
   * 5. Parse the command.
***************
*** 2989,2994 ****
--- 2829,3007 ----
  #endif
  
  /*
+  * Parse the address range, if any, in "eap".
+  * Return FAIL and set "errormsg" or return OK.
+  */
+     int
+ parse_cmd_address(exarg_T *eap, char_u **errormsg)
+ {
+     int               address_count = 1;
+     linenr_T  lnum;
+ 
+     // Repeat for all ',' or ';' separated addresses.
+     for (;;)
+     {
+       eap->line1 = eap->line2;
+       switch (eap->addr_type)
+       {
+           case ADDR_LINES:
+               // default is current line number
+               eap->line2 = curwin->w_cursor.lnum;
+               break;
+           case ADDR_WINDOWS:
+               eap->line2 = CURRENT_WIN_NR;
+               break;
+           case ADDR_ARGUMENTS:
+               eap->line2 = curwin->w_arg_idx + 1;
+               if (eap->line2 > ARGCOUNT)
+                   eap->line2 = ARGCOUNT;
+               break;
+           case ADDR_LOADED_BUFFERS:
+           case ADDR_BUFFERS:
+               eap->line2 = curbuf->b_fnum;
+               break;
+           case ADDR_TABS:
+               eap->line2 = CURRENT_TAB_NR;
+               break;
+           case ADDR_TABS_RELATIVE:
+               eap->line2 = 1;
+               break;
+ #ifdef FEAT_QUICKFIX
+           case ADDR_QUICKFIX:
+               eap->line2 = qf_get_cur_valid_idx(eap);
+               break;
+ #endif
+       }
+       eap->cmd = skipwhite(eap->cmd);
+       lnum = get_address(eap, &eap->cmd, eap->addr_type, eap->skip,
+                                       eap->addr_count == 0, address_count++);
+       if (eap->cmd == NULL)   // error detected
+           return FAIL;
+       if (lnum == MAXLNUM)
+       {
+           if (*eap->cmd == '%')   // '%' - all lines
+           {
+               ++eap->cmd;
+               switch (eap->addr_type)
+               {
+                   case ADDR_LINES:
+                       eap->line1 = 1;
+                       eap->line2 = curbuf->b_ml.ml_line_count;
+                       break;
+                   case ADDR_LOADED_BUFFERS:
+                       {
+                           buf_T       *buf = firstbuf;
+ 
+                           while (buf->b_next != NULL
+                                                 && buf->b_ml.ml_mfp == NULL)
+                               buf = buf->b_next;
+                           eap->line1 = buf->b_fnum;
+                           buf = lastbuf;
+                           while (buf->b_prev != NULL
+                                                 && buf->b_ml.ml_mfp == NULL)
+                               buf = buf->b_prev;
+                           eap->line2 = buf->b_fnum;
+                           break;
+                       }
+                   case ADDR_BUFFERS:
+                       eap->line1 = firstbuf->b_fnum;
+                       eap->line2 = lastbuf->b_fnum;
+                       break;
+                   case ADDR_WINDOWS:
+                   case ADDR_TABS:
+                       if (IS_USER_CMDIDX(eap->cmdidx))
+                       {
+                           eap->line1 = 1;
+                           eap->line2 = eap->addr_type == ADDR_WINDOWS
+                                                 ? LAST_WIN_NR : LAST_TAB_NR;
+                       }
+                       else
+                       {
+                           // there is no Vim command which uses '%' and
+                           // ADDR_WINDOWS or ADDR_TABS
+                           *errormsg = (char_u *)_(e_invrange);
+                           return FAIL;
+                       }
+                       break;
+                   case ADDR_TABS_RELATIVE:
+                       *errormsg = (char_u *)_(e_invrange);
+                       return FAIL;
+                   case ADDR_ARGUMENTS:
+                       if (ARGCOUNT == 0)
+                           eap->line1 = eap->line2 = 0;
+                       else
+                       {
+                           eap->line1 = 1;
+                           eap->line2 = ARGCOUNT;
+                       }
+                       break;
+ #ifdef FEAT_QUICKFIX
+                   case ADDR_QUICKFIX:
+                       eap->line1 = 1;
+                       eap->line2 = qf_get_size(eap);
+                       if (eap->line2 == 0)
+                           eap->line2 = 1;
+                       break;
+ #endif
+               }
+               ++eap->addr_count;
+           }
+           else if (*eap->cmd == '*' && vim_strchr(p_cpo, CPO_STAR) == NULL)
+           {
+               pos_T       *fp;
+ 
+               // '*' - visual area
+               if (eap->addr_type != ADDR_LINES)
+               {
+                   *errormsg = (char_u *)_(e_invrange);
+                   return FAIL;
+               }
+ 
+               ++eap->cmd;
+               if (!eap->skip)
+               {
+                   fp = getmark('<', FALSE);
+                   if (check_mark(fp) == FAIL)
+                       return FAIL;
+                   eap->line1 = fp->lnum;
+                   fp = getmark('>', FALSE);
+                   if (check_mark(fp) == FAIL)
+                       return FAIL;
+                   eap->line2 = fp->lnum;
+                   ++eap->addr_count;
+               }
+           }
+       }
+       else
+           eap->line2 = lnum;
+       eap->addr_count++;
+ 
+       if (*eap->cmd == ';')
+       {
+           if (!eap->skip)
+           {
+               curwin->w_cursor.lnum = eap->line2;
+               // don't leave the cursor on an illegal line or column
+               check_cursor();
+           }
+       }
+       else if (*eap->cmd != ',')
+           break;
+       ++eap->cmd;
+     }
+ 
+     // One address given: set start and end lines.
+     if (eap->addr_count == 1)
+     {
+       eap->line1 = eap->line2;
+       // ... but only implicit: really no address given
+       if (lnum == MAXLNUM)
+           eap->addr_count = 0;
+     }
+     return OK;
+ }
+ 
+ /*
   * Check for an Ex command with optional tail.
   * If there is a match advance "pp" to the argument and return TRUE.
   */
***************
*** 4292,4298 ****
  }
  
  /*
!  * skip a range specifier of the form: addr [,addr] [;addr] ..
   *
   * Backslashed delimiters after / or ? will be skipped, and commands will
   * not be expanded between /'s and ?'s or after "'".
--- 4305,4311 ----
  }
  
  /*
!  * Skip a range specifier of the form: addr [,addr] [;addr] ..
   *
   * Backslashed delimiters after / or ? will be skipped, and commands will
   * not be expanded between /'s and ?'s or after "'".
*** ../vim-8.1.0265/src/proto/ex_docmd.pro      2018-07-29 17:35:19.493750319 
+0200
--- src/proto/ex_docmd.pro      2018-08-10 23:08:41.983672969 +0200
***************
*** 4,9 ****
--- 4,10 ----
  int do_cmdline(char_u *cmdline, char_u *(*fgetline)(int, void *, int), void 
*cookie, int flags);
  int getline_equal(char_u *(*fgetline)(int, void *, int), void *cookie, char_u 
*(*func)(int, void *, int));
  void *getline_cookie(char_u *(*fgetline)(int, void *, int), void *cookie);
+ int parse_cmd_address(exarg_T *eap, char_u **errormsg);
  int checkforcmd(char_u **pp, char *cmd, int len);
  int modifier_len(char_u *cmd);
  int cmd_exists(char_u *name);
*** ../vim-8.1.0265/src/version.c       2018-08-10 22:07:28.821903829 +0200
--- src/version.c       2018-08-10 22:39:25.770183225 +0200
***************
*** 796,797 ****
--- 796,799 ----
  {   /* Add new patch number below this line */
+ /**/
+     266,
  /**/

-- 
Permission is granted to read this message out aloud on Kings Cross Road,
London, under the condition that the orator is properly dressed.

 /// Bram Moolenaar -- b...@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    ///

-- 
-- 
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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui