# HG changeset patch # User Bram Moolenaar # Date 1586204139 -7200 # Node ID 3ff714d765bac9696552bbb9fc0ee47e3fd80440 # Parent 005e707a7988c067acb38de63bdd7f144f62393f patch 8.2.0523: loops are repeated Commit: https://github.com/vim/vim/commit/00d253e2b2f435a5386582c3f857008e7ac355c2 Author: Bram Moolenaar Date: Mon Apr 6 22:13:01 2020 +0200 patch 8.2.0523: loops are repeated Problem: Loops are repeated. Solution: Use FOR_ALL_ macros. (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/5882) diff --git a/src/buffer.c b/src/buffer.c --- a/src/buffer.c +++ b/src/buffer.c @@ -52,6 +52,9 @@ static void clear_wininfo(buf_T *buf); # define dev_T unsigned #endif +#define FOR_ALL_BUFS_FROM_LAST(buf) \ + for ((buf) = lastbuf; (buf) != NULL; (buf) = (buf)->b_prev) + #if defined(FEAT_QUICKFIX) static char *msg_loclist = N_("[Location List]"); static char *msg_qflist = N_("[Quickfix List]"); @@ -415,7 +418,7 @@ buf_valid(buf_T *buf) // Assume that we more often have a recent buffer, start with the last // one. - for (bp = lastbuf; bp != NULL; bp = bp->b_prev) + FOR_ALL_BUFS_FROM_LAST(bp) if (bp == buf) return TRUE; return FALSE; @@ -2510,7 +2513,7 @@ buflist_findname_stat( buf_T *buf; // Start at the last buffer, expect to find a match sooner. - for (buf = lastbuf; buf != NULL; buf = buf->b_prev) + FOR_ALL_BUFS_FROM_LAST(buf) if ((buf->b_flags & BF_DUMMY) == 0 && !otherfile_buf(buf, ffname #ifdef UNIX , stp @@ -2593,7 +2596,7 @@ buflist_findpat( return -1; } - for (buf = lastbuf; buf != NULL; buf = buf->b_prev) + FOR_ALL_BUFS_FROM_LAST(buf) if (buf->b_p_bl == find_listed #ifdef FEAT_DIFF && (!diffmode || diff_mode_buf(buf)) diff --git a/src/drawscreen.c b/src/drawscreen.c --- a/src/drawscreen.c +++ b/src/drawscreen.c @@ -963,7 +963,7 @@ redraw_win_toolbar(win_T *wp) int button_attr = syn_name2attr((char_u *)"ToolbarButton"); vim_free(wp->w_winbar_items); - for (menu = wp->w_winbar->children; menu != NULL; menu = menu->next) + FOR_ALL_CHILD_MENUS(wp->w_winbar, menu) ++item_count; wp->w_winbar_items = ALLOC_CLEAR_MULT(winbar_item_T, item_count + 1); diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -5008,7 +5008,7 @@ f_inputlist(typval_T *argvars, typval_T l = argvars[0].vval.v_list; range_list_materialize(l); - FOR_ALL_LIST_ITEMS(argvars[0].vval.v_list, li) + FOR_ALL_LIST_ITEMS(l, li) { msg_puts((char *)tv_get_string(&li->li_tv)); msg_putchar('\n'); @@ -7317,7 +7317,7 @@ f_setreg(typval_T *argvars, typval_T *re if (ll != NULL) { range_list_materialize(ll); - for (li = ll->lv_first; li != NULL; li = li->li_next) + FOR_ALL_LIST_ITEMS(ll, li) { strval = tv_get_string_buf_chk(&li->li_tv, buf); if (strval == NULL) diff --git a/src/evalwindow.c b/src/evalwindow.c --- a/src/evalwindow.c +++ b/src/evalwindow.c @@ -444,8 +444,7 @@ get_tabpage_info(tabpage_T *tp, int tp_i l = list_alloc(); if (l != NULL) { - for (wp = (tp == curtab) ? firstwin : tp->tp_firstwin; - wp != NULL; wp = wp->w_next) + FOR_ALL_WINDOWS_IN_TAB(tp, wp) list_append_number(l, (varnumber_T)wp->w_id); dict_add_list(dict, "windows", l); } diff --git a/src/globals.h b/src/globals.h --- a/src/globals.h +++ b/src/globals.h @@ -574,6 +574,10 @@ EXTERN vimmenu_T *root_menu INIT(= NULL) * overruling of menus that the user already defined. */ EXTERN int sys_menu INIT(= FALSE); + +#define FOR_ALL_MENUS(m) for ((m) = root_menu; (m) != NULL; (m) = (m)->next) +#define FOR_ALL_CHILD_MENUS(p, c) \ + for ((c) = (p)->children; (c) != NULL; (c) = (c)->next) #endif #ifdef FEAT_GUI @@ -724,7 +728,8 @@ EXTERN buf_T *firstbuf INIT(= NULL); // EXTERN buf_T *lastbuf INIT(= NULL); // last buffer EXTERN buf_T *curbuf INIT(= NULL); // currently active buffer -#define FOR_ALL_BUFFERS(buf) for (buf = firstbuf; buf != NULL; buf = buf->b_next) +#define FOR_ALL_BUFFERS(buf) \ + for ((buf) = firstbuf; (buf) != NULL; (buf) = (buf)->b_next) #define FOR_ALL_BUF_WININFO(buf, wip) \ for ((wip) = (buf)->b_wininfo; (wip) != NULL; (wip) = (wip)->wi_next) @@ -1484,7 +1489,7 @@ EXTERN disptick_T display_tick INIT(= 0) EXTERN linenr_T spell_redraw_lnum INIT(= 0); #define FOR_ALL_SPELL_LANGS(slang) \ - for ((slang) = first_lang; (slang) != NULL; (slang) = slang->sl_next) + for ((slang) = first_lang; (slang) != NULL; (slang) = (slang)->sl_next) #endif #ifdef FEAT_CONCEAL @@ -1545,20 +1550,20 @@ EXTERN char e_font[] INIT(= N_("E235: U EXTERN char e_fontwidth[] INIT(= N_("E236: Font \"%s\" is not fixed-width")); #endif EXTERN char e_internal[] INIT(= N_("E473: Internal error")); -EXTERN char e_intern2[] INIT(= N_("E685: Internal error: %s")); -EXTERN char e_interr[] INIT(= N_("Interrupted")); -EXTERN char e_invarg[] INIT(= N_("E474: Invalid argument")); -EXTERN char e_invarg2[] INIT(= N_("E475: Invalid argument: %s")); -EXTERN char e_duparg2[] INIT(= N_("E983: Duplicate argument: %s")); +EXTERN char e_intern2[] INIT(= N_("E685: Internal error: %s")); +EXTERN char e_interr[] INIT(= N_("Interrupted")); +EXTERN char e_invarg[] INIT(= N_("E474: Invalid argument")); +EXTERN char e_invarg2[] INIT(= N_("E475: Invalid argument: %s")); +EXTERN char e_duparg2[] INIT(= N_("E983: Duplicate argument: %s")); EXTERN char e_invargval[] INIT(= N_("E475: Invalid value for argument %s")); EXTERN char e_invargNval[] INIT(= N_("E475: Invalid value for argument %s: %s")); #ifdef FEAT_EVAL EXTERN char e_invexpr2[] INIT(= N_("E15: Invalid expression: %s")); #endif EXTERN char e_invrange[] INIT(= N_("E16: Invalid range")); -EXTERN char e_invcmd[] INIT(= N_("E476: Invalid command")); +EXTERN char e_invcmd[] INIT(= N_("E476: Invalid command")); #if defined(UNIX) || defined(FEAT_SYN_HL) || defined(FEAT_SPELL) -EXTERN char e_isadir2[] INIT(= N_("E17: \"%s\" is a directory")); +EXTERN char e_isadir2[] INIT(= N_("E17: \"%s\" is a directory")); #endif #ifdef FEAT_LIBCALL EXTERN char e_libcall[] INIT(= N_("E364: Library call failed for \"%s()\"")); @@ -1614,8 +1619,8 @@ EXTERN char e_noserver[] INIT(= N_("E247 #endif EXTERN char e_notcreate[] INIT(= N_("E482: Can't create file %s")); EXTERN char e_notmp[] INIT(= N_("E483: Can't get temp file name")); -EXTERN char e_notopen[] INIT(= N_("E484: Can't open file %s")); -EXTERN char e_notread[] INIT(= N_("E485: Can't read file %s")); +EXTERN char e_notopen[] INIT(= N_("E484: Can't open file %s")); +EXTERN char e_notread[] INIT(= N_("E485: Can't read file %s")); EXTERN char e_null[] INIT(= N_("E38: Null argument")); #if defined(FEAT_DIGRAPHS) || defined(FEAT_TIMERS) || defined(FEAT_EVAL) EXTERN char e_number_exp[] INIT(= N_("E39: Number expected")); @@ -1837,6 +1842,16 @@ EXTERN HINSTANCE g_hinst INIT(= NULL); EXTERN int did_repeated_msg INIT(= 0); # define REPEATED_MSG_LOOKING 1 # define REPEATED_MSG_SAFESTATE 2 + +#define FOR_ALL_CHANNELS(ch) \ + for ((ch) = first_channel; (ch) != NULL; (ch) = (ch)->ch_next) +#define FOR_ALL_JOBS(job) \ + for ((job) = first_job; (job) != NULL; (job) = (job)->jv_next) +#endif + +#if defined(FEAT_DIFF) +#define FOR_ALL_DIFFBLOCKS_IN_TAB(tp, dp) \ + for ((dp) = (tp)->tp_first_diff; (dp) != NULL; (dp) = (dp)->df_next) #endif #define FOR_ALL_LIST_ITEMS(l, li) \ diff --git a/src/gui_athena.c b/src/gui_athena.c --- a/src/gui_athena.c +++ b/src/gui_athena.c @@ -954,7 +954,7 @@ gui_mch_new_menu_font(void) vimmenu_T *mp; int max_height = 9999; - for (mp = root_menu; mp != NULL; mp = mp->next) + FOR_ALL_MENUS(mp) { if (menu_is_menubar(mp->dname)) { @@ -1280,7 +1280,7 @@ gui_mch_show_toolbar(int showit) vimmenu_T *toolbar; vimmenu_T *cur; - for (toolbar = root_menu; toolbar; toolbar = toolbar->next) + FOR_ALL_MENUS(toolbar) if (menu_is_toolbar(toolbar->dname)) break; // Assumption: toolbar is NULL if there is no toolbar, @@ -1632,7 +1632,7 @@ gui_athena_popup_callback( { vimmenu_T *i; - for (i = menu->parent->children; i != NULL; i = i->next) + FOR_ALL_CHILD_MENUS(menu->parent, i) { if (i->submenu_id != NULL && XtIsManaged(i->submenu_id)) XtPopdown(i->submenu_id); diff --git a/src/gui_gtk.c b/src/gui_gtk.c --- a/src/gui_gtk.c +++ b/src/gui_gtk.c @@ -824,7 +824,7 @@ gui_gtk_set_mnemonics(int enable) vimmenu_T *menu; char_u *name; - for (menu = root_menu; menu != NULL; menu = menu->next) + FOR_ALL_MENUS(menu) { if (menu->id == NULL) continue; diff --git a/src/gui_motif.c b/src/gui_motif.c --- a/src/gui_motif.c +++ b/src/gui_motif.c @@ -889,7 +889,7 @@ do_set_mnemonics(int enable) { vimmenu_T *menu; - for (menu = root_menu; menu != NULL; menu = menu->next) + FOR_ALL_MENUS(menu) if (menu->id != (Widget)0) XtVaSetValues(menu->id, XmNmnemonic, enable ? menu->mnemonic : NUL, @@ -1094,7 +1094,7 @@ gui_mch_compute_menu_height( // Find any menu Widget, to be able to call XtManageChild() else - for (mp = root_menu; mp != NULL; mp = mp->next) + FOR_ALL_MENUS(mp) if (mp->id != (Widget)0 && menu_is_menubar(mp->name)) { id = mp->id; @@ -1112,7 +1112,7 @@ gui_mch_compute_menu_height( * Now find the menu item that is the furthest down, and get its position. */ maxy = 0; - for (mp = root_menu; mp != NULL; mp = mp->next) + FOR_ALL_MENUS(mp) { if (mp->id != (Widget)0 && menu_is_menubar(mp->name)) { @@ -2928,7 +2928,7 @@ gui_mch_show_toolbar(int showit) vimmenu_T *toolbar; vimmenu_T *cur; - for (toolbar = root_menu; toolbar; toolbar = toolbar->next) + FOR_ALL_MENUS(toolbar) if (menu_is_toolbar(toolbar->dname)) break; // Assumption: toolbar is NULL if there is no toolbar, diff --git a/src/gui_w32.c b/src/gui_w32.c --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -7591,7 +7591,7 @@ gui_mch_tearoff( for (col = 0; col < 2; col++) { columnWidths[col] = 0; - for (pmenu = menu->children; pmenu != NULL; pmenu = pmenu->next) + FOR_ALL_CHILD_MENUS(menu, pmenu) { // Use "dname" here to compute the width of the visible text. text = (col == 0) ? pmenu->dname : pmenu->actext; diff --git a/src/list.c b/src/list.c --- a/src/list.c +++ b/src/list.c @@ -20,6 +20,9 @@ static char *e_listblobarg = N_("E899: A // List heads for garbage collection. static list_T *first_list = NULL; // list of all lists +#define FOR_ALL_WATCHERS(l, lw) \ + for ((lw) = (l)->lv_watch; (lw) != NULL; (lw) = (lw)->lw_next) + static void list_free_item(list_T *l, listitem_T *item); /* @@ -42,7 +45,7 @@ list_rem_watch(list_T *l, listwatch_T *l listwatch_T *lw, **lwp; lwp = &l->lv_watch; - for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) + FOR_ALL_WATCHERS(l, lw) { if (lw == lwrem) { @@ -62,7 +65,7 @@ list_fix_watch(list_T *l, listitem_T *it { listwatch_T *lw; - for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) + FOR_ALL_WATCHERS(l, lw) if (lw->lw_item == item) lw->lw_item = item->li_next; } diff --git a/src/menu.c b/src/menu.c --- a/src/menu.c +++ b/src/menu.c @@ -1980,7 +1980,7 @@ show_popupmenu(void) apply_autocmds(EVENT_MENUPOPUP, (char_u*)mode, NULL, FALSE, curbuf); - for (menu = root_menu; menu != NULL; menu = menu->next) + FOR_ALL_MENUS(menu) if (STRNCMP("PopUp", menu->name, 5) == 0 && STRNCMP(menu->name + 5, mode, mode_len) == 0) break; @@ -2133,7 +2133,7 @@ gui_is_menu_shortcut(int key) if (key < 256) key = TOLOWER_LOC(key); - for (menu = root_menu; menu != NULL; menu = menu->next) + FOR_ALL_MENUS(menu) if (menu->mnemonic == key || (menu->mnemonic < 256 && TOLOWER_LOC(menu->mnemonic) == key)) return TRUE; diff --git a/src/popupmenu.c b/src/popupmenu.c --- a/src/popupmenu.c +++ b/src/popupmenu.c @@ -1379,7 +1379,7 @@ pum_execute_menu(vimmenu_T *menu, int mo int idx = 0; exarg_T ea; - for (mp = menu->children; mp != NULL; mp = mp->next) + FOR_ALL_CHILD_MENUS(menu, mp) if ((mp->modes & mp->enabled & mode) && idx++ == pum_selected) { vim_memset(&ea, 0, sizeof(ea)); @@ -1407,7 +1407,7 @@ pum_show_popupmenu(vimmenu_T *menu) pum_size = 0; mode = get_menu_mode_flag(); - for (mp = menu->children; mp != NULL; mp = mp->next) + FOR_ALL_CHILD_MENUS(menu, mp) if (menu_is_separator(mp->dname) || (mp->modes & mp->enabled & mode)) ++pum_size; @@ -1424,7 +1424,7 @@ pum_show_popupmenu(vimmenu_T *menu) if (array == NULL) return; - for (mp = menu->children; mp != NULL; mp = mp->next) + FOR_ALL_CHILD_MENUS(menu, mp) if (menu_is_separator(mp->dname)) array[idx++].pum_text = (char_u *)""; else if (mp->modes & mp->enabled & mode) diff --git a/src/popupwin.c b/src/popupwin.c --- a/src/popupwin.c +++ b/src/popupwin.c @@ -2133,7 +2133,7 @@ popup_close_and_callback(win_T *wp, typv // - another popup window with a terminal // - the previous window // - the first one. - for (owp = first_popupwin; owp != NULL; owp = owp->w_next) + FOR_ALL_POPUPWINS(owp) if (owp != curwin && owp->w_buffer->b_term != NULL) break; if (owp != NULL) diff --git a/src/quickfix.c b/src/quickfix.c --- a/src/quickfix.c +++ b/src/quickfix.c @@ -6276,7 +6276,7 @@ wipe_dummy_buffer(buf_T *buf, char_u *di win_T *wp; if (firstwin->w_next != NULL) - for (wp = firstwin; wp != NULL; wp = wp->w_next) + FOR_ALL_WINDOWS(wp) if (wp->w_buffer == buf) { if (win_close(wp, FALSE) == OK) diff --git a/src/syntax.c b/src/syntax.c --- a/src/syntax.c +++ b/src/syntax.c @@ -256,6 +256,9 @@ static reg_extmatch_T *next_match_extmat #define INVALID_STATE(ssp) ((ssp)->ga_itemsize == 0) #define VALID_STATE(ssp) ((ssp)->ga_itemsize != 0) +#define FOR_ALL_SYNSTATES(sb, sst) \ + for ((sst) = (sb)->b_sst_first; (sst) != NULL; (sst) = (sst)->sst_next) + /* * The current state (within the line) of the recognition engine. * When current_state.ga_itemsize is 0 the current state is invalid. @@ -438,7 +441,7 @@ syntax_start(win_T *wp, linenr_T lnum) if (INVALID_STATE(¤t_state) && syn_block->b_sst_array != NULL) { // Find last valid saved state before start_lnum. - for (p = syn_block->b_sst_first; p != NULL; p = p->sst_next) + FOR_ALL_SYNSTATES(syn_block, p) { if (p->sst_lnum > lnum) break; @@ -1044,7 +1047,7 @@ syn_stack_free_block(synblock_T *block) if (block->b_sst_array != NULL) { - for (p = block->b_sst_first; p != NULL; p = p->sst_next) + FOR_ALL_SYNSTATES(block, p) clear_syn_state(p); VIM_CLEAR(block->b_sst_array); block->b_sst_first = NULL; @@ -1353,7 +1356,7 @@ store_current_state(void) else { // find the entry just before this one to adjust sst_next - for (p = syn_block->b_sst_first; p != NULL; p = p->sst_next) + FOR_ALL_SYNSTATES(syn_block, p) if (p->sst_next == sp) break; if (p != NULL) // just in case diff --git a/src/time.c b/src/time.c --- a/src/time.c +++ b/src/time.c @@ -21,6 +21,9 @@ static char tz_cache[64]; #endif +#define FOR_ALL_TIMERS(t) \ + for ((t) = first_timer; (t) != NULL; (t) = (t)->tr_next) + /* * Call either localtime(3) or localtime_r(3) from POSIX libc time.h, with the * latter version preferred for reentrancy. @@ -583,7 +586,7 @@ find_timer(long id) if (id >= 0) { - for (timer = first_timer; timer != NULL; timer = timer->tr_next) + FOR_ALL_TIMERS(timer) if (timer->tr_id == id) return timer; } @@ -659,7 +662,7 @@ add_timer_info_all(typval_T *rettv) { timer_T *timer; - for (timer = first_timer; timer != NULL; timer = timer->tr_next) + FOR_ALL_TIMERS(timer) if (timer->tr_id != -1) add_timer_info(rettv, timer); } diff --git a/src/userfunc.c b/src/userfunc.c --- a/src/userfunc.c +++ b/src/userfunc.c @@ -1643,7 +1643,7 @@ func_call( int r = 0; range_list_materialize(l); - FOR_ALL_LIST_ITEMS(args->vval.v_list, item) + FOR_ALL_LIST_ITEMS(l, item) { if (argc == MAX_FUNC_ARGS - (partial == NULL ? 0 : partial->pt_argc)) { diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -739,6 +739,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 523, +/**/ 522, /**/ 521, diff --git a/src/vim9compile.c b/src/vim9compile.c --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -3984,7 +3984,7 @@ compile_assignment(char_u *arg, exarg_T l = heredoc_get(eap, op + 3); // Push each line and the create the list. - for (li = l->lv_first; li != NULL; li = li->li_next) + FOR_ALL_LIST_ITEMS(l, li) { generate_PUSHS(cctx, li->li_tv.vval.v_string); li->li_tv.vval.v_string = NULL;