Compare commits

...

4 Commits

Author SHA1 Message Date
Bram Moolenaar
c93df6b075 updated for version 7.4.004
Problem:    When closing a window fails ":bwipe" may hang.
Solution:   Let win_close() return FAIL and break out of the loop.
2013-08-14 17:11:20 +02:00
Bram Moolenaar
ebefd997bb updated for version 7.4.003
Problem:    Memory access error in Ruby syntax highlighting. (Christopher Chow)
Solution:   Refresh stale pointer. (James McCoy)
2013-08-14 14:18:40 +02:00
Bram Moolenaar
3f0df06c28 updated for version 7.4.002
Problem:    Pattern with two alternative look-behind matches does not match.
            (Amadeus Demarzi)
Solution:   When comparing PIMs also compare their state ID to see if they are
            different.
2013-08-14 13:34:25 +02:00
Bram Moolenaar
1cfad52a03 updated for version 7.4.001
Problem:    Character classes such as [a-z] to not react to 'ignorecase'.
            Breaks man page highlighting. (Mario Grgic)
Solution:   Add separate items for classes that react to 'ignorecase'.  Clean
            up logic handling character classes.  Add more tests.
2013-08-14 12:06:49 +02:00
7 changed files with 197 additions and 62 deletions

View File

@@ -1186,7 +1186,10 @@ do_buffer(action, start, dir, count, forceit)
&& !(curwin->w_closing || curwin->w_buffer->b_closing)
# endif
&& (firstwin != lastwin || first_tabpage->tp_next != NULL))
win_close(curwin, FALSE);
{
if (win_close(curwin, FALSE) == FAIL)
break;
}
#endif
/*

View File

@@ -9,7 +9,7 @@ void win_move_after __ARGS((win_T *win1, win_T *win2));
void win_equal __ARGS((win_T *next_curwin, int current, int dir));
void close_windows __ARGS((buf_T *buf, int keep_curwin));
int one_window __ARGS((void));
void win_close __ARGS((win_T *win, int free_buf));
int win_close __ARGS((win_T *win, int free_buf));
void win_close_othertab __ARGS((win_T *win, int free_buf, tabpage_T *tp));
void win_free_all __ARGS((void));
win_T *winframe_remove __ARGS((win_T *win, int *dirp, tabpage_T *tp));

View File

@@ -29,6 +29,9 @@
# define NFA_REGEXP_DEBUG_LOG "nfa_regexp_debug.log"
#endif
/* Added to NFA_ANY - NFA_NUPPER_IC to include a NL. */
#define NFA_ADD_NL 31
enum
{
NFA_SPLIT = -1024,
@@ -183,6 +186,13 @@ enum
NFA_NLOWER, /* Match non-lowercase char */
NFA_UPPER, /* Match uppercase char */
NFA_NUPPER, /* Match non-uppercase char */
NFA_LOWER_IC, /* Match [a-z] */
NFA_NLOWER_IC, /* Match [^a-z] */
NFA_UPPER_IC, /* Match [A-Z] */
NFA_NUPPER_IC, /* Match [^A-Z] */
NFA_FIRST_NL = NFA_ANY + NFA_ADD_NL,
NFA_LAST_NL = NFA_NUPPER_IC + NFA_ADD_NL,
NFA_CURSOR, /* Match cursor pos */
NFA_LNUM, /* Match line number */
@@ -199,9 +209,6 @@ enum
NFA_MARK_LT, /* Match < mark */
NFA_VISUAL, /* Match Visual area */
NFA_FIRST_NL = NFA_ANY + ADD_NL,
NFA_LAST_NL = NFA_NUPPER + ADD_NL,
/* Character classes [:alnum:] etc */
NFA_CLASS_ALNUM,
NFA_CLASS_ALPHA,
@@ -578,6 +585,8 @@ realloc_post_list()
* On failure, return 0 (=FAIL)
* Start points to the first char of the range, while end should point
* to the closing brace.
* Keep in mind that 'ignorecase' applies at execution time, thus [a-z] may
* need to be interpreted as [a-zA-Z].
*/
static int
nfa_recognize_char_class(start, end, extra_newl)
@@ -681,7 +690,7 @@ nfa_recognize_char_class(start, end, extra_newl)
return FAIL;
if (newl == TRUE)
extra_newl = ADD_NL;
extra_newl = NFA_ADD_NL;
switch (config)
{
@@ -710,13 +719,13 @@ nfa_recognize_char_class(start, end, extra_newl)
case CLASS_not | CLASS_az | CLASS_AZ:
return extra_newl + NFA_NALPHA;
case CLASS_az:
return extra_newl + NFA_LOWER;
return extra_newl + NFA_LOWER_IC;
case CLASS_not | CLASS_az:
return extra_newl + NFA_NLOWER;
return extra_newl + NFA_NLOWER_IC;
case CLASS_AZ:
return extra_newl + NFA_UPPER;
return extra_newl + NFA_UPPER_IC;
case CLASS_not | CLASS_AZ:
return extra_newl + NFA_NUPPER;
return extra_newl + NFA_NUPPER_IC;
}
return FAIL;
}
@@ -914,7 +923,7 @@ nfa_regatom()
break;
}
extra = ADD_NL;
extra = NFA_ADD_NL;
/* "\_[" is collection plus newline */
if (c == '[')
@@ -970,7 +979,7 @@ nfa_regatom()
}
#endif
EMIT(nfa_classcodes[p - classchars]);
if (extra == ADD_NL)
if (extra == NFA_ADD_NL)
{
EMIT(NFA_NEWL);
EMIT(NFA_OR);
@@ -1240,21 +1249,21 @@ collection:
{
/*
* Try to reverse engineer character classes. For example,
* recognize that [0-9] stands for \d and [A-Za-z_] with \h,
* recognize that [0-9] stands for \d and [A-Za-z_] for \h,
* and perform the necessary substitutions in the NFA.
*/
result = nfa_recognize_char_class(regparse, endp,
extra == ADD_NL);
extra == NFA_ADD_NL);
if (result != FAIL)
{
if (result >= NFA_DIGIT && result <= NFA_NUPPER)
EMIT(result);
else /* must be char class + newline */
if (result >= NFA_FIRST_NL && result <= NFA_LAST_NL)
{
EMIT(result - ADD_NL);
EMIT(result - NFA_ADD_NL);
EMIT(NFA_NEWL);
EMIT(NFA_OR);
}
else
EMIT(result);
regparse = endp;
mb_ptr_adv(regparse);
return OK;
@@ -1504,7 +1513,7 @@ collection:
* collection, add an OR below. But not for negated
* range. */
if (!negated)
extra = ADD_NL;
extra = NFA_ADD_NL;
}
else
{
@@ -1537,7 +1546,7 @@ collection:
EMIT(NFA_END_COLL);
/* \_[] also matches \n but it's not negated */
if (extra == ADD_NL)
if (extra == NFA_ADD_NL)
{
EMIT(reg_string ? NL : NFA_NEWL);
EMIT(NFA_OR);
@@ -2011,7 +2020,7 @@ nfa_set_code(c)
if (c >= NFA_FIRST_NL && c <= NFA_LAST_NL)
{
addnl = TRUE;
c -= ADD_NL;
c -= NFA_ADD_NL;
}
STRCPY(code, "");
@@ -2217,6 +2226,10 @@ nfa_set_code(c)
case NFA_NLOWER:STRCPY(code, "NFA_NLOWER"); break;
case NFA_UPPER: STRCPY(code, "NFA_UPPER"); break;
case NFA_NUPPER:STRCPY(code, "NFA_NUPPER"); break;
case NFA_LOWER_IC: STRCPY(code, "NFA_LOWER_IC"); break;
case NFA_NLOWER_IC: STRCPY(code, "NFA_NLOWER_IC"); break;
case NFA_UPPER_IC: STRCPY(code, "NFA_UPPER_IC"); break;
case NFA_NUPPER_IC: STRCPY(code, "NFA_NUPPER_IC"); break;
default:
STRCPY(code, "CHAR(x)");
@@ -2687,6 +2700,10 @@ nfa_max_width(startstate, depth)
case NFA_NLOWER:
case NFA_UPPER:
case NFA_NUPPER:
case NFA_LOWER_IC:
case NFA_NLOWER_IC:
case NFA_UPPER_IC:
case NFA_NUPPER_IC:
/* possibly non-ascii */
#ifdef FEAT_MBYTE
if (has_mbyte)
@@ -3765,6 +3782,9 @@ pim_equal(one, two)
if (two_unused)
/* one is used and two is not: not equal */
return FALSE;
/* compare the state id */
if (one->state->id != two->state->id)
return FALSE;
/* compare the position */
if (REG_MULTI)
return one->end.pos.lnum == two->end.pos.lnum
@@ -3841,6 +3861,10 @@ match_follows(startstate, depth)
case NFA_NLOWER:
case NFA_UPPER:
case NFA_NUPPER:
case NFA_LOWER_IC:
case NFA_NLOWER_IC:
case NFA_UPPER_IC:
case NFA_NUPPER_IC:
case NFA_START_COLL:
case NFA_START_NEG_COLL:
case NFA_NEWL:
@@ -4096,7 +4120,7 @@ skip_add:
sub = &subs->norm;
}
#ifdef FEAT_SYN_HL
else if (state->c >= NFA_ZOPEN)
else if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9)
{
subidx = state->c - NFA_ZOPEN;
sub = &subs->synt;
@@ -4165,6 +4189,13 @@ skip_add:
}
subs = addstate(l, state->out, subs, pim, off);
/* "subs" may have changed, need to set "sub" again */
#ifdef FEAT_SYN_HL
if (state->c >= NFA_ZOPEN && state->c <= NFA_ZOPEN9)
sub = &subs->synt;
else
#endif
sub = &subs->norm;
if (save_in_use == -1)
{
@@ -4213,7 +4244,7 @@ skip_add:
sub = &subs->norm;
}
#ifdef FEAT_SYN_HL
else if (state->c >= NFA_ZCLOSE)
else if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9)
{
subidx = state->c - NFA_ZCLOSE;
sub = &subs->synt;
@@ -4257,6 +4288,13 @@ skip_add:
}
subs = addstate(l, state->out, subs, pim, off);
/* "subs" may have changed, need to set "sub" again */
#ifdef FEAT_SYN_HL
if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9)
sub = &subs->synt;
else
#endif
sub = &subs->norm;
if (REG_MULTI)
sub->list.multi[subidx].end = save_lpos;
@@ -5872,6 +5910,28 @@ nfa_regmatch(prog, start, submatch, m)
ADD_STATE_IF_MATCH(t->state);
break;
case NFA_LOWER_IC: /* [a-z] */
result = ri_lower(curc) || (ireg_ic && ri_upper(curc));
ADD_STATE_IF_MATCH(t->state);
break;
case NFA_NLOWER_IC: /* [^a-z] */
result = curc != NUL
&& !(ri_lower(curc) || (ireg_ic && ri_upper(curc)));
ADD_STATE_IF_MATCH(t->state);
break;
case NFA_UPPER_IC: /* [A-Z] */
result = ri_upper(curc) || (ireg_ic && ri_lower(curc));
ADD_STATE_IF_MATCH(t->state);
break;
case NFA_NUPPER_IC: /* ^[A-Z] */
result = curc != NUL
&& !(ri_upper(curc) || (ireg_ic && ri_lower(curc)));
ADD_STATE_IF_MATCH(t->state);
break;
case NFA_BACKREF1:
case NFA_BACKREF2:
case NFA_BACKREF3:

View File

@@ -289,15 +289,29 @@ STARTTEST
:call add(tl, [2, '.a\%$', " a\n "])
:call add(tl, [2, '.a\%$', " a\n_a", "_a"])
:"
:"""" Test recognition of some character classes
:call add(tl, [2, '[0-9]', '8', '8'])
:call add(tl, [2, '[^0-9]', '8'])
:call add(tl, [2, '[0-9a-fA-F]*', '0a7', '0a7'])
:call add(tl, [2, '[^0-9A-Fa-f]\+', '0a7'])
:call add(tl, [2, '[a-z_A-Z0-9]\+', 'aso_sfoij', 'aso_sfoij'])
:call add(tl, [2, '[a-z]', 'a', 'a'])
:call add(tl, [2, '[a-zA-Z]', 'a', 'a'])
:call add(tl, [2, '[A-Z]', 'a'])
:"""" Test recognition of character classes
:call add(tl, [2, '[0-7]\+', 'x0123456789x', '01234567'])
:call add(tl, [2, '[^0-7]\+', '0a;X+% 897', 'a;X+% 89'])
:call add(tl, [2, '[0-9]\+', 'x0123456789x', '0123456789'])
:call add(tl, [2, '[^0-9]\+', '0a;X+% 9', 'a;X+% '])
:call add(tl, [2, '[0-9a-fA-F]\+', 'x0189abcdefg', '0189abcdef'])
:call add(tl, [2, '[^0-9A-Fa-f]\+', '0189g;X+% ab', 'g;X+% '])
:call add(tl, [2, '[a-z_A-Z0-9]\+', ';+aso_SfOij ', 'aso_SfOij'])
:call add(tl, [2, '[^a-z_A-Z0-9]\+', 'aSo_;+% sfOij', ';+% '])
:call add(tl, [2, '[a-z_A-Z]\+', '0abyz_ABYZ;', 'abyz_ABYZ'])
:call add(tl, [2, '[^a-z_A-Z]\+', 'abAB_09;+% yzYZ', '09;+% '])
:call add(tl, [2, '[a-z]\+', '0abcxyz1', 'abcxyz'])
:call add(tl, [2, '[a-z]\+', 'AabxyzZ', 'abxyz'])
:call add(tl, [2, '[^a-z]\+', 'a;X09+% x', ';X09+% '])
:call add(tl, [2, '[^a-z]\+', 'abX0;%yz', 'X0;%'])
:call add(tl, [2, '[a-zA-Z]\+', '0abABxzXZ9', 'abABxzXZ'])
:call add(tl, [2, '[^a-zA-Z]\+', 'ab09_;+ XZ', '09_;+ '])
:call add(tl, [2, '[A-Z]\+', 'aABXYZz', 'ABXYZ'])
:call add(tl, [2, '[^A-Z]\+', 'ABx0;%YZ', 'x0;%'])
:call add(tl, [2, '[a-z]\+\c', '0abxyzABXYZ;', 'abxyzABXYZ'])
:call add(tl, [2, '[A-Z]\+\c', '0abABxzXZ9', 'abABxzXZ'])
:call add(tl, [2, '\c[^a-z]\+', 'ab09_;+ XZ', '09_;+ '])
:call add(tl, [2, '\c[^A-Z]\+', 'ab09_;+ XZ', '09_;+ '])
:call add(tl, [2, '\C[^A-Z]\+', 'ABCOIJDEOIFNSD jsfoij sa', ' jsfoij sa'])
:"
:"""" Tests for \z features
@@ -407,6 +421,9 @@ STARTTEST
:call add(tl, [2, '\(foo\)\@<=\>', 'barfoo', '', 'foo'])
:call add(tl, [2, '\(foo\)\@<=.*', 'foobar', 'bar', 'foo'])
:"
:" complicated look-behind match
:call add(tl, [2, '\(r\@<=\|\w\@<!\)\/', 'x = /word/;', '/'])
:"
:""""" \@>
:call add(tl, [2, '\(a*\)\@>a', 'aaaa'])
:call add(tl, [2, '\(a*\)\@>b', 'aaab', 'aaab', 'aaa'])

