Patch 9.0.0386
Problem:    Some code blocks are nested too deep.
Solution:   Bail out earlier. (Yegappan Lakshmanan, closes #11058)
Files:      src/alloc.c, src/arglist.c


*** ../vim-9.0.0385/src/alloc.c 2022-08-25 16:02:09.677816456 +0100
--- src/alloc.c 2022-09-05 14:30:43.542835013 +0100
***************
*** 87,103 ****
      j = 0;
      for (i = 0; i < MEM_SIZES - 1; i++)
      {
!       if (mem_allocs[i] || mem_frees[i])
        {
!           if (mem_frees[i] > mem_allocs[i])
!               printf("\r\n%s", _("ERROR: "));
!           printf("[%4d / %4lu-%-4lu] ", i + 1, mem_allocs[i], mem_frees[i]);
!           j++;
!           if (j > 3)
!           {
!               j = 0;
!               printf("\r\n");
!           }
        }
      }
  
--- 87,103 ----
      j = 0;
      for (i = 0; i < MEM_SIZES - 1; i++)
      {
!       if (mem_allocs[i] == 0 && mem_frees[i] == 0)
!           continue;
! 
!       if (mem_frees[i] > mem_allocs[i])
!           printf("\r\n%s", _("ERROR: "));
!       printf("[%4d / %4lu-%-4lu] ", i + 1, mem_allocs[i], mem_frees[i]);
!       j++;
!       if (j > 3)
        {
!           j = 0;
!           printf("\r\n");
        }
      }
  
***************
*** 332,353 ****
      void
  do_outofmem_msg(size_t size)
  {
!     if (!did_outofmem_msg)
!     {
!       // Don't hide this message
!       emsg_silent = 0;
  
!       // Must come first to avoid coming back here when printing the error
!       // message fails, e.g. when setting v:errmsg.
!       did_outofmem_msg = TRUE;
! 
!       semsg(_(e_out_of_memory_allocating_nr_bytes), (long_u)size);
! 
!       if (starting == NO_SCREEN)
!           // Not even finished with initializations and already out of
!           // memory?  Then nothing is going to work, exit.
!           mch_exit(123);
!     }
  }
  
  #if defined(EXITFREE) || defined(PROTO)
--- 332,353 ----
      void
  do_outofmem_msg(size_t size)
  {
!     if (did_outofmem_msg)
!       return;
  
!     // Don't hide this message
!     emsg_silent = 0;
! 
!     // Must come first to avoid coming back here when printing the error
!     // message fails, e.g. when setting v:errmsg.
!     did_outofmem_msg = TRUE;
! 
!     semsg(_(e_out_of_memory_allocating_nr_bytes), (long_u)size);
! 
!     if (starting == NO_SCREEN)
!       // Not even finished with initializations and already out of
!       // memory?  Then nothing is going to work, exit.
!       mch_exit(123);
  }
  
  #if defined(EXITFREE) || defined(PROTO)
***************
*** 780,799 ****
        len += (int)STRLEN(((char_u **)(gap->ga_data))[i]) + sep_len;
  
      s = alloc(len + 1);
!     if (s != NULL)
      {
!       *s = NUL;
!       p = s;
!       for (i = 0; i < gap->ga_len; ++i)
        {
!           if (p != s)
!           {
!               STRCPY(p, sep);
!               p += sep_len;
!           }
!           STRCPY(p, ((char_u **)(gap->ga_data))[i]);
!           p += STRLEN(p);
        }
      }
      return s;
  }
--- 780,799 ----
        len += (int)STRLEN(((char_u **)(gap->ga_data))[i]) + sep_len;
  
      s = alloc(len + 1);
!     if (s == NULL)
!       return NULL;
! 
!     *s = NUL;
!     p = s;
!     for (i = 0; i < gap->ga_len; ++i)
      {
!       if (p != s)
        {
!           STRCPY(p, sep);
!           p += sep_len;
        }
+       STRCPY(p, ((char_u **)(gap->ga_data))[i]);
+       p += STRLEN(p);
      }
      return s;
  }
*** ../vim-9.0.0385/src/arglist.c       2022-07-31 18:34:28.238324299 +0100
--- src/arglist.c       2022-09-05 14:28:40.887124282 +0100
***************
*** 105,129 ****
      char_u    *save_p_su = p_su;
      int               i;
  
      // Don't use 'suffixes' here.  This should work like the shell did the
      // expansion.  Also, the vimrc file isn't read yet, thus the user
      // can't set the options.
      p_su = empty_option;
!     old_arg_files = ALLOC_MULT(char_u *, GARGCOUNT);
!     if (old_arg_files != NULL)
!     {
!       for (i = 0; i < GARGCOUNT; ++i)
!           old_arg_files[i] = vim_strsave(GARGLIST[i].ae_fname);
!       old_arg_count = GARGCOUNT;
!       if (expand_wildcards(old_arg_count, old_arg_files,
!                   &new_arg_file_count, &new_arg_files,
!                   EW_FILE|EW_NOTFOUND|EW_ADDSLASH|EW_NOERROR) == OK
!               && new_arg_file_count > 0)
!       {
!           alist_set(&global_alist, new_arg_file_count, new_arg_files,
!                                                  TRUE, fnum_list, fnum_len);
!           FreeWild(old_arg_count, old_arg_files);
!       }
      }
      p_su = save_p_su;
  }
--- 105,129 ----
      char_u    *save_p_su = p_su;
      int               i;
  
+     old_arg_files = ALLOC_MULT(char_u *, GARGCOUNT);
+     if (old_arg_files == NULL)
+       return;
+ 
      // Don't use 'suffixes' here.  This should work like the shell did the
      // expansion.  Also, the vimrc file isn't read yet, thus the user
      // can't set the options.
      p_su = empty_option;
!     for (i = 0; i < GARGCOUNT; ++i)
!       old_arg_files[i] = vim_strsave(GARGLIST[i].ae_fname);
!     old_arg_count = GARGCOUNT;
!     if (expand_wildcards(old_arg_count, old_arg_files,
!               &new_arg_file_count, &new_arg_files,
!               EW_FILE|EW_NOTFOUND|EW_ADDSLASH|EW_NOERROR) == OK
!           && new_arg_file_count > 0)
!     {
!       alist_set(&global_alist, new_arg_file_count, new_arg_files,
!               TRUE, fnum_list, fnum_len);
!       FreeWild(old_arg_count, old_arg_files);
      }
      p_su = save_p_su;
  }
***************
*** 384,389 ****
--- 384,440 ----
  }
  
  /*
+  * Delete the file names in 'alist_ga' from the argument list.
+  */
+     static void
+ arglist_del_files(garray_T *alist_ga)
+ {
+     regmatch_T        regmatch;
+     int               didone;
+     int               i;
+     char_u    *p;
+     int               match;
+ 
+     // Delete the items: use each item as a regexp and find a match in the
+     // argument list.
+     regmatch.rm_ic = p_fic;   // ignore case when 'fileignorecase' is set
+     for (i = 0; i < alist_ga->ga_len && !got_int; ++i)
+     {
+       p = ((char_u **)alist_ga->ga_data)[i];
+       p = file_pat_to_reg_pat(p, NULL, NULL, FALSE);
+       if (p == NULL)
+           break;
+       regmatch.regprog = vim_regcomp(p, magic_isset() ? RE_MAGIC : 0);
+       if (regmatch.regprog == NULL)
+       {
+           vim_free(p);
+           break;
+       }
+ 
+       didone = FALSE;
+       for (match = 0; match < ARGCOUNT; ++match)
+           if (vim_regexec(&regmatch, alist_name(&ARGLIST[match]),
+                       (colnr_T)0))
+           {
+               didone = TRUE;
+               vim_free(ARGLIST[match].ae_fname);
+               mch_memmove(ARGLIST + match, ARGLIST + match + 1,
+                       (ARGCOUNT - match - 1) * sizeof(aentry_T));
+               --ALIST(curwin)->al_ga.ga_len;
+               if (curwin->w_arg_idx > match)
+                   --curwin->w_arg_idx;
+               --match;
+           }
+ 
+       vim_regfree(regmatch.regprog);
+       vim_free(p);
+       if (!didone)
+           semsg(_(e_no_match_str_2), ((char_u **)alist_ga->ga_data)[i]);
+     }
+     ga_clear(alist_ga);
+ }
+ 
+ /*
   * "what" == AL_SET: Redefine the argument list to 'str'.
   * "what" == AL_ADD: add files in 'str' to the argument list after "after".
   * "what" == AL_DEL: remove files in 'str' from the argument list.
***************
*** 401,408 ****
      int               exp_count;
      char_u    **exp_files;
      int               i;
-     char_u    *p;
-     int               match;
      int               arg_escaped = TRUE;
  
      if (check_arglist_locked() == FAIL)
--- 452,457 ----
***************
*** 422,469 ****
        return FAIL;
  
      if (what == AL_DEL)
!     {
!       regmatch_T      regmatch;
!       int             didone;
! 
!       // Delete the items: use each item as a regexp and find a match in the
!       // argument list.
!       regmatch.rm_ic = p_fic; // ignore case when 'fileignorecase' is set
!       for (i = 0; i < new_ga.ga_len && !got_int; ++i)
!       {
!           p = ((char_u **)new_ga.ga_data)[i];
!           p = file_pat_to_reg_pat(p, NULL, NULL, FALSE);
!           if (p == NULL)
!               break;
!           regmatch.regprog = vim_regcomp(p, magic_isset() ? RE_MAGIC : 0);
!           if (regmatch.regprog == NULL)
!           {
!               vim_free(p);
!               break;
!           }
! 
!           didone = FALSE;
!           for (match = 0; match < ARGCOUNT; ++match)
!               if (vim_regexec(&regmatch, alist_name(&ARGLIST[match]),
!                                                                 (colnr_T)0))
!               {
!                   didone = TRUE;
!                   vim_free(ARGLIST[match].ae_fname);
!                   mch_memmove(ARGLIST + match, ARGLIST + match + 1,
!                           (ARGCOUNT - match - 1) * sizeof(aentry_T));
!                   --ALIST(curwin)->al_ga.ga_len;
!                   if (curwin->w_arg_idx > match)
!                       --curwin->w_arg_idx;
!                   --match;
!               }
! 
!           vim_regfree(regmatch.regprog);
!           vim_free(p);
!           if (!didone)
!               semsg(_(e_no_match_str_2), ((char_u **)new_ga.ga_data)[i]);
!       }
!       ga_clear(&new_ga);
!     }
      else
      {
        i = expand_wildcards(new_ga.ga_len, (char_u **)new_ga.ga_data,
--- 471,477 ----
        return FAIL;
  
      if (what == AL_DEL)
!       arglist_del_files(&new_ga);
      else
      {
        i = expand_wildcards(new_ga.ga_len, (char_u **)new_ga.ga_data,
***************
*** 576,614 ****
      }
      else if (eap->cmdidx == CMD_args)
      {
        // ":args": list arguments.
!       if (ARGCOUNT > 0)
!       {
!           char_u **items = ALLOC_MULT(char_u *, ARGCOUNT);
  
!           if (items != NULL)
!           {
!               // Overwrite the command, for a short list there is no
!               // scrolling required and no wait_return().
!               gotocmdline(TRUE);
! 
!               for (i = 0; i < ARGCOUNT; ++i)
!                   items[i] = alist_name(&ARGLIST[i]);
!               list_in_columns(items, ARGCOUNT, curwin->w_arg_idx);
!               vim_free(items);
!           }
!       }
      }
      else if (eap->cmdidx == CMD_arglocal)
      {
        garray_T        *gap = &curwin->w_alist->al_ga;
  
        // ":argslocal": make a local copy of the global argument list.
!       if (GA_GROW_OK(gap, GARGCOUNT))
!           for (i = 0; i < GARGCOUNT; ++i)
!               if (GARGLIST[i].ae_fname != NULL)
!               {
!                   AARGLIST(curwin->w_alist)[gap->ga_len].ae_fname =
!                                           vim_strsave(GARGLIST[i].ae_fname);
!                   AARGLIST(curwin->w_alist)[gap->ga_len].ae_fnum =
!                                                         GARGLIST[i].ae_fnum;
!                   ++gap->ga_len;
!               }
      }
  }
  
--- 584,625 ----
      }
      else if (eap->cmdidx == CMD_args)
      {
+       char_u **items;
+ 
        // ":args": list arguments.
!       if (ARGCOUNT <= 0)
!           return;
  
!       items = ALLOC_MULT(char_u *, ARGCOUNT);
!       if (items == NULL)
!           return;
! 
!       // Overwrite the command, for a short list there is no scrolling
!       // required and no wait_return().
!       gotocmdline(TRUE);
! 
!       for (i = 0; i < ARGCOUNT; ++i)
!           items[i] = alist_name(&ARGLIST[i]);
!       list_in_columns(items, ARGCOUNT, curwin->w_arg_idx);
!       vim_free(items);
      }
      else if (eap->cmdidx == CMD_arglocal)
      {
        garray_T        *gap = &curwin->w_alist->al_ga;
  
        // ":argslocal": make a local copy of the global argument list.
!       if (GA_GROW_FAILS(gap, GARGCOUNT))
!           return;
! 
!       for (i = 0; i < GARGCOUNT; ++i)
!           if (GARGLIST[i].ae_fname != NULL)
!           {
!               AARGLIST(curwin->w_alist)[gap->ga_len].ae_fname =
!                   vim_strsave(GARGLIST[i].ae_fname);
!               AARGLIST(curwin->w_alist)[gap->ga_len].ae_fnum =
!                   GARGLIST[i].ae_fnum;
!               ++gap->ga_len;
!           }
      }
  }
  
***************
*** 1374,1413 ****
                    && check_for_opt_number_arg(argvars, 1) == FAIL)))
        return;
  
!     if (argvars[0].v_type != VAR_UNKNOWN)
      {
!       if (argvars[1].v_type == VAR_UNKNOWN)
!       {
!           arglist = ARGLIST;
!           argcount = ARGCOUNT;
!       }
!       else if (argvars[1].v_type == VAR_NUMBER
!                                          && tv_get_number(&argvars[1]) == -1)
!       {
!           arglist = GARGLIST;
!           argcount = GARGCOUNT;
!       }
!       else
!       {
!           win_T       *wp = find_win_by_nr_or_id(&argvars[1]);
! 
!           if (wp != NULL)
!           {
!               // Use the argument list of the specified window
!               arglist = WARGLIST(wp);
!               argcount = WARGCOUNT(wp);
!           }
!       }
  
!       rettv->v_type = VAR_STRING;
!       rettv->vval.v_string = NULL;
!       idx = tv_get_number_chk(&argvars[0], NULL);
!       if (arglist != NULL && idx >= 0 && idx < argcount)
!           rettv->vval.v_string = vim_strsave(alist_name(&arglist[idx]));
!       else if (idx == -1)
!           get_arglist_as_rettv(arglist, argcount, rettv);
      }
      else
!       get_arglist_as_rettv(ARGLIST, ARGCOUNT, rettv);
  }
  #endif
--- 1385,1425 ----
                    && check_for_opt_number_arg(argvars, 1) == FAIL)))
        return;
  
!     if (argvars[0].v_type == VAR_UNKNOWN)
      {
!       get_arglist_as_rettv(ARGLIST, ARGCOUNT, rettv);
!       return;
!     }
  
!     if (argvars[1].v_type == VAR_UNKNOWN)
!     {
!       arglist = ARGLIST;
!       argcount = ARGCOUNT;
!     }
!     else if (argvars[1].v_type == VAR_NUMBER
!           && tv_get_number(&argvars[1]) == -1)
!     {
!       arglist = GARGLIST;
!       argcount = GARGCOUNT;
      }
      else
!     {
!       win_T   *wp = find_win_by_nr_or_id(&argvars[1]);
! 
!       if (wp != NULL)
!       {
!           // Use the argument list of the specified window
!           arglist = WARGLIST(wp);
!           argcount = WARGCOUNT(wp);
!       }
!     }
! 
!     rettv->v_type = VAR_STRING;
!     rettv->vval.v_string = NULL;
!     idx = tv_get_number_chk(&argvars[0], NULL);
!     if (arglist != NULL && idx >= 0 && idx < argcount)
!       rettv->vval.v_string = vim_strsave(alist_name(&arglist[idx]));
!     else if (idx == -1)
!       get_arglist_as_rettv(arglist, argcount, rettv);
  }
  #endif
*** ../vim-9.0.0385/src/version.c       2022-09-05 13:05:26.034229996 +0100
--- src/version.c       2022-09-05 14:29:47.018967798 +0100
***************
*** 705,706 ****
--- 705,708 ----
  {   /* Add new patch number below this line */
+ /**/
+     386,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
5. You find yourself brainstorming for new subjects to search.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            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/20220905133425.510731C0CE4%40moolenaar.net.

Raspunde prin e-mail lui