Skip to content

Commit

Permalink
updated for version 7.3.963
Browse files Browse the repository at this point in the history
Problem:    Setting curbuf without curwin causes trouble.
Solution:   Add switch_buffer() and restore_buffer().  Block autocommands to
            avoid trouble.
  • Loading branch information
brammool committed May 17, 2013
1 parent 55b8ad3 commit 105bc35
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 85 deletions.
51 changes: 5 additions & 46 deletions src/eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -11894,7 +11894,7 @@ getwinvar(argvars, rettv, off)
win_T *win, *oldcurwin;
char_u *varname;
dictitem_T *v;
tabpage_T *tp;
tabpage_T *tp, *oldtabpage;
int done = FALSE;

#ifdef FEAT_WINDOWS
Expand All @@ -11912,11 +11912,9 @@ getwinvar(argvars, rettv, off)

if (win != NULL && varname != NULL)
{
/* Set curwin to be our win, temporarily. Also set curbuf, so
* that we can get buffer-local options. */
oldcurwin = curwin;
curwin = win;
curbuf = win->w_buffer;
/* Set curwin to be our win, temporarily. Also set the tabpage,
* otherwise the window is not valid. */
switch_win(&oldcurwin, &oldtabpage, win, tp);

if (*varname == '&') /* window-local-option */
{
Expand All @@ -11936,8 +11934,7 @@ getwinvar(argvars, rettv, off)
}

/* restore previous notion of curwin */
curwin = oldcurwin;
curbuf = curwin->w_buffer;
restore_win(oldcurwin, oldtabpage);
}

if (!done && argvars[off + 2].v_type != VAR_UNKNOWN)
Expand Down Expand Up @@ -16641,44 +16638,6 @@ f_setwinvar(argvars, rettv)
setwinvar(argvars, rettv, 0);
}

int
switch_win(save_curwin, save_curtab, win, tp)
win_T **save_curwin;
tabpage_T **save_curtab;
win_T *win;
tabpage_T *tp;
{
#ifdef FEAT_WINDOWS
/* set curwin to be our win, temporarily */
*save_curwin = curwin;
*save_curtab = curtab;
goto_tabpage_tp(tp, FALSE, FALSE);
if (!win_valid(win))
return FAIL;
curwin = win;
curbuf = curwin->w_buffer;
#endif
return OK;
}

void
restore_win(save_curwin, save_curtab)
win_T *save_curwin;
tabpage_T *save_curtab;
{
#ifdef FEAT_WINDOWS
/* Restore current tabpage and window, if still valid (autocommands can
* make them invalid). */
if (valid_tabpage(save_curtab))
goto_tabpage_tp(save_curtab, FALSE, FALSE);
if (win_valid(save_curwin))
{
curwin = save_curwin;
curbuf = curwin->w_buffer;
}
#endif
}