View File

@@ -650,30 +650,72 @@ OK 2 - .a\%$
OK 0 - .a\%$
OK 1 - .a\%$
OK 2 - .a\%$
OK 0 - [0-9]
OK 1 - [0-9]
OK 2 - [0-9]
OK 0 - [^0-9]
OK 1 - [^0-9]
OK 2 - [^0-9]
OK 0 - [0-9a-fA-F]*
OK 1 - [0-9a-fA-F]*
OK 2 - [0-9a-fA-F]*
OK 0 - [0-7]\+
OK 1 - [0-7]\+
OK 2 - [0-7]\+
OK 0 - [^0-7]\+
OK 1 - [^0-7]\+
OK 2 - [^0-7]\+
OK 0 - [0-9]\+
OK 1 - [0-9]\+
OK 2 - [0-9]\+
OK 0 - [^0-9]\+
OK 1 - [^0-9]\+
OK 2 - [^0-9]\+
OK 0 - [0-9a-fA-F]\+
OK 1 - [0-9a-fA-F]\+
OK 2 - [0-9a-fA-F]\+
OK 0 - [^0-9A-Fa-f]\+
OK 1 - [^0-9A-Fa-f]\+
OK 2 - [^0-9A-Fa-f]\+
OK 0 - [a-z_A-Z0-9]\+
OK 1 - [a-z_A-Z0-9]\+
OK 2 - [a-z_A-Z0-9]\+
OK 0 - [a-z]
OK 1 - [a-z]
OK 2 - [a-z]
OK 0 - [a-zA-Z]
OK 1 - [a-zA-Z]
OK 2 - [a-zA-Z]
OK 0 - [A-Z]
OK 1 - [A-Z]
OK 2 - [A-Z]
OK 0 - [^a-z_A-Z0-9]\+
OK 1 - [^a-z_A-Z0-9]\+
OK 2 - [^a-z_A-Z0-9]\+
OK 0 - [a-z_A-Z]\+
OK 1 - [a-z_A-Z]\+
OK 2 - [a-z_A-Z]\+
OK 0 - [^a-z_A-Z]\+
OK 1 - [^a-z_A-Z]\+
OK 2 - [^a-z_A-Z]\+
OK 0 - [a-z]\+
OK 1 - [a-z]\+
OK 2 - [a-z]\+
OK 0 - [a-z]\+
OK 1 - [a-z]\+
OK 2 - [a-z]\+
OK 0 - [^a-z]\+
OK 1 - [^a-z]\+
OK 2 - [^a-z]\+
OK 0 - [^a-z]\+
OK 1 - [^a-z]\+
OK 2 - [^a-z]\+
OK 0 - [a-zA-Z]\+
OK 1 - [a-zA-Z]\+
OK 2 - [a-zA-Z]\+
OK 0 - [^a-zA-Z]\+
OK 1 - [^a-zA-Z]\+
OK 2 - [^a-zA-Z]\+
OK 0 - [A-Z]\+
OK 1 - [A-Z]\+
OK 2 - [A-Z]\+
OK 0 - [^A-Z]\+
OK 1 - [^A-Z]\+
OK 2 - [^A-Z]\+
OK 0 - [a-z]\+\c
OK 1 - [a-z]\+\c
OK 2 - [a-z]\+\c
OK 0 - [A-Z]\+\c
OK 1 - [A-Z]\+\c
OK 2 - [A-Z]\+\c
OK 0 - \c[^a-z]\+
OK 1 - \c[^a-z]\+
OK 2 - \c[^a-z]\+
OK 0 - \c[^A-Z]\+
OK 1 - \c[^A-Z]\+
OK 2 - \c[^A-Z]\+
OK 0 - \C[^A-Z]\+
OK 1 - \C[^A-Z]\+
OK 2 - \C[^A-Z]\+
@@ -932,6 +974,9 @@ OK 2 - \(foo\)\@<=\>
OK 0 - \(foo\)\@<=.*
OK 1 - \(foo\)\@<=.*
OK 2 - \(foo\)\@<=.*
OK 0 - \(r\@<=\|\w\@<!\)\/
OK 1 - \(r\@<=\|\w\@<!\)\/
OK 2 - \(r\@<=\|\w\@<!\)\/
OK 0 - \(a*\)\@>a
OK 1 - \(a*\)\@>a
OK 2 - \(a*\)\@>a

View File

@@ -727,6 +727,14 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
4,
/**/
3,
/**/
2,
/**/
1,
/**/
0
};

View File

@@ -2172,8 +2172,9 @@ close_last_window_tabpage(win, free_buf, prev_curtab)
* If "free_buf" is TRUE related buffer may be unloaded.
*
* Called by :quit, :close, :xit, :wq and findtag().
* Returns FAIL when the window was not closed.
*/
void
int
win_close(win, free_buf)
win_T *win;
int free_buf;
@@ -2190,21 +2191,21 @@ win_close(win, free_buf)
if (last_window())
{
EMSG(_("E444: Cannot close last window"));
return;
return FAIL;
}
#ifdef FEAT_AUTOCMD
if (win->w_closing || (win->w_buffer != NULL && win->w_buffer->b_closing))
return; /* window is already being closed */
return FAIL; /* window is already being closed */
if (win == aucmd_win)
{
EMSG(_("E813: Cannot close autocmd window"));
return;
return FAIL;
}
if ((firstwin == aucmd_win || lastwin == aucmd_win) && one_window())
{
EMSG(_("E814: Cannot close window, only autocmd window would remain"));
return;
return FAIL;
}
#endif
@@ -2212,7 +2213,7 @@ win_close(win, free_buf)
* and then close the window and the tab page to avoid that curwin and
* curtab are invalid while we are freeing memory. */
if (close_last_window_tabpage(win, free_buf, prev_curtab))
return;
return FAIL;
/* When closing the help window, try restoring a snapshot after closing
* the window. Otherwise clear the snapshot, it's now invalid. */
@@ -2240,22 +2241,22 @@ win_close(win, free_buf)
win->w_closing = TRUE;
apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
if (!win_valid(win))
return;
return FAIL;
win->w_closing = FALSE;
if (last_window())
return;
return FAIL;
}
win->w_closing = TRUE;
apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf);
if (!win_valid(win))
return;
return FAIL;
win->w_closing = FALSE;
if (last_window())
return;
return FAIL;
# ifdef FEAT_EVAL
/* autocmds may abort script processing */
if (aborting())
return;
return FAIL;
# endif
}
#endif
@@ -2303,7 +2304,7 @@ win_close(win, free_buf)
* other window or moved to another tab page. */
else if (!win_valid(win) || last_window() || curtab != prev_curtab
|| close_last_window_tabpage(win, free_buf, prev_curtab))
return;
return FAIL;
/* Free the memory used for the window and get the window that received
* the screen space. */
@@ -2383,6 +2384,7 @@ win_close(win, free_buf)
#endif
redraw_all_later(NOT_VALID);
return OK;
}
/*