To: vim_dev@googlegroups.com Subject: Patch 9.0.0386 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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(®match, 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(®match, 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 -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///