/*
* "setwinvar()" and "settabwinvar()" functions
*/
Expand Down
64 changes: 30 additions & 34 deletions src/if_py_both.h
Original file line number Diff line number Diff line change
Expand Up @@ -1413,14 +1413,14 @@ set_option_value_for(key, numval, stringval, opt_flags, opt_type, from)
{
win_T *save_curwin;
tabpage_T *save_curtab;
aco_save_T aco;
buf_T *save_curbuf;
int r = 0;

switch (opt_type)
{
case SREQ_WIN:
if (switch_win(&save_curwin, &save_curtab, (win_T *) from, curtab)
== FAIL)
if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
win_find_tabpage((win_T *)from)) == FAIL)
{
PyErr_SetVim("Problem while switching windows.");
return -1;
Expand All @@ -1429,9 +1429,9 @@ set_option_value_for(key, numval, stringval, opt_flags, opt_type, from)
restore_win(save_curwin, save_curtab);
break;
case SREQ_BUF:
aucmd_prepbuf(&aco, (buf_T *) from);
switch_buffer(&save_curbuf, (buf_T *)from);
set_option_value(key, numval, stringval, opt_flags);
aucmd_restbuf(&aco);
restore_buffer(save_curbuf);
break;
case SREQ_GLOBAL:
set_option_value(key, numval, stringval, opt_flags);
Expand Down Expand Up @@ -2240,23 +2240,23 @@ SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
*/
if (line == Py_None || line == NULL)
{
buf_T *savebuf = curbuf;
buf_T *savebuf;

PyErr_Clear();
curbuf = buf;
switch_buffer(&savebuf, buf);

if (u_savedel((linenr_T)n, 1L) == FAIL)
PyErr_SetVim(_("cannot save undo information"));
else if (ml_delete((linenr_T)n, FALSE) == FAIL)
PyErr_SetVim(_("cannot delete line"));
else
{
if (buf == curwin->w_buffer)
if (buf == savebuf)
py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
deleted_lines_mark((linenr_T)n, 1L);
}

curbuf = savebuf;
restore_buffer(savebuf);

if (PyErr_Occurred() || VimErrorCheck())
return FAIL;
Expand All @@ -2269,14 +2269,14 @@ SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
else if (PyString_Check(line))
{
char *save = StringToLine(line);
buf_T *savebuf = curbuf;
buf_T *savebuf;

if (save == NULL)
return FAIL;

/* We do not need to free "save" if ml_replace() consumes it. */
PyErr_Clear();
curbuf = buf;
switch_buffer(&savebuf, buf);

if (u_savesub((linenr_T)n) == FAIL)
{
Expand All @@ -2291,10 +2291,10 @@ SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
else
changed_bytes((linenr_T)n, 0);

curbuf = savebuf;
restore_buffer(savebuf);

/* Check that the cursor is not beyond the end of the line now. */
if (buf == curwin->w_buffer)
if (buf == savebuf)
check_cursor_col();

if (PyErr_Occurred() || VimErrorCheck())
Expand Down Expand Up @@ -2333,10 +2333,10 @@ SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_cha
{
PyInt i;
PyInt n = (int)(hi - lo);
buf_T *savebuf = curbuf;
buf_T *savebuf;

PyErr_Clear();
curbuf = buf;
switch_buffer(&savebuf, buf);

if (u_savedel((linenr_T)lo, (long)n) == FAIL)
PyErr_SetVim(_("cannot save undo information"));
Expand All @@ -2350,12 +2350,12 @@ SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_cha
break;
}
}
if (buf == curwin->w_buffer)
if (buf == savebuf)
py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
deleted_lines_mark((linenr_T)lo, (long)i);
}

curbuf = savebuf;
restore_buffer(savebuf);

if (PyErr_Occurred() || VimErrorCheck())
return FAIL;
Expand Down Expand Up @@ -2400,10 +2400,10 @@ SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_cha
}
}

savebuf = curbuf;

PyErr_Clear();
curbuf = buf;

// START of region without "return". Must call restore_buffer()!
switch_buffer(&savebuf, buf);

if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
PyErr_SetVim(_("cannot save undo information"));
Expand Down Expand Up @@ -2480,10 +2480,11 @@ SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_cha
(long)MAXLNUM, (long)extra);
changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);

if (buf == curwin->w_buffer)
if (buf == savebuf)
py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);

curbuf = savebuf;
// END of region without "return".
restore_buffer(savebuf);

if (PyErr_Occurred() || VimErrorCheck())
return FAIL;
Expand Down Expand Up @@ -2522,10 +2523,8 @@ InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
if (str == NULL)
return FAIL;

savebuf = curbuf;

PyErr_Clear();
curbuf = buf;
switch_buffer(&savebuf, buf);

if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
PyErr_SetVim(_("cannot save undo information"));
Expand All @@ -2535,7 +2534,7 @@ InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
appended_lines_mark((linenr_T)n, 1L);

vim_free(str);
curbuf = savebuf;
restore_buffer(savebuf);
update_screen(VALID);

if (PyErr_Occurred() || VimErrorCheck())
Expand Down Expand Up @@ -2574,10 +2573,8 @@ InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
}
}

savebuf = curbuf;

PyErr_Clear();
curbuf = buf;
switch_buffer(&savebuf, buf);

if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
PyErr_SetVim(_("cannot save undo information"));
Expand Down Expand Up @@ -2607,7 +2604,7 @@ InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
*/
vim_free(array);

curbuf = savebuf;
restore_buffer(savebuf);
update_screen(VALID);

