diff options
-rw-r--r-- | src/nvim/buffer_defs.h | 4 | ||||
-rw-r--r-- | src/nvim/eval.lua | 4 | ||||
-rw-r--r-- | src/nvim/ex_cmds.c | 5 | ||||
-rw-r--r-- | src/nvim/ex_docmd.c | 2 | ||||
-rw-r--r-- | src/nvim/getchar.c | 93 | ||||
-rw-r--r-- | src/nvim/globals.h | 2 | ||||
-rw-r--r-- | src/nvim/main.c | 10 | ||||
-rw-r--r-- | src/nvim/quickfix.c | 7 | ||||
-rw-r--r-- | src/nvim/testdir/Makefile | 2 | ||||
-rw-r--r-- | src/nvim/testdir/test_quickfix.vim | 11 |
10 files changed, 81 insertions, 59 deletions
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 69cefe2247..4b0e680c25 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -133,14 +133,14 @@ typedef struct buffheader buffheader_T; */ struct buffblock { buffblock_T *b_next; // pointer to next buffblock - char_u b_str[1]; // contents (actually longer) + char_u b_str[]; // contents (flexible array) }; /* * header used for the stuff buffer and the redo buffer */ struct buffheader { - buffblock_T bh_first; // first (dummy) block of list + buffblock_T *bh_first; // first block of the list buffblock_T *bh_curr; // buffblock for appending size_t bh_index; // index for reading size_t bh_space; // space in bh_curr for appending diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index f36a7ea6c0..6159103767 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -20,10 +20,10 @@ return { ['and']={args=2}, api_info={}, append={args=2}, - argc={}, + argc={args={0, 1}}, argidx={}, arglistid={args={0, 2}}, - argv={args={0, 1}}, + argv={args={0, 2}}, asin={args=1, func="float_op_wrapper", data="&asin"}, -- WJMc assert_beeps={args={1, 2}}, assert_equal={args={2, 3}}, diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 30667b64e5..71ed5f6ec1 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -1934,8 +1934,9 @@ void do_wqall(exarg_T *eap) int error = 0; int save_forceit = eap->forceit; - if (eap->cmdidx == CMD_xall || eap->cmdidx == CMD_wqall) - exiting = TRUE; + if (eap->cmdidx == CMD_xall || eap->cmdidx == CMD_wqall) { + exiting = true; + } FOR_ALL_BUFFERS(buf) { if (!bufIsChanged(buf)) { diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 0e8455bb07..a494463f89 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -6018,7 +6018,7 @@ static void ex_highlight(exarg_T *eap) */ void not_exiting(void) { - exiting = FALSE; + exiting = false; } static bool before_quit_autocmds(win_T *wp, bool quit_all, int forceit) diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 13700328fd..465c41457a 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -77,15 +77,15 @@ FileDescriptor *scriptin[NSCRIPT] = { NULL }; #define MINIMAL_SIZE 20 /* minimal size for b_str */ -static buffheader_T redobuff = { { NULL, { NUL } }, NULL, 0, 0 }; -static buffheader_T old_redobuff = { { NULL, { NUL } }, NULL, 0, 0 }; -static buffheader_T recordbuff = { { NULL, { NUL } }, NULL, 0, 0 }; +static buffheader_T redobuff = { NULL, NULL, 0, 0 }; +static buffheader_T old_redobuff = { NULL, NULL, 0, 0 }; +static buffheader_T recordbuff = { NULL, NULL, 0, 0 }; // First read ahead buffer. Used for translated commands. -static buffheader_T readbuf1 = {{NULL, {NUL}}, NULL, 0, 0}; +static buffheader_T readbuf1 = { NULL, NULL, 0, 0 }; // Second read ahead buffer. Used for redo. -static buffheader_T readbuf2 = {{NULL, {NUL}}, NULL, 0, 0}; +static buffheader_T readbuf2 = { NULL, NULL, 0, 0 }; static int typeahead_char = 0; /* typeahead char that's not flushed */ @@ -163,11 +163,12 @@ void free_buff(buffheader_T *buf) { buffblock_T *p, *np; - for (p = buf->bh_first.b_next; p != NULL; p = np) { + for (p = buf->bh_first; p != NULL; p = np) { np = p->b_next; xfree(p); } - buf->bh_first.b_next = NULL; + buf->bh_first = NULL; + buf->bh_curr = NULL; } /* @@ -181,18 +182,21 @@ static char_u *get_buffcont(buffheader_T *buffer, size_t count = 0; char_u *p = NULL; char_u *p2; - char_u *str; - /* compute the total length of the string */ - for (buffblock_T *bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next) + // compute the total length of the string + for (const buffblock_T *bp = buffer->bh_first; bp != NULL; bp = bp->b_next) { count += STRLEN(bp->b_str); + } if (count || dozero) { p = xmalloc(count + 1); p2 = p; - for (buffblock_T *bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next) - for (str = bp->b_str; *str; ) + for (const buffblock_T *bp = buffer->bh_first; + bp != NULL; bp = bp->b_next) { + for (const char_u *str = bp->b_str; *str;) { *p2++ = *str++; + } + } *p2 = NUL; } return p; @@ -257,16 +261,16 @@ static void add_buff(buffheader_T *const buf, const char *const s, return; } - if (buf->bh_first.b_next == NULL) { // first add to list + if (buf->bh_first == NULL) { // first add to list buf->bh_space = 0; - buf->bh_curr = &(buf->bh_first); + buf->bh_curr = NULL; } else if (buf->bh_curr == NULL) { // buffer has already been read IEMSG(_("E222: Add to read buffer")); return; } else if (buf->bh_index != 0) { - memmove(buf->bh_first.b_next->b_str, - buf->bh_first.b_next->b_str + buf->bh_index, - STRLEN(buf->bh_first.b_next->b_str + buf->bh_index) + 1); + memmove(buf->bh_first->b_str, + buf->bh_first->b_str + buf->bh_index, + STRLEN(buf->bh_first->b_str + buf->bh_index) + 1); } buf->bh_index = 0; @@ -281,13 +285,19 @@ static void add_buff(buffheader_T *const buf, const char *const s, } else { len = (size_t)slen; } - buffblock_T *p = xmalloc(sizeof(buffblock_T) + len); + buffblock_T *p = xmalloc(sizeof(buffblock_T) + len + 1); buf->bh_space = len - (size_t)slen; STRLCPY(p->b_str, s, slen + 1); - p->b_next = buf->bh_curr->b_next; - buf->bh_curr->b_next = p; - buf->bh_curr = p; + if (buf->bh_curr == NULL) { + p->b_next = NULL; + buf->bh_first = p; + buf->bh_curr = p; + } else { + p->b_next = buf->bh_curr->b_next; + buf->bh_curr->b_next = p; + buf->bh_curr = p; + } } return; } @@ -356,17 +366,17 @@ static int read_readbuffers(int advance) static int read_readbuf(buffheader_T *buf, int advance) { char_u c; - buffblock_T *curr; - if (buf->bh_first.b_next == NULL) /* buffer is empty */ + if (buf->bh_first == NULL) { // buffer is empty return NUL; + } - curr = buf->bh_first.b_next; + buffblock_T *const curr = buf->bh_first; c = curr->b_str[buf->bh_index]; if (advance) { if (curr->b_str[++buf->bh_index] == NUL) { - buf->bh_first.b_next = curr->b_next; + buf->bh_first = curr->b_next; xfree(curr); buf->bh_index = 0; } @@ -379,12 +389,12 @@ static int read_readbuf(buffheader_T *buf, int advance) */ static void start_stuff(void) { - if (readbuf1.bh_first.b_next != NULL) { - readbuf1.bh_curr = &(readbuf1.bh_first); + if (readbuf1.bh_first != NULL) { + readbuf1.bh_curr = readbuf1.bh_first; readbuf1.bh_space = 0; } - if (readbuf2.bh_first.b_next != NULL) { - readbuf2.bh_curr = &(readbuf2.bh_first); + if (readbuf2.bh_first != NULL) { + readbuf2.bh_curr = readbuf2.bh_first; readbuf2.bh_space = 0; } } @@ -394,7 +404,8 @@ static void start_stuff(void) */ int stuff_empty(void) { - return (readbuf1.bh_first.b_next == NULL && readbuf2.bh_first.b_next == NULL); + return (readbuf1.bh_first == NULL + && readbuf2.bh_first == NULL); } /* @@ -403,7 +414,7 @@ int stuff_empty(void) */ int readbuf1_empty(void) { - return (readbuf1.bh_first.b_next == NULL); + return (readbuf1.bh_first == NULL); } /* @@ -461,7 +472,7 @@ void ResetRedobuff(void) if (!block_redo) { free_buff(&old_redobuff); old_redobuff = redobuff; - redobuff.bh_first.b_next = NULL; + redobuff.bh_first = NULL; } } @@ -474,7 +485,7 @@ void CancelRedo(void) if (!block_redo) { free_buff(&redobuff); redobuff = old_redobuff; - old_redobuff.bh_first.b_next = NULL; + old_redobuff.bh_first = NULL; start_stuff(); while (read_readbuffers(TRUE) != NUL) { } @@ -486,9 +497,9 @@ void CancelRedo(void) void saveRedobuff(save_redo_T *save_redo) { save_redo->sr_redobuff = redobuff; - redobuff.bh_first.b_next = NULL; + redobuff.bh_first = NULL; save_redo->sr_old_redobuff = old_redobuff; - old_redobuff.bh_first.b_next = NULL; + old_redobuff.bh_first = NULL; // Make a copy, so that ":normal ." in a function works. char *const s = (char *)get_buffcont(&save_redo->sr_redobuff, false); @@ -668,12 +679,10 @@ static int read_redo(bool init, bool old_redo) int i; if (init) { - if (old_redo) - bp = old_redobuff.bh_first.b_next; - else - bp = redobuff.bh_first.b_next; - if (bp == NULL) + bp = old_redo ? old_redobuff.bh_first : redobuff.bh_first; + if (bp == NULL) { return FAIL; + } p = bp->b_str; return OK; } @@ -1206,9 +1215,9 @@ void save_typeahead(tasave_T *tp) old_char = -1; tp->save_readbuf1 = readbuf1; - readbuf1.bh_first.b_next = NULL; + readbuf1.bh_first = NULL; tp->save_readbuf2 = readbuf2; - readbuf2.bh_first.b_next = NULL; + readbuf2.bh_first = NULL; } /* diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 4fce02613c..dbbc7cdafd 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -510,7 +510,7 @@ EXTERN int sc_col; /* column for shown command */ // First NO_SCREEN, then NO_BUFFERS, then 0 when startup finished. EXTERN int starting INIT(= NO_SCREEN); // true when planning to exit. Might keep running if there is a changed buffer. -EXTERN int exiting INIT(= false); +EXTERN bool exiting INIT(= false); // is stdin a terminal? EXTERN int stdin_isatty INIT(= true); // is stdout a terminal? diff --git a/src/nvim/main.c b/src/nvim/main.c index 2c182abb96..55be97d3f4 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -584,9 +584,7 @@ int main(int argc, char **argv) void getout(int exitval) FUNC_ATTR_NORETURN { - tabpage_T *tp, *next_tp; - - exiting = TRUE; + exiting = true; /* When running in Ex mode an error causes us to exit with a non-zero exit * code. POSIX requires this, although it's not 100% clear from the @@ -603,8 +601,10 @@ void getout(int exitval) hash_debug_results(); if (get_vim_var_nr(VV_DYING) <= 1) { - /* Trigger BufWinLeave for all windows, but only once per buffer. */ - for (tp = first_tabpage; tp != NULL; tp = next_tp) { + const tabpage_T *next_tp; + + // Trigger BufWinLeave for all windows, but only once per buffer. + for (const tabpage_T *tp = first_tabpage; tp != NULL; tp = next_tp) { next_tp = tp->tp_next; FOR_ALL_WINDOWS_IN_TAB(wp, tp) { if (wp->w_buffer == NULL) { diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 0e4fa0afc6..3c744310b3 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -5368,8 +5368,11 @@ void ex_cexpr(exarg_T *eap) apply_autocmds(EVENT_QUICKFIXCMDPOST, (char_u *)au_name, curbuf->b_fname, true, curbuf); } - if (res > 0 && (eap->cmdidx == CMD_cexpr || eap->cmdidx == CMD_lexpr)) { - qf_jump(qi, 0, 0, eap->forceit); // display first error + if (res > 0 + && (eap->cmdidx == CMD_cexpr || eap->cmdidx == CMD_lexpr) + && qi == GET_LOC_LIST(curwin)) { + // Jump to the first error if autocmds didn't free the list. + qf_jump(qi, 0, 0, eap->forceit); } } else { EMSG(_("E777: String or List expected")); diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index 7b1f0f59cc..fe9e0bc9c8 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -32,14 +32,12 @@ NEW_TESTS_ALOT := test_alot_utf8 test_alot NEW_TESTS_IN_ALOT := $(shell sed '/^source/ s/^source //;s/\.vim$$//' test_alot*.vim) # Ignored tests. # test_alot_latin: Nvim does not allow setting encoding. -# test_arglist: ported to Lua, but kept for easier merging. # test_autochdir: ported to Lua, but kept for easier merging. # test_eval_func: used as include in old-style test (test_eval.in). # test_listlbr: Nvim does not allow setting encoding. # test_largefile: uses too much resources to run on CI. NEW_TESTS_IGNORE := $(NEW_TESTS_IN_ALOT) $(NEW_TESTS_ALOT) \ test_alot_latin \ - test_arglist \ test_autochdir \ test_eval_func \ test_listlbr \ diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index fcb02d3437..4d78c67f5c 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -3373,6 +3373,17 @@ func Test_lbuffer_with_bwipe() augroup END endfunc +func Test_setloclist_in_aucmd() + " This was using freed memory. + augroup nasty + au * * call setloclist(0, [], 'f') + augroup END + lexpr "x" + augroup nasty + au! + augroup END +endfunc + " Tests for the "CTRL-W <CR>" command. func Xview_result_split_tests(cchar) call s:setup_commands(a:cchar) |