Patch 9.0.1246
Problem:    Code is indented more than necessary.
Solution:   Use an early return where it makes sense. (Yegappan Lakshmanan,
            closes #11887)
Files:      src/ui.c, src/undo.c, src/uninstall.c, src/userfunc.c,
            src/version.c, src/vim9compile.c, src/vim9execute.c,
            src/vim9instr.c, src/vim9script.c, src/vim9type.c, src/viminfo.c,
            src/winclip.c, src/window.c


*** ../vim-9.0.1245/src/ui.c    2022-11-30 18:11:52.694904295 +0000
--- src/ui.c    2023-01-26 11:56:00.566262685 +0000
***************
*** 83,102 ****
      if (ta_str != NULL)
        newlen += ta_len - ta_off;
      new = alloc(newlen);
!     if (new != NULL)
      {
!       if (ta_str != NULL)
!       {
!           mch_memmove(new, ta_str + ta_off, (size_t)(ta_len - ta_off));
!           mch_memmove(new + ta_len - ta_off, s, (size_t)len);
!           vim_free(ta_str);
!       }
!       else
!           mch_memmove(new, s, (size_t)len);
!       ta_str = new;
!       ta_len = newlen;
!       ta_off = 0;
      }
  }
  #endif
  
--- 83,102 ----
      if (ta_str != NULL)
        newlen += ta_len - ta_off;
      new = alloc(newlen);
!     if (new == NULL)
!       return;
! 
!     if (ta_str != NULL)
      {
!       mch_memmove(new, ta_str + ta_off, (size_t)(ta_len - ta_off));
!       mch_memmove(new + ta_len - ta_off, s, (size_t)len);
!       vim_free(ta_str);
      }
+     else
+       mch_memmove(new, s, (size_t)len);
+     ta_str = new;
+     ta_len = newlen;
+     ta_off = 0;
  }
  #endif
  
***************
*** 815,839 ****
  {
      garray_T  *gap = (garray_T *)p;
  
!     if (gap != NULL)
      {
!       if (gap->ga_data != NULL)
        {
!           if (overwrite || inbufcount + gap->ga_len >= INBUFLEN)
!           {
!               mch_memmove(inbuf, gap->ga_data, gap->ga_len);
!               inbufcount = gap->ga_len;
!           }
!           else
!           {
!               mch_memmove(inbuf + gap->ga_len, inbuf, inbufcount);
!               mch_memmove(inbuf, gap->ga_data, gap->ga_len);
!               inbufcount += gap->ga_len;
!           }
!           vim_free(gap->ga_data);
        }
!       vim_free(gap);
      }
  }
  
  /*
--- 815,839 ----
  {
      garray_T  *gap = (garray_T *)p;
  
!     if (gap == NULL)
!       return;
! 
!     if (gap->ga_data != NULL)
      {
!       if (overwrite || inbufcount + gap->ga_len >= INBUFLEN)
        {
!           mch_memmove(inbuf, gap->ga_data, gap->ga_len);
!           inbufcount = gap->ga_len;
!       }
!       else
!       {
!           mch_memmove(inbuf + gap->ga_len, inbuf, inbufcount);
!           mch_memmove(inbuf, gap->ga_data, gap->ga_len);
!           inbufcount += gap->ga_len;
        }
!       vim_free(gap->ga_data);
      }
+     vim_free(gap);
  }
  
  /*
*** ../vim-9.0.1245/src/undo.c  2023-01-02 18:10:00.019271226 +0000
--- src/undo.c  2023-01-26 11:56:00.566262685 +0000
***************
*** 1164,1184 ****
  {
      char_u  *ptr = alloc(len + 1);
  
!     if (ptr != NULL)
      {
!       if (len > 0 && undo_read(bi, ptr, len) == FAIL)
!       {
!           vim_free(ptr);
!           return NULL;
!       }
!       // In case there are text properties there already is a NUL, but
!       // checking for that is more expensive than just adding a dummy byte.
!       ptr[len] = NUL;
  #ifdef FEAT_CRYPT
!       if (bi->bi_state != NULL && bi->bi_buffer == NULL)
!           crypt_decode_inplace(bi->bi_state, ptr, len, FALSE);
  #endif
-     }
      return ptr;
  }
  
--- 1164,1184 ----
  {
      char_u  *ptr = alloc(len + 1);
  
!     if (ptr == NULL)
!       return NULL;
! 
!     if (len > 0 && undo_read(bi, ptr, len) == FAIL)
      {
!       vim_free(ptr);
!       return NULL;
!     }
!     // In case there are text properties there already is a NUL, but
!     // checking for that is more expensive than just adding a dummy byte.
!     ptr[len] = NUL;
  #ifdef FEAT_CRYPT
!     if (bi->bi_state != NULL && bi->bi_buffer == NULL)
!       crypt_decode_inplace(bi->bi_state, ptr, len, FALSE);
  #endif
      return ptr;
  }
  
***************
*** 3510,3521 ****
      void
  u_clearline(void)
  {
!     if (curbuf->b_u_line_ptr.ul_line != NULL)
!     {
!       VIM_CLEAR(curbuf->b_u_line_ptr.ul_line);
!       curbuf->b_u_line_ptr.ul_len = 0;
!       curbuf->b_u_line_lnum = 0;
!     }
  }
  
  /*
--- 3510,3521 ----
      void
  u_clearline(void)
  {
!     if (curbuf->b_u_line_ptr.ul_line == NULL)
!       return;
! 
!     VIM_CLEAR(curbuf->b_u_line_ptr.ul_line);
!     curbuf->b_u_line_ptr.ul_len = 0;
!     curbuf->b_u_line_lnum = 0;
  }
  
  /*
***************
*** 3726,3749 ****
      void
  f_undotree(typval_T *argvars UNUSED, typval_T *rettv)
  {
!     if (rettv_dict_alloc(rettv) == OK)
!     {
!       dict_T *dict = rettv->vval.v_dict;
!       list_T *list;
  
!       dict_add_number(dict, "synced", (long)curbuf->b_u_synced);
!       dict_add_number(dict, "seq_last", curbuf->b_u_seq_last);
!       dict_add_number(dict, "save_last", curbuf->b_u_save_nr_last);
!       dict_add_number(dict, "seq_cur", curbuf->b_u_seq_cur);
!       dict_add_number(dict, "time_cur", (long)curbuf->b_u_time_cur);
!       dict_add_number(dict, "save_cur", curbuf->b_u_save_nr_cur);
  
!       list = list_alloc();
!       if (list != NULL)
!       {
!           u_eval_tree(curbuf->b_u_oldhead, list);
!           dict_add_list(dict, "entries", list);
!       }
      }
  }
  
--- 3726,3749 ----
      void
  f_undotree(typval_T *argvars UNUSED, typval_T *rettv)
  {
!     if (rettv_dict_alloc(rettv) == FAIL)
!       return;
  
!     dict_T *dict = rettv->vval.v_dict;
!     list_T *list;
  
!     dict_add_number(dict, "synced", (long)curbuf->b_u_synced);
!     dict_add_number(dict, "seq_last", curbuf->b_u_seq_last);
!     dict_add_number(dict, "save_last", curbuf->b_u_save_nr_last);
!     dict_add_number(dict, "seq_cur", curbuf->b_u_seq_cur);
!     dict_add_number(dict, "time_cur", (long)curbuf->b_u_time_cur);
!     dict_add_number(dict, "save_cur", curbuf->b_u_save_nr_cur);
! 
!     list = list_alloc();
!     if (list != NULL)
!     {
!       u_eval_tree(curbuf->b_u_oldhead, list);
!       dict_add_list(dict, "entries", list);
      }
  }
  
*** ../vim-9.0.1245/src/uninstall.c     2023-01-22 21:14:32.621863614 +0000
--- src/uninstall.c     2023-01-26 11:56:00.570262677 +0000
***************
*** 205,222 ****
      int               found = FALSE;
  
      fd = fopen(path, "r");
!     if (fd != NULL)
      {
!       while (fgets(line, sizeof(line), fd) != NULL)
        {
!           if (strncmp(line, VIMBAT_UNINSTKEY, key_len) == 0)
!           {
!               found = TRUE;
!               break;
!           }
        }
-       fclose(fd);
      }
      return found;
  }
  
--- 205,222 ----
      int               found = FALSE;
  
      fd = fopen(path, "r");
!     if (fd == NULL)
!       return FALSE;
! 
!     while (fgets(line, sizeof(line), fd) != NULL)
      {
!       if (strncmp(line, VIMBAT_UNINSTKEY, key_len) == 0)
        {
!           found = TRUE;
!           break;
        }
      }
+     fclose(fd);
      return found;
  }
  
***************
*** 261,272 ****
      sprintf(buf, "%s\\%s", path, filename);
  
      fd = fopen(buf, "r");
!     if (fd != NULL)
!     {
!       fclose(fd);
!       printf("removing %s\n", buf);
!       remove(buf);
!     }
  }
  
      static void
--- 261,272 ----
      sprintf(buf, "%s\\%s", path, filename);
  
      fd = fopen(buf, "r");
!     if (fd == NULL)
!       return;
! 
!     fclose(fd);
!     printf("removing %s\n", buf);
!     remove(buf);
  }
  
      static void
***************
*** 287,307 ****
      int               i;
      struct stat st;
  
!     if (get_shell_folder_path(path, VIM_STARTMENU))
      {
!       for (i = 1; i < TARGET_COUNT; ++i)
!           remove_if_exists(path, targets[i].lnkname);
!       remove_if_exists(path, "uninstall.lnk");
!       remove_if_exists(path, "Help.lnk");
!       // Win95 uses .pif, WinNT uses .lnk
!       remove_if_exists(path, "Vim tutor.pif");
!       remove_if_exists(path, "Vim tutor.lnk");
!       remove_if_exists(path, "Vim online.url");
!       if (stat(path, &st) == 0)
!       {
!           printf("removing %s\n", path);
!           rmdir(path);
!       }
      }
  }
  
--- 287,307 ----
      int               i;
      struct stat st;
  
!     if (get_shell_folder_path(path, VIM_STARTMENU) == FAIL)
!       return;
! 
!     for (i = 1; i < TARGET_COUNT; ++i)
!       remove_if_exists(path, targets[i].lnkname);
!     remove_if_exists(path, "uninstall.lnk");
!     remove_if_exists(path, "Help.lnk");
!     // Win95 uses .pif, WinNT uses .lnk
!     remove_if_exists(path, "Vim tutor.pif");
!     remove_if_exists(path, "Vim tutor.lnk");
!     remove_if_exists(path, "Vim online.url");
!     if (stat(path, &st) == 0)
      {
!       printf("removing %s\n", path);
!       rmdir(path);
      }
  }
  
*** ../vim-9.0.1245/src/userfunc.c      2023-01-25 12:27:09.454493126 +0000
--- src/userfunc.c      2023-01-26 11:56:00.570262677 +0000
***************
*** 770,794 ****
      static void
  function_using_block_scopes(ufunc_T *fp, cstack_T *cstack)
  {
!     if (cstack != NULL && cstack->cs_idx >= 0)
!     {
!       int         count = cstack->cs_idx + 1;
!       int         i;
  
!       fp->uf_block_ids = ALLOC_MULT(int, count);
!       if (fp->uf_block_ids != NULL)
!       {
!           mch_memmove(fp->uf_block_ids, cstack->cs_block_id,
!                                                         sizeof(int) * count);
!           fp->uf_block_depth = count;
!       }
  
!       // Set flag in each block to indicate a function was defined.  This
!       // is used to keep the variable when leaving the block, see
!       // hide_script_var().
!       for (i = 0; i <= cstack->cs_idx; ++i)
!           cstack->cs_flags[i] |= CSF_FUNC_DEF;
!     }
  }
  
  /*
--- 770,794 ----
      static void
  function_using_block_scopes(ufunc_T *fp, cstack_T *cstack)
  {
!     if (cstack == NULL || cstack->cs_idx < 0)
!       return;
  
!     int           count = cstack->cs_idx + 1;
!     int           i;
  
!     fp->uf_block_ids = ALLOC_MULT(int, count);
!     if (fp->uf_block_ids != NULL)
!     {
!       mch_memmove(fp->uf_block_ids, cstack->cs_block_id,
!               sizeof(int) * count);
!       fp->uf_block_depth = count;
!     }
! 
!     // Set flag in each block to indicate a function was defined.  This
!     // is used to keep the variable when leaving the block, see
!     // hide_script_var().
!     for (i = 0; i <= cstack->cs_idx; ++i)
!       cstack->cs_flags[i] |= CSF_FUNC_DEF;
  }
  
  /*
***************
*** 2433,2453 ****
        return FALSE;
  
      hi = hash_find(&func_hashtab, UF2HIKEY(fp));
!     if (!HASHITEM_EMPTY(hi))
      {
!       // When there is a def-function index do not actually remove the
!       // function, so we can find the index when defining the function again.
!       // Do remove it when it's a copy.
!       if (fp->uf_def_status == UF_COMPILED && (fp->uf_flags & FC_COPY) == 0)
!       {
!           fp->uf_flags |= FC_DEAD;
!           return FALSE;
!       }
!       hash_remove(&func_hashtab, hi, "remove function");
!       fp->uf_flags |= FC_DELETED;
!       return TRUE;
      }
!     return FALSE;
  }
  
      static void
--- 2433,2452 ----
        return FALSE;
  
      hi = hash_find(&func_hashtab, UF2HIKEY(fp));
!     if (HASHITEM_EMPTY(hi))
!       return FALSE;
! 
!     // When there is a def-function index do not actually remove the
!     // function, so we can find the index when defining the function again.
!     // Do remove it when it's a copy.
!     if (fp->uf_def_status == UF_COMPILED && (fp->uf_flags & FC_COPY) == 0)
      {
!       fp->uf_flags |= FC_DEAD;
!       return FALSE;
      }
!     hash_remove(&func_hashtab, hi, "remove function");
!     fp->uf_flags |= FC_DELETED;
!     return TRUE;
  }
  
      static void
*** ../vim-9.0.1245/src/version.c       2023-01-25 21:05:35.131042802 +0000
--- src/version.c       2023-01-26 11:57:00.850190166 +0000
***************
*** 57,82 ****
      void
  init_longVersion(void)
  {
!     if (longVersion == NULL)
!     {
  #ifdef BUILD_DATE
!       char *date_time = BUILD_DATE;
  #else
!       char *date_time = __DATE__ " " __TIME__;
  #endif
!       char *msg = _("%s (%s, compiled %s)");
!       size_t len = strlen(msg)
!                   + strlen(VIM_VERSION_LONG_ONLY)
!                   + strlen(VIM_VERSION_DATE_ONLY)
!                   + strlen(date_time);
  
!       longVersion = alloc(len);
!       if (longVersion == NULL)
!           longVersion = VIM_VERSION_LONG;
!       else
!           vim_snprintf(longVersion, len, msg,
!                     VIM_VERSION_LONG_ONLY, VIM_VERSION_DATE_ONLY, date_time);
!     }
  }
  # endif
  #else
--- 57,82 ----
      void
  init_longVersion(void)
  {
!     if (longVersion != NULL)
!       return;
! 
  #ifdef BUILD_DATE
!     char *date_time = BUILD_DATE;
  #else
!     char *date_time = __DATE__ " " __TIME__;
  #endif
!     char *msg = _("%s (%s, compiled %s)");
!     size_t len = strlen(msg)
!       + strlen(VIM_VERSION_LONG_ONLY)
!       + strlen(VIM_VERSION_DATE_ONLY)
!       + strlen(date_time);
  
!     longVersion = alloc(len);
!     if (longVersion == NULL)
!       longVersion = VIM_VERSION_LONG;
!     else
!       vim_snprintf(longVersion, len, msg,
!               VIM_VERSION_LONG_ONLY, VIM_VERSION_DATE_ONLY, date_time);
  }
  # endif
  #else
*** ../vim-9.0.1245/src/vim9compile.c   2023-01-18 14:51:03.767305352 +0000
--- src/vim9compile.c   2023-01-26 11:56:00.570262677 +0000
***************
*** 3939,3956 ****
      void
  unlink_def_function(ufunc_T *ufunc)
  {
!     if (ufunc->uf_dfunc_idx > 0)
!     {
!       dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
!                                                        + ufunc->uf_dfunc_idx;
! 
!       if (--dfunc->df_refcount <= 0)
!           delete_def_function_contents(dfunc, TRUE);
!       ufunc->uf_def_status = UF_NOT_COMPILED;
!       ufunc->uf_dfunc_idx = 0;
!       if (dfunc->df_ufunc == ufunc)
!           dfunc->df_ufunc = NULL;
!     }
  }
  
  /*
--- 3939,3956 ----
      void
  unlink_def_function(ufunc_T *ufunc)
  {
!     if (ufunc->uf_dfunc_idx <= 0)
!       return;
! 
!     dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
!       + ufunc->uf_dfunc_idx;
! 
!     if (--dfunc->df_refcount <= 0)
!       delete_def_function_contents(dfunc, TRUE);
!     ufunc->uf_def_status = UF_NOT_COMPILED;
!     ufunc->uf_dfunc_idx = 0;
!     if (dfunc->df_ufunc == ufunc)
!       dfunc->df_ufunc = NULL;
  }
  
  /*
***************
*** 3959,3971 ****
      void
  link_def_function(ufunc_T *ufunc)
  {
!     if (ufunc->uf_dfunc_idx > 0)
!     {
!       dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
!                                                        + ufunc->uf_dfunc_idx;
  
!       ++dfunc->df_refcount;
!     }
  }
  
  #if defined(EXITFREE) || defined(PROTO)
--- 3959,3971 ----
      void
  link_def_function(ufunc_T *ufunc)
  {
!     if (ufunc->uf_dfunc_idx <= 0)
!       return;
! 
!     dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
!       + ufunc->uf_dfunc_idx;
  
!     ++dfunc->df_refcount;
  }
  
  #if defined(EXITFREE) || defined(PROTO)
*** ../vim-9.0.1245/src/vim9execute.c   2023-01-20 18:49:42.763170966 +0000
--- src/vim9execute.c   2023-01-26 11:56:00.570262677 +0000
***************
*** 279,292 ****
      void
  update_has_breakpoint(ufunc_T *ufunc)
  {
!     if (ufunc->uf_debug_tick != debug_tick)
!     {
!       linenr_T breakpoint;
  
!       ufunc->uf_debug_tick = debug_tick;
!       breakpoint = dbg_find_breakpoint(FALSE, ufunc->uf_name, 0);
!       ufunc->uf_has_breakpoint = breakpoint > 0;
!     }
  }
  
  static garray_T dict_stack = GA_EMPTY;
--- 279,292 ----
      void
  update_has_breakpoint(ufunc_T *ufunc)
  {
!     if (ufunc->uf_debug_tick == debug_tick)
!       return;
  
!     linenr_T breakpoint;
! 
!     ufunc->uf_debug_tick = debug_tick;
!     breakpoint = dbg_find_breakpoint(FALSE, ufunc->uf_name, 0);
!     ufunc->uf_has_breakpoint = breakpoint > 0;
  }
  
  static garray_T dict_stack = GA_EMPTY;
***************
*** 383,411 ****
      static int
  check_ufunc_arg_types(ufunc_T *ufunc, int argcount, int off, ectx_T *ectx)
  {
!     if (ufunc->uf_arg_types != NULL || ufunc->uf_va_type != NULL)
!     {
!       typval_T        *argv = STACK_TV_BOT(0) - argcount - off;
  
!       // The function can change at runtime, check that the argument
!       // types are correct.
!       for (int i = 0; i < argcount; ++i)
!       {
!           type_T *type = NULL;
  
!           // assume a v:none argument, using the default value, is always OK
!           if (argv[i].v_type == VAR_SPECIAL
!                                        && argv[i].vval.v_number == VVAL_NONE)
!               continue;
! 
!           if (i < ufunc->uf_args.ga_len && ufunc->uf_arg_types != NULL)
!               type = ufunc->uf_arg_types[i];
!           else if (ufunc->uf_va_type != NULL)
!               type = ufunc->uf_va_type->tt_member;
!           if (type != NULL && check_typval_arg_type(type,
!                                           &argv[i], NULL, i + 1) == FAIL)
!               return FAIL;
!       }
      }
      return OK;
  }
--- 383,411 ----
      static int
  check_ufunc_arg_types(ufunc_T *ufunc, int argcount, int off, ectx_T *ectx)
  {
!     if (ufunc->uf_arg_types == NULL && ufunc->uf_va_type == NULL)
!       return OK;
  
!     typval_T  *argv = STACK_TV_BOT(0) - argcount - off;
  
!     // The function can change at runtime, check that the argument
!     // types are correct.
!     for (int i = 0; i < argcount; ++i)
!     {
!       type_T *type = NULL;
! 
!       // assume a v:none argument, using the default value, is always OK
!       if (argv[i].v_type == VAR_SPECIAL
!               && argv[i].vval.v_number == VVAL_NONE)
!           continue;
! 
!       if (i < ufunc->uf_args.ga_len && ufunc->uf_arg_types != NULL)
!           type = ufunc->uf_arg_types[i];
!       else if (ufunc->uf_va_type != NULL)
!           type = ufunc->uf_va_type->tt_member;
!       if (type != NULL && check_typval_arg_type(type,
!                   &argv[i], NULL, i + 1) == FAIL)
!           return FAIL;
      }
      return OK;
  }
***************
*** 1527,1547 ****
      static int
  do_2string(typval_T *tv, int is_2string_any, int tolerant)
  {
!     if (tv->v_type != VAR_STRING)
!     {
!       char_u *str;
  
!       if (is_2string_any)
        {
!           switch (tv->v_type)
!           {
!               case VAR_SPECIAL:
!               case VAR_BOOL:
!               case VAR_NUMBER:
!               case VAR_FLOAT:
!               case VAR_BLOB:  break;
  
!               case VAR_LIST:
                                if (tolerant)
                                {
                                    char_u      *s, *e, *p;
--- 1527,1548 ----
      static int
  do_2string(typval_T *tv, int is_2string_any, int tolerant)
  {
!     if (tv->v_type == VAR_STRING)
!       return OK;
! 
!     char_u *str;
  
!     if (is_2string_any)
!     {
!       switch (tv->v_type)
        {
!           case VAR_SPECIAL:
!           case VAR_BOOL:
!           case VAR_NUMBER:
!           case VAR_FLOAT:
!           case VAR_BLOB:      break;
  
!           case VAR_LIST:
                                if (tolerant)
                                {
                                    char_u      *s, *e, *p;
***************
*** 1560,1566 ****
                                    {
                                        *e = NUL;
                                        p = vim_strsave_fnameescape(s,
!                                                                    VSE_NONE);
                                        if (p != NULL)
                                        {
                                            ga_concat(&ga, p);
--- 1561,1567 ----
                                    {
                                        *e = NUL;
                                        p = vim_strsave_fnameescape(s,
!                                               VSE_NONE);
                                        if (p != NULL)
                                        {
                                            ga_concat(&ga, p);
***************
*** 1576,1590 ****
                                    return OK;
                                }
                                // FALLTHROUGH
!               default:        to_string_error(tv->v_type);
!                               return FAIL;
!           }
        }
-       str = typval_tostring(tv, TRUE);
-       clear_tv(tv);
-       tv->v_type = VAR_STRING;
-       tv->vval.v_string = str;
      }
      return OK;
  }
  
--- 1577,1590 ----
                                    return OK;
                                }
                                // FALLTHROUGH
!           default:    to_string_error(tv->v_type);
!                       return FAIL;
        }
      }
+     str = typval_tostring(tv, TRUE);
+     clear_tv(tv);
+     tv->v_type = VAR_STRING;
+     tv->vval.v_string = str;
      return OK;
  }
  
*** ../vim-9.0.1245/src/vim9instr.c     2023-01-16 20:47:53.889287080 +0000
--- src/vim9instr.c     2023-01-26 11:56:00.570262677 +0000
***************
*** 2306,2346 ****
                            lhs->lhs_opt_flags, lhs->lhs_vimvaridx,
                            lhs->lhs_type, lhs->lhs_name, lhs);
  
!     if (lhs->lhs_lvar != NULL)
      {
!       garray_T        *instr = &cctx->ctx_instr;
!       isn_T           *isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
  
!       // Optimization: turn "var = 123" from ISN_PUSHNR + ISN_STORE into
!       // ISN_STORENR.
!       // And "var = 0" does not need any instruction.
!       if (lhs->lhs_lvar->lv_from_outer == 0
!               && instr->ga_len == instr_count + 1
!               && isn->isn_type == ISN_PUSHNR)
        {
!           varnumber_T val = isn->isn_arg.number;
!           garray_T    *stack = &cctx->ctx_type_stack;
! 
!           if (val == 0 && is_decl && !inside_loop_scope(cctx))
!           {
!               // zero is the default value, no need to do anything
!               --instr->ga_len;
!           }
!           else
!           {
!               isn->isn_type = ISN_STORENR;
!               isn->isn_arg.storenr.stnr_idx = lhs->lhs_lvar->lv_idx;
!               isn->isn_arg.storenr.stnr_val = val;
!           }
!           if (stack->ga_len > 0)
!               --stack->ga_len;
        }
-       else if (lhs->lhs_lvar->lv_from_outer > 0)
-           generate_STOREOUTER(cctx, lhs->lhs_lvar->lv_idx,
-                    lhs->lhs_lvar->lv_from_outer, lhs->lhs_lvar->lv_loop_idx);
        else
!           generate_STORE(cctx, ISN_STORE, lhs->lhs_lvar->lv_idx, NULL);
      }
      return OK;
  }
  
--- 2306,2346 ----
                            lhs->lhs_opt_flags, lhs->lhs_vimvaridx,
                            lhs->lhs_type, lhs->lhs_name, lhs);
  
!     if (lhs->lhs_lvar == NULL)
!       return OK;
! 
!     garray_T  *instr = &cctx->ctx_instr;
!     isn_T             *isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
! 
!     // Optimization: turn "var = 123" from ISN_PUSHNR + ISN_STORE into
!     // ISN_STORENR.
!     // And "var = 0" does not need any instruction.
!     if (lhs->lhs_lvar->lv_from_outer == 0
!           && instr->ga_len == instr_count + 1
!           && isn->isn_type == ISN_PUSHNR)
      {
!       varnumber_T val = isn->isn_arg.number;
!       garray_T    *stack = &cctx->ctx_type_stack;
  
!       if (val == 0 && is_decl && !inside_loop_scope(cctx))
        {
!           // zero is the default value, no need to do anything
!           --instr->ga_len;
        }
        else
!       {
!           isn->isn_type = ISN_STORENR;
!           isn->isn_arg.storenr.stnr_idx = lhs->lhs_lvar->lv_idx;
!           isn->isn_arg.storenr.stnr_val = val;
!       }
!       if (stack->ga_len > 0)
!           --stack->ga_len;
      }
+     else if (lhs->lhs_lvar->lv_from_outer > 0)
+       generate_STOREOUTER(cctx, lhs->lhs_lvar->lv_idx,
+               lhs->lhs_lvar->lv_from_outer, lhs->lhs_lvar->lv_loop_idx);
+     else
+       generate_STORE(cctx, ISN_STORE, lhs->lhs_lvar->lv_idx, NULL);
      return OK;
  }
  
*** ../vim-9.0.1245/src/vim9script.c    2023-01-03 19:08:46.005020599 +0000
--- src/vim9script.c    2023-01-26 11:56:00.574262676 +0000
***************
*** 1007,1048 ****
      // The typval is moved into the sallvar_T.
      script_hi = hash_find(script_ht, sv->sv_name);
      all_hi = hash_find(all_ht, sv->sv_name);
!     if (!HASHITEM_EMPTY(script_hi) && !HASHITEM_EMPTY(all_hi))
      {
!       dictitem_T      *di = HI2DI(script_hi);
!       sallvar_T       *sav = HI2SAV(all_hi);
!       sallvar_T       *sav_prev = NULL;
  
!       // There can be multiple entries with the same name in different
!       // blocks, find the right one.
!       while (sav != NULL && sav->sav_var_vals_idx != idx)
!       {
!           sav_prev = sav;
!           sav = sav->sav_next;
!       }
!       if (sav != NULL)
!       {
!           if (func_defined)
!           {
!               // move the typval from the dictitem to the sallvar
!               sav->sav_tv = di->di_tv;
!               di->di_tv.v_type = VAR_UNKNOWN;
!               sav->sav_flags = di->di_flags;
!               sav->sav_di = NULL;
!               sv->sv_tv = &sav->sav_tv;
!           }
!           else
!           {
!               if (sav_prev == NULL)
!                   hash_remove(all_ht, all_hi, "hide variable");
!               else
!                   sav_prev->sav_next = sav->sav_next;
!               sv->sv_name = NULL;
!               vim_free(sav);
!           }
!           delete_var(script_ht, script_hi);
!       }
      }
  }
  
  /*
--- 1007,1049 ----
      // The typval is moved into the sallvar_T.
      script_hi = hash_find(script_ht, sv->sv_name);
      all_hi = hash_find(all_ht, sv->sv_name);
! 
!     if (HASHITEM_EMPTY(script_hi) || HASHITEM_EMPTY(all_hi))
!       return;
! 
!     dictitem_T        *di = HI2DI(script_hi);
!     sallvar_T *sav = HI2SAV(all_hi);
!     sallvar_T *sav_prev = NULL;
! 
!     // There can be multiple entries with the same name in different
!     // blocks, find the right one.
!     while (sav != NULL && sav->sav_var_vals_idx != idx)
      {
!       sav_prev = sav;
!       sav = sav->sav_next;
!     }
!     if (sav == NULL)
!       return;
  
!     if (func_defined)
!     {
!       // move the typval from the dictitem to the sallvar
!       sav->sav_tv = di->di_tv;
!       di->di_tv.v_type = VAR_UNKNOWN;
!       sav->sav_flags = di->di_flags;
!       sav->sav_di = NULL;
!       sv->sv_tv = &sav->sav_tv;
!     }
!     else
!     {
!       if (sav_prev == NULL)
!           hash_remove(all_ht, all_hi, "hide variable");
!       else
!           sav_prev->sav_next = sav->sav_next;
!       sv->sv_name = NULL;
!       vim_free(sav);
      }
+     delete_var(script_ht, script_hi);
  }
  
  /*
*** ../vim-9.0.1245/src/vim9type.c      2023-01-20 18:49:42.763170966 +0000
--- src/vim9type.c      2023-01-26 11:56:00.574262676 +0000
***************
*** 37,47 ****
      if (ga_grow(type_gap, 1) == FAIL)
        return NULL;
      type = ALLOC_CLEAR_ONE(type_T);
!     if (type != NULL)
!     {
!       ((type_T **)type_gap->ga_data)[type_gap->ga_len] = type;
!       ++type_gap->ga_len;
!     }
      return type;
  }
  
--- 37,47 ----
      if (ga_grow(type_gap, 1) == FAIL)
        return NULL;
      type = ALLOC_CLEAR_ONE(type_T);
!     if (type == NULL)
!       return NULL;
! 
!     ((type_T **)type_gap->ga_data)[type_gap->ga_len] = type;
!     ++type_gap->ga_len;
      return type;
  }
  
***************
*** 628,644 ****
  {
      type_T *type = typval2type_int(tv, copyID, type_gap, flags);
  
!     if (type != NULL)
!     {
!       if (type != &t_bool && (tv->v_type == VAR_NUMBER
!                   && (tv->vval.v_number == 0 || tv->vval.v_number == 1)))
!           // Number 0 and 1 and expression with "&&" or "||" can also be used
!           // for bool.
!           type = &t_number_bool;
!       else if (type != &t_float && tv->v_type == VAR_NUMBER)
!           // A number can also be used for float.
!           type = &t_number_float;
!     }
      return type;
  }
  
--- 628,644 ----
  {
      type_T *type = typval2type_int(tv, copyID, type_gap, flags);
  
!     if (type == NULL)
!       return NULL;
! 
!     if (type != &t_bool && (tv->v_type == VAR_NUMBER
!               && (tv->vval.v_number == 0 || tv->vval.v_number == 1)))
!       // Number 0 and 1 and expression with "&&" or "||" can also be used
!       // for bool.
!       type = &t_number_bool;
!     else if (type != &t_float && tv->v_type == VAR_NUMBER)
!       // A number can also be used for float.
!       type = &t_number_float;
      return type;
  }
  
*** ../vim-9.0.1245/src/viminfo.c       2022-12-08 15:32:11.087034211 +0000
--- src/viminfo.c       2023-01-26 11:56:00.574262676 +0000
***************
*** 385,407 ****
      size_t  n;
  
      name = home_replace_save(NULL, name);
!     if (name != NULL)
      {
!       for (p = p_viminfo; *p; )
        {
!           copy_option_part(&p, part, 51, ", ");
!           if (part[0] == 'r')
            {
!               n = STRLEN(part + 1);
!               if (MB_STRNICMP(part + 1, name, n) == 0)
!               {
!                   retval = TRUE;
!                   break;
!               }
            }
        }
-       vim_free(name);
      }
      return retval;
  }
  
--- 385,406 ----
      size_t  n;
  
      name = home_replace_save(NULL, name);
!     if (name == NULL)
!       return FALSE;
!     for (p = p_viminfo; *p; )
      {
!       copy_option_part(&p, part, 51, ", ");
!       if (part[0] == 'r')
        {
!           n = STRLEN(part + 1);
!           if (MB_STRNICMP(part + 1, name, n) == 0)
            {
!               retval = TRUE;
!               break;
            }
        }
      }
+     vim_free(name);
      return retval;
  }
  
***************
*** 534,582 ****
  {
      int               type;
      long_u    len;
!     char_u    *val;
      char_u    *p;
  
      type = hist_char2type(virp->vir_line[0]);
!     if (viminfo_hisidx[type] < viminfo_hislen[type])
!     {
!       val = viminfo_readstring(virp, 1, TRUE);
!       if (val != NULL && *val != NUL)
!       {
!           int sep = (*val == ' ' ? NUL : *val);
  
!           if (!in_history(type, val + (type == HIST_SEARCH),
!                                         viminfo_add_at_front, sep, writing))
!           {
!               // Need to re-allocate to append the separator byte.
!               len = STRLEN(val);
!               p = alloc(len + 2);
!               if (p != NULL)
!               {
!                   if (type == HIST_SEARCH)
!                   {
!                       // Search entry: Move the separator from the first
!                       // column to after the NUL.
!                       mch_memmove(p, val + 1, (size_t)len);
!                       p[len] = sep;
!                   }
!                   else
!                   {
!                       // Not a search entry: No separator in the viminfo
!                       // file, add a NUL separator.
!                       mch_memmove(p, val, (size_t)len + 1);
!                       p[len + 1] = NUL;
!                   }
!                   viminfo_history[type][viminfo_hisidx[type]].hisstr = p;
!                   viminfo_history[type][viminfo_hisidx[type]].time_set = 0;
!                   viminfo_history[type][viminfo_hisidx[type]].viminfo = TRUE;
!                   viminfo_history[type][viminfo_hisidx[type]].hisnum = 0;
!                   viminfo_hisidx[type]++;
!               }
!           }
!       }
!       vim_free(val);
      }
      return viminfo_readline(virp);
  }
  
--- 533,583 ----
  {
      int               type;
      long_u    len;
!     char_u    *val = NULL;
      char_u    *p;
  
      type = hist_char2type(virp->vir_line[0]);
!     if (viminfo_hisidx[type] >= viminfo_hislen[type])
!       goto done;
  
!     val = viminfo_readstring(virp, 1, TRUE);
!     if (val == NULL || *val == NUL)
!       goto done;
! 
!     int sep = (*val == ' ' ? NUL : *val);
! 
!     if (in_history(type, val + (type == HIST_SEARCH), viminfo_add_at_front,
!                                                               sep, writing))
!       goto done;
! 
!     // Need to re-allocate to append the separator byte.
!     len = STRLEN(val);
!     p = alloc(len + 2);
!     if (p == NULL)
!       goto done;
! 
!     if (type == HIST_SEARCH)
!     {
!       // Search entry: Move the separator from the first
!       // column to after the NUL.
!       mch_memmove(p, val + 1, (size_t)len);
!       p[len] = sep;
      }
+     else
+     {
+       // Not a search entry: No separator in the viminfo
+       // file, add a NUL separator.
+       mch_memmove(p, val, (size_t)len + 1);
+       p[len + 1] = NUL;
+     }
+     viminfo_history[type][viminfo_hisidx[type]].hisstr = p;
+     viminfo_history[type][viminfo_hisidx[type]].time_set = 0;
+     viminfo_history[type][viminfo_hisidx[type]].viminfo = TRUE;
+     viminfo_history[type][viminfo_hisidx[type]].hisnum = 0;
+     viminfo_hisidx[type]++;
+ 
+ done:
+     vim_free(val);
      return viminfo_readline(virp);
  }
  
***************
*** 607,660 ****
      type = vp[0].bv_nr;
      if (type >= HIST_COUNT)
        return;
-     if (viminfo_hisidx[type] < viminfo_hislen[type])
-     {
-       val = vp[3].bv_string;
-       if (val != NULL && *val != NUL)
-       {
-           int sep = type == HIST_SEARCH && vp[2].bv_type == BVAL_NR
-                                                     ? vp[2].bv_nr : NUL;
-           int idx;
-           int overwrite = FALSE;
  
!           if (!in_history(type, val, viminfo_add_at_front, sep, writing))
!           {
!               // If lines were written by an older Vim we need to avoid
!               // getting duplicates. See if the entry already exists.
!               for (idx = 0; idx < viminfo_hisidx[type]; ++idx)
!               {
!                   p = viminfo_history[type][idx].hisstr;
!                   if (STRCMP(val, p) == 0
!                         && (type != HIST_SEARCH || sep == p[STRLEN(p) + 1]))
!                   {
!                       overwrite = TRUE;
!                       break;
!                   }
!               }
  
!               if (!overwrite)
!               {
!                   // Need to re-allocate to append the separator byte.
!                   len = vp[3].bv_len;
!                   p = alloc(len + 2);
!               }
!               else
!                   len = 0; // for picky compilers
!               if (p != NULL)
!               {
!                   viminfo_history[type][idx].time_set = vp[1].bv_nr;
!                   if (!overwrite)
!                   {
!                       mch_memmove(p, val, (size_t)len + 1);
!                       // Put the separator after the NUL.
!                       p[len + 1] = sep;
!                       viminfo_history[type][idx].hisstr = p;
!                       viminfo_history[type][idx].hisnum = 0;
!                       viminfo_history[type][idx].viminfo = TRUE;
!                       viminfo_hisidx[type]++;
!                   }
!               }
!           }
        }
      }
  }
--- 608,662 ----
      type = vp[0].bv_nr;
      if (type >= HIST_COUNT)
        return;
  
!     if (viminfo_hisidx[type] >= viminfo_hislen[type])
!       return;
  
!     val = vp[3].bv_string;
!     if (val == NULL || *val == NUL)
!       return;
! 
!     int sep = type == HIST_SEARCH && vp[2].bv_type == BVAL_NR
!                                                       ? vp[2].bv_nr : NUL;
!     int idx;
!     int overwrite = FALSE;
! 
!     if (in_history(type, val, viminfo_add_at_front, sep, writing))
!       return;
! 
!     // If lines were written by an older Vim we need to avoid
!     // getting duplicates. See if the entry already exists.
!     for (idx = 0; idx < viminfo_hisidx[type]; ++idx)
!     {
!       p = viminfo_history[type][idx].hisstr;
!       if (STRCMP(val, p) == 0
!               && (type != HIST_SEARCH || sep == p[STRLEN(p) + 1]))
!       {
!           overwrite = TRUE;
!           break;
!       }
!     }
! 
!     if (!overwrite)
!     {
!       // Need to re-allocate to append the separator byte.
!       len = vp[3].bv_len;
!       p = alloc(len + 2);
!     }
!     else
!       len = 0; // for picky compilers
!     if (p != NULL)
!     {
!       viminfo_history[type][idx].time_set = vp[1].bv_nr;
!       if (!overwrite)
!       {
!           mch_memmove(p, val, (size_t)len + 1);
!           // Put the separator after the NUL.
!           p[len + 1] = sep;
!           viminfo_history[type][idx].hisstr = p;
!           viminfo_history[type][idx].hisnum = 0;
!           viminfo_history[type][idx].viminfo = TRUE;
!           viminfo_hisidx[type]++;
        }
      }
  }
***************
*** 943,961 ****
      int               seen_useful = FALSE;
      char      *line;
  
!     if (gap->ga_len > 0)
!     {
!       fputs(_("\n# Bar lines, copied verbatim:\n"), fp_out);
  
!       // Skip over continuation lines until seeing a useful line.
!       for (i = 0; i < gap->ga_len; ++i)
        {
!           line = ((char **)(gap->ga_data))[i];
!           if (seen_useful || line[1] != '<')
!           {
!               fputs(line, fp_out);
!               seen_useful = TRUE;
!           }
        }
      }
  }
--- 945,963 ----
      int               seen_useful = FALSE;
      char      *line;
  
!     if (gap->ga_len <= 0)
!       return;
! 
!     fputs(_("\n# Bar lines, copied verbatim:\n"), fp_out);
  
!     // Skip over continuation lines until seeing a useful line.
!     for (i = 0; i < gap->ga_len; ++i)
!     {
!       line = ((char **)(gap->ga_data))[i];
!       if (seen_useful || line[1] != '<')
        {
!           fputs(line, fp_out);
!           seen_useful = TRUE;
        }
      }
  }
***************
*** 1408,1418 ****
  {
      char_u *old_sub = get_old_sub();
  
!     if (get_viminfo_parameter('/') != 0 && old_sub != NULL)
!     {
!       fputs(_("\n# Last Substitute String:\n$"), fp);
!       viminfo_writestring(fp, old_sub);
!     }
  }
  
  /*
--- 1410,1420 ----
  {
      char_u *old_sub = get_old_sub();
  
!     if (get_viminfo_parameter('/') == 0 || old_sub == NULL)
!       return;
! 
!     fputs(_("\n# Last Substitute String:\n$"), fp);
!     viminfo_writestring(fp, old_sub);
  }
  
  /*
***************
*** 1511,1544 ****
      int               sc)     // dir char
  {
      spat_T    *spat = get_spat(idx);
!     if (spat->pat != NULL)
!     {
!       fprintf(fp, _("\n# Last %sSearch Pattern:\n~"), s);
!       // off.dir is not stored, it's reset to forward
!       fprintf(fp, "%c%c%c%c%ld%s%c",
!               spat->magic    ? 'M' : 'm',     // magic
!               spat->no_scs   ? 's' : 'S',     // smartcase
!               spat->off.line ? 'L' : 'l',     // line offset
!               spat->off.end  ? 'E' : 'e',     // offset from end
!               spat->off.off,                  // offset
!               get_spat_last_idx() == idx ? "~" : "",  // last used pat
!               sc);
!       viminfo_writestring(fp, spat->pat);
!     }
  }
  
      static void
  write_viminfo_search_pattern(FILE *fp)
  {
!     if (get_viminfo_parameter('/') != 0)
!     {
  #ifdef FEAT_SEARCH_EXTRA
!       fprintf(fp, "\n# hlsearch on (H) or off (h):\n~%c",
            (no_hlsearch || find_viminfo_parameter('h') != NULL) ? 'h' : 'H');
  #endif
!       wvsp_one(fp, RE_SEARCH, "", '/');
!       wvsp_one(fp, RE_SUBST, _("Substitute "), '&');
!     }
  }
  
  /*
--- 1513,1546 ----
      int               sc)     // dir char
  {
      spat_T    *spat = get_spat(idx);
!     if (spat->pat == NULL)
!       return;
! 
!     fprintf(fp, _("\n# Last %sSearch Pattern:\n~"), s);
!     // off.dir is not stored, it's reset to forward
!     fprintf(fp, "%c%c%c%c%ld%s%c",
!           spat->magic    ? 'M' : 'm', // magic
!           spat->no_scs   ? 's' : 'S', // smartcase
!           spat->off.line ? 'L' : 'l', // line offset
!           spat->off.end  ? 'E' : 'e', // offset from end
!           spat->off.off,                      // offset
!           get_spat_last_idx() == idx ? "~" : "",      // last used pat
!           sc);
!     viminfo_writestring(fp, spat->pat);
  }
  
      static void
  write_viminfo_search_pattern(FILE *fp)
  {
!     if (get_viminfo_parameter('/') == 0)
!       return;
! 
  #ifdef FEAT_SEARCH_EXTRA
!     fprintf(fp, "\n# hlsearch on (H) or off (h):\n~%c",
            (no_hlsearch || find_viminfo_parameter('h') != NULL) ? 'h' : 'H');
  #endif
!     wvsp_one(fp, RE_SEARCH, "", '/');
!     wvsp_one(fp, RE_SUBST, _("Substitute "), '&');
  }
  
  /*
***************
*** 1565,1581 ****
      int               i;
      int               j;
  
!     if (y_read_regs != NULL)
!     {
!       for (i = 0; i < NUM_REGISTERS; ++i)
!           if (y_read_regs[i].y_array != NULL)
!           {
!               for (j = 0; j < y_read_regs[i].y_size; j++)
!                   vim_free(y_read_regs[i].y_array[j]);
!               vim_free(y_read_regs[i].y_array);
!           }
!       VIM_CLEAR(y_read_regs);
!     }
  }
  
      static int
--- 1567,1583 ----
      int               i;
      int               j;
  
!     if (y_read_regs == NULL)
!       return;
! 
!     for (i = 0; i < NUM_REGISTERS; ++i)
!       if (y_read_regs[i].y_array != NULL)
!       {
!           for (j = 0; j < y_read_regs[i].y_size; j++)
!               vim_free(y_read_regs[i].y_array[j]);
!           vim_free(y_read_regs[i].y_array);
!       }
!     VIM_CLEAR(y_read_regs);
  }
  
      static int
*** ../vim-9.0.1245/src/winclip.c       2022-11-18 22:14:04.802988148 +0000
--- src/winclip.c       2023-01-26 11:56:00.574262676 +0000
***************
*** 149,159 ****
      *outlen = MultiByteToWideChar(cp, flags, in, inlen, 0, 0);
      // Add one word to avoid a zero-length alloc().
      *out = ALLOC_MULT(WCHAR, *outlen + 1);
!     if (*out != NULL)
!     {
!       MultiByteToWideChar(cp, flags, in, inlen, *out, *outlen);
!       (*out)[*outlen] = 0;
!     }
  }
  
  /*
--- 149,159 ----
      *outlen = MultiByteToWideChar(cp, flags, in, inlen, 0, 0);
      // Add one word to avoid a zero-length alloc().
      *out = ALLOC_MULT(WCHAR, *outlen + 1);
!     if (*out == NULL)
!       return;
! 
!     MultiByteToWideChar(cp, flags, in, inlen, *out, *outlen);
!     (*out)[*outlen] = 0;
  }
  
  /*
***************
*** 169,179 ****
      *outlen = WideCharToMultiByte(cp, flags, in, inlen, NULL, 0, def, 
useddef);
      // Add one byte to avoid a zero-length alloc().
      *out = alloc(*outlen + 1);
!     if (*out != NULL)
!     {
!       WideCharToMultiByte(cp, flags, in, inlen, *out, *outlen, def, useddef);
!       (*out)[*outlen] = 0;
!     }
  }
  
  
--- 169,178 ----
      *outlen = WideCharToMultiByte(cp, flags, in, inlen, NULL, 0, def, 
useddef);
      // Add one byte to avoid a zero-length alloc().
      *out = alloc(*outlen + 1);
!     if (*out == NULL)
!       return;
!     WideCharToMultiByte(cp, flags, in, inlen, *out, *outlen, def, useddef);
!     (*out)[*outlen] = 0;
  }
  
  
***************
*** 743,754 ****
  
      MultiByteToWideChar_alloc(GetACP(), 0, (LPCSTR)str, str_size,
                                                            &widestr, outlen);
!     if (widestr != NULL)
!     {
!       ++*outlen;      // Include the 0 after the string
!       *out = utf16_to_enc((short_u *)widestr, outlen);
!       vim_free(widestr);
!     }
  }
  
  /*
--- 742,752 ----
  
      MultiByteToWideChar_alloc(GetACP(), 0, (LPCSTR)str, str_size,
                                                            &widestr, outlen);
!     if (widestr == NULL)
!       return;
!     ++*outlen;        // Include the 0 after the string
!     *out = utf16_to_enc((short_u *)widestr, outlen);
!     vim_free(widestr);
  }
  
  /*
***************
*** 768,777 ****
      int               len = str_size;
  
      widestr = (WCHAR *)enc_to_utf16(str, &len);
!     if (widestr != NULL)
!     {
!       WideCharToMultiByte_alloc(GetACP(), 0, widestr, len,
!                                               (LPSTR *)out, outlen, 0, 0);
!       vim_free(widestr);
!     }
  }
--- 766,774 ----
      int               len = str_size;
  
      widestr = (WCHAR *)enc_to_utf16(str, &len);
!     if (widestr == NULL)
!       return;
!     WideCharToMultiByte_alloc(GetACP(), 0, widestr, len,
!           (LPSTR *)out, outlen, 0, 0);
!     vim_free(widestr);
  }
*** ../vim-9.0.1245/src/window.c        2022-12-13 12:26:04.855054169 +0000
--- src/window.c        2023-01-26 11:56:00.574262676 +0000
***************
*** 2469,2505 ****
      int               free_buf,
      tabpage_T   *prev_curtab)
  {
!     if (ONE_WINDOW)
!     {
!       buf_T   *old_curbuf = curbuf;
  
!       /*
!        * Closing the last window in a tab page.  First go to another tab
!        * page and then close the window and the tab page.  This avoids that
!        * curwin and curtab are invalid while we are freeing memory, they may
!        * be used in GUI events.
!        * Don't trigger autocommands yet, they may use wrong values, so do
!        * that below.
!        */
!       goto_tabpage_tp(alt_tabpage(), FALSE, TRUE);
  
!       // Safety check: Autocommands may have closed the window when jumping
!       // to the other tab page.
!       if (valid_tabpage(prev_curtab) && prev_curtab->tp_firstwin == win)
!           win_close_othertab(win, free_buf, prev_curtab);
  #ifdef FEAT_JOB_CHANNEL
!       entering_window(curwin);
  #endif
!       // Since goto_tabpage_tp above did not trigger *Enter autocommands, do
!       // that now.
!       apply_autocmds(EVENT_TABCLOSED, NULL, NULL, FALSE, curbuf);
!       apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
!       apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf);
!       if (old_curbuf != curbuf)
!           apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
!       return TRUE;
!     }
!     return FALSE;
  }
  
  /*
--- 2469,2504 ----
      int               free_buf,
      tabpage_T   *prev_curtab)
  {
!     if (!ONE_WINDOW)
!       return FALSE;
  
!     buf_T     *old_curbuf = curbuf;
! 
!     /*
!      * Closing the last window in a tab page.  First go to another tab
!      * page and then close the window and the tab page.  This avoids that
!      * curwin and curtab are invalid while we are freeing memory, they may
!      * be used in GUI events.
!      * Don't trigger autocommands yet, they may use wrong values, so do
!      * that below.
!      */
!     goto_tabpage_tp(alt_tabpage(), FALSE, TRUE);
  
!     // Safety check: Autocommands may have closed the window when jumping
!     // to the other tab page.
!     if (valid_tabpage(prev_curtab) && prev_curtab->tp_firstwin == win)
!       win_close_othertab(win, free_buf, prev_curtab);
  #ifdef FEAT_JOB_CHANNEL
!     entering_window(curwin);
  #endif
!     // Since goto_tabpage_tp above did not trigger *Enter autocommands, do
!     // that now.
!     apply_autocmds(EVENT_TABCLOSED, NULL, NULL, FALSE, curbuf);
!     apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
!     apply_autocmds(EVENT_TABENTER, NULL, NULL, FALSE, curbuf);
!     if (old_curbuf != curbuf)
!       apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
!     return TRUE;
  }
  
  /*
***************
*** 4205,4219 ****
      win_T *wp;
  
      wp = win_alloc(NULL, TRUE);
!     if (wp != NULL)
!     {
!       // We need to initialize options with something, using the current
!       // window makes most sense.
!       win_init_some(wp, curwin);
  
!       RESET_BINDING(wp);
!       new_frame(wp);
!     }
      return wp;
  }
  
--- 4204,4217 ----
      win_T *wp;
  
      wp = win_alloc(NULL, TRUE);
!     if (wp == NULL)
!       return NULL;
!     // We need to initialize options with something, using the current
!     // window makes most sense.
!     win_init_some(wp, curwin);
  
!     RESET_BINDING(wp);
!     new_frame(wp);
      return wp;
  }
  
***************
*** 4287,4297 ****
      frame_T *frp = ALLOC_CLEAR_ONE(frame_T);
  
      wp->w_frame = frp;
!     if (frp != NULL)
!     {
!       frp->fr_layout = FR_LEAF;
!       frp->fr_win = wp;
!     }
  }
  
  /*
--- 4285,4294 ----
      frame_T *frp = ALLOC_CLEAR_ONE(frame_T);
  
      wp->w_frame = frp;
!     if (frp == NULL)
!       return;
!     frp->fr_layout = FR_LEAF;
!     frp->fr_win = wp;
  }
  
  /*
***************
*** 4489,4501 ****
      int               n = (cmdmod.cmod_tab == 0)
                                       ? postponed_split_tab : cmdmod.cmod_tab;
  
!     if (n != 0)
!     {
!       cmdmod.cmod_tab = 0;        // reset it to avoid doing it twice
!       postponed_split_tab = 0;
!       return win_new_tabpage(n);
!     }
!     return FAIL;
  }
  
  /*
--- 4486,4497 ----
      int               n = (cmdmod.cmod_tab == 0)
                                       ? postponed_split_tab : cmdmod.cmod_tab;
  
!     if (n == 0)
!       return FAIL;
! 
!     cmdmod.cmod_tab = 0;          // reset it to avoid doing it twice
!     postponed_split_tab = 0;
!     return win_new_tabpage(n);
  }
  
  /*
***************
*** 4880,4891 ****
      int
  goto_tabpage_lastused(void)
  {
!     if (valid_tabpage(lastused_tabpage))
!     {
!       goto_tabpage_tp(lastused_tabpage, TRUE, TRUE);
!       return OK;
!     }
!     return FAIL;
  }
  
  /*
--- 4876,4886 ----
      int
  goto_tabpage_lastused(void)
  {
!     if (!valid_tabpage(lastused_tabpage))
!       return FAIL;
! 
!     goto_tabpage_tp(lastused_tabpage, TRUE, TRUE);
!     return OK;
  }
  
  /*
***************
*** 5907,5923 ****
      win_T     *wp;
  
      ga_init2(gap, sizeof(int), 1);
!     if (ga_grow(gap, win_count() * 2 + 1) == OK)
!     {
!       // first entry is value of 'lines'
!       ((int *)gap->ga_data)[gap->ga_len++] = Rows;
  
!       FOR_ALL_WINDOWS(wp)
!       {
!           ((int *)gap->ga_data)[gap->ga_len++] =
!                                              wp->w_width + wp->w_vsep_width;
!           ((int *)gap->ga_data)[gap->ga_len++] = wp->w_height;
!       }
      }
  }
  
--- 5902,5918 ----
      win_T     *wp;
  
      ga_init2(gap, sizeof(int), 1);
!     if (ga_grow(gap, win_count() * 2 + 1) == FAIL)
!       return;
  
!     // first entry is value of 'lines'
!     ((int *)gap->ga_data)[gap->ga_len++] = Rows;
! 
!     FOR_ALL_WINDOWS(wp)
!     {
!       ((int *)gap->ga_data)[gap->ga_len++] =
!           wp->w_width + wp->w_vsep_width;
!       ((int *)gap->ga_data)[gap->ga_len++] = wp->w_height;
      }
  }
  
***************
*** 7429,7440 ****
      static void
  clear_snapshot_rec(frame_T *fr)
  {
!     if (fr != NULL)
!     {
!       clear_snapshot_rec(fr->fr_next);
!       clear_snapshot_rec(fr->fr_child);
!       vim_free(fr);
!     }
  }
  
  /*
--- 7424,7434 ----
      static void
  clear_snapshot_rec(frame_T *fr)
  {
!     if (fr == NULL)
!       return;
!     clear_snapshot_rec(fr->fr_next);
!     clear_snapshot_rec(fr->fr_child);
!     vim_free(fr);
  }
  
  /*
*** ../vim-9.0.1245/src/version.c       2023-01-25 21:05:35.131042802 +0000
--- src/version.c       2023-01-26 11:57:00.850190166 +0000
***************
*** 697,698 ****
--- 697,700 ----
  {   /* Add new patch number below this line */
+ /**/
+     1246,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
48. You get a tatoo that says "This body best viewed with Netscape 3.1 or
    higher."

 /// 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/20230126120029.4204A1C065A%40moolenaar.net.

Raspunde prin e-mail lui