if (PyErr_Occurred() || VimErrorCheck())
Expand Down Expand Up @@ -3023,7 +3020,7 @@ BufferMark(PyObject *self, PyObject *args)
pos_T *posp;
char *pmark;
char mark;
buf_T *curbuf_save;
buf_T *savebuf;

if (CheckBuffer((BufferObject *)(self)))
return NULL;
Expand All @@ -3032,10 +3029,9 @@ BufferMark(PyObject *self, PyObject *args)
return NULL;
mark = *pmark;

curbuf_save = curbuf;
curbuf = ((BufferObject *)(self))->buf;
switch_buffer(&savebuf, ((BufferObject *)(self))->buf);
posp = getmark(mark, FALSE);
curbuf = curbuf_save;
restore_buffer(savebuf);

if (posp == NULL)
{
Expand Down
6 changes: 2 additions & 4 deletions src/proto/eval.pro
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ void prof_child_enter __ARGS((proftime_T *tm));
void prof_child_exit __ARGS((proftime_T *tm));
int eval_foldexpr __ARGS((char_u *arg, int *cp));
void ex_let __ARGS((exarg_T *eap));
void list_add_watch __ARGS((list_T *l, listwatch_T *lw));
void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem));
void *eval_for_line __ARGS((char_u *arg, int *errp, char_u **nextcmdp, int skip));
int next_for_item __ARGS((void *fi_void, char_u *arg));
void free_for_info __ARGS((void *fi_void));
Expand Down Expand Up @@ -125,8 +127,4 @@ void last_set_msg __ARGS((scid_T scriptID));
void ex_oldfiles __ARGS((exarg_T *eap));
int modify_fname __ARGS((char_u *src, int *usedlen, char_u **fnamep, char_u **bufp, int *fnamelen));
char_u *do_string_sub __ARGS((char_u *str, char_u *pat, char_u *sub, char_u *flags));
int switch_win __ARGS((win_T **, tabpage_T **, win_T *, tabpage_T *));
void restore_win __ARGS((win_T *, tabpage_T *));
void list_add_watch __ARGS((list_T *l, listwatch_T *lw));
void list_rem_watch __ARGS((list_T *l, listwatch_T *lwrem));
/* vim: set ft=c : */
5 changes: 5 additions & 0 deletions src/proto/window.pro
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ void goto_tabpage_win __ARGS((tabpage_T *tp, win_T *wp));
void tabpage_move __ARGS((int nr));
void win_goto __ARGS((win_T *wp));
win_T *win_find_nr __ARGS((int winnr));
tabpage_T *win_find_tabpage __ARGS((win_T *win));
void win_enter __ARGS((win_T *wp, int undo_sync));
win_T *buf_jump_open_win __ARGS((buf_T *buf));
win_T *buf_jump_open_tab __ARGS((buf_T *buf));
Expand Down Expand Up @@ -69,6 +70,10 @@ int only_one_window __ARGS((void));
void check_lnums __ARGS((int do_curwin));
void make_snapshot __ARGS((int idx));
void restore_snapshot __ARGS((int idx, int close_curwin));
int switch_win __ARGS((win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage_T *tp));
void restore_win __ARGS((win_T *save_curwin, tabpage_T *save_curtab));
void switch_buffer __ARGS((buf_T **save_curbuf, buf_T *buf));
void restore_buffer __ARGS((buf_T *save_curbuf));
int win_hasvertsplit __ARGS((void));
int match_add __ARGS((win_T *wp, char_u *grp, char_u *pat, int prio, int id));
int match_delete __ARGS((win_T *wp, int id, int perr));
Expand Down
2 changes: 1 addition & 1 deletion src/testdir/test86.ok
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ Number of tabs: 4
Current tab pages:
<tabpage 0>(1): 1 windows, current is <window object (unknown)>
Windows:
<window object (unknown)>(0): displays buffer <buffer test86.in>; cursor is at (955, 0)
<window object (unknown)>(0): displays buffer <buffer test86.in>; cursor is at (954, 0)
<tabpage 1>(2): 1 windows, current is <window object (unknown)>
Windows:
<window object (unknown)>(0): displays buffer <buffer 0>; cursor is at (1, 0)
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
963,
/**/
962,
/**/
Expand Down
Loading

0 comments on commit 105bc35

Please sign in to comment.