aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--BACKERS.md2
-rw-r--r--CMakeLists.txt12
-rw-r--r--Makefile3
-rw-r--r--runtime/doc/options.txt4
-rw-r--r--src/nvim/CMakeLists.txt4
-rw-r--r--src/nvim/edit.c8
-rw-r--r--src/nvim/eval.c65
-rw-r--r--src/nvim/ex_getln.c27
-rw-r--r--src/nvim/farsi.c2007
-rw-r--r--src/nvim/fold.c83
-rw-r--r--src/nvim/fold.h4
-rw-r--r--src/nvim/indent_c.c2
-rw-r--r--src/nvim/menu.c59
-rw-r--r--src/nvim/misc1.c2
-rw-r--r--src/nvim/move.c52
-rw-r--r--src/nvim/normal.c21
-rw-r--r--src/nvim/ops.c4
-rw-r--r--src/nvim/option.c12
-rw-r--r--src/nvim/os/event.c34
-rw-r--r--src/nvim/os_unix.c36
-rw-r--r--src/nvim/path.c69
-rw-r--r--src/nvim/popupmnu.c26
-rw-r--r--src/nvim/regexp.c149
-rw-r--r--src/nvim/regexp_defs.h30
-rw-r--r--src/nvim/regexp_nfa.c35
-rw-r--r--src/nvim/terminal.c10
-rw-r--r--src/nvim/testdir/Makefile13
-rw-r--r--src/nvim/testdir/test1.in10
-rw-r--r--src/nvim/testdir/test38.in35
-rw-r--r--src/nvim/testdir/test38.ok13
-rw-r--r--src/nvim/testdir/test44.in68
-rw-r--r--src/nvim/testdir/test44.ok24
-rw-r--r--src/nvim/testdir/test70.in62
-rw-r--r--src/nvim/testdir/test70.ok6
-rw-r--r--src/nvim/testdir/test85.in84
-rw-r--r--src/nvim/testdir/test85.ok7
-rw-r--r--src/nvim/testdir/test92.in48
-rw-r--r--src/nvim/testdir/test92.ok26
-rw-r--r--src/nvim/testdir/test93.in48
-rw-r--r--src/nvim/testdir/test93.ok26
-rw-r--r--src/nvim/testdir/test99.in68
-rw-r--r--src/nvim/testdir/test99.ok24
-rw-r--r--src/nvim/tui/tui.c14
-rw-r--r--src/nvim/version.c4
-rw-r--r--src/nvim/window.c2
-rw-r--r--test/benchmark/bench_re_freeze_spec.lua67
-rw-r--r--test/benchmark/preload.lua4
-rw-r--r--test/benchmark/samples/re.freeze.txt6
-rw-r--r--test/functional/legacy/038_virtual_replace_spec.lua58
-rw-r--r--test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua147
-rw-r--r--test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua98
-rw-r--r--test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua95
53 files changed, 1471 insertions, 2348 deletions
diff --git a/.gitignore b/.gitignore
index 78db2fa75f..d483afdd73 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,8 +22,6 @@
# Files generated by the tests
/src/nvim/testdir/del
/src/nvim/testdir/mbyte.vim
-/src/nvim/testdir/mzscheme.vim
-/src/nvim/testdir/lua.vim
/src/nvim/testdir/small.vim
/src/nvim/testdir/tiny.vim
/src/nvim/testdir/test*.out
diff --git a/BACKERS.md b/BACKERS.md
index 531264d205..10c6f42f27 100644
--- a/BACKERS.md
+++ b/BACKERS.md
@@ -140,12 +140,10 @@ Thank you to everyone who backed our [Bountysource fundraiser](https://www.bount
- Stanley Chan (Happy-Dude)
- Stefan Penner
- Steve Vermeulen https://github.com/svermeulen
-- Steve Vermeulen https://github.com/svermeulen
- Steven Myint (https://github.com/myint)
- Tae Sandoval Murgan <taecilla.github.io>
- The Kompanee http://thekompanee.com
- Thomas Cannon <http://thomascannon.net>
-- Tim Oxley http://campjs.com
- Tim Oxley http://campjs.com/
- Timo Schmiade
- Timothy Dahlin
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a026af7a1a..4219c69b62 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -331,4 +331,16 @@ if(BUSTED_PRG)
-DTEST_TYPE=functional
-P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake
DEPENDS nvim tty-test)
+
+ add_custom_target(benchmark
+ COMMAND ${CMAKE_COMMAND}
+ -DBUSTED_PRG=${BUSTED_PRG}
+ -DNVIM_PRG=$<TARGET_FILE:nvim>
+ -DWORKING_DIR=${CMAKE_CURRENT_SOURCE_DIR}
+ -DBUSTED_OUTPUT_TYPE=${BUSTED_OUTPUT_TYPE}
+ -DTEST_DIR=${CMAKE_CURRENT_SOURCE_DIR}/test
+ -DBUILD_DIR=${CMAKE_BINARY_DIR}
+ -DTEST_TYPE=benchmark
+ -P ${PROJECT_SOURCE_DIR}/cmake/RunTests.cmake
+ DEPENDS nvim tty-test)
endif()
diff --git a/Makefile b/Makefile
index 1683c558e8..721474a3ec 100644
--- a/Makefile
+++ b/Makefile
@@ -89,6 +89,9 @@ test: functionaltest
unittest: | nvim
+$(BUILD_CMD) -C build unittest
+benchmark: | nvim
+ +$(BUILD_CMD) -C build benchmark
+
clean:
+test -d build && $(BUILD_CMD) -C build clean || true
$(MAKE) -C src/nvim/testdir clean
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 0c964ae519..c0f1888d84 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -5383,6 +5383,10 @@ A jump table for the options with a short description can be found at |Q_op|.
Note that when using the NFA engine and the pattern contains something
that is not supported the pattern will not match. This is only useful
for debugging the regexp engine.
+ Using automatic selection enables Vim to switch the engine, if the
+ default engine becomes too costly. E.g., when the NFA engine uses too
+ many states. This should prevent Vim from hanging on a combination of
+ a complex pattern with long text.
*'relativenumber'* *'rnu'* *'norelativenumber'* *'nornu'*
'relativenumber' 'rnu' boolean (default off)
diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt
index 47782e8b6b..09b709b6ce 100644
--- a/src/nvim/CMakeLists.txt
+++ b/src/nvim/CMakeLists.txt
@@ -58,9 +58,7 @@ set(CONV_SOURCES
ex_cmds.c
ex_docmd.c
ex_getln.c
- farsi.c
fileio.c
- fold.c
getchar.c
if_cscope.c
mbyte.c
@@ -68,11 +66,9 @@ set(CONV_SOURCES
menu.c
message.c
misc1.c
- move.c
normal.c
ops.c
path.c
- popupmnu.c
quickfix.c
regexp.c
screen.c
diff --git a/src/nvim/edit.c b/src/nvim/edit.c
index c60d987ddd..b860ce8898 100644
--- a/src/nvim/edit.c
+++ b/src/nvim/edit.c
@@ -7354,9 +7354,9 @@ static int ins_bs(int c, int mode, int *inserted_space_p)
*inserted_space_p = FALSE;
if (p_sta && in_indent)
- ts = (int)get_sw_value(curbuf);
+ ts = get_sw_value(curbuf);
else
- ts = (int)get_sts_value();
+ ts = get_sts_value();
/* Compute the virtual column where we want to be. Since
* 'showbreak' may get in the way, need to get the last column of
* the previous character. */
@@ -7826,9 +7826,9 @@ static int ins_tab(void)
AppendToRedobuff((char_u *)"\t");
if (p_sta && ind) /* insert tab in indent, use 'shiftwidth' */
- temp = (int)get_sw_value(curbuf);
+ temp = get_sw_value(curbuf);
else if (curbuf->b_p_sts != 0) /* use 'softtabstop' when set */
- temp = (int)get_sts_value();
+ temp = get_sts_value();
else /* otherwise use 'tabstop' */
temp = (int)curbuf->b_p_ts;
temp -= get_nolist_virtcol() % temp;
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 4ab31985b5..231b92db3c 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -5942,18 +5942,23 @@ dictitem_T *dict_find(dict_T *d, char_u *key, int len)
return HI2DI(hi);
}
-// Get a function from a dictionary
-static ufunc_T *get_dict_callback(dict_T *d, char *key)
+/// Get a function from a dictionary
+/// @param[out] result The address where a pointer to the wanted callback
+/// will be left.
+/// @return true/false on success/failure.
+static bool get_dict_callback(dict_T *d, char *key, ufunc_T **result)
{
dictitem_T *di = dict_find(d, (uint8_t *)key, -1);
if (di == NULL) {
- return NULL;
+ *result = NULL;
+ return true;
}
if (di->di_tv.v_type != VAR_FUNC && di->di_tv.v_type != VAR_STRING) {
EMSG(_("Argument is not a function or function name"));
- return NULL;
+ *result = NULL;
+ return false;
}
uint8_t *name = di->di_tv.vval.v_string;
@@ -5970,11 +5975,13 @@ static ufunc_T *get_dict_callback(dict_T *d, char *key)
if (!rv) {
EMSG2(_("Function %s doesn't exist"), name);
- return NULL;
+ *result = NULL;
+ return false;
}
rv->uf_refcount++;
- return rv;
+ *result = rv;
+ return true;
}
/*
@@ -10810,6 +10817,8 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv)
return;
}
+ assert(args->lv_first);
+
if (!os_can_exe(args->lv_first->li_tv.vval.v_string, NULL)) {
// String is not executable
EMSG2(e_jobexe, args->lv_first->li_tv.vval.v_string);
@@ -10820,8 +10829,7 @@ static void f_jobstart(typval_T *argvars, typval_T *rettv)
ufunc_T *on_stdout = NULL, *on_stderr = NULL, *on_exit = NULL;
if (argvars[1].v_type == VAR_DICT) {
job_opts = argvars[1].vval.v_dict;
- common_job_callbacks(job_opts, &on_stdout, &on_stderr, &on_exit);
- if (did_emsg) {
+ if (!common_job_callbacks(job_opts, &on_stdout, &on_stderr, &on_exit)) {
return;
}
}
@@ -15077,8 +15085,7 @@ static void f_termopen(typval_T *argvars, typval_T *rettv)
dict_T *job_opts = NULL;
if (argvars[1].v_type == VAR_DICT) {
job_opts = argvars[1].vval.v_dict;
- common_job_callbacks(job_opts, &on_stdout, &on_stderr, &on_exit);
- if (did_emsg) {
+ if (!common_job_callbacks(job_opts, &on_stdout, &on_stderr, &on_exit)) {
return;
}
}
@@ -20051,27 +20058,27 @@ static inline JobOptions common_job_options(char **argv, ufunc_T *on_stdout,
return opts;
}
-static inline void common_job_callbacks(dict_T *vopts, ufunc_T **on_stdout,
- ufunc_T **on_stderr, ufunc_T **on_exit)
+/// Return true/false on success/failure.
+static inline bool common_job_callbacks(dict_T *vopts, ufunc_T **on_stdout,
+ ufunc_T **on_stderr, ufunc_T **on_exit)
{
- *on_stdout = get_dict_callback(vopts, "on_stdout");
- *on_stderr = get_dict_callback(vopts, "on_stderr");
- *on_exit = get_dict_callback(vopts, "on_exit");
- if (did_emsg) {
- if (*on_stdout) {
- user_func_unref(*on_stdout);
- }
- if (*on_stderr) {
- user_func_unref(*on_stderr);
- }
- if (*on_exit) {
- user_func_unref(*on_exit);
- }
- return;
+ if (get_dict_callback(vopts, "on_stdout", on_stdout)
+ && get_dict_callback(vopts, "on_stderr", on_stderr)
+ && get_dict_callback(vopts, "on_exit", on_exit)) {
+ vopts->internal_refcount++;
+ vopts->dv_refcount++;
+ return true;
}
-
- vopts->internal_refcount++;
- vopts->dv_refcount++;
+ if (*on_stdout) {
+ user_func_unref(*on_stdout);
+ }
+ if (*on_stderr) {
+ user_func_unref(*on_stderr);
+ }
+ if (*on_exit) {
+ user_func_unref(*on_exit);
+ }
+ return false;
}
static inline Job *common_job_start(JobOptions opts, typval_T *rettv)
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index d430509cfd..6b74e85acb 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -10,7 +10,6 @@
* ex_getln.c: Functions for entering and editing an Ex command line.
*/
-#include <assert.h>
#include <errno.h>
#include <stdbool.h>
#include <string.h>
@@ -1785,7 +1784,7 @@ getexmodeline (
}
if (c1 == Ctrl_T) {
- long sw = get_sw_value(curbuf);
+ int sw = get_sw_value(curbuf);
p = (char_u *)line_ga.ga_data;
p[line_ga.ga_len] = NUL;
@@ -3629,6 +3628,7 @@ ExpandFromContext (
}
if (xp->xp_context == EXPAND_SHELLCMD) {
+ *file = NULL;
expand_shellcmd(pat, num_file, file, flags);
return OK;
}
@@ -3810,16 +3810,17 @@ void ExpandGeneric(
reset_expand_highlight();
}
-/*
- * Complete a shell command.
- */
-static void
-expand_shellcmd (
- char_u *filepat, /* pattern to match with command names */
- int *num_file, /* return: number of matches */
- char_u ***file, /* return: array with matches */
- int flagsarg /* EW_ flags */
-)
+/// Complete a shell command.
+///
+/// @param filepat is a pattern to match with command names.
+/// @param[out] num_file is pointer to number of matches.
+/// @param[out] file is pointer to array of pointers to matches.
+/// *file will either be set to NULL or point to
+/// allocated memory.
+/// @param flagsarg is a combination of EW_* flags.
+static void expand_shellcmd(char_u *filepat, int *num_file, char_u ***file,
+ int flagsarg)
+ FUNC_ATTR_NONNULL_ALL
{
char_u *pat;
int i;
@@ -3875,10 +3876,8 @@ expand_shellcmd (
STRLCPY(buf + l, pat, MAXPATHL - l);
/* Expand matches in one directory of $PATH. */
- char_u **prev_file = *file;
ret = expand_wildcards(1, &buf, num_file, file, flags);
if (ret == OK) {
- assert(*file != prev_file);
ga_grow(&ga, *num_file);
{
for (i = 0; i < *num_file; ++i) {
diff --git a/src/nvim/farsi.c b/src/nvim/farsi.c
index 2ca581ebd3..f9d6b14edc 100644
--- a/src/nvim/farsi.c
+++ b/src/nvim/farsi.c
@@ -2,6 +2,7 @@
///
/// Functions for Farsi language
+#include <assert.h>
#include <stdbool.h>
#include "nvim/cursor.h"
@@ -29,26 +30,23 @@
// Special Farsi text messages
const char_u farsi_text_1[] = {
- YE_, _SIN, RE, ALEF_, _FE, ' ', 'V', 'I', 'M',
- ' ', F_HE, _BE, ' ', SHIN, RE, _GAF, DAL, ' ', NOON,
- ALEF_, _YE, ALEF_, _PE, '\0'
+ YE_, _SIN, RE, ALEF_, _FE, ' ', 'V', 'I', 'M', ' ', F_HE, _BE, ' ', SHIN, RE,
+ _GAF, DAL, ' ', NOON, ALEF_, _YE, ALEF_, _PE, '\0'
};
const char_u farsi_text_2[] = {
- YE_, _SIN, RE, ALEF_, _FE, ' ', FARSI_3, FARSI_3,
- FARSI_4, FARSI_2, ' ', DAL, RE, ALEF, DAL, _NOON,
- ALEF_, _TE, _SIN, ALEF, ' ', F_HE, _BE, ' ', SHIN,
- RE, _GAF, DAL, ' ', NOON, ALEF_, _YE, ALEF_, _PE, '\0'
+ YE_, _SIN, RE, ALEF_, _FE, ' ', FARSI_3, FARSI_3, FARSI_4, FARSI_2, ' ', DAL,
+ RE, ALEF, DAL, _NOON, ALEF_, _TE, _SIN, ALEF, ' ', F_HE, _BE, ' ', SHIN, RE,
+ _GAF, DAL, ' ', NOON, ALEF_, _YE, ALEF_, _PE, '\0'
};
const char_u farsi_text_3[] = {
- DAL, WAW, _SHIN, _YE, _MIM, _NOON, ' ', YE_, _NOON,
- ALEF_, _BE, _YE, _TE, _SHIN, _PE, ' ', 'R', 'E', 'P', 'L',
- 'A', 'C', 'E', ' ', NOON, ALEF_, _MIM, RE, _FE, ZE, ALEF,
- ' ', 'R', 'E', 'V', 'E', 'R', 'S', 'E', ' ', 'I', 'N',
- 'S', 'E', 'R', 'T', ' ', SHIN, WAW, RE, ' ', ALEF_, _BE,
- ' ', YE_, _SIN, RE, ALEF_, _FE, ' ', RE, DAL, ' ', RE,
- ALEF_, _KAF, ' ', MIM, ALEF_, _GAF, _NOON, _HE, '\0'
+ DAL, WAW, _SHIN, _YE, _MIM, _NOON, ' ', YE_, _NOON, ALEF_, _BE, _YE, _TE,
+ _SHIN, _PE, ' ', 'R', 'E', 'P', 'L', 'A', 'C', 'E', ' ', NOON, ALEF_, _MIM,
+ RE, _FE, ZE, ALEF, ' ', 'R', 'E', 'V', 'E', 'R', 'S', 'E', ' ', 'I', 'N', 'S',
+ 'E', 'R', 'T', ' ', SHIN, WAW, RE, ' ', ALEF_, _BE, ' ', YE_, _SIN, RE, ALEF_,
+ _FE, ' ', RE, DAL, ' ', RE, ALEF_, _KAF, ' ', MIM, ALEF_, _GAF, _NOON, _HE,
+ '\0'
};
const char_u farsi_text_5[] = {
@@ -65,93 +63,41 @@ const char_u farsi_text_5[] = {
/// @param c The character to convert.
///
/// @return Farsi character converted to a _X or _X_ type.
-static int toF_Xor_X_(int c)
+static char_u toF_Xor_X_(int c)
{
- int tempc;
+ char_u tempc;
switch (c) {
- case BE:
- return _BE;
-
- case PE:
- return _PE;
-
- case TE:
- return _TE;
-
- case SE:
- return _SE;
-
- case JIM:
- return _JIM;
-
- case CHE:
- return _CHE;
-
- case HE_J:
- return _HE_J;
-
- case XE:
- return _XE;
-
- case SIN:
- return _SIN;
-
- case SHIN:
- return _SHIN;
-
- case SAD:
- return _SAD;
-
- case ZAD:
- return _ZAD;
-
- case AYN:
- return _AYN;
-
- case AYN_:
- return _AYN_;
-
- case GHAYN:
- return _GHAYN;
-
- case GHAYN_:
- return _GHAYN_;
-
- case FE:
- return _FE;
-
- case GHAF:
- return _GHAF;
-
- case KAF:
- return _KAF;
-
- case GAF:
- return _GAF;
-
- case LAM:
- return _LAM;
-
- case MIM:
- return _MIM;
-
- case NOON:
- return _NOON;
-
- case YE:
- case YE_:
- return _YE;
-
- case YEE:
- case YEE_:
- return _YEE;
-
- case IE:
- case IE_:
- return _IE;
-
- case F_HE:
+ case BE : tempc = _BE ; break;
+ case PE : tempc = _PE ; break;
+ case TE : tempc = _TE ; break;
+ case SE : tempc = _SE ; break;
+ case JIM : tempc = _JIM ; break;
+ case CHE : tempc = _CHE ; break;
+ case HE_J : tempc = _HE_J ; break;
+ case XE : tempc = _XE ; break;
+ case SIN : tempc = _SIN ; break;
+ case SHIN : tempc = _SHIN ; break;
+ case SAD : tempc = _SAD ; break;
+ case ZAD : tempc = _ZAD ; break;
+ case AYN : tempc = _AYN ; break;
+ case AYN_ : tempc = _AYN_ ; break;
+ case GHAYN : tempc = _GHAYN ; break;
+ case GHAYN_ : tempc = _GHAYN_ ; break;
+ case FE : tempc = _FE ; break;
+ case GHAF : tempc = _GHAF ; break;
+ case KAF : tempc = _KAF ; break;
+ case GAF : tempc = _GAF ; break;
+ case LAM : tempc = _LAM ; break;
+ case MIM : tempc = _MIM ; break;
+ case NOON : tempc = _NOON ; break;
+ case YE :
+ case YE_ : tempc = _YE ; break;
+ case YEE :
+ case YEE_ : tempc = _YEE ; break;
+ case IE :
+ case IE_ : tempc = _IE ; break;
+ case F_HE :
tempc = _HE;
if (p_ri &&
@@ -171,9 +117,13 @@ static int toF_Xor_X_(int c)
inc_cursor();
}
- return tempc;
+ break;
+
+ default:
+ tempc = 0;
}
- return 0;
+
+ return tempc;
}
/// Convert the given Farsi character into Farsi capital character.
@@ -181,104 +131,51 @@ static int toF_Xor_X_(int c)
/// @param c The character to convert.
///
/// @return Character converted to the Farsi capital leter.
-int toF_TyA(int c)
+char_u toF_TyA(char_u c)
{
- switch (c) {
- case ALEF_:
- return ALEF;
-
- case ALEF_U_H_:
- return ALEF_U_H;
-
- case _BE:
- return BE;
-
- case _PE:
- return PE;
-
- case _TE:
- return TE;
-
- case _SE:
- return SE;
-
- case _JIM:
- return JIM;
-
- case _CHE:
- return CHE;
-
- case _HE_J:
- return HE_J;
-
- case _XE:
- return XE;
-
- case _SIN:
- return SIN;
-
- case _SHIN:
- return SHIN;
-
- case _SAD:
- return SAD;
-
- case _ZAD:
- return ZAD;
-
- case _AYN:
- case AYN_:
- case _AYN_:
- return AYN;
-
- case _GHAYN:
- case GHAYN_:
- case _GHAYN_:
- return GHAYN;
-
- case _FE:
- return FE;
+ char_u tempc;
- case _GHAF:
- return GHAF;
-
- // I am not sure what it is !!!
- // case _KAF_H:
- case _KAF:
- return KAF;
-
- case _GAF:
- return GAF;
-
- case _LAM:
- return LAM;
-
- case _MIM:
- return MIM;
-
- case _NOON:
- return NOON;
-
- case _YE:
- case YE_:
- return YE;
-
- case _YEE:
- case YEE_:
- return YEE;
-
- case TEE_:
- return TEE;
-
- case _IE:
- case IE_:
- return IE;
-
- case _HE:
- case _HE_:
- return F_HE;
+ switch (c) {
+ case ALEF_ : tempc = ALEF ; break;
+ case ALEF_U_H_ : tempc = ALEF_U_H ; break;
+ case _BE : tempc = BE ; break;
+ case _PE : tempc = PE ; break;
+ case _TE : tempc = TE ; break;
+ case _SE : tempc = SE ; break;
+ case _JIM : tempc = JIM ; break;
+ case _CHE : tempc = CHE ; break;
+ case _HE_J : tempc = HE_J ; break;
+ case _XE : tempc = XE ; break;
+ case _SIN : tempc = SIN ; break;
+ case _SHIN : tempc = SHIN ; break;
+ case _SAD : tempc = SAD ; break;
+ case _ZAD : tempc = ZAD ; break;
+ case _AYN :
+ case AYN_ :
+ case _AYN_ : tempc = AYN ; break;
+ case _GHAYN :
+ case GHAYN_ :
+ case _GHAYN_ : tempc = GHAYN ; break;
+ case _FE : tempc = FE ; break;
+ case _GHAF : tempc = GHAF ; break;
+ case _KAF : tempc = KAF ; break;
+ case _GAF : tempc = GAF ; break;
+ case _LAM : tempc = LAM ; break;
+ case _MIM : tempc = MIM ; break;
+ case _NOON : tempc = NOON ; break;
+ case _YE :
+ case YE_ : tempc = YE ; break;
+ case _YEE :
+ case YEE_ : tempc = YEE ; break;
+ case TEE_ : tempc = TEE ; break;
+ case _IE :
+ case IE_ : tempc = IE ; break;
+ case _HE :
+ case _HE_ : tempc = F_HE ; break;
+ default : tempc = c ;
}
- return c;
+
+ return tempc;
}
/// Is the character under the cursor+offset in the given buffer a join type.
@@ -388,51 +285,34 @@ static bool F_is_TyC_TyD(int c)
/// @param c The character to convert.
///
/// @return The character converted into a leading type.
-static int toF_TyB(int c)
+static char_u toF_TyB(int c)
{
- switch (c) {
- case ALEF_:
- return ALEF;
-
- case ALEF_U_H_:
- return ALEF_U_H;
-
- case _AYN_:
- return _AYN;
-
- case AYN_:
- // exception - there are many of them
- return AYN;
-
- case _GHAYN_:
- return _GHAYN;
-
- case GHAYN_:
- // exception - there are many of them
- return GHAYN;
-
- case _HE_:
- return _HE;
-
- case YE_:
- return YE;
-
- case IE_:
- return IE;
-
- case TEE_:
- return TEE;
+ char_u tempc;
- case YEE_:
- return YEE;
+ switch (c) {
+ case ALEF_ : tempc = ALEF ; break;
+ case ALEF_U_H_ : tempc = ALEF_U_H ; break;
+ case _AYN_ : tempc = _AYN ; break;
+ case AYN_ : tempc = AYN ; break; // exception - there are many
+ case _GHAYN_ : tempc = _GHAYN ; break;
+ case GHAYN_ : tempc = GHAYN ; break; // exception - there are many
+ case _HE_ : tempc = _HE ; break;
+ case YE_ : tempc = YE ; break;
+ case IE_ : tempc = IE ; break;
+ case TEE_ : tempc = TEE ; break;
+ case YEE_ : tempc = YEE ; break;
+ default:
+ assert(c >= 0 && c <= UCHAR_MAX);
+ tempc = (char_u)c;
}
- return c;
+
+ return tempc;
}
/// Overwrite the current redo and cursor characters + left adjust
///
/// @param c
-static void put_curr_and_l_to_X(int c)
+static void put_curr_and_l_to_X(char_u c)
{
int tempc;
@@ -465,7 +345,7 @@ static void put_curr_and_l_to_X(int c)
put_and_redo(c);
}
-static void put_and_redo(int c)
+static void put_and_redo(char_u c)
{
pchar_cursor(c);
AppendCharToRedobuff(K_BS);
@@ -475,110 +355,39 @@ static void put_and_redo(int c)
/// Change the char. under the cursor to a X_ or X type
static void chg_c_toX_orX(void)
{
- int tempc, curc;
+ int curc;
+ char_u tempc;
switch ((curc = gchar_cursor())) {
- case _BE:
- tempc = BE;
- break;
-
- case _PE:
- tempc = PE;
- break;
-
- case _TE:
- tempc = TE;
- break;
-
- case _SE:
- tempc = SE;
- break;
-
- case _JIM:
- tempc = JIM;
- break;
-
- case _CHE:
- tempc = CHE;
- break;
-
- case _HE_J:
- tempc = HE_J;
- break;
-
- case _XE:
- tempc = XE;
- break;
-
- case _SIN:
- tempc = SIN;
- break;
-
- case _SHIN:
- tempc = SHIN;
- break;
-
- case _SAD:
- tempc = SAD;
- break;
-
- case _ZAD:
- tempc = ZAD;
- break;
-
- case _FE:
- tempc = FE;
- break;
-
- case _GHAF:
- tempc = GHAF;
- break;
-
- case _KAF_H:
- case _KAF:
- tempc = KAF;
- break;
-
- case _GAF:
- tempc = GAF;
- break;
-
- case _AYN:
- tempc = AYN;
- break;
-
- case _AYN_:
- tempc = AYN_;
- break;
-
- case _GHAYN:
- tempc = GHAYN;
- break;
-
- case _GHAYN_:
- tempc = GHAYN_;
- break;
-
- case _LAM:
- tempc = LAM;
- break;
-
- case _MIM:
- tempc = MIM;
- break;
-
- case _NOON:
- tempc = NOON;
- break;
-
- case _HE:
- case _HE_:
- tempc = F_HE;
- break;
-
- case _YE:
- case _IE:
- case _YEE:
+ case _BE : tempc = BE ; break ;
+ case _PE : tempc = PE ; break ;
+ case _TE : tempc = TE ; break ;
+ case _SE : tempc = SE ; break ;
+ case _JIM : tempc = JIM ; break ;
+ case _CHE : tempc = CHE ; break ;
+ case _HE_J : tempc = HE_J ; break ;
+ case _XE : tempc = XE ; break ;
+ case _SIN : tempc = SIN ; break ;
+ case _SHIN : tempc = SHIN ; break ;
+ case _SAD : tempc = SAD ; break ;
+ case _ZAD : tempc = ZAD ; break ;
+ case _FE : tempc = FE ; break ;
+ case _GHAF : tempc = GHAF ; break ;
+ case _KAF_H :
+ case _KAF : tempc = KAF ; break ;
+ case _GAF : tempc = GAF ; break ;
+ case _AYN : tempc = AYN ; break ;
+ case _AYN_ : tempc = AYN_ ; break ;
+ case _GHAYN : tempc = GHAYN ; break ;
+ case _GHAYN_ : tempc = GHAYN_ ; break ;
+ case _LAM : tempc = LAM ; break ;
+ case _MIM : tempc = MIM ; break ;
+ case _NOON : tempc = NOON ; break ;
+ case _HE :
+ case _HE_ : tempc = F_HE ; break;
+ case _YE :
+ case _IE :
+ case _YEE :
if (p_ri) {
inc_cursor();
@@ -621,55 +430,21 @@ static void chg_c_toX_orX(void)
/// Change the char. under the cursor to a _X_ or X_ type
static void chg_c_to_X_orX_(void)
{
- int tempc;
+ char_u tempc;
switch (gchar_cursor()) {
- case ALEF:
- tempc = ALEF_;
- break;
-
- case ALEF_U_H:
- tempc = ALEF_U_H_;
- break;
-
- case _AYN:
- tempc = _AYN_;
- break;
-
- case AYN:
- tempc = AYN_;
- break;
-
- case _GHAYN:
- tempc = _GHAYN_;
- break;
-
- case GHAYN:
- tempc = GHAYN_;
- break;
-
- case _HE:
- tempc = _HE_;
- break;
-
- case YE:
- tempc = YE_;
- break;
-
- case IE:
- tempc = IE_;
- break;
-
- case TEE:
- tempc = TEE_;
- break;
-
- case YEE:
- tempc = YEE_;
- break;
-
- default:
- tempc = 0;
+ case ALEF : tempc = ALEF_ ; break;
+ case ALEF_U_H : tempc = ALEF_U_H_ ; break;
+ case _AYN : tempc = _AYN_ ; break;
+ case AYN : tempc = AYN_ ; break;
+ case _GHAYN : tempc = _GHAYN_ ; break;
+ case GHAYN : tempc = GHAYN_ ; break;
+ case _HE : tempc = _HE_ ; break;
+ case YE : tempc = YE_ ; break;
+ case IE : tempc = IE_ ; break;
+ case TEE : tempc = TEE_ ; break;
+ case YEE : tempc = YEE_ ; break;
+ default : tempc = 0 ;
}
if (tempc) {
@@ -689,15 +464,14 @@ static void chg_c_to_X_or_X(void)
if ((tempc == F_HE) && (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))) {
tempc = _HE_;
dec_cursor();
- put_and_redo(tempc);
+ put_and_redo((char_u)tempc);
return;
}
-
dec_cursor();
}
if ((tempc = toF_Xor_X_(tempc)) != 0) {
- put_and_redo(tempc);
+ put_and_redo((char_u)tempc);
}
}
@@ -722,56 +496,22 @@ static void chg_l_to_X_orX_(void)
}
switch (gchar_cursor()) {
- case ALEF:
- tempc = ALEF_;
- break;
-
- case ALEF_U_H:
- tempc = ALEF_U_H_;
- break;
-
- case _AYN:
- tempc = _AYN_;
- break;
-
- case AYN:
- tempc = AYN_;
- break;
-
- case _GHAYN:
- tempc = _GHAYN_;
- break;
-
- case GHAYN:
- tempc = GHAYN_;
- break;
-
- case _HE:
- tempc = _HE_;
- break;
-
- case YE:
- tempc = YE_;
- break;
-
- case IE:
- tempc = IE_;
- break;
-
- case TEE:
- tempc = TEE_;
- break;
-
- case YEE:
- tempc = YEE_;
- break;
-
- default:
- tempc = 0;
+ case ALEF : tempc = ALEF_ ; break;
+ case ALEF_U_H : tempc = ALEF_U_H_ ; break;
+ case _AYN : tempc = _AYN_ ; break;
+ case AYN : tempc = AYN_ ; break;
+ case _GHAYN : tempc = _GHAYN_ ; break;
+ case GHAYN : tempc = GHAYN_ ; break;
+ case _HE : tempc = _HE_ ; break;
+ case YE : tempc = YE_ ; break;
+ case IE : tempc = IE_ ; break;
+ case TEE : tempc = TEE_ ; break;
+ case YEE : tempc = YEE_ ; break;
+ default : tempc = 0 ;
}
if (tempc) {
- put_and_redo(tempc);
+ put_and_redo((char_u)tempc);
}
if (p_ri) {
@@ -784,7 +524,7 @@ static void chg_l_to_X_orX_(void)
/// Change the character left to the cursor to a X or _X type
static void chg_l_toXor_X(void)
{
- int tempc;
+ char_u tempc;
if ((curwin->w_cursor.col != 0) &&
(curwin->w_cursor.col + 1 == (colnr_T)STRLEN(get_cursor_line_ptr()))) {
@@ -802,52 +542,18 @@ static void chg_l_toXor_X(void)
}
switch (gchar_cursor()) {
- case ALEF_:
- tempc = ALEF;
- break;
-
- case ALEF_U_H_:
- tempc = ALEF_U_H;
- break;
-
- case _AYN_:
- tempc = _AYN;
- break;
-
- case AYN_:
- tempc = AYN;
- break;
-
- case _GHAYN_:
- tempc = _GHAYN;
- break;
-
- case GHAYN_:
- tempc = GHAYN;
- break;
-
- case _HE_:
- tempc = _HE;
- break;
-
- case YE_:
- tempc = YE;
- break;
-
- case IE_:
- tempc = IE;
- break;
-
- case TEE_:
- tempc = TEE;
- break;
-
- case YEE_:
- tempc = YEE;
- break;
-
- default:
- tempc = 0;
+ case ALEF_ : tempc = ALEF ; break;
+ case ALEF_U_H_ : tempc = ALEF_U_H ; break;
+ case _AYN_ : tempc = _AYN ; break;
+ case AYN_ : tempc = AYN ; break;
+ case _GHAYN_ : tempc = _GHAYN ; break;
+ case GHAYN_ : tempc = GHAYN ; break;
+ case _HE_ : tempc = _HE ; break;
+ case YE_ : tempc = YE ; break;
+ case IE_ : tempc = IE ; break;
+ case TEE_ : tempc = TEE ; break;
+ case YEE_ : tempc = YEE ; break;
+ default : tempc = 0 ;
}
if (tempc) {
@@ -864,7 +570,8 @@ static void chg_l_toXor_X(void)
/// Change the character right to the cursor to a _X or _X_ type
static void chg_r_to_Xor_X_(void)
{
- int tempc, c;
+ int tempc;
+ char_u c;
if (curwin->w_cursor.col) {
if (!p_ri) {
@@ -893,13 +600,13 @@ int fkmap(int c)
}
if (VIM_ISDIGIT(c)
- || (((c == '.')
- || (c == '+')
- || (c == '-')
- || (c == '^')
- || (c == '%')
- || (c == '#')
- || (c == '='))
+ || ((c == '.'
+ || c == '+'
+ || c == '-'
+ || c == '^'
+ || c == '%'
+ || c == '#'
+ || c == '=')
&& revins)) {
if (!revins) {
if (curwin->w_cursor.col) {
@@ -1060,158 +767,57 @@ int fkmap(int c)
if (!p_ri) {
if (!curwin->w_cursor.col) {
switch (c) {
- case '0':
- return FARSI_0;
-
- case '1':
- return FARSI_1;
-
- case '2':
- return FARSI_2;
-
- case '3':
- return FARSI_3;
-
- case '4':
- return FARSI_4;
-
- case '5':
- return FARSI_5;
-
- case '6':
- return FARSI_6;
-
- case '7':
- return FARSI_7;
-
- case '8':
- return FARSI_8;
-
- case '9':
- return FARSI_9;
-
- case 'B':
- return F_PSP;
-
- case 'E':
- return JAZR_N;
-
- case 'F':
- return ALEF_D_H;
-
- case 'H':
- return ALEF_A;
-
- case 'I':
- return TASH;
-
- case 'K':
- return F_LQUOT;
-
- case 'L':
- return F_RQUOT;
-
- case 'M':
- return HAMZE;
-
- case 'O':
- return '[';
-
- case 'P':
- return ']';
-
- case 'Q':
- return OO;
-
- case 'R':
- return MAD_N;
-
- case 'T':
- return OW;
-
- case 'U':
- return MAD;
-
- case 'W':
- return OW_OW;
-
- case 'Y':
- return JAZR;
-
- case '`':
- return F_PCN;
-
- case '!':
- return F_EXCL;
-
- case '@':
- return F_COMMA;
-
- case '#':
- return F_DIVIDE;
-
- case '$':
- return F_CURRENCY;
-
- case '%':
- return F_PERCENT;
-
- case '^':
- return F_MUL;
-
- case '&':
- return F_BCOMMA;
-
- case '*':
- return F_STAR;
-
- case '(':
- return F_LPARENT;
-
- case ')':
- return F_RPARENT;
-
- case '-':
- return F_MINUS;
-
- case '_':
- return F_UNDERLINE;
-
- case '=':
- return F_EQUALS;
-
- case '+':
- return F_PLUS;
-
- case '\\':
- return F_BSLASH;
-
- case '|':
- return F_PIPE;
-
- case ':':
- return F_DCOLON;
-
- case '"':
- return F_SEMICOLON;
-
- case '.':
- return F_PERIOD;
-
- case '/':
- return F_SLASH;
-
- case '<':
- return F_LESS;
-
- case '>':
- return F_GREATER;
-
- case '?':
- return F_QUESTION;
-
- case ' ':
- return F_BLANK;
+ case '0' : return FARSI_0 ;
+ case '1' : return FARSI_1 ;
+ case '2' : return FARSI_2 ;
+ case '3' : return FARSI_3 ;
+ case '4' : return FARSI_4 ;
+ case '5' : return FARSI_5 ;
+ case '6' : return FARSI_6 ;
+ case '7' : return FARSI_7 ;
+ case '8' : return FARSI_8 ;
+ case '9' : return FARSI_9 ;
+ case 'B' : return F_PSP ;
+ case 'E' : return JAZR_N ;
+ case 'F' : return ALEF_D_H ;
+ case 'H' : return ALEF_A ;
+ case 'I' : return TASH ;
+ case 'K' : return F_LQUOT ;
+ case 'L' : return F_RQUOT ;
+ case 'M' : return HAMZE ;
+ case 'O' : return '[' ;
+ case 'P' : return ']' ;
+ case 'Q' : return OO ;
+ case 'R' : return MAD_N ;
+ case 'T' : return OW ;
+ case 'U' : return MAD ;
+ case 'W' : return OW_OW ;
+ case 'Y' : return JAZR ;
+ case '`' : return F_PCN ;
+ case '!' : return F_EXCL ;
+ case '@' : return F_COMMA ;
+ case '#' : return F_DIVIDE ;
+ case '$' : return F_CURRENCY ;
+ case '%' : return F_PERCENT ;
+ case '^' : return F_MUL ;
+ case '&' : return F_BCOMMA ;
+ case '*' : return F_STAR ;
+ case '(' : return F_LPARENT ;
+ case ')' : return F_RPARENT ;
+ case '-' : return F_MINUS ;
+ case '_' : return F_UNDERLINE ;
+ case '=' : return F_EQUALS ;
+ case '+' : return F_PLUS ;
+ case '\\' : return F_BSLASH ;
+ case '|' : return F_PIPE ;
+ case ':' : return F_DCOLON ;
+ case '"' : return F_SEMICOLON ;
+ case '.' : return F_PERIOD ;
+ case '/' : return F_SLASH ;
+ case '<' : return F_LESS ;
+ case '>' : return F_GREATER ;
+ case '?' : return F_QUESTION ;
+ case ' ' : return F_BLANK ;
}
break;
}
@@ -1246,7 +852,7 @@ int fkmap(int c)
case _HE_:
case _TA:
case _ZA:
- put_curr_and_l_to_X(toF_TyA(tempc));
+ put_curr_and_l_to_X(toF_TyA((char_u)tempc));
break;
case _AYN:
@@ -1276,7 +882,7 @@ int fkmap(int c)
inc_cursor();
}
- put_curr_and_l_to_X(tempc);
+ put_curr_and_l_to_X((char_u)tempc);
break;
case _GHAYN:
@@ -1307,7 +913,7 @@ int fkmap(int c)
inc_cursor();
}
- put_curr_and_l_to_X(tempc);
+ put_curr_and_l_to_X((char_u)tempc);
break;
case _YE:
@@ -1316,8 +922,8 @@ int fkmap(int c)
if (!p_ri) {
if (!curwin->w_cursor.col) {
- put_curr_and_l_to_X((tempc == _YE ? YE :
- (tempc == _IE ? IE : YEE)));
+ put_curr_and_l_to_X(
+ (tempc == _YE ? YE : tempc == _IE ? IE : YEE));
break;
}
}
@@ -1329,11 +935,9 @@ int fkmap(int c)
}
if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) {
- tempc = (tempc == _YE ? YE_ :
- (tempc == _IE ? IE_ : YEE_));
+ tempc = (tempc == _YE ? YE_ : tempc == _IE ? IE_ : YEE_);
} else {
- tempc = (tempc == _YE ? YE :
- (tempc == _IE ? IE : YEE));
+ tempc = (tempc == _YE ? YE : tempc == _IE ? IE : YEE);
}
if (p_ri) {
@@ -1342,7 +946,7 @@ int fkmap(int c)
inc_cursor();
}
- put_curr_and_l_to_X(tempc);
+ put_curr_and_l_to_X((char_u)tempc);
break;
}
@@ -1353,200 +957,70 @@ int fkmap(int c)
tempc = 0;
switch (c) {
- case '0':
- return FARSI_0;
-
- case '1':
- return FARSI_1;
-
- case '2':
- return FARSI_2;
-
- case '3':
- return FARSI_3;
-
- case '4':
- return FARSI_4;
-
- case '5':
- return FARSI_5;
-
- case '6':
- return FARSI_6;
-
- case '7':
- return FARSI_7;
-
- case '8':
- return FARSI_8;
-
- case '9':
- return FARSI_9;
-
- case 'B':
- return F_PSP;
-
- case 'E':
- return JAZR_N;
-
- case 'F':
- return ALEF_D_H;
-
- case 'H':
- return ALEF_A;
-
- case 'I':
- return TASH;
-
- case 'K':
- return F_LQUOT;
-
- case 'L':
- return F_RQUOT;
-
- case 'M':
- return HAMZE;
-
- case 'O':
- return '[';
-
- case 'P':
- return ']';
-
- case 'Q':
- return OO;
-
- case 'R':
- return MAD_N;
-
- case 'T':
- return OW;
-
- case 'U':
- return MAD;
-
- case 'W':
- return OW_OW;
-
- case 'Y':
- return JAZR;
-
- case '`':
- return F_PCN;
-
- case '!':
- return F_EXCL;
-
- case '@':
- return F_COMMA;
-
- case '#':
- return F_DIVIDE;
-
- case '$':
- return F_CURRENCY;
-
- case '%':
- return F_PERCENT;
-
- case '^':
- return F_MUL;
-
- case '&':
- return F_BCOMMA;
-
- case '*':
- return F_STAR;
-
- case '(':
- return F_LPARENT;
-
- case ')':
- return F_RPARENT;
-
- case '-':
- return F_MINUS;
-
- case '_':
- return F_UNDERLINE;
-
- case '=':
- return F_EQUALS;
-
- case '+':
- return F_PLUS;
-
- case '\\':
- return F_BSLASH;
-
- case '|':
- return F_PIPE;
-
- case ':':
- return F_DCOLON;
-
- case '"':
- return F_SEMICOLON;
-
- case '.':
- return F_PERIOD;
-
- case '/':
- return F_SLASH;
-
- case '<':
- return F_LESS;
-
- case '>':
- return F_GREATER;
-
- case '?':
- return F_QUESTION;
-
- case ' ':
- return F_BLANK;
+ case '0' : return FARSI_0 ;
+ case '1' : return FARSI_1 ;
+ case '2' : return FARSI_2 ;
+ case '3' : return FARSI_3 ;
+ case '4' : return FARSI_4 ;
+ case '5' : return FARSI_5 ;
+ case '6' : return FARSI_6 ;
+ case '7' : return FARSI_7 ;
+ case '8' : return FARSI_8 ;
+ case '9' : return FARSI_9 ;
+ case 'B' : return F_PSP ;
+ case 'E' : return JAZR_N ;
+ case 'F' : return ALEF_D_H ;
+ case 'H' : return ALEF_A ;
+ case 'I' : return TASH ;
+ case 'K' : return F_LQUOT ;
+ case 'L' : return F_RQUOT ;
+ case 'M' : return HAMZE ;
+ case 'O' : return '[' ;
+ case 'P' : return ']' ;
+ case 'Q' : return OO ;
+ case 'R' : return MAD_N ;
+ case 'T' : return OW ;
+ case 'U' : return MAD ;
+ case 'W' : return OW_OW ;
+ case 'Y' : return JAZR ;
+ case '`' : return F_PCN ;
+ case '!' : return F_EXCL ;
+ case '@' : return F_COMMA ;
+ case '#' : return F_DIVIDE ;
+ case '$' : return F_CURRENCY ;
+ case '%' : return F_PERCENT ;
+ case '^' : return F_MUL ;
+ case '&' : return F_BCOMMA ;
+ case '*' : return F_STAR ;
+ case '(' : return F_LPARENT ;
+ case ')' : return F_RPARENT ;
+ case '-' : return F_MINUS ;
+ case '_' : return F_UNDERLINE ;
+ case '=' : return F_EQUALS ;
+ case '+' : return F_PLUS ;
+ case '\\' : return F_BSLASH ;
+ case '|' : return F_PIPE ;
+ case ':' : return F_DCOLON ;
+ case '"' : return F_SEMICOLON ;
+ case '.' : return F_PERIOD ;
+ case '/' : return F_SLASH ;
+ case '<' : return F_LESS ;
+ case '>' : return F_GREATER ;
+ case '?' : return F_QUESTION ;
+ case ' ' : return F_BLANK ;
}
break;
- case 'a':
- tempc = _SHIN;
- break;
-
- case 'A':
- tempc = WAW_H;
- break;
-
- case 'b':
- tempc = ZAL;
- break;
-
- case 'c':
- tempc = ZE;
- break;
-
- case 'C':
- tempc = JE;
- break;
-
- case 'd':
- tempc = _YE;
- break;
-
- case 'D':
- tempc = _YEE;
- break;
-
- case 'e':
- tempc = _SE;
- break;
-
- case 'f':
- tempc = _BE;
- break;
-
- case 'g':
- tempc = _LAM;
- break;
+ case 'a' : tempc = _SHIN ; break;
+ case 'A' : tempc = WAW_H ; break;
+ case 'b' : tempc = ZAL ; break;
+ case 'c' : tempc = ZE ; break;
+ case 'C' : tempc = JE ; break;
+ case 'd' : tempc = _YE ; break;
+ case 'D' : tempc = _YEE ; break;
+ case 'e' : tempc = _SE ; break;
+ case 'f' : tempc = _BE ; break;
+ case 'g' : tempc = _LAM ; break;
case 'G':
if (!curwin->w_cursor.col && STRLEN(get_cursor_line_ptr())) {
@@ -1621,7 +1095,6 @@ int fkmap(int c)
return tempc;
case 'i':
-
if (!curwin->w_cursor.col && STRLEN(get_cursor_line_ptr())) {
if (!p_ri && !F_is_TyE(tempc)) {
chg_c_to_X_orX_();
@@ -1656,7 +1129,6 @@ int fkmap(int c)
break;
case 'J':
-
if (!curwin->w_cursor.col && STRLEN(get_cursor_line_ptr())) {
if (p_ri) {
chg_c_to_X_or_X();
@@ -1683,50 +1155,18 @@ int fkmap(int c)
return tempc;
- case 'k':
- tempc = _NOON;
- break;
-
- case 'l':
- tempc = _MIM;
- break;
-
- case 'm':
- tempc = _PE;
- break;
-
- case 'n':
- case 'N':
- tempc = DAL;
- break;
-
- case 'o':
- tempc = _XE;
- break;
-
- case 'p':
- tempc = _HE_J;
- break;
-
- case 'q':
- tempc = _ZAD;
- break;
-
- case 'r':
- tempc = _GHAF;
- break;
-
- case 's':
- tempc = _SIN;
- break;
-
- case 'S':
- tempc = _IE;
- break;
-
- case 't':
- tempc = _FE;
- break;
+ case 'k' : tempc = _NOON ; break;
+ case 'l' : tempc = _MIM ; break;
+ case 'm' : tempc = _PE ; break;
+ case 'n' :
+ case 'N' : tempc = DAL ; break;
+ case 'o' : tempc = _XE ; break;
+ case 'p' : tempc = _HE_J ; break;
+ case 'q' : tempc = _ZAD ; break;
+ case 'r' : tempc = _GHAF ; break;
+ case 's' : tempc = _SIN ; break;
+ case 'S' : tempc = _IE ; break;
+ case 't' : tempc = _FE ; break;
case 'u':
if (!curwin->w_cursor.col && STRLEN(get_cursor_line_ptr())) {
@@ -1758,19 +1198,11 @@ int fkmap(int c)
}
break;
- case 'v':
- case 'V':
- tempc = RE;
- break;
-
- case 'w':
- tempc = _SAD;
- break;
-
- case 'x':
- case 'X':
- tempc = _TA;
- break;
+ case 'v' :
+ case 'V' : tempc = RE ; break;
+ case 'w' : tempc = _SAD ; break;
+ case 'x' :
+ case 'X' : tempc = _TA ; break;
case 'y':
if (!curwin->w_cursor.col && STRLEN(get_cursor_line_ptr())) {
@@ -1803,33 +1235,13 @@ int fkmap(int c)
break;
- case 'z':
- tempc = _ZA;
- break;
-
- case 'Z':
- tempc = _KAF_H;
- break;
-
- case ';':
- tempc = _KAF;
- break;
-
- case '\'':
- tempc = _GAF;
- break;
-
- case ',':
- tempc = WAW;
- break;
-
- case '[':
- tempc = _JIM;
- break;
-
- case ']':
- tempc = _CHE;
- break;
+ case 'z' : tempc = _ZA ; break;
+ case 'Z' : tempc = _KAF_H ; break;
+ case ';' : tempc = _KAF ; break;
+ case '\'' : tempc = _GAF ; break;
+ case ',' : tempc = WAW ; break;
+ case '[' : tempc = _JIM ; break;
+ case ']' : tempc = _CHE ; break;
}
if ((F_isalpha(tempc) || F_isdigit(tempc))) {
@@ -1871,99 +1283,50 @@ int fkmap(int c)
/// @param c The character to convert.
///
/// @return The non-leading Farsi character converted to a leading type.
-static int toF_leading(int c)
+static char_u toF_leading(char_u c)
{
- switch (c) {
- case ALEF_:
- return ALEF;
-
- case ALEF_U_H_:
- return ALEF_U_H;
-
- case BE:
- return _BE;
-
- case PE:
- return _PE;
+ char_u tempc;
- case TE:
- return _TE;
-
- case SE:
- return _SE;
-
- case JIM:
- return _JIM;
-
- case CHE:
- return _CHE;
-
- case HE_J:
- return _HE_J;
-
- case XE:
- return _XE;
-
- case SIN:
- return _SIN;
-
- case SHIN:
- return _SHIN;
-
- case SAD:
- return _SAD;
-
- case ZAD:
- return _ZAD;
-
- case AYN:
- case AYN_:
- case _AYN_:
- return _AYN;
-
- case GHAYN:
- case GHAYN_:
- case _GHAYN_:
- return _GHAYN;
-
- case FE:
- return _FE;
-
- case GHAF:
- return _GHAF;
-
- case KAF:
- return _KAF;
-
- case GAF:
- return _GAF;
-
- case LAM:
- return _LAM;
-
- case MIM:
- return _MIM;
-
- case NOON:
- return _NOON;
-
- case _HE_:
- case F_HE:
- return _HE;
-
- case YE:
- case YE_:
- return _YE;
-
- case IE_:
- case IE:
- return _IE;
-
- case YEE:
- case YEE_:
- return _YEE;
+ switch (c) {
+ case ALEF_ : tempc = ALEF ; break;
+ case ALEF_U_H_ : tempc = ALEF_U_H ; break;
+ case BE : tempc = _BE ; break;
+ case PE : tempc = _PE ; break;
+ case TE : tempc = _TE ; break;
+ case SE : tempc = _SE ; break;
+ case JIM : tempc = _JIM ; break;
+ case CHE : tempc = _CHE ; break;
+ case HE_J : tempc = _HE_J ; break;
+ case XE : tempc = _XE ; break;
+ case SIN : tempc = _SIN ; break;
+ case SHIN : tempc = _SHIN ; break;
+ case SAD : tempc = _SAD ; break;
+ case ZAD : tempc = _ZAD ; break;
+ case AYN :
+ case AYN_ :
+ case _AYN_ : tempc = _AYN ; break;
+ case GHAYN :
+ case GHAYN_ :
+ case _GHAYN_ : tempc = _GHAYN ; break;
+ case FE : tempc = _FE ; break;
+ case GHAF : tempc = _GHAF ; break;
+ case KAF : tempc = _KAF ; break;
+ case GAF : tempc = _GAF ; break;
+ case LAM : tempc = _LAM ; break;
+ case MIM : tempc = _MIM ; break;
+ case NOON : tempc = _NOON ; break;
+ case _HE_ :
+ case F_HE : tempc = _HE ; break;
+ case YE :
+ case YE_ : tempc = _YE ; break;
+ case IE_ :
+ case IE : tempc = _IE ; break;
+ case YEE :
+ case YEE_ : tempc = _YEE ; break;
+ default : tempc = c;
}
- return c;
+
+ return tempc;
}
/// Convert a given Farsi char into right joining type.
@@ -1971,102 +1334,51 @@ static int toF_leading(int c)
/// @param c The character to convert.
///
/// @return The Farsi character converted into a right joining type
-static int toF_Rjoin(int c)
+static char_u toF_Rjoin(char_u c)
{
- switch (c) {
- case ALEF:
- return ALEF_;
-
- case ALEF_U_H:
- return ALEF_U_H_;
-
- case BE:
- return _BE;
-
- case PE:
- return _PE;
-
- case TE:
- return _TE;
-
- case SE:
- return _SE;
-
- case JIM:
- return _JIM;
+ char_u tempc;
- case CHE:
- return _CHE;
-
- case HE_J:
- return _HE_J;
-
- case XE:
- return _XE;
-
- case SIN:
- return _SIN;
-
- case SHIN:
- return _SHIN;
-
- case SAD:
- return _SAD;
-
- case ZAD:
- return _ZAD;
-
- case AYN:
- case AYN_:
- case _AYN:
- return _AYN_;
-
- case GHAYN:
- case GHAYN_:
- case _GHAYN_:
- return _GHAYN_;
-
- case FE:
- return _FE;
-
- case GHAF:
- return _GHAF;
-
- case KAF:
- return _KAF;
-
- case GAF:
- return _GAF;
-
- case LAM:
- return _LAM;
-
- case MIM:
- return _MIM;
-
- case NOON:
- return _NOON;
-
- case _HE:
- case F_HE:
- return _HE_;
-
- case YE:
- case YE_:
- return _YE;
-
- case IE_:
- case IE:
- return _IE;
-
- case TEE:
- return TEE_;
-
- case YEE:
- case YEE_:
- return _YEE;
+ switch (c) {
+ case ALEF : tempc = ALEF_ ; break;
+ case ALEF_U_H : tempc = ALEF_U_H_ ; break;
+ case BE : tempc = _BE ; break;
+ case PE : tempc = _PE ; break;
+ case TE : tempc = _TE ; break;
+ case SE : tempc = _SE ; break;
+ case JIM : tempc = _JIM ; break;
+ case CHE : tempc = _CHE ; break;
+ case HE_J : tempc = _HE_J ; break;
+ case XE : tempc = _XE ; break;
+ case SIN : tempc = _SIN ; break;
+ case SHIN : tempc = _SHIN ; break;
+ case SAD : tempc = _SAD ; break;
+ case ZAD : tempc = _ZAD ; break;
+ case AYN :
+ case AYN_ :
+ case _AYN : tempc = _AYN_ ; break;
+ case GHAYN :
+ case GHAYN_ :
+ case _GHAYN_ : tempc = _GHAYN_ ; break;
+ case FE : tempc = _FE ; break;
+ case GHAF : tempc = _GHAF ; break;
+ case KAF : tempc = _KAF ; break;
+ case GAF : tempc = _GAF ; break;
+ case LAM : tempc = _LAM ; break;
+ case MIM : tempc = _MIM ; break;
+ case NOON : tempc = _NOON ; break;
+ case _HE :
+ case F_HE : tempc = _HE_ ; break;
+ case YE :
+ case YE_ : tempc = _YE ; break;
+ case IE_ :
+ case IE : tempc = _IE ; break;
+ case TEE : tempc = TEE_ ; break;
+ case YEE :
+ case YEE_ : tempc = _YEE ; break;
+ default : tempc = c ;
}
- return c;
+
+ return tempc;
}
/// Can a given Farsi character join via its left edj.
@@ -2074,7 +1386,7 @@ static int toF_Rjoin(int c)
/// @param c The character to check.
///
/// @return true if the character can join via its left edj.
-static bool canF_Ljoin(int c)
+static bool canF_Ljoin(char_u c)
{
switch (c) {
case _BE:
@@ -2148,7 +1460,7 @@ static bool canF_Ljoin(int c)
/// @param c
///
/// @return true if the character can join via its right edj.
-static bool canF_Rjoin(int c)
+static bool canF_Rjoin(char_u c)
{
switch (c) {
case ALEF:
@@ -2174,7 +1486,7 @@ static bool canF_Rjoin(int c)
/// @param c
///
/// @return true if the character is a terminating type.
-static bool F_isterm(int c)
+static bool F_isterm(char_u c)
{
switch (c) {
case ALEF:
@@ -2200,105 +1512,48 @@ static bool F_isterm(int c)
/// @param c The character to convert.
///
/// @return The character converted into an ending type.
-static int toF_ending(int c)
+static char_u toF_ending(char_u c)
{
- switch (c) {
- case _BE:
- return BE;
-
- case _PE:
- return PE;
-
- case _TE:
- return TE;
-
- case _SE:
- return SE;
-
- case _JIM:
- return JIM;
-
- case _CHE:
- return CHE;
-
- case _HE_J:
- return HE_J;
-
- case _XE:
- return XE;
-
- case _SIN:
- return SIN;
-
- case _SHIN:
- return SHIN;
-
- case _SAD:
- return SAD;
+ char_u tempc;
- case _ZAD:
- return ZAD;
-
- case _AYN:
- return AYN;
-
- case _AYN_:
- return AYN_;
-
- case _GHAYN:
- return GHAYN;
-
- case _GHAYN_:
- return GHAYN_;
-
- case _FE:
- return FE;
-
- case _GHAF:
- return GHAF;
-
- case _KAF_H:
- case _KAF:
- return KAF;
-
- case _GAF:
- return GAF;
-
- case _LAM:
- return LAM;
-
- case _MIM:
- return MIM;
-
- case _NOON:
- return NOON;
-
- case _YE:
- return YE_;
-
- case YE_:
- return YE;
-
- case _YEE:
- return YEE_;
-
- case YEE_:
- return YEE;
-
- case TEE:
- return TEE_;
-
- case _IE:
- return IE_;
-
- case IE_:
- return IE;
-
- case _HE:
- case _HE_:
- return F_HE;
+ switch (c) {
+ case _BE : tempc = BE ; break;
+ case _PE : tempc = PE ; break;
+ case _TE : tempc = TE ; break;
+ case _SE : tempc = SE ; break;
+ case _JIM : tempc = JIM ; break;
+ case _CHE : tempc = CHE ; break;
+ case _HE_J : tempc = HE_J ; break;
+ case _XE : tempc = XE ; break;
+ case _SIN : tempc = SIN ; break;
+ case _SHIN : tempc = SHIN ; break;
+ case _SAD : tempc = SAD ; break;
+ case _ZAD : tempc = ZAD ; break;
+ case _AYN : tempc = AYN ; break;
+ case _AYN_ : tempc = AYN_ ; break;
+ case _GHAYN : tempc = GHAYN ; break;
+ case _GHAYN_ : tempc = GHAYN_ ; break;
+ case _FE : tempc = FE ; break;
+ case _GHAF : tempc = GHAF ; break;
+ case _KAF_H :
+ case _KAF : tempc = KAF ; break;
+ case _GAF : tempc = GAF ; break;
+ case _LAM : tempc = LAM ; break;
+ case _MIM : tempc = MIM ; break;
+ case _NOON : tempc = NOON ; break;
+ case _YE : tempc = YE_ ; break;
+ case YE_ : tempc = YE ; break;
+ case _YEE : tempc = YEE_ ; break;
+ case YEE_ : tempc = YEE ; break;
+ case TEE : tempc = TEE_ ; break;
+ case _IE : tempc = IE_ ; break;
+ case IE_ : tempc = IE ; break;
+ case _HE :
+ case _HE_ : tempc = F_HE ; break;
+ default : tempc = c ;
}
- return c;
+
+ return tempc;
}
/// Convert the Farsi 3342 standard into Farsi VIM.
@@ -2369,7 +1624,7 @@ void conv_to_pstd(void)
static void lrswapbuf(char_u *buf, int len)
{
char_u *s, *e;
- int c;
+ char_u c;
s = buf;
e = buf + len - 1;
@@ -2442,6 +1697,7 @@ char_u* lrF_sub(char_u *ibuf)
// Find the boundary of the search path
while (((p = vim_strchr(p + 1, '/')) != NULL) && p[-1] == '\\') {
+ // empty
}
if (p == NULL) {
@@ -2560,15 +1816,15 @@ int cmdl_fkmap(int c)
case _NOON:
case _HE:
case _HE_:
- cmd_pchar(toF_TyA(tempc), AT_CURSOR);
+ cmd_pchar(toF_TyA((char_u)tempc), AT_CURSOR);
break;
case _AYN_:
- cmd_pchar(AYN_, AT_CURSOR);
+ cmd_pchar(AYN_, AT_CURSOR);
break;
case _GHAYN_:
- cmd_pchar(GHAYN_, AT_CURSOR);
+ cmd_pchar(GHAYN_, AT_CURSOR);
break;
case _IE:
@@ -2596,190 +1852,70 @@ int cmdl_fkmap(int c)
}
switch (c) {
- case '0':
- return FARSI_0;
-
- case '1':
- return FARSI_1;
-
- case '2':
- return FARSI_2;
-
- case '3':
- return FARSI_3;
-
- case '4':
- return FARSI_4;
-
- case '5':
- return FARSI_5;
-
- case '6':
- return FARSI_6;
-
- case '7':
- return FARSI_7;
-
- case '8':
- return FARSI_8;
-
- case '9':
- return FARSI_9;
-
- case 'B':
- return F_PSP;
-
- case 'E':
- return JAZR_N;
-
- case 'F':
- return ALEF_D_H;
-
- case 'H':
- return ALEF_A;
-
- case 'I':
- return TASH;
-
- case 'K':
- return F_LQUOT;
-
- case 'L':
- return F_RQUOT;
-
- case 'M':
- return HAMZE;
-
- case 'O':
- return '[';
-
- case 'P':
- return ']';
-
- case 'Q':
- return OO;
-
- case 'R':
- return MAD_N;
-
- case 'T':
- return OW;
-
- case 'U':
- return MAD;
-
- case 'W':
- return OW_OW;
-
- case 'Y':
- return JAZR;
-
- case '`':
- return F_PCN;
-
- case '!':
- return F_EXCL;
-
- case '@':
- return F_COMMA;
-
- case '#':
- return F_DIVIDE;
-
- case '$':
- return F_CURRENCY;
-
- case '%':
- return F_PERCENT;
-
- case '^':
- return F_MUL;
-
- case '&':
- return F_BCOMMA;
-
- case '*':
- return F_STAR;
-
- case '(':
- return F_LPARENT;
-
- case ')':
- return F_RPARENT;
-
- case '-':
- return F_MINUS;
-
- case '_':
- return F_UNDERLINE;
-
- case '=':
- return F_EQUALS;
-
- case '+':
- return F_PLUS;
-
- case '\\':
- return F_BSLASH;
-
- case '|':
- return F_PIPE;
-
- case ':':
- return F_DCOLON;
-
- case '"':
- return F_SEMICOLON;
-
- case '.':
- return F_PERIOD;
-
- case '/':
- return F_SLASH;
-
- case '<':
- return F_LESS;
-
- case '>':
- return F_GREATER;
-
- case '?':
- return F_QUESTION;
-
- case ' ':
- return F_BLANK;
+ case '0' : return FARSI_0 ;
+ case '1' : return FARSI_1 ;
+ case '2' : return FARSI_2 ;
+ case '3' : return FARSI_3 ;
+ case '4' : return FARSI_4 ;
+ case '5' : return FARSI_5 ;
+ case '6' : return FARSI_6 ;
+ case '7' : return FARSI_7 ;
+ case '8' : return FARSI_8 ;
+ case '9' : return FARSI_9 ;
+ case 'B' : return F_PSP ;
+ case 'E' : return JAZR_N ;
+ case 'F' : return ALEF_D_H ;
+ case 'H' : return ALEF_A ;
+ case 'I' : return TASH ;
+ case 'K' : return F_LQUOT ;
+ case 'L' : return F_RQUOT ;
+ case 'M' : return HAMZE ;
+ case 'O' : return '[' ;
+ case 'P' : return ']' ;
+ case 'Q' : return OO ;
+ case 'R' : return MAD_N ;
+ case 'T' : return OW ;
+ case 'U' : return MAD ;
+ case 'W' : return OW_OW ;
+ case 'Y' : return JAZR ;
+ case '`' : return F_PCN ;
+ case '!' : return F_EXCL ;
+ case '@' : return F_COMMA ;
+ case '#' : return F_DIVIDE ;
+ case '$' : return F_CURRENCY ;
+ case '%' : return F_PERCENT ;
+ case '^' : return F_MUL ;
+ case '&' : return F_BCOMMA ;
+ case '*' : return F_STAR ;
+ case '(' : return F_LPARENT ;
+ case ')' : return F_RPARENT ;
+ case '-' : return F_MINUS ;
+ case '_' : return F_UNDERLINE ;
+ case '=' : return F_EQUALS ;
+ case '+' : return F_PLUS ;
+ case '\\' : return F_BSLASH ;
+ case '|' : return F_PIPE ;
+ case ':' : return F_DCOLON ;
+ case '"' : return F_SEMICOLON ;
+ case '.' : return F_PERIOD ;
+ case '/' : return F_SLASH ;
+ case '<' : return F_LESS ;
+ case '>' : return F_GREATER ;
+ case '?' : return F_QUESTION ;
+ case ' ' : return F_BLANK ;
}
break;
- case 'a':
- return _SHIN;
-
- case 'A':
- return WAW_H;
-
- case 'b':
- return ZAL;
-
- case 'c':
- return ZE;
-
- case 'C':
- return JE;
-
- case 'd':
- return _YE;
-
- case 'D':
- return _YEE;
-
- case 'e':
- return _SE;
-
- case 'f':
- return _BE;
-
- case 'g':
- return _LAM;
+ case 'a' : return _SHIN ;
+ case 'A' : return WAW_H ;
+ case 'b' : return ZAL ;
+ case 'c' : return ZE ;
+ case 'C' : return JE ;
+ case 'd' : return _YE ;
+ case 'D' : return _YEE ;
+ case 'e' : return _SE ;
+ case 'f' : return _BE ;
+ case 'g' : return _LAM ;
case 'G':
if (cmd_gchar(AT_CURSOR) == _LAM) {
@@ -2823,39 +1959,18 @@ int cmdl_fkmap(int c)
return TEE;
}
- case 'k':
- return _NOON;
-
- case 'l':
- return _MIM;
-
- case 'm':
- return _PE;
-
- case 'n':
- case 'N':
- return DAL;
-
- case 'o':
- return _XE;
-
- case 'p':
- return _HE_J;
-
- case 'q':
- return _ZAD;
-
- case 'r':
- return _GHAF;
-
- case 's':
- return _SIN;
-
- case 'S':
- return _IE;
-
- case 't':
- return _FE;
+ case 'k' : return _NOON ;
+ case 'l' : return _MIM ;
+ case 'm' : return _PE ;
+ case 'n' :
+ case 'N' : return DAL ;
+ case 'o' : return _XE ;
+ case 'p' : return _HE_J ;
+ case 'q' : return _ZAD ;
+ case 'r' : return _GHAF ;
+ case 's' : return _SIN ;
+ case 'S' : return _IE ;
+ case 't' : return _FE ;
case 'u':
if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR)) {
@@ -2864,16 +1979,11 @@ int cmdl_fkmap(int c)
return _AYN;
}
- case 'v':
- case 'V':
- return RE;
-
- case 'w':
- return _SAD;
-
- case 'x':
- case 'X':
- return _TA;
+ case 'v' :
+ case 'V' : return RE ;
+ case 'w' : return _SAD ;
+ case 'x' :
+ case 'X' : return _TA ;
case 'y':
if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR)) {
@@ -2882,24 +1992,13 @@ int cmdl_fkmap(int c)
return _GHAYN;
}
- case 'z':
- case 'Z':
- return _ZA;
-
- case ';':
- return _KAF;
-
- case '\'':
- return _GAF;
-
- case ',':
- return WAW;
-
- case '[':
- return _JIM;
-
- case ']':
- return _CHE;
+ case 'z' :
+ case 'Z' : return _ZA ;
+ case ';' : return _KAF ;
+ case '\'' : return _GAF ;
+ case ',' : return WAW ;
+ case '[' : return _JIM ;
+ case ']' : return _CHE ;
}
return c;
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index 267c586543..281e5b5768 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -114,9 +114,9 @@ static int prev_lnum_lvl = -1;
#define DONE_ACTION 1 /* did close or open a fold */
#define DONE_FOLD 2 /* did find a fold */
-static int foldstartmarkerlen;
+static size_t foldstartmarkerlen;
static char_u *foldendmarker;
-static int foldendmarkerlen;
+static size_t foldendmarkerlen;
/* Exported folding functions. {{{1 */
/* copyFoldingState() {{{2 */
@@ -622,7 +622,7 @@ void foldCreate(linenr_T start, linenr_T end)
if (end_rel < fp[cont - 1].fd_top + fp[cont - 1].fd_len - 1)
end_rel = fp[cont - 1].fd_top + fp[cont - 1].fd_len - 1;
/* Move contained folds to inside new fold. */
- memmove(fold_ga.ga_data, fp, sizeof(fold_T) * cont);
+ memmove(fold_ga.ga_data, fp, sizeof(fold_T) * (size_t)cont);
fold_ga.ga_len += cont;
i += cont;
@@ -634,7 +634,7 @@ void foldCreate(linenr_T start, linenr_T end)
/* Move remaining entries to after the new fold. */
if (i < gap->ga_len)
memmove(fp + 1, (fold_T *)gap->ga_data + i,
- sizeof(fold_T) * (gap->ga_len - i));
+ sizeof(fold_T) * (size_t)(gap->ga_len - i));
gap->ga_len = gap->ga_len + 1 - cont;
/* insert new fold */
@@ -1051,7 +1051,7 @@ static int foldFind(garray_T *gap, linenr_T lnum, fold_T **fpp)
low = 0;
high = gap->ga_len - 1;
while (low <= high) {
- int i = (low + high) / 2;
+ linenr_T i = (low + high) / 2;
if (fp[i].fd_top > lnum)
/* fold below lnum, adjust high */
high = i - 1;
@@ -1292,7 +1292,6 @@ static void deleteFoldEntry(garray_T *gap, int idx, int recursive)
{
fold_T *fp;
int i;
- long moved;
fold_T *nfp;
fp = (fold_T *)gap->ga_data + idx;
@@ -1301,12 +1300,12 @@ static void deleteFoldEntry(garray_T *gap, int idx, int recursive)
deleteFoldRecurse(&fp->fd_nested);
--gap->ga_len;
if (idx < gap->ga_len)
- memmove(fp, fp + 1, sizeof(fold_T) * (gap->ga_len - idx));
+ memmove(fp, fp + 1, sizeof(fold_T) * (size_t)(gap->ga_len - idx));
} else {
/* Move nested folds one level up, to overwrite the fold that is
* deleted. */
- moved = fp->fd_nested.ga_len;
- ga_grow(gap, (int)(moved - 1));
+ int moved = fp->fd_nested.ga_len;
+ ga_grow(gap, moved - 1);
{
/* Get "fp" again, the array may have been reallocated. */
fp = (fold_T *)gap->ga_data + idx;
@@ -1324,9 +1323,9 @@ static void deleteFoldEntry(garray_T *gap, int idx, int recursive)
/* move the existing folds down to make room */
if (idx + 1 < gap->ga_len)
memmove(fp + moved, fp + 1,
- sizeof(fold_T) * (gap->ga_len - (idx + 1)));
+ sizeof(fold_T) * (size_t)(gap->ga_len - (idx + 1)));
/* move the contained folds one level up */
- memmove(fp, nfp, (size_t)(sizeof(fold_T) * moved));
+ memmove(fp, nfp, sizeof(fold_T) * (size_t)moved);
free(nfp);
gap->ga_len += moved - 1;
}
@@ -1584,17 +1583,16 @@ static void foldCreateMarkers(linenr_T start, linenr_T end)
/*
* Add "marker[markerlen]" in 'commentstring' to line "lnum".
*/
-static void foldAddMarker(linenr_T lnum, char_u *marker, int markerlen)
+static void foldAddMarker(linenr_T lnum, char_u *marker, size_t markerlen)
{
char_u *cms = curbuf->b_p_cms;
char_u *line;
- int line_len;
char_u *newline;
char_u *p = (char_u *)strstr((char *)curbuf->b_p_cms, "%s");
/* Allocate a new line: old-line + 'cms'-start + marker + 'cms'-end */
line = ml_get(lnum);
- line_len = (int)STRLEN(line);
+ size_t line_len = STRLEN(line);
if (u_save(lnum - 1, lnum + 1) == OK) {
newline = xmalloc(line_len + markerlen + STRLEN(cms) + 1);
@@ -1629,8 +1627,8 @@ deleteFoldMarkers (
}
}
foldDelMarker(fp->fd_top + lnum_off, curwin->w_p_fmr, foldstartmarkerlen);
- foldDelMarker(fp->fd_top + lnum_off + fp->fd_len - 1,
- foldendmarker, foldendmarkerlen);
+ foldDelMarker(fp->fd_top + lnum_off + fp->fd_len - 1, foldendmarker,
+ foldendmarkerlen);
}
/* foldDelMarker() {{{2 */
@@ -1640,7 +1638,7 @@ deleteFoldMarkers (
* If the marker is not found, there is no error message. Could a missing
* close-marker.
*/
-static void foldDelMarker(linenr_T lnum, char_u *marker, int markerlen)
+static void foldDelMarker(linenr_T lnum, char_u *marker, size_t markerlen)
{
char_u *newline;
char_u *cms = curbuf->b_p_cms;
@@ -1652,7 +1650,7 @@ static void foldDelMarker(linenr_T lnum, char_u *marker, int markerlen)
continue;
}
/* Found the marker, include a digit if it's there. */
- int len = markerlen;
+ size_t len = markerlen;
if (VIM_ISDIGIT(p[len]))
++len;
if (*cms != NUL) {
@@ -1662,7 +1660,7 @@ static void foldDelMarker(linenr_T lnum, char_u *marker, int markerlen)
&& STRNCMP(p - (cms2 - cms), cms, cms2 - cms) == 0
&& STRNCMP(p + len, cms2 + 2, STRLEN(cms2 + 2)) == 0) {
p -= cms2 - cms;
- len += (int)STRLEN(cms) - 2;
+ len += STRLEN(cms) - 2;
}
}
if (u_save(lnum - 1, lnum + 1) == OK) {
@@ -1781,27 +1779,23 @@ char_u *get_foldtext(win_T *wp, linenr_T lnum, linenr_T lnume,
*/
void foldtext_cleanup(char_u *str)
{
- char_u *cms_start; /* first part or the whole comment */
- int cms_slen = 0; /* length of cms_start */
- char_u *cms_end; /* last part of the comment or NULL */
- int cms_elen = 0; /* length of cms_end */
char_u *s;
char_u *p;
- int len;
int did1 = FALSE;
int did2 = FALSE;
/* Ignore leading and trailing white space in 'commentstring'. */
- cms_start = skipwhite(curbuf->b_p_cms);
- cms_slen = (int)STRLEN(cms_start);
+ char_u *cms_start = skipwhite(curbuf->b_p_cms);
+ size_t cms_slen = STRLEN(cms_start);
while (cms_slen > 0 && vim_iswhite(cms_start[cms_slen - 1]))
--cms_slen;
/* locate "%s" in 'commentstring', use the part before and after it. */
- cms_end = (char_u *)strstr((char *)cms_start, "%s");
+ char_u *cms_end = (char_u *)strstr((char *)cms_start, "%s");
+ size_t cms_elen = 0;
if (cms_end != NULL) {
- cms_elen = cms_slen - (int)(cms_end - cms_start);
- cms_slen = (int)(cms_end - cms_start);
+ cms_elen = cms_slen - (size_t)(cms_end - cms_start);
+ cms_slen = (size_t)(cms_end - cms_start);
/* exclude white space before "%s" */
while (cms_slen > 0 && vim_iswhite(cms_start[cms_slen - 1]))
@@ -1809,13 +1803,13 @@ void foldtext_cleanup(char_u *str)
/* skip "%s" and white space after it */
s = skipwhite(cms_end + 2);
- cms_elen -= (int)(s - cms_end);
+ cms_elen -= (size_t)(s - cms_end);
cms_end = s;
}
parseMarker(curwin);
for (s = str; *s != NUL; ) {
- len = 0;
+ size_t len = 0;
if (STRNCMP(s, curwin->w_p_fmr, foldstartmarkerlen) == 0)
len = foldstartmarkerlen;
else if (STRNCMP(s, foldendmarker, foldendmarkerlen) == 0)
@@ -1830,7 +1824,7 @@ void foldtext_cleanup(char_u *str)
;
if (p >= str + cms_slen
&& STRNCMP(p - cms_slen, cms_start, cms_slen) == 0) {
- len += (int)(s - p) + cms_slen;
+ len += (size_t)(s - p) + cms_slen;
s = p - cms_slen;
}
} else if (cms_end != NULL) {
@@ -2035,8 +2029,8 @@ static void foldUpdateIEMS(win_T *wp, linenr_T top, linenr_T bot)
if (fline.lvl > 0) {
invalid_top = fline.lnum;
invalid_bot = end;
- end = foldUpdateIEMSRecurse(&wp->w_folds,
- 1, start, &fline, getlevel, end, FD_LEVEL);
+ end = foldUpdateIEMSRecurse(&wp->w_folds, 1, start, &fline, getlevel, end,
+ FD_LEVEL);
start = fline.lnum;
} else {
if (fline.lnum == wp->w_buffer->b_ml.ml_line_count)
@@ -2095,7 +2089,7 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
linenr_T startlnum, fline_T *flp,
LevelGetter getlevel,
linenr_T bot,
- int topflags /* flags used by containing fold */
+ char topflags /* containing fold flags */
)
{
linenr_T ll;
@@ -2333,8 +2327,8 @@ static linenr_T foldUpdateIEMSRecurse(garray_T *gap, int level,
flp->off += fp->fd_top;
i = (int)(fp - (fold_T *)gap->ga_data);
bot = foldUpdateIEMSRecurse(&fp->fd_nested, level + 1,
- startlnum2 - fp->fd_top, flp, getlevel,
- bot - fp->fd_top, fp->fd_flags);
+ startlnum2 - fp->fd_top, flp, getlevel,
+ bot - fp->fd_top, fp->fd_flags);
fp = (fold_T *)gap->ga_data + i;
flp->lnum += fp->fd_top;
flp->lnum_save += fp->fd_top;
@@ -2468,7 +2462,7 @@ static void foldInsert(garray_T *gap, int i)
fp = (fold_T *)gap->ga_data + i;
if (i < gap->ga_len)
- memmove(fp + 1, fp, sizeof(fold_T) * (gap->ga_len - i));
+ memmove(fp + 1, fp, sizeof(fold_T) * (size_t)(gap->ga_len - i));
++gap->ga_len;
ga_init(&fp->fd_nested, (int)sizeof(fold_T), 10);
}
@@ -2649,9 +2643,7 @@ static void foldlevelIndent(fline_T *flp)
} else
flp->lvl = get_indent_buf(buf, lnum) / get_sw_value(curbuf);
if (flp->lvl > flp->wp->w_p_fdn) {
- flp->lvl = flp->wp->w_p_fdn;
- if (flp->lvl < 0)
- flp->lvl = 0;
+ flp->lvl = (int) MAX(0, flp->wp->w_p_fdn);
}
}
@@ -2768,8 +2760,8 @@ static void foldlevelExpr(fline_T *flp)
static void parseMarker(win_T *wp)
{
foldendmarker = vim_strchr(wp->w_p_fmr, ',');
- foldstartmarkerlen = (int)(foldendmarker++ - wp->w_p_fmr);
- foldendmarkerlen = (int)STRLEN(foldendmarker);
+ foldstartmarkerlen = (size_t)(foldendmarker++ - wp->w_p_fmr);
+ foldendmarkerlen = STRLEN(foldendmarker);
}
/* foldlevelMarker() {{{2 */
@@ -2822,9 +2814,8 @@ static void foldlevelMarker(fline_T *flp)
++flp->lvl_next;
++flp->start;
}
- } else if (*s == cend
- && STRNCMP(s + 1, foldendmarker + 1,
- foldendmarkerlen - 1) == 0) {
+ } else if (*s == cend && STRNCMP(s + 1, foldendmarker + 1,
+ foldendmarkerlen - 1) == 0) {
/* found endmarker: set flp->lvl_next */
s += foldendmarkerlen;
if (VIM_ISDIGIT(*s)) {
diff --git a/src/nvim/fold.h b/src/nvim/fold.h
index 1cbd7af5da..2ff10c0e91 100644
--- a/src/nvim/fold.h
+++ b/src/nvim/fold.h
@@ -1,14 +1,16 @@
#ifndef NVIM_FOLD_H
#define NVIM_FOLD_H
+#include "nvim/pos.h"
+
/*
* Info used to pass info about a fold from the fold-detection code to the
* code that displays the foldcolumn.
*/
typedef struct foldinfo {
+ linenr_T fi_lnum; /* line number where fold starts */
int fi_level; /* level of the fold; when this is zero the
other fields are invalid */
- int fi_lnum; /* line number where fold starts */
int fi_low_level; /* lowest fold level that starts in the same
line */
} foldinfo_T;
diff --git a/src/nvim/indent_c.c b/src/nvim/indent_c.c
index 8310f635c9..3b9214abc1 100644
--- a/src/nvim/indent_c.c
+++ b/src/nvim/indent_c.c
@@ -1332,7 +1332,7 @@ void parse_cino(buf_T *buf)
char_u *l;
int divider;
int fraction = 0;
- int sw = (int)get_sw_value(buf);
+ int sw = get_sw_value(buf);
/*
* Set the default values.
diff --git a/src/nvim/menu.c b/src/nvim/menu.c
index 95cc33e4d9..8d9b5045b9 100644
--- a/src/nvim/menu.c
+++ b/src/nvim/menu.c
@@ -300,8 +300,6 @@ add_menu_path (
} else
en_name = NULL;
dname = menu_text(name, NULL, NULL);
- if (dname == NULL)
- goto erret;
if (*dname == NUL) {
/* Only a mnemonic or accelerator is not valid. */
EMSG(_("E792: Empty menu name"));
@@ -1156,14 +1154,20 @@ static char_u *popup_mode_name(char_u *name, int idx)
}
-/*
- * Duplicate the menu item text and then process to see if a mnemonic key
- * and/or accelerator text has been identified.
- * Returns a pointer to allocated memory, or NULL for failure.
- * If mnemonic != NULL, *mnemonic is set to the character after the first '&'.
- * If actext != NULL, *actext is set to the text after the first TAB.
- */
-static char_u *menu_text(char_u *str, int *mnemonic, char_u **actext)
+/// Duplicate the menu item text and then process to see if a mnemonic key
+/// and/or accelerator text has been identified.
+///
+/// @param str The menu item text.
+/// @param[out] mnemonic If non-NULL, *mnemonic is set to the character after
+/// the first '&'.
+/// @param[out] actext If non-NULL, *actext is set to the text after the first
+/// TAB, but only if a TAB was found. Memory pointed to is newly
+/// allocated.
+///
+/// @return a pointer to allocated memory.
+static char_u *menu_text(const char_u *str, int *mnemonic, char_u **actext)
+ FUNC_ATTR_NONNULL_RET FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT
+ FUNC_ATTR_NONNULL_ARG(1)
{
char_u *p;
char_u *text;
@@ -1463,19 +1467,14 @@ void ex_menutranslate(exarg_T *eap)
from = vim_strsave(from);
from_noamp = menu_text(from, NULL, NULL);
to = vim_strnsave(to, (int)(arg - to));
- if (from_noamp != NULL) {
- menu_translate_tab_and_shift(from);
- menu_translate_tab_and_shift(to);
- menu_unescape_name(from);
- menu_unescape_name(to);
- menutrans_T* tp = GA_APPEND_VIA_PTR(menutrans_T, &menutrans_ga);
- tp->from = from;
- tp->from_noamp = from_noamp;
- tp->to = to;
- } else {
- free(from);
- free(to);
- }
+ menu_translate_tab_and_shift(from);
+ menu_translate_tab_and_shift(to);
+ menu_unescape_name(from);
+ menu_unescape_name(to);
+ menutrans_T* tp = GA_APPEND_VIA_PTR(menutrans_T, &menutrans_ga);
+ tp->from = from;
+ tp->from_noamp = from_noamp;
+ tp->to = to;
}
}
}
@@ -1502,7 +1501,7 @@ static char_u *menutrans_lookup(char_u *name, int len)
menutrans_T *tp = (menutrans_T *)menutrans_ga.ga_data;
char_u *dname;
- for (int i = 0; i < menutrans_ga.ga_len; ++i) {
+ for (int i = 0; i < menutrans_ga.ga_len; i++) {
if (STRNCMP(name, tp[i].from, len) == 0 && tp[i].from[len] == NUL) {
return tp[i].to;
}
@@ -1513,15 +1512,13 @@ static char_u *menutrans_lookup(char_u *name, int len)
name[len] = NUL;
dname = menu_text(name, NULL, NULL);
name[len] = c;
- if (dname != NULL) {
- for (int i = 0; i < menutrans_ga.ga_len; ++i) {
- if (STRCMP(dname, tp[i].from_noamp) == 0) {
- free(dname);
- return tp[i].to;
- }
+ for (int i = 0; i < menutrans_ga.ga_len; i++) {
+ if (STRCMP(dname, tp[i].from_noamp) == 0) {
+ free(dname);
+ return tp[i].to;
}
- free(dname);
}
+ free(dname);
return NULL;
}
diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c
index 5d8b88601e..e58ec71e77 100644
--- a/src/nvim/misc1.c
+++ b/src/nvim/misc1.c
@@ -796,7 +796,7 @@ open_line (
) {
++curwin->w_cursor.lnum;
if (did_si) {
- int sw = (int)get_sw_value(curbuf);
+ int sw = get_sw_value(curbuf);
if (p_sr)
newindent -= newindent % sw;
diff --git a/src/nvim/move.c b/src/nvim/move.c
index 1ba064c65f..65f2853073 100644
--- a/src/nvim/move.c
+++ b/src/nvim/move.c
@@ -16,6 +16,7 @@
* The 'scrolloff' option makes this a bit complicated.
*/
+#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
@@ -135,13 +136,13 @@ void update_topline(void)
{
long line_count;
int halfheight;
- int n;
+ long n;
linenr_T old_topline;
int old_topfill;
linenr_T lnum;
int check_topline = FALSE;
int check_botline = FALSE;
- int save_so = p_so;
+ long save_so = p_so;
if (!screen_valid(TRUE))
return;
@@ -342,9 +343,9 @@ void update_topline_win(win_T* win)
*/
static int scrolljump_value(void)
{
- if (p_sj >= 0)
- return (int)p_sj;
- return (curwin->w_height * -p_sj) / 100;
+ long result = p_sj >= 0 ? p_sj : (curwin->w_height * -p_sj) / 100;
+ assert(result <= INT_MAX);
+ return (int)result;
}
/*
@@ -711,7 +712,7 @@ int win_col_off(win_T *wp)
{
return ((wp->w_p_nu || wp->w_p_rnu) ? number_width(wp) + 1 : 0)
+ (cmdwin_type == 0 || wp != curwin ? 0 : 1)
- + wp->w_p_fdc
+ + (int)wp->w_p_fdc
+ (wp->w_buffer->b_signlist != NULL ? 2 : 0)
;
}
@@ -831,9 +832,9 @@ curs_columns (
* If we get closer to the edge than 'sidescrolloff', scroll a little
* extra
*/
- off_left = (int)startcol - (int)curwin->w_leftcol - p_siso;
- off_right = (int)endcol - (int)(curwin->w_leftcol + curwin->w_width
- - p_siso) + 1;
+ assert(p_siso <= INT_MAX);
+ off_left = startcol - curwin->w_leftcol - (int)p_siso;
+ off_right = endcol - curwin->w_leftcol - curwin->w_width + (int)p_siso + 1;
if (off_left < 0 || off_right > 0) {
if (off_left < 0)
diff = -off_left;
@@ -845,8 +846,10 @@ curs_columns (
if (p_ss == 0 || diff >= textwidth / 2 || off_right >= off_left)
new_leftcol = curwin->w_wcol - extra - textwidth / 2;
else {
- if (diff < p_ss)
- diff = p_ss;
+ if (diff < p_ss) {
+ assert(p_ss <= INT_MAX);
+ diff = (int)p_ss;
+ }
if (off_left < 0)
new_leftcol = curwin->w_leftcol - diff;
else
@@ -902,8 +905,10 @@ curs_columns (
if (p_lines == 0)
p_lines = plines_win(curwin, curwin->w_cursor.lnum, FALSE);
--p_lines;
- if (p_lines > curwin->w_wrow + p_so)
- n = curwin->w_wrow + p_so;
+ if (p_lines > curwin->w_wrow + p_so) {
+ assert(p_so <= INT_MAX);
+ n = curwin->w_wrow + (int)p_so;
+ }
else
n = p_lines;
if ((colnr_T)n >= curwin->w_height + curwin->w_skipcol / width)
@@ -922,7 +927,8 @@ curs_columns (
curwin->w_skipcol = n * width;
} else if (extra == 1) {
/* less then 'scrolloff' lines above, decrease skipcol */
- extra = (curwin->w_skipcol + p_so * width - curwin->w_virtcol
+ assert(p_so <= INT_MAX);
+ extra = (curwin->w_skipcol + (int)p_so * width - curwin->w_virtcol
+ width - 1) / width;
if (extra > 0) {
if ((colnr_T)(extra * width) > curwin->w_skipcol)
@@ -974,7 +980,7 @@ scrolldown (
int byfold /* TRUE: count a closed fold as one line */
)
{
- long done = 0; /* total # of physical lines done */
+ int done = 0; /* total # of physical lines done */
int wrow;
int moved = FALSE;
@@ -1331,7 +1337,8 @@ void scroll_cursor_top(int min_scroll, int always)
linenr_T old_topline = curwin->w_topline;
linenr_T old_topfill = curwin->w_topfill;
linenr_T new_topline;
- int off = p_so;
+ assert(p_so <= INT_MAX);
+ int off = (int)p_so;
if (mouse_dragging > 0)
off = mouse_dragging - 1;
@@ -1472,7 +1479,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot)
int old_topfill = curwin->w_topfill;
int fill_below_window;
linenr_T old_botline = curwin->w_botline;
- linenr_T old_valid = curwin->w_valid;
+ int old_valid = curwin->w_valid;
int old_empty_rows = curwin->w_empty_rows;
linenr_T cln; /* Cursor Line Number */
@@ -1708,8 +1715,9 @@ void cursor_correct(void)
* How many lines we would like to have above/below the cursor depends on
* whether the first/last line of the file is on screen.
*/
- above_wanted = p_so;
- below_wanted = p_so;
+ assert(p_so <= INT_MAX);
+ above_wanted = (int)p_so;
+ below_wanted = (int)p_so;
if (mouse_dragging > 0) {
above_wanted = mouse_dragging - 1;
below_wanted = mouse_dragging - 1;
@@ -2040,14 +2048,14 @@ void halfpage(bool flag, linenr_T Prenum)
{
long scrolled = 0;
int i;
- int n;
int room;
if (Prenum)
curwin->w_p_scr = (Prenum > curwin->w_height) ?
curwin->w_height : Prenum;
- n = (curwin->w_p_scr <= curwin->w_height) ?
- curwin->w_p_scr : curwin->w_height;
+ assert(curwin->w_p_scr <= INT_MAX);
+ int n = curwin->w_p_scr <= curwin->w_height ? (int)curwin->w_p_scr
+ : curwin->w_height;
validate_botline();
room = curwin->w_empty_rows;
diff --git a/src/nvim/normal.c b/src/nvim/normal.c
index e26f5a3d77..c210c8fe8f 100644
--- a/src/nvim/normal.c
+++ b/src/nvim/normal.c
@@ -4361,7 +4361,7 @@ static void nv_ident(cmdarg_T *cap)
/* put pattern in search history */
init_history();
add_to_history(HIST_SEARCH, buf, true, NUL);
- normal_search(cap, cmdchar == '*' ? '/' : '?', buf, 0);
+ (void)normal_search(cap, cmdchar == '*' ? '/' : '?', buf, 0);
} else
do_cmdline_cmd(buf);
@@ -4785,7 +4785,7 @@ static void nv_search(cmdarg_T *cap)
return;
}
- normal_search(cap, cap->cmdchar, cap->searchbuf,
+ (void)normal_search(cap, cap->cmdchar, cap->searchbuf,
(cap->arg ? 0 : SEARCH_MARK));
}
@@ -4795,15 +4795,25 @@ static void nv_search(cmdarg_T *cap)
*/
static void nv_next(cmdarg_T *cap)
{
- normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg);
+ pos_T old = curwin->w_cursor;
+ int i = normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg);
+
+ if (i == 1 && equalpos(old, curwin->w_cursor)) {
+ // Avoid getting stuck on the current cursor position, which can happen when
+ // an offset is given and the cursor is on the last char in the buffer:
+ // Repeat with count + 1.
+ cap->count1 += 1;
+ (void)normal_search(cap, 0, NULL, SEARCH_MARK | cap->arg);
+ cap->count1 -= 1;
+ }
}
/*
* Search for "pat" in direction "dir" ('/' or '?', 0 for repeat).
* Uses only cap->count1 and cap->oap from "cap".
+ * Return 0 for failure, 1 for found, 2 for found and line offset added.
*/
-static void
-normal_search (
+static int normal_search(
cmdarg_T *cap,
int dir,
char_u *pat,
@@ -4832,6 +4842,7 @@ normal_search (
/* "/$" will put the cursor after the end of the line, may need to
* correct that here */
check_cursor();
+ return i;
}
/*
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 5921e27282..4c5a002f81 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -278,7 +278,7 @@ shift_line (
{
int count;
int i, j;
- int p_sw = (int)get_sw_value(curbuf);
+ int p_sw = get_sw_value(curbuf);
count = get_indent(); /* get current indent */
@@ -321,7 +321,7 @@ static void shift_block(oparg_T *oap, int amount)
int total;
char_u *newp, *oldp;
int oldcol = curwin->w_cursor.col;
- int p_sw = (int)get_sw_value(curbuf);
+ int p_sw = get_sw_value(curbuf);
int p_ts = (int)curbuf->b_p_ts;
struct block_def bd;
int incr;
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 2d016d8350..929b96a3f8 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -7653,18 +7653,22 @@ int check_ff_value(char_u *p)
* Return the effective shiftwidth value for current buffer, using the
* 'tabstop' value when 'shiftwidth' is zero.
*/
-long get_sw_value(buf_T *buf)
+int get_sw_value(buf_T *buf)
{
- return buf->b_p_sw ? buf->b_p_sw : buf->b_p_ts;
+ long result = buf->b_p_sw ? buf->b_p_sw : buf->b_p_ts;
+ assert(result >= 0 && result <= INT_MAX);
+ return (int)result;
}
/*
* Return the effective softtabstop value for the current buffer, using the
* 'tabstop' value when 'softtabstop' is negative.
*/
-long get_sts_value(void)
+int get_sts_value(void)
{
- return curbuf->b_p_sts < 0 ? get_sw_value(curbuf) : curbuf->b_p_sts;
+ long result = curbuf->b_p_sts < 0 ? get_sw_value(curbuf) : curbuf->b_p_sts;
+ assert(result >= 0 && result <= INT_MAX);
+ return (int)result;
}
/*
diff --git a/src/nvim/os/event.c b/src/nvim/os/event.c
index fd9ff5b230..9bc509bb16 100644
--- a/src/nvim/os/event.c
+++ b/src/nvim/os/event.c
@@ -28,12 +28,6 @@
#define _destroy_event(x) // do nothing
KLIST_INIT(Event, Event, _destroy_event)
-typedef struct {
- bool timed_out;
- int ms;
- uv_timer_t *timer;
-} TimerData;
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/event.c.generated.h"
#endif
@@ -107,19 +101,12 @@ void event_poll(int ms)
uv_run_mode run_mode = UV_RUN_ONCE;
uv_timer_t timer;
- uv_prepare_t timer_prepare;
- TimerData timer_data = {.ms = ms, .timed_out = false, .timer = &timer};
if (ms > 0) {
uv_timer_init(uv_default_loop(), &timer);
- // This prepare handle that actually starts the timer
- uv_prepare_init(uv_default_loop(), &timer_prepare);
- // Timeout passed as argument to the timer
- timer.data = &timer_data;
- // We only start the timer after the loop is running, for that we
- // use a prepare handle(pass the interval as data to it)
- timer_prepare.data = &timer_data;
- uv_prepare_start(&timer_prepare, timer_prepare_cb);
+ // Use a repeating timeout of ms milliseconds to make sure
+ // we do not block indefinitely for I/O.
+ uv_timer_start(&timer, timer_cb, (uint64_t)ms, (uint64_t)ms);
} else if (ms == 0) {
// For ms == 0, we need to do a non-blocking event poll by
// setting the run mode to UV_RUN_NOWAIT.
@@ -129,12 +116,10 @@ void event_poll(int ms)
loop(run_mode);
if (ms > 0) {
- // Ensure the timer-related handles are closed and run the event loop
+ // Ensure the timer handle is closed and run the event loop
// once more to let libuv perform it's cleanup
uv_timer_stop(&timer);
- uv_prepare_stop(&timer_prepare);
uv_close((uv_handle_t *)&timer, NULL);
- uv_close((uv_handle_t *)&timer_prepare, NULL);
loop(UV_RUN_NOWAIT);
}
@@ -183,19 +168,8 @@ static void process_events_from(klist_t(Event) *queue)
}
}
-// Set a flag in the `event_poll` loop for signaling of a timeout
static void timer_cb(uv_timer_t *handle)
{
- TimerData *data = handle->data;
- data->timed_out = true;
-}
-
-static void timer_prepare_cb(uv_prepare_t *handle)
-{
- TimerData *data = handle->data;
- assert(data->ms > 0);
- uv_timer_start(data->timer, timer_cb, (uint32_t)data->ms, 0);
- uv_prepare_stop(handle);
}
static void loop(uv_run_mode run_mode)
diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c
index 70cafc62ca..26a4cdb083 100644
--- a/src/nvim/os_unix.c
+++ b/src/nvim/os_unix.c
@@ -189,19 +189,6 @@ void mch_exit(int r)
exit(r);
}
-/*
- * mch_expand_wildcards() - this code does wild-card pattern matching using
- * the shell
- *
- * return OK for success, FAIL for error (you may lose some memory) and put
- * an error message in *file.
- *
- * num_pat is number of input patterns
- * pat is array of pointers to input patterns
- * num_file is pointer to number of matched file names
- * file is pointer to array of pointers to matched file names
- */
-
#ifndef SEEK_SET
# define SEEK_SET 0
#endif
@@ -211,10 +198,27 @@ void mch_exit(int r)
#define SHELL_SPECIAL (char_u *)"\t \"&'$;<>()\\|"
+/// Does wildcard pattern matching using the shell.
+///
+/// @param num_pat is the number of input patterns.
+/// @param pat is an array of pointers to input patterns.
+/// @param[out] num_file is pointer to number of matched file names.
+/// Set to the number of pointers in *file.
+/// @param[out] file is pointer to array of pointers to matched file names.
+/// Memory pointed to by the initial value of *file will
+/// not be freed.
+/// Set to NULL if FAIL is returned. Otherwise points to
+/// allocated memory.
+/// @param flags is a combination of EW_* flags used in
+/// expand_wildcards().
+/// If matching fails but EW_NOTFOUND is set in flags or
+/// there are no wildcards, the patterns from pat are
+/// copied into *file.
+///
+/// @returns OK for success or FAIL for error.
int mch_expand_wildcards(int num_pat, char_u **pat, int *num_file,
- char_u ***file,
- int flags /* EW_* flags */
- )
+ char_u ***file, int flags) FUNC_ATTR_NONNULL_ARG(3)
+ FUNC_ATTR_NONNULL_ARG(4)
{
int i;
size_t len;
diff --git a/src/nvim/path.c b/src/nvim/path.c
index e83b4e44ed..9515205643 100644
--- a/src/nvim/path.c
+++ b/src/nvim/path.c
@@ -1029,25 +1029,26 @@ static int has_special_wildchar(char_u *p)
}
#endif
-/*
- * Generic wildcard expansion code.
- *
- * Characters in "pat" that should not be expanded must be preceded with a
- * backslash. E.g., "/path\ with\ spaces/my\*star*"
- *
- * Return FAIL when no single file was found. In this case "num_file" is not
- * set, and "file" may contain an error message.
- * Return OK when some files found. "num_file" is set to the number of
- * matches, "file" to the array of matches. Call FreeWild() later.
- */
-int
-gen_expand_wildcards (
- int num_pat, /* number of input patterns */
- char_u **pat, /* array of input patterns */
- int *num_file, /* resulting number of files */
- char_u ***file, /* array of resulting files */
- int flags /* EW_* flags */
-)
+/// Generic wildcard expansion code.
+///
+/// Characters in pat that should not be expanded must be preceded with a
+/// backslash. E.g., "/path\ with\ spaces/my\*star*".
+///
+/// @param num_pat is number of input patterns.
+/// @param pat is an array of pointers to input patterns.
+/// @param[out] num_file is pointer to number of matched file names.
+/// @param[out] file is pointer to array of pointers to matched file names.
+/// @param flags is a combination of EW_* flags used in
+/// expand_wildcards().
+///
+/// @returns OK when some files were found. *num_file is set to the
+/// number of matches, *file to the allocated array of
+/// matches. Call FreeWild() later.
+/// If FAIL is returned, *num_file and *file are either
+/// unchanged or *num_file is set to 0 and *file is set
+/// to NULL or points to "".
+int gen_expand_wildcards(int num_pat, char_u **pat, int *num_file,
+ char_u ***file, int flags)
{
int i;
garray_T ga;
@@ -1863,19 +1864,23 @@ int expand_wildcards_eval(char_u **pat, int *num_file, char_u ***file,
return ret;
}
-/*
- * Expand wildcards. Calls gen_expand_wildcards() and removes files matching
- * 'wildignore'.
- * Returns OK or FAIL. When FAIL then "num_file" won't be set.
- */
-int
-expand_wildcards (
- int num_pat, /* number of input patterns */
- char_u **pat, /* array of input patterns */
- int *num_file, /* resulting number of files */
- char_u ***file, /* array of resulting files */
- int flags /* EW_DIR, etc. */
-)
+/// Expand wildcards. Calls gen_expand_wildcards() and removes files matching
+/// 'wildignore'.
+///
+/// @param num_pat is number of input patterns.
+/// @param pat is an array of pointers to input patterns.
+/// @param[out] num_file is pointer to number of matched file names.
+/// @param[out] file is pointer to array of pointers to matched file names.
+/// @param flags is a combination of EW_* flags.
+///
+/// @returns OK when some files were found. *num_file is set to the
+/// number of matches, *file to the allocated array of
+/// matches.
+/// If FAIL is returned, *num_file and *file are either
+/// unchanged or *num_file is set to 0 and *file is set to
+/// NULL or points to "".
+int expand_wildcards(int num_pat, char_u **pat, int *num_file, char_u ***file,
+ int flags)
{
int retval;
int i, j;
diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c
index 1ea12d6862..7ef962fa2f 100644
--- a/src/nvim/popupmnu.c
+++ b/src/nvim/popupmnu.c
@@ -2,6 +2,7 @@
///
/// Popup menu (PUM)
//
+#include <assert.h>
#include <inttypes.h>
#include <stdbool.h>
@@ -101,7 +102,7 @@ redo:
}
if ((p_ph > 0) && (pum_height > p_ph)) {
- pum_height = p_ph;
+ pum_height = (int)p_ph;
}
// Put the pum below "row" if possible. If there are few lines decide on
@@ -126,8 +127,8 @@ redo:
}
if ((p_ph > 0) && (pum_height > p_ph)) {
- pum_row += pum_height - p_ph;
- pum_height = p_ph;
+ pum_row += pum_height - (int)p_ph;
+ pum_height = (int)p_ph;
}
} else {
// pum below "row"
@@ -148,7 +149,7 @@ redo:
}
if ((p_ph > 0) && (pum_height > p_ph)) {
- pum_height = p_ph;
+ pum_height = (int)p_ph;
}
}
@@ -219,7 +220,9 @@ redo:
if (curwin->w_p_rl) {
pum_width = pum_col - pum_scrollbar + 1;
} else {
- pum_width = Columns - pum_col - pum_scrollbar;
+ assert(Columns - pum_col - pum_scrollbar >= INT_MIN
+ && Columns - pum_col - pum_scrollbar <= INT_MAX);
+ pum_width = (int)(Columns - pum_col - pum_scrollbar);
}
if ((pum_width > max_width + kind_width + extra_width + 1)
@@ -233,11 +236,13 @@ redo:
} else if (Columns < def_width) {
// not enough room, will use what we have
if (curwin->w_p_rl) {
- pum_col = Columns - 1;
+ assert(Columns - 1 >= INT_MIN);
+ pum_col = (int)(Columns - 1);
} else {
pum_col = 0;
}
- pum_width = Columns - 1;
+ assert(Columns - 1 >= INT_MIN);
+ pum_width = (int)(Columns - 1);
} else {
if (max_width > PUM_DEF_WIDTH) {
// truncate
@@ -247,7 +252,8 @@ redo:
if (curwin->w_p_rl) {
pum_col = max_width - 1;
} else {
- pum_col = Columns - max_width;
+ assert(Columns - max_width >= INT_MIN && Columns - max_width <= INT_MAX);
+ pum_col = (int)(Columns - max_width);
}
pum_width = max_width - pum_scrollbar;
}
@@ -345,7 +351,7 @@ void pum_redraw(void)
// Display the text that fits or comes before a Tab.
// First convert it to printable characters.
char_u *st;
- int saved = *p;
+ char_u saved = *p;
*p = NUL;
st = transstr(s);
@@ -535,7 +541,7 @@ static int pum_set_selected(int n, int repeat)
g_do_tagpreview = 3;
if ((p_pvh > 0) && (p_pvh < g_do_tagpreview)) {
- g_do_tagpreview = p_pvh;
+ g_do_tagpreview = (int)p_pvh;
}
RedrawingDisabled++;
resized = prepare_tagpreview(false);
diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c
index 8b7033b64b..d5e963c2f8 100644
--- a/src/nvim/regexp.c
+++ b/src/nvim/regexp.c
@@ -6914,13 +6914,8 @@ static regengine_T bt_regengine =
bt_regcomp,
bt_regfree,
bt_regexec_nl,
- bt_regexec_multi
-#ifdef REGEXP_DEBUG
- ,(char_u *)""
-#endif
-#ifdef DEBUG
- ,NULL
-#endif
+ bt_regexec_multi,
+ (char_u *)""
};
@@ -6934,21 +6929,14 @@ static regengine_T nfa_regengine =
nfa_regcomp,
nfa_regfree,
nfa_regexec_nl,
- nfa_regexec_multi
-#ifdef REGEXP_DEBUG
- ,(char_u *)""
-#endif
-#ifdef DEBUG
- , NULL
-#endif
+ nfa_regexec_multi,
+ (char_u *)""
};
/* Which regexp engine to use? Needed for vim_regcomp().
* Must match with 'regexpengine'. */
static int regexp_engine = 0;
-#define AUTOMATIC_ENGINE 0
-#define BACKTRACKING_ENGINE 1
-#define NFA_ENGINE 2
+
#ifdef REGEXP_DEBUG
static char_u regname[][30] = {
"AUTOMATIC Regexp Engine",
@@ -6990,10 +6978,8 @@ regprog_T *vim_regcomp(char_u *expr_arg, int re_flags)
regexp_engine = AUTOMATIC_ENGINE;
}
}
-#ifdef REGEXP_DEBUG
bt_regengine.expr = expr;
nfa_regengine.expr = expr;
-#endif
/*
* First try the NFA engine, unless backtracking was requested.
@@ -7003,11 +6989,12 @@ regprog_T *vim_regcomp(char_u *expr_arg, int re_flags)
else
prog = bt_regengine.regcomp(expr, re_flags);
- if (prog == NULL) { /* error compiling regexp with initial engine */
+ // Check for error compiling regexp with initial engine.
+ if (prog == NULL) {
#ifdef BT_REGEXP_DEBUG_LOG
- if (regexp_engine != BACKTRACKING_ENGINE) { /* debugging log for NFA */
- FILE *f;
- f = fopen(BT_REGEXP_DEBUG_LOG_NAME, "a");
+ // Debugging log for NFA.
+ if (regexp_engine != BACKTRACKING_ENGINE) {
+ FILE *f = fopen(BT_REGEXP_DEBUG_LOG_NAME, "a");
if (f) {
fprintf(f, "Syntax error in \"%s\"\n", expr);
fclose(f);
@@ -7016,12 +7003,22 @@ regprog_T *vim_regcomp(char_u *expr_arg, int re_flags)
BT_REGEXP_DEBUG_LOG_NAME);
}
#endif
- /*
- * If the NFA engine failed, the backtracking engine won't work either.
- *
- if (regexp_engine == AUTOMATIC_ENGINE)
- prog = bt_regengine.regcomp(expr, re_flags);
- */
+ // If the NFA engine failed, try the backtracking engine.
+ // Disabled for now, both engines fail on the same patterns.
+ // Re-enable when regcomp() fails when the pattern would work better
+ // with the other engine.
+ //
+ // if (regexp_engine == AUTOMATIC_ENGINE) {
+ // prog = bt_regengine.regcomp(expr, re_flags);
+ // regexp_engine = BACKTRACKING_ENGINE;
+ // }
+ }
+
+ if (prog != NULL) {
+ // Store the info needed to call regcomp() again when the engine turns out
+ // to be very slow when executing it.
+ prog->re_engine = regexp_engine;
+ prog->re_flags = re_flags;
}
return prog;
@@ -7036,29 +7033,62 @@ void vim_regfree(regprog_T *prog)
prog->engine->regfree(prog);
}
-/*
- * Match a regexp against a string.
- * "rmp->regprog" is a compiled regexp as returned by vim_regcomp().
- * Uses curbuf for line count and 'iskeyword'.
- *
- * Return TRUE if there is a match, FALSE if not.
- */
-int
-vim_regexec (
- regmatch_T *rmp,
- char_u *line, /* string to match against */
- colnr_T col /* column to start looking for match */
-)
+static void report_re_switch(char_u *pat)
{
- return rmp->regprog->engine->regexec_nl(rmp, line, col, false);
+ if (p_verbose > 0) {
+ verbose_enter();
+ MSG_PUTS(_("Switching to backtracking RE engine for pattern: "));
+ MSG_PUTS(pat);
+ verbose_leave();
+ }
}
-/*
- * Like vim_regexec(), but consider a "\n" in "line" to be a line break.
- */
+/// Matches a regexp against a string.
+/// "rmp->regprog" is a compiled regexp as returned by vim_regcomp().
+/// Uses curbuf for line count and 'iskeyword'.
+/// When "nl" is true consider a "\n" in "line" to be a line break.
+///
+/// @param rmp
+/// @param line the string to match against
+/// @param col the column to start looking for match
+/// @param nl
+///
+/// @return TRUE if there is a match, FALSE if not.
+static int vim_regexec_both(regmatch_T *rmp, char_u *line, colnr_T col, bool nl)
+{
+ int result = rmp->regprog->engine->regexec_nl(rmp, line, col, nl);
+
+ // NFA engine aborted because it's very slow, use backtracking engine instead.
+ if (rmp->regprog->re_engine == AUTOMATIC_ENGINE
+ && result == NFA_TOO_EXPENSIVE) {
+ int save_p_re = p_re;
+ int re_flags = rmp->regprog->re_flags;
+ char_u *pat = vim_strsave(((nfa_regprog_T *)rmp->regprog)->pattern);
+
+ p_re = BACKTRACKING_ENGINE;
+ vim_regfree(rmp->regprog);
+ report_re_switch(pat);
+ rmp->regprog = vim_regcomp(pat, re_flags);
+ if (rmp->regprog != NULL) {
+ result = rmp->regprog->engine->regexec_nl(rmp, line, col, nl);
+ }
+
+ free(pat);
+ p_re = save_p_re;
+ }
+
+ return result;
+}
+
+int vim_regexec(regmatch_T *rmp, char_u *line, colnr_T col)
+{
+ return vim_regexec_both(rmp, line, col, false);
+}
+
+// Like vim_regexec(), but consider a "\n" in "line" to be a line break.
int vim_regexec_nl(regmatch_T *rmp, char_u *line, colnr_T col)
{
- return rmp->regprog->engine->regexec_nl(rmp, line, col, true);
+ return vim_regexec_both(rmp, line, col, true);
}
/*
@@ -7078,5 +7108,28 @@ long vim_regexec_multi(
proftime_T *tm /* timeout limit or NULL */
)
{
- return rmp->regprog->engine->regexec_multi(rmp, win, buf, lnum, col, tm);
+ int result = rmp->regprog->engine->regexec_multi(rmp, win, buf, lnum, col,
+ tm);
+
+ // NFA engine aborted because it's very slow, use backtracking engine instead.
+ if (rmp->regprog->re_engine == AUTOMATIC_ENGINE
+ && result == NFA_TOO_EXPENSIVE) {
+ int save_p_re = p_re;
+ int re_flags = rmp->regprog->re_flags;
+ char_u *pat = vim_strsave(((nfa_regprog_T *)rmp->regprog)->pattern);
+
+ p_re = BACKTRACKING_ENGINE;
+ vim_regfree(rmp->regprog);
+ report_re_switch(pat);
+ rmp->regprog = vim_regcomp(pat, re_flags);
+ if (rmp->regprog != NULL) {
+ result = rmp->regprog->engine->regexec_multi(rmp, win, buf, lnum, col,
+ tm);
+ }
+
+ free(pat);
+ p_re = save_p_re;
+ }
+
+ return result;
}
diff --git a/src/nvim/regexp_defs.h b/src/nvim/regexp_defs.h
index 1e00f14ac6..6426ee441b 100644
--- a/src/nvim/regexp_defs.h
+++ b/src/nvim/regexp_defs.h
@@ -30,6 +30,16 @@
*/
#define NFA_MAX_BRACES 20
+// In the NFA engine: how many states are allowed.
+#define NFA_MAX_STATES 100000
+#define NFA_TOO_EXPENSIVE -1
+
+// Which regexp engine to use? Needed for vim_regcomp().
+// Must match with 'regexpengine'.
+#define AUTOMATIC_ENGINE 0
+#define BACKTRACKING_ENGINE 1
+#define NFA_ENGINE 2
+
typedef struct regengine regengine_T;
/*
@@ -38,8 +48,10 @@ typedef struct regengine regengine_T;
* structures are used. See code below.
*/
typedef struct regprog {
- regengine_T *engine;
+ regengine_T *engine;
unsigned regflags;
+ unsigned re_engine; ///< Automatic, backtracking or NFA engine.
+ unsigned re_flags; ///< Second argument for vim_regcomp().
} regprog_T;
/*
@@ -48,9 +60,11 @@ typedef struct regprog {
* See regexp.c for an explanation.
*/
typedef struct {
- /* These two members implement regprog_T */
- regengine_T *engine;
+ // These four members implement regprog_T.
+ regengine_T *engine;
unsigned regflags;
+ unsigned re_engine;
+ unsigned re_flags; ///< Second argument for vim_regcomp().
int regstart;
char_u reganch;
@@ -78,9 +92,11 @@ struct nfa_state {
* Structure used by the NFA matcher.
*/
typedef struct {
- /* These two members implement regprog_T */
- regengine_T *engine;
+ // These four members implement regprog_T.
+ regengine_T *engine;
unsigned regflags;
+ unsigned re_engine;
+ unsigned re_flags; ///< Second argument for vim_regcomp().
nfa_state_T *start; /* points into state[] */
@@ -91,9 +107,7 @@ typedef struct {
int has_zend; /* pattern contains \ze */
int has_backref; /* pattern contains \1 .. \9 */
int reghasz;
-#ifdef DEBUG
char_u *pattern;
-#endif
int nsubexp; /* number of () */
int nstate;
nfa_state_T state[1]; /* actually longer.. */
@@ -143,9 +157,7 @@ struct regengine {
int (*regexec_nl)(regmatch_T*, char_u*, colnr_T, bool);
long (*regexec_multi)(regmmatch_T*, win_T*, buf_T*, linenr_T, colnr_T,
proftime_T*);
-#ifdef DEBUG
char_u *expr;
-#endif
};
#endif // NVIM_REGEXP_DEFS_H
diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c
index 6ed42303ef..1de167c40f 100644
--- a/src/nvim/regexp_nfa.c
+++ b/src/nvim/regexp_nfa.c
@@ -2347,7 +2347,6 @@ static void nfa_set_code(int c)
}
-#ifdef REGEXP_DEBUG
static FILE *log_fd;
/*
@@ -2468,7 +2467,6 @@ static void nfa_dump(nfa_regprog_T *prog)
}
}
#endif /* REGEXP_DEBUG */
-#endif /* REGEXP_DEBUG */
/*
* Parse r.e. @expr and convert it into postfix form.
@@ -4908,6 +4906,12 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm
nextlist->n = 0; /* clear nextlist */
nextlist->has_pim = FALSE;
++nfa_listid;
+ if (prog->re_engine == AUTOMATIC_ENGINE && nfa_listid >= NFA_MAX_STATES) {
+ // Too many states, retry with old engine.
+ nfa_match = NFA_TOO_EXPENSIVE;
+ goto theend;
+ }
+
thislist->id = nfa_listid;
nextlist->id = nfa_listid + 1;
@@ -5082,6 +5086,10 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm
*/
result = recursive_regmatch(t->state, NULL, prog,
submatch, m, &listids);
+ if (result == NFA_TOO_EXPENSIVE) {
+ nfa_match = result;
+ goto theend;
+ }
/* for \@! and \@<! it is a match when the result is
* FALSE */
@@ -5180,6 +5188,10 @@ static int nfa_regmatch(nfa_regprog_T *prog, nfa_state_T *start, regsubs_T *subm
/* First try matching the pattern. */
result = recursive_regmatch(t->state, NULL, prog,
submatch, m, &listids);
+ if (result == NFA_TOO_EXPENSIVE) {
+ nfa_match = result;
+ goto theend;
+ }
if (result) {
int bytelen;
@@ -6019,6 +6031,7 @@ nextchar:
log_fd = NULL;
#endif
+theend:
/* Free memory */
free(list[0].t);
free(list[1].t);
@@ -6068,8 +6081,12 @@ static long nfa_regtry(nfa_regprog_T *prog, colnr_T col)
clear_sub(&subs.synt);
clear_sub(&m.synt);
- if (nfa_regmatch(prog, start, &subs, &m) == FALSE)
+ int result = nfa_regmatch(prog, start, &subs, &m);
+ if (result == FALSE) {
return 0;
+ } else if (result == NFA_TOO_EXPENSIVE) {
+ return result;
+ }
cleanup_subexpr();
if (REG_MULTI) {
@@ -6186,9 +6203,7 @@ nfa_regexec_both (
nfa_nsubexpr = prog->nsubexp;
nfa_listid = 1;
nfa_alt_listid = 2;
-#ifdef REGEXP_DEBUG
nfa_regengine.expr = prog->pattern;
-#endif
if (prog->reganch && col > 0)
return 0L;
@@ -6228,9 +6243,7 @@ nfa_regexec_both (
retval = nfa_regtry(prog, col);
-#ifdef REGEXP_DEBUG
nfa_regengine.expr = NULL;
-#endif
theend:
return retval;
@@ -6248,9 +6261,7 @@ static regprog_T *nfa_regcomp(char_u *expr, int re_flags)
if (expr == NULL)
return NULL;
-#ifdef REGEXP_DEBUG
nfa_regengine.expr = expr;
-#endif
init_class_tab();
@@ -6325,10 +6336,8 @@ static regprog_T *nfa_regcomp(char_u *expr, int re_flags)
#endif
/* Remember whether this pattern has any \z specials in it. */
prog->reghasz = re_has_z;
-#ifdef REGEXP_DEBUG
prog->pattern = vim_strsave(expr);
nfa_regengine.expr = NULL;
-#endif
out:
free(post_start);
@@ -6342,9 +6351,7 @@ fail:
#ifdef REGEXP_DEBUG
nfa_postfix_dump(expr, FAIL);
#endif
-#ifdef REGEXP_DEBUG
nfa_regengine.expr = NULL;
-#endif
goto out;
}
@@ -6355,9 +6362,7 @@ static void nfa_regfree(regprog_T *prog)
{
if (prog != NULL) {
free(((nfa_regprog_T *)prog)->match_text);
-#ifdef REGEXP_DEBUG
free(((nfa_regprog_T *)prog)->pattern);
-#endif
free(prog);
}
}
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c
index d603a6a877..2149f0f998 100644
--- a/src/nvim/terminal.c
+++ b/src/nvim/terminal.c
@@ -1071,7 +1071,7 @@ static void redraw(bool restore_cursor)
setcursor();
} else if (restore_cursor) {
ui_cursor_goto(save_row, save_col);
- } else {
+ } else if (term) {
// exiting terminal focus, put the window cursor in a valid position
int height, width;
vterm_get_size(term->vt, &height, &width);
@@ -1123,28 +1123,30 @@ static bool is_focused(Terminal *term)
do { \
Error err; \
o = dict_get_value(t->buf->b_vars, cstr_as_string(k), &err); \
- if (obj.type == kObjectTypeNil) { \
+ if (o.type == kObjectTypeNil) { \
o = dict_get_value(&globvardict, cstr_as_string(k), &err); \
} \
} while (0)
static char *get_config_string(Terminal *term, char *key)
{
- Object obj = OBJECT_INIT;
+ Object obj;
GET_CONFIG_VALUE(term, key, obj);
if (obj.type == kObjectTypeString) {
return obj.data.string.data;
}
+ api_free_object(obj);
return NULL;
}
static int get_config_int(Terminal *term, char *key)
{
- Object obj = OBJECT_INIT;
+ Object obj;
GET_CONFIG_VALUE(term, key, obj);
if (obj.type == kObjectTypeInteger) {
return (int)obj.data.integer;
}
+ api_free_object(obj);
return 0;
}
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile
index 70e6f8ee4c..a530e3cf23 100644
--- a/src/nvim/testdir/Makefile
+++ b/src/nvim/testdir/Makefile
@@ -16,19 +16,18 @@ SCRIPTS := test_autoformat_join.out \
test24.out \
test26.out test27.out test29.out test30.out \
test31.out test32.out test34.out \
- test36.out test37.out test38.out test39.out test40.out \
- test42.out test43.out test44.out test45.out \
+ test36.out test37.out test39.out test40.out \
+ test42.out test43.out test45.out \
test46.out test47.out test48.out test49.out \
test52.out test53.out test55.out \
test57.out test58.out test59.out test60.out \
test61.out test62.out test63.out test64.out test65.out \
- test68.out test69.out test70.out \
+ test68.out test69.out \
test71.out test73.out test74.out \
test76.out test78.out test79.out test80.out \
- test82.out test83.out test85.out \
+ test82.out test83.out \
test86.out test87.out test88.out \
- test92.out test93.out \
- test96.out test99.out \
+ test96.out \
test_listlbr.out \
test_breakindent.out
@@ -86,7 +85,7 @@ test1.out: $(VIMPROG)
$(SCRIPTS) $(SCRIPTS_GUI): $(VIMPROG) test1.out
RM_ON_RUN := test.out X* viminfo
-RM_ON_START := tiny.vim small.vim mbyte.vim mzscheme.vim lua.vim test.ok
+RM_ON_START := tiny.vim small.vim mbyte.vim test.ok
RUN_VIM := VIMRUNTIME=$(SCRIPTSOURCE); export VIMRUNTIME; $(TOOL) $(VIMPROG) -u unix.vim -U NONE -i viminfo --noplugin -s dotest.in
clean:
diff --git a/src/nvim/testdir/test1.in b/src/nvim/testdir/test1.in
index 735d539673..85ff1b4db2 100644
--- a/src/nvim/testdir/test1.in
+++ b/src/nvim/testdir/test1.in
@@ -14,8 +14,6 @@ set like small.vim above. tiny.vim is sourced by tests that require the
If Vim was not compiled with the +multi_byte feature, the mbyte.vim script will
be set like small.vim above. mbyte.vim is sourced by tests that require the
+multi_byte feature.
-Similar logic is applied to the +mzscheme feature, using mzscheme.vim.
-Similar logic is applied to the +lua feature, using lua.vim.
STARTTEST
:" If columns or lines are too small, create wrongtermsize.
@@ -32,18 +30,10 @@ ae! test.ok
w! test.out
qa!
:w! mbyte.vim
-:w! mzscheme.vim
-:w! lua.vim
:"
:" If +multi_byte feature supported, make mbyte.vim empty.
:if has("multi_byte") | sp another | w! mbyte.vim | q | endif
:"
-:" If +mzscheme feature supported, make mzscheme.vim empty.
-:if has("mzscheme") | sp another | w! mzscheme.vim | q | endif
-:"
-:" If +lua feature supported, make lua.vim empty.
-:if has("lua") | sp another | w! lua.vim | q | endif
-:"
:" If +eval feature supported quit here, leaving tiny.vim and small.vim empty.
:" Otherwise write small.vim to skip the test.
:if 1 | q! | endif
diff --git a/src/nvim/testdir/test38.in b/src/nvim/testdir/test38.in
deleted file mode 100644
index 3e0236251b..0000000000
--- a/src/nvim/testdir/test38.in
+++ /dev/null
@@ -1,35 +0,0 @@
-
-Test Virtual replace mode.
-
-STARTTEST
-:so small.vim
-:" make sure that backspace works, no matter what termcap is used
-:set t_kD=x7f t_kb=x08
-ggdGa
-abcdefghi
-jk lmn
- opq rst
-uvwxyz
-gg:set ai
-:set bs=2
-gR0 1
-A
-BCDEFGHIJ
- KL
-MNO
-PQRG:ka
-o0
-abcdefghi
-jk lmn
- opq rst
-uvwxyz
-'ajgR0 1
-A
-BCDEFGHIJ
- KL
-MNO
-PQR:$
-iab cdefghi jkl0gRAB......CDEFGHI.Jo:
-iabcdefghijklmnopqrst0gRAB IJKLMNO QR:wq! test.out
-ENDTEST
-
diff --git a/src/nvim/testdir/test38.ok b/src/nvim/testdir/test38.ok
deleted file mode 100644
index e10209667b..0000000000
--- a/src/nvim/testdir/test38.ok
+++ /dev/null
@@ -1,13 +0,0 @@
- 1
- A
- BCDEFGHIJ
- KL
- MNO
- PQR
- 1
-abcdefghi
-jk lmn
- opq rst
-uvwxyz
-AB......CDEFGHI.Jkl
-AB IJKLMNO QRst
diff --git a/src/nvim/testdir/test44.in b/src/nvim/testdir/test44.in
deleted file mode 100644
index 65b08b08b8..0000000000
--- a/src/nvim/testdir/test44.in
+++ /dev/null
@@ -1,68 +0,0 @@
-Tests for regexp with multi-byte encoding and various magic settings.
-Test matchstr() with a count and multi-byte chars.
-See test99 for exactly the same test with re=2.
-
-STARTTEST
-:so mbyte.vim
-:set encoding=utf-8 termencoding=latin1
-:set re=1
-/^1
-/a*b\{2}c\+/e
-x/\Md\*e\{2}f\+/e
-x:set nomagic
-/g\*h\{2}i\+/e
-x/\mj*k\{2}l\+/e
-x/\vm*n{2}o+/e
-x/\V^aa$
-x:set magic
-/\v(a)(b)\2\1\1/e
-x/\V[ab]\(\[xy]\)\1
-x:" Now search for multi-byte without composing char
-/ม
-x:" Now search for multi-byte with composing char
-/ม่
-x:" find word by change of word class
-/ち\<カヨ\>は
-x:" Test \%u, [\u] and friends
-/\%u20ac
-x/[\u4f7f\u5929]\+
-x/\%U12345678
-x/[\U1234abcd\u1234\uabcd]
-x/\%d21879b
-x/ [[=A=]]* [[=B=]]* [[=C=]]* [[=D=]]* [[=E=]]* [[=F=]]* [[=G=]]* [[=H=]]* [[=I=]]* [[=J=]]* [[=K=]]* [[=L=]]* [[=M=]]* [[=N=]]* [[=O=]]* [[=P=]]* [[=Q=]]* [[=R=]]* [[=S=]]* [[=T=]]* [[=U=]]* [[=V=]]* [[=W=]]* [[=X=]]* [[=Y=]]* [[=Z=]]*/e
-x/ [[=a=]]* [[=b=]]* [[=c=]]* [[=d=]]* [[=e=]]* [[=f=]]* [[=g=]]* [[=h=]]* [[=i=]]* [[=j=]]* [[=k=]]* [[=l=]]* [[=m=]]* [[=n=]]* [[=o=]]* [[=p=]]* [[=q=]]* [[=r=]]* [[=s=]]* [[=t=]]* [[=u=]]* [[=v=]]* [[=w=]]* [[=x=]]* [[=y=]]* [[=z=]]*/e
-x:" Test backwards search from a multi-byte char
-/x
-x?.
-x:let @w=':%s#comb[i]nations#œ̄ṣ́m̥̄ᾱ̆́#g'
-:@w
-:?^1?,$w! test.out
-:e! test.out
-G:put =matchstr(\"אבגד\", \".\", 0, 2) " ב
-:put =matchstr(\"אבגד\", \"..\", 0, 2) " בג
-:put =matchstr(\"אבגד\", \".\", 0, 0) " א
-:put =matchstr(\"אבגד\", \".\", 4, -1) " ג
-:w!
-:qa!
-ENDTEST
-
-1 a aa abb abbccc
-2 d dd dee deefff
-3 g gg ghh ghhiii
-4 j jj jkk jkklll
-5 m mm mnn mnnooo
-6 x ^aa$ x
-7 (a)(b) abbaa
-8 axx [ab]xx
-9 หม่x อมx
-a อมx หม่x
-b ちカヨは
-c x ¬€x
-d 天使x
-e y
-f z
-g a啷bb
-h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐẔ
-i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑẕ
-j 0123❤x
-k combinations
diff --git a/src/nvim/testdir/test44.ok b/src/nvim/testdir/test44.ok
deleted file mode 100644
index 0bd0b8ab73..0000000000
--- a/src/nvim/testdir/test44.ok
+++ /dev/null
@@ -1,24 +0,0 @@
-1 a aa abb abbcc
-2 d dd dee deeff
-3 g gg ghh ghhii
-4 j jj jkk jkkll
-5 m mm mnn mnnoo
-6 x aa$ x
-7 (a)(b) abba
-8 axx ab]xx
-9 หม่x อx
-a อมx หx
-b カヨは
-c x ¬x
-d 使x
-e y
-f z
-g abb
-h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐ
-i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑ
-j 012❤
-k œ̄ṣ́m̥̄ᾱ̆́
-בג
diff --git a/src/nvim/testdir/test70.in b/src/nvim/testdir/test70.in
deleted file mode 100644
index 24d2e4c446..0000000000
--- a/src/nvim/testdir/test70.in
+++ /dev/null
@@ -1,62 +0,0 @@
-Smoke test for MzScheme interface and mzeval() function
-
-STARTTEST
-:so mzscheme.vim
-:function! MzRequire()
-:redir => l:mzversion
-:mz (version)
-:redir END
-:if strpart(l:mzversion, 1, 1) < "4"
-:" MzScheme versions < 4.x:
-:mz (require (prefix vim- vimext))
-:else
-:" newer versions:
-:mz (require (prefix-in vim- 'vimext))
-:mz (require r5rs)
-:endif
-:endfunction
-:silent call MzRequire()
-:mz (define l '("item0" "dictionary with list OK" "item2"))
-:mz (define h (make-hash))
-:mz (hash-set! h "list" l)
-/^1
-:" change buffer contents
-:mz (vim-set-buff-line (vim-eval "line('.')") "1 changed line 1")
-:" scalar test
-:let tmp_string = mzeval('"string"')
-:let tmp_1000 = mzeval('1000')
-:if tmp_string . tmp_1000 == "string1000"
-:let scalar_res = "OK"
-:else
-:let scalar_res = "FAILED"
-:endif
-:call append(search("^1"), "scalar test " . scalar_res)
-:" dictionary containing a list
-:let tmp = mzeval("h")["list"][1]
-:/^2/put =tmp
-:" circular list (at the same time test lists containing lists)
-:mz (set-car! (cddr l) l)
-:let l2 = mzeval("h")["list"]
-:if l2[2] == l2
-:let res = "OK"
-:else
-:let res = "FAILED: " . l2[2]
-:endif
-:call setline(search("^3"), "circular test " . res)
-:" funcrefs
-:mz (define vim:max (vim-eval "function('max')"))
-:mz (define m (vim:max '(1 100 8)))
-:let m = mzeval('m')
-:if m == 100
-:let fref_res = "OK"
-:else
-:let fref_res = "FAILED: " . m
-:end
-:call append(line('$'), 'funcrefs '. fref_res)
-:?^1?,$w! test.out
-:qa!
-ENDTEST
-
-1 line 1
-2 line 2
-3 line 3
diff --git a/src/nvim/testdir/test70.ok b/src/nvim/testdir/test70.ok
deleted file mode 100644
index 9c82a86f2d..0000000000
--- a/src/nvim/testdir/test70.ok
+++ /dev/null
@@ -1,6 +0,0 @@
-1 changed line 1
-scalar test OK
-2 line 2
-dictionary with list OK
-circular test OK
-funcrefs OK
diff --git a/src/nvim/testdir/test85.in b/src/nvim/testdir/test85.in
deleted file mode 100644
index f7112792e9..0000000000
--- a/src/nvim/testdir/test85.in
+++ /dev/null
@@ -1,84 +0,0 @@
-Test for Lua interface and luaeval() function
-
-STARTTEST
-:so small.vim
-:so lua.vim
-:lua l = vim.list():add"item0":add"dictionary with list OK":add"item2"
-:lua h = vim.dict(); h.list = l
-:call garbagecollect()
-/^1
-:" change buffer contents
-:lua curbuf = vim.buffer()
-:lua curline = vim.eval"line('.')"
-:lua curbuf[curline] = "1 changed line 1"
-:" scalar test
-:let tmp_string = luaeval('"string"')
-:let tmp_1000 = luaeval('1000')
-:if printf("%s%.0f", tmp_string, tmp_1000) == "string1000"
-:let scalar_res = "OK"
-:else
-:let scalar_res = "FAILED"
-:endif
-:call append(search("^1"), "scalar test " . scalar_res)
-:" dictionary containing a list
-:let tmp = luaeval("h").list[1]
-:/^2/put =tmp
-:" circular list (at the same time test lists containing lists)
-:lua l[2] = l
-:let l2 = luaeval("h").list
-:if l2[2] == l2
-:let res = "OK"
-:else
-:let res = "FAILED"
-:endif
-:call setline(search("^3"), "circular test " . res)
-
-:let l = []
-:lua l = vim.eval("l")
-:lua l:add(123)
-:lua l:add("abc")
-:lua l:add(vim.eval("[1, 2, 3]"))
-:lua l:add(vim.eval("{'a':1, 'b':2, 'c':3}"))
-:lua l:insert(123)
-:lua l:insert("abc")
-:lua l:insert(vim.eval("[1, 2, 3]"))
-:lua l:insert(vim.eval("{'a':1, 'b':2, 'c':3}"))
-:lua l[0] = l[0]
-:lua l[1] = l[1]
-:lua l[2] = l[2]
-:lua l[3] = l[3]
-:lua l[0] = 123
-:lua l[1] = "abc"
-:lua l[2] = vim.eval("[1, 2, 3]")
-:lua l[3] = vim.eval("{'a':1, 'b':2, 'c':3}")
-:lua l[3] = nil
-:lua l[2] = nil
-:lua l[1] = nil
-:lua l[0] = nil
-:lua l = nil
-:$put =string(l)
-
-:let d = {}
-:lua d = vim.eval("d")
-:lua d[0] = 123
-:lua d[1] = "abc"
-:lua d[2] = vim.eval("[1, 2, 3]")
-:lua d[3] = vim.eval("{'a':1, 'b':2, 'c':3}")
-:lua d[4] = d[0]
-:lua d[5] = d[1]
-:lua d[6] = d[2]
-:lua d[7] = d[3]
-:lua d[3] = nil
-:lua d[2] = nil
-:lua d[1] = nil
-:lua d[0] = nil
-:lua d = nil
-:$put =string(d)
-
-:?^1?,$w! test.out
-:qa!
-ENDTEST
-
-1 line 1
-2 line 2
-3 line 3
diff --git a/src/nvim/testdir/test85.ok b/src/nvim/testdir/test85.ok
deleted file mode 100644
index 4753483240..0000000000
--- a/src/nvim/testdir/test85.ok
+++ /dev/null
@@ -1,7 +0,0 @@
-1 changed line 1
-scalar test OK
-2 line 2
-dictionary with list OK
-circular test OK
-[123.0, 'abc', [1, 2, 3], {'a': 1, 'b': 2, 'c': 3}]
-{'4': 123.0, '5': 'abc', '6': [1, 2, 3], '7': {'a': 1, 'b': 2, 'c': 3}}
diff --git a/src/nvim/testdir/test92.in b/src/nvim/testdir/test92.in
deleted file mode 100644
index 9593aec4c7..0000000000
--- a/src/nvim/testdir/test92.in
+++ /dev/null
@@ -1,48 +0,0 @@
-vim: set ft=vim fenc=utf-8:
-
-Tests if :mksession saves cursor columns correctly in presence of tab and
-multibyte characters when fileencoding=utf-8.
-
-STARTTEST
-:so mbyte.vim
-:if !has('mksession')
-: e! test.ok
-: wq! test.out
-:endif
-:set sessionoptions=buffers splitbelow fileencoding=utf-8
-/^start:
-:vsplit
-j16|:split
-j16|:split
-j16|:split
-j8|:split
-j8|:split
-j16|:split
-j16|:split
-j16|:wincmd l
-/^start:
-:set nowrap
-j16|3zl:split
-j016|3zl:split
-j016|3zl:split
-j08|3zl:split
-j08|3zl:split
-j016|3zl:split
-j016|3zl:split
-j016|3zl:split
-:mksession! test.out
-:new test.out
-:v/\(^ *normal! 0\|^ *exe 'normal!\)/d
-:w! test.out
-:qa!
-ENDTEST
-
-start:
-no multibyte chAracter
- one leaDing tab
- four leadinG spaces
-two consecutive tabs
-two tabs in one line
-one … multibyteCharacter
-a “b” two multiByte characters
-“c”1€ three mulTibyte characters
diff --git a/src/nvim/testdir/test92.ok b/src/nvim/testdir/test92.ok
deleted file mode 100644
index cca5ec487c..0000000000
--- a/src/nvim/testdir/test92.ok
+++ /dev/null
@@ -1,26 +0,0 @@
-normal! 016|
-normal! 016|
-normal! 016|
-normal! 08|
-normal! 08|
-normal! 016|
-normal! 016|
-normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 8 . '|'
- normal! 08|
- exe 'normal! ' . s:c . '|zs' . 8 . '|'
- normal! 08|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
diff --git a/src/nvim/testdir/test93.in b/src/nvim/testdir/test93.in
deleted file mode 100644
index 877838ce1b..0000000000
--- a/src/nvim/testdir/test93.in
+++ /dev/null
@@ -1,48 +0,0 @@
-vim: set ft=vim fenc=latin1:
-
-Tests if :mksession saves cursor columns correctly in presence of tab and
-multibyte characters when fileencoding=latin1.
-
-STARTTEST
-:so mbyte.vim
-:if !has('mksession')
-: e! test.ok
-: wq! test.out
-:endif
-:set sessionoptions=buffers splitbelow fileencoding=latin1
-/^start:
-:vsplit
-j16|:split
-j16|:split
-j16|:split
-j8|:split
-j8|:split
-j16|:split
-j16|:split
-j16|:wincmd l
-/^start:
-:set nowrap
-j16|3zl:split
-j016|3zl:split
-j016|3zl:split
-j08|3zl:split
-j08|3zl:split
-j016|3zl:split
-j016|3zl:split
-j016|3zl:split
-:mksession! test.out
-:new test.out
-:v/\(^ *normal! 0\|^ *exe 'normal!\)/d
-:w! test.out
-:qa!
-ENDTEST
-
-start:
-no multibyte chAracter
- one leaDing tab
- four leadinG spaces
-two consecutive tabs
-two tabs in one line
-one multibyteCharacter
-a two multiByte characters
-A three mulTibyte characters
diff --git a/src/nvim/testdir/test93.ok b/src/nvim/testdir/test93.ok
deleted file mode 100644
index cca5ec487c..0000000000
--- a/src/nvim/testdir/test93.ok
+++ /dev/null
@@ -1,26 +0,0 @@
-normal! 016|
-normal! 016|
-normal! 016|
-normal! 08|
-normal! 08|
-normal! 016|
-normal! 016|
-normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 8 . '|'
- normal! 08|
- exe 'normal! ' . s:c . '|zs' . 8 . '|'
- normal! 08|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
- exe 'normal! ' . s:c . '|zs' . 16 . '|'
- normal! 016|
diff --git a/src/nvim/testdir/test99.in b/src/nvim/testdir/test99.in
deleted file mode 100644
index 32bc68cce4..0000000000
--- a/src/nvim/testdir/test99.in
+++ /dev/null
@@ -1,68 +0,0 @@
-Tests for regexp with multi-byte encoding and various magic settings.
-Test matchstr() with a count and multi-byte chars.
-See test44 for exactly the same test with re=1.
-
-STARTTEST
-:so mbyte.vim
-:set encoding=utf-8 termencoding=latin1
-:set re=2
-/^1
-/a*b\{2}c\+/e
-x/\Md\*e\{2}f\+/e
-x:set nomagic
-/g\*h\{2}i\+/e
-x/\mj*k\{2}l\+/e
-x/\vm*n{2}o+/e
-x/\V^aa$
-x:set magic
-/\v(a)(b)\2\1\1/e
-x/\V[ab]\(\[xy]\)\1
-x:" Now search for multi-byte without composing char
-/ม
-x:" Now search for multi-byte with composing char
-/ม่
-x:" find word by change of word class
-/ち\<カヨ\>は
-x:" Test \%u, [\u] and friends
-/\%u20ac
-x/[\u4f7f\u5929]\+
-x/\%U12345678
-x/[\U1234abcd\u1234\uabcd]
-x/\%d21879b
-x/ [[=A=]]* [[=B=]]* [[=C=]]* [[=D=]]* [[=E=]]* [[=F=]]* [[=G=]]* [[=H=]]* [[=I=]]* [[=J=]]* [[=K=]]* [[=L=]]* [[=M=]]* [[=N=]]* [[=O=]]* [[=P=]]* [[=Q=]]* [[=R=]]* [[=S=]]* [[=T=]]* [[=U=]]* [[=V=]]* [[=W=]]* [[=X=]]* [[=Y=]]* [[=Z=]]*/e
-x/ [[=a=]]* [[=b=]]* [[=c=]]* [[=d=]]* [[=e=]]* [[=f=]]* [[=g=]]* [[=h=]]* [[=i=]]* [[=j=]]* [[=k=]]* [[=l=]]* [[=m=]]* [[=n=]]* [[=o=]]* [[=p=]]* [[=q=]]* [[=r=]]* [[=s=]]* [[=t=]]* [[=u=]]* [[=v=]]* [[=w=]]* [[=x=]]* [[=y=]]* [[=z=]]*/e
-x:" Test backwards search from a multi-byte char
-/x
-x?.
-x:let @w=':%s#comb[i]nations#œ̄ṣ́m̥̄ᾱ̆́#g'
-:@w
-:?^1?,$w! test.out
-:e! test.out
-G:put =matchstr(\"אבגד\", \".\", 0, 2) " ב
-:put =matchstr(\"אבגד\", \"..\", 0, 2) " בג
-:put =matchstr(\"אבגד\", \".\", 0, 0) " א
-:put =matchstr(\"אבגד\", \".\", 4, -1) " ג
-:w!
-:qa!
-ENDTEST
-
-1 a aa abb abbccc
-2 d dd dee deefff
-3 g gg ghh ghhiii
-4 j jj jkk jkklll
-5 m mm mnn mnnooo
-6 x ^aa$ x
-7 (a)(b) abbaa
-8 axx [ab]xx
-9 หม่x อมx
-a อมx หม่x
-b ちカヨは
-c x ¬€x
-d 天使x
-e y
-f z
-g a啷bb
-h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐẔ
-i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑẕ
-j 0123❤x
-k combinations
diff --git a/src/nvim/testdir/test99.ok b/src/nvim/testdir/test99.ok
deleted file mode 100644
index 0bd0b8ab73..0000000000
--- a/src/nvim/testdir/test99.ok
+++ /dev/null
@@ -1,24 +0,0 @@
-1 a aa abb abbcc
-2 d dd dee deeff
-3 g gg ghh ghhii
-4 j jj jkk jkkll
-5 m mm mnn mnnoo
-6 x aa$ x
-7 (a)(b) abba
-8 axx ab]xx
-9 หม่x อx
-a อมx หx
-b カヨは
-c x ¬x
-d 使x
-e y
-f z
-g abb
-h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐ
-i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑ
-j 012❤
-k œ̄ṣ́m̥̄ᾱ̆́
-בג
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 72f93976c1..6d23c2cf74 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -50,6 +50,7 @@ typedef struct {
int out_fd;
int old_height;
bool can_use_terminal_scroll;
+ bool mouse_enabled;
bool busy;
HlAttrs attrs, print_attrs;
Cell **screen;
@@ -84,7 +85,7 @@ typedef struct {
} while (0)
-void tui_start(void)
+UI *tui_start(void)
{
TUIData *data = xcalloc(1, sizeof(TUIData));
UI *ui = xcalloc(1, sizeof(UI));
@@ -119,7 +120,6 @@ void tui_start(void)
unibi_out(ui, unibi_clear_screen);
// Enable bracketed paste
unibi_out(ui, data->unibi_ext.enable_bracketed_paste);
-
// setup output handle in a separate event loop(we wanna do synchronous
// write to the tty)
data->write_loop = xmalloc(sizeof(uv_loop_t));
@@ -162,6 +162,7 @@ void tui_start(void)
ui->set_icon = tui_set_icon;
// Attach
ui_attach(ui);
+ return ui;
}
static void tui_stop(UI *ui)
@@ -384,12 +385,14 @@ static void tui_mouse_on(UI *ui)
{
TUIData *data = ui->data;
unibi_out(ui, data->unibi_ext.enable_mouse);
+ data->mouse_enabled = true;
}
static void tui_mouse_off(UI *ui)
{
TUIData *data = ui->data;
unibi_out(ui, data->unibi_ext.disable_mouse);
+ data->mouse_enabled = false;
}
static void tui_insert_mode(UI *ui)
@@ -561,9 +564,14 @@ static void tui_flush(UI *ui)
static void tui_suspend(UI *ui)
{
+ TUIData *data = ui->data;
+ bool enable_mouse = data->mouse_enabled;
tui_stop(ui);
kill(0, SIGTSTP);
- tui_start();
+ ui = tui_start();
+ if (enable_mouse) {
+ tui_mouse_on(ui);
+ }
}
static void tui_set_title(UI *ui, char *title)
diff --git a/src/nvim/version.c b/src/nvim/version.c
index 8cdc06dba5..1a5eb523fa 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -104,7 +104,7 @@ static int included_patches[] = {
//639,
//638,
637,
- //636,
+ 636,
//635,
//634,
//633,
@@ -243,7 +243,7 @@ static int included_patches[] = {
500,
499,
//498 NA
- //497,
+ 497,
//496 NA
//495 NA
494,
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 9f07f2bddc..9c56cc5b82 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -1766,7 +1766,7 @@ static int close_last_window_tabpage(win_T *win, int free_buf, tabpage_T *prev_c
}
buf_T *old_curbuf = curbuf;
- Terminal *term = win->w_buffer->terminal;
+ Terminal *term = win->w_buffer ? win->w_buffer->terminal : NULL;
if (term) {
// Don't free terminal buffers
free_buf = false;
diff --git a/test/benchmark/bench_re_freeze_spec.lua b/test/benchmark/bench_re_freeze_spec.lua
new file mode 100644
index 0000000000..7242f43c8e
--- /dev/null
+++ b/test/benchmark/bench_re_freeze_spec.lua
@@ -0,0 +1,67 @@
+-- Test for benchmarking RE engine.
+
+local helpers = require('test.functional.helpers')
+local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local clear, execute, wait = helpers.clear, helpers.execute, helpers.wait
+
+-- Temporary file for gathering benchmarking results for each regexp engine.
+local result_file = 'benchmark.out'
+-- Fixture containing an HTML fragment that can make a search appear to freeze.
+local sample_file = 'test/benchmark/samples/re.freeze.txt'
+
+-- Vim script code that does both the work and the benchmarking of that work.
+local measure_cmd =
+ [[call Measure(%d, ']] .. sample_file .. [[', '\s\+\%%#\@<!$', '+5')]]
+local measure_script = [[
+ func! Measure(re, file, pattern, arg)
+ let sstart=reltime()
+
+ execute 'set re=' . a:re
+ execute 'split' a:arg a:file
+ call search(a:pattern, '', '', 10000)
+ q!
+
+ $put =printf('file: %s, re: %d, time: %s', a:file, a:re, reltimestr(reltime(sstart)))
+ endfunc]]
+
+describe('regexp search', function()
+ -- The test cases rely on a small Vim script, which we source here, and also
+ -- on a temporary result file, which we prepare and write to disk.
+ setup(function()
+ clear()
+ source(measure_script)
+ insert('" Benchmark_results:')
+ execute('write! ' .. result_file)
+ end)
+
+ -- At the end of the test run we just print the contents of the result file
+ -- for human inspection and promptly delete the file.
+ teardown(function()
+ print ''
+ for line in io.lines(result_file) do
+ print(line)
+ end
+ os.remove(result_file)
+ end)
+
+ it('is working with regexpengine=0', function()
+ local regexpengine = 0
+ execute(string.format(measure_cmd, regexpengine))
+ execute('write')
+ wait()
+ end)
+
+ it('is working with regexpengine=1', function()
+ local regexpengine = 1
+ execute(string.format(measure_cmd, regexpengine))
+ execute('write')
+ wait()
+ end)
+
+ it('is working with regexpengine=2', function()
+ local regexpengine = 2
+ execute(string.format(measure_cmd, regexpengine))
+ execute('write')
+ wait()
+ end)
+end)
diff --git a/test/benchmark/preload.lua b/test/benchmark/preload.lua
new file mode 100644
index 0000000000..1971ef77cc
--- /dev/null
+++ b/test/benchmark/preload.lua
@@ -0,0 +1,4 @@
+-- Modules loaded here will not be cleared and reloaded by Busted.
+-- Busted started doing this to help provide more isolation. See issue #62
+-- for more information about this.
+local helpers = require('test.functional.helpers')
diff --git a/test/benchmark/samples/re.freeze.txt b/test/benchmark/samples/re.freeze.txt
new file mode 100644
index 0000000000..d768c23c5e
--- /dev/null
+++ b/test/benchmark/samples/re.freeze.txt
@@ -0,0 +1,6 @@
+:set re=0 or 2
+Search for the pattern: /\s\+\%#\@<!$/
+vim should not freeze.
+
+<td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td><td style="border-bottom windowtext 0.5pt solid; border-left windowtext;" class=abc align=right><font face=arial><font color=#ff0000><b>5</b></font></font></td>
+
diff --git a/test/functional/legacy/038_virtual_replace_spec.lua b/test/functional/legacy/038_virtual_replace_spec.lua
new file mode 100644
index 0000000000..239ffa47e6
--- /dev/null
+++ b/test/functional/legacy/038_virtual_replace_spec.lua
@@ -0,0 +1,58 @@
+-- Test Virtual replace mode.
+
+local helpers = require('test.functional.helpers')
+local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
+
+describe('Virtual replace mode', function()
+ setup(clear)
+
+ it('is working', function()
+ -- Make sure that backspace works, no matter what termcap is used.
+ execute('set t_kD=x7f t_kb=x08')
+ feed('ggdGa<cr>')
+ feed('abcdefghi<cr>')
+ feed('jk<tab>lmn<cr>')
+ feed('<Space><Space><Space><Space>opq<tab>rst<cr>')
+ feed('<C-d>uvwxyz<cr>')
+ feed('<esc>gg')
+ execute('set ai')
+ execute('set bs=2')
+ feed('gR0<C-d> 1<cr>')
+ feed('A<cr>')
+ feed('BCDEFGHIJ<cr>')
+ feed('<tab>KL<cr>')
+ feed('MNO<cr>')
+ feed('PQR<esc>G')
+ execute('ka')
+ feed('o0<C-d><cr>')
+ feed('abcdefghi<cr>')
+ feed('jk<tab>lmn<cr>')
+ feed('<Space><Space><Space><Space>opq<tab>rst<cr>')
+ feed('<C-d>uvwxyz<cr>')
+ feed([[<esc>'ajgR0<C-d> 1<cr>]])
+ feed('A<cr>')
+ feed('BCDEFGHIJ<cr>')
+ feed('<tab>KL<cr>')
+ feed('MNO<cr>')
+ feed('PQR<C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><C-h><esc>:$<cr>')
+ feed('iab<tab>cdefghi<tab>jkl<esc>0gRAB......CDEFGHI.J<esc>o<esc>:<cr>')
+ feed('iabcdefghijklmnopqrst<esc>0gRAB<tab>IJKLMNO<tab>QR<esc>')
+
+ -- Assert buffer contents.
+ expect([=[
+ 1
+ A
+ BCDEFGHIJ
+ KL
+ MNO
+ PQR
+ 1
+ abcdefghi
+ jk lmn
+ opq rst
+ uvwxyz
+ AB......CDEFGHI.Jkl
+ AB IJKLMNO QRst]=])
+ end)
+end)
diff --git a/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua b/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua
new file mode 100644
index 0000000000..de628b0b52
--- /dev/null
+++ b/test/functional/legacy/044_099_regexp_multibyte_magic_spec.lua
@@ -0,0 +1,147 @@
+-- Tests for regexp with multi-byte encoding and various magic settings.
+-- Test matchstr() with a count and multi-byte chars.
+--
+-- This test contains both "test44" and "test99" from the old test suite.
+
+local helpers = require('test.functional.helpers')
+local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
+
+-- Runs the test protocol with the given 'regexpengine' setting. In the old test
+-- suite the test protocol was duplicated in test44 and test99, the only
+-- difference being the 'regexpengine' setting. We've extracted it here.
+local function run_test_with_regexpengine(regexpengine)
+ insert([[
+ 1 a aa abb abbccc
+ 2 d dd dee deefff
+ 3 g gg ghh ghhiii
+ 4 j jj jkk jkklll
+ 5 m mm mnn mnnooo
+ 6 x ^aa$ x
+ 7 (a)(b) abbaa
+ 8 axx [ab]xx
+ 9 หม่x อมx
+ a อมx หม่x
+ b ちカヨは
+ c x ¬€x
+ d 天使x
+ e y
+ f z
+ g a啷bb
+ h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐẔ
+ i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑẕ
+ j 0123❤x
+ k combinations]])
+
+ execute('set encoding=utf-8 termencoding=latin1')
+ execute('set re=' .. regexpengine)
+
+ -- Lines 1-8. Exercise regexp search with various magic settings. On each
+ -- line the character on which the cursor is expected to land is deleted.
+ feed('/^1<cr>')
+ feed([[/a*b\{2}c\+/e<cr>x]])
+ feed([[/\Md\*e\{2}f\+/e<cr>x]])
+ execute('set nomagic')
+ feed([[/g\*h\{2}i\+/e<cr>x]])
+ feed([[/\mj*k\{2}l\+/e<cr>x]])
+ feed([[/\vm*n{2}o+/e<cr>x]])
+ feed([[/\V^aa$<cr>x]])
+ execute('set magic')
+ feed([[/\v(a)(b)\2\1\1/e<cr>x]])
+ feed([[/\V[ab]\(\[xy]\)\1<cr>x]])
+
+ -- Line 9. Search for multi-byte character without combining character.
+ feed('/ม<cr>x')
+
+ -- Line a. Search for multi-byte character with combining character.
+ feed('/ม่<cr>x')
+
+ -- Line b. Find word by change of word class.
+ -- (The "<" character in this test step seemed to confuse our "feed" test
+ -- helper, which is why we've resorted to "execute" here.)
+ execute([[/ち\<カヨ\>は]])
+ feed('x')
+
+ -- Lines c-i. Test \%u, [\u], and friends.
+ feed([[/\%u20ac<cr>x]])
+ feed([[/[\u4f7f\u5929]\+<cr>x]])
+ feed([[/\%U12345678<cr>x]])
+ feed([[/[\U1234abcd\u1234\uabcd]<cr>x]])
+ feed([[/\%d21879b<cr>x]])
+ feed('/ [[=A=]]* [[=B=]]* [[=C=]]* [[=D=]]* [[=E=]]* [[=F=]]* ' ..
+ '[[=G=]]* [[=H=]]* [[=I=]]* [[=J=]]* [[=K=]]* [[=L=]]* [[=M=]]* ' ..
+ '[[=N=]]* [[=O=]]* [[=P=]]* [[=Q=]]* [[=R=]]* [[=S=]]* [[=T=]]* ' ..
+ '[[=U=]]* [[=V=]]* [[=W=]]* [[=X=]]* [[=Y=]]* [[=Z=]]*/e<cr>x')
+ feed('/ [[=a=]]* [[=b=]]* [[=c=]]* [[=d=]]* [[=e=]]* [[=f=]]* ' ..
+ '[[=g=]]* [[=h=]]* [[=i=]]* [[=j=]]* [[=k=]]* [[=l=]]* [[=m=]]* ' ..
+ '[[=n=]]* [[=o=]]* [[=p=]]* [[=q=]]* [[=r=]]* [[=s=]]* [[=t=]]* ' ..
+ '[[=u=]]* [[=v=]]* [[=w=]]* [[=x=]]* [[=y=]]* [[=z=]]*/e<cr>x')
+
+ -- Line j. Test backwards search from a multi-byte character.
+ feed('/x<cr>x')
+ feed('?.<cr>x')
+
+ -- Line k. Test substitution with combining characters by executing register
+ -- contents.
+ execute([[let @w=':%s#comb[i]nations#œ̄ṣ́m̥̄ᾱ̆́#g']])
+ execute('@w')
+
+ -- Additional tests. Test matchstr() with multi-byte characters.
+ feed('G')
+ execute([[put =matchstr(\"אבגד\", \".\", 0, 2)]]) -- ב
+ execute([[put =matchstr(\"אבגד\", \"..\", 0, 2)]]) -- בג
+ execute([[put =matchstr(\"אבגד\", \".\", 0, 0)]]) -- א
+ execute([[put =matchstr(\"אבגד\", \".\", 4, -1)]]) -- ג
+
+ -- Test that a search with "/e" offset wraps around at the end of the buffer.
+ execute('new')
+ execute([[$put =['dog(a', 'cat('] ]])
+ feed('/(/e+<cr>')
+ feed('"ayn')
+ execute('bd!')
+ execute([[$put ='']])
+ feed('G"ap')
+
+ -- Assert buffer contents.
+ expect([[
+ 1 a aa abb abbcc
+ 2 d dd dee deeff
+ 3 g gg ghh ghhii
+ 4 j jj jkk jkkll
+ 5 m mm mnn mnnoo
+ 6 x aa$ x
+ 7 (a)(b) abba
+ 8 axx ab]xx
+ 9 หม่x อx
+ a อมx หx
+ b カヨは
+ c x ¬x
+ d 使x
+ e y
+ f z
+ g abb
+ h AÀÁÂÃÄÅĀĂĄǍǞǠẢ BḂḆ CÇĆĈĊČ DĎĐḊḎḐ EÈÉÊËĒĔĖĘĚẺẼ FḞ GĜĞĠĢǤǦǴḠ HĤĦḢḦḨ IÌÍÎÏĨĪĬĮİǏỈ JĴ KĶǨḰḴ LĹĻĽĿŁḺ MḾṀ NÑŃŅŇṄṈ OÒÓÔÕÖØŌŎŐƠǑǪǬỎ PṔṖ Q RŔŖŘṘṞ SŚŜŞŠṠ TŢŤŦṪṮ UÙÚÛÜŨŪŬŮŰŲƯǓỦ VṼ WŴẀẂẄẆ XẊẌ YÝŶŸẎỲỶỸ ZŹŻŽƵẐ
+ i aàáâãäåāăąǎǟǡả bḃḇ cçćĉċč dďđḋḏḑ eèéêëēĕėęěẻẽ fḟ gĝğġģǥǧǵḡ hĥħḣḧḩẖ iìíîïĩīĭįǐỉ jĵǰ kķǩḱḵ lĺļľŀłḻ mḿṁ nñńņňʼnṅṉ oòóôõöøōŏőơǒǫǭỏ pṕṗ q rŕŗřṙṟ sśŝşšṡ tţťŧṫṯẗ uùúûüũūŭůűųưǔủ vṽ wŵẁẃẅẇẘ xẋẍ yýÿŷẏẙỳỷỹ zźżžƶẑ
+ j 012❤
+ k œ̄ṣ́m̥̄ᾱ̆́
+ ב
+ בג
+ א
+ ג
+ a
+ cat(]])
+end
+
+describe('multi-byte regexp search with magic settings', function()
+ before_each(clear)
+
+ it('is working with regexpengine=1', function()
+ -- The old test44.
+ run_test_with_regexpengine(1)
+ end)
+
+ it('is working with regexpengine=2', function()
+ -- The old test99.
+ run_test_with_regexpengine(2)
+ end)
+end)
diff --git a/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua b/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua
new file mode 100644
index 0000000000..e0cc39dc40
--- /dev/null
+++ b/test/functional/legacy/092_mksession_cursor_cols_utf8_spec.lua
@@ -0,0 +1,98 @@
+-- Tests if :mksession saves cursor columns correctly in presence of tab and
+-- multibyte characters when fileencoding=utf-8.
+--
+-- Same as legacy test 93 but using UTF-8 file encoding.
+
+local helpers = require('test.functional.helpers')
+local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
+
+describe('store cursor position in session file in UTF-8', function()
+ setup(clear)
+
+ teardown(function()
+ os.remove('test.in')
+ os.remove('test.out')
+ end)
+
+ it('is working', function()
+ insert([[
+ start:
+ no multibyte chAracter
+ one leaDing tab
+ four leadinG spaces
+ two consecutive tabs
+ two tabs in one line
+ one … multibyteCharacter
+ a “b” two multiByte characters
+ “c”1€ three mulTibyte characters]])
+ -- This test requires the buffer to correspond to a file on disk, here named
+ -- "test.in", because otherwise :mksession won't write out the cursor column
+ -- info needed for verification.
+ execute('write! test.in')
+
+ execute('set sessionoptions=buffers splitbelow fileencoding=utf-8')
+
+ -- Move the cursor through the buffer lines and position it with "|". Using
+ -- :split after every normal mode command is a trick to have multiple
+ -- cursors on the screen that can all be stored in the session file.
+ execute('/^start:')
+ execute('vsplit')
+ feed('j16|:split<cr>')
+ feed('j16|:split<cr>')
+ feed('j16|:split<cr>')
+ feed('j8|:split<cr>')
+ feed('j8|:split<cr>')
+ feed('j16|:split<cr>')
+ feed('j16|:split<cr>')
+ feed('j16|')
+
+ -- Again move the cursor through the buffer and position it with "|". This
+ -- time also perform a horizontal scroll at every step.
+ execute('wincmd l')
+ execute('/^start:')
+ execute('set nowrap')
+ feed('j16|3zl:split<cr>')
+ feed('j016|3zl:split<cr>')
+ feed('j016|3zl:split<cr>')
+ feed('j08|3zl:split<cr>')
+ feed('j08|3zl:split<cr>')
+ feed('j016|3zl:split<cr>')
+ feed('j016|3zl:split<cr>')
+ feed('j016|3zl:split<cr>')
+
+ -- Create the session file, read it back in, and prepare for verification.
+ execute('mksession! test.out')
+ execute('new test.out')
+ execute([[v/\(^ *normal! 0\|^ *exe 'normal!\)/d]])
+
+ -- Assert buffer contents.
+ expect([[
+ normal! 016|
+ normal! 016|
+ normal! 016|
+ normal! 08|
+ normal! 08|
+ normal! 016|
+ normal! 016|
+ normal! 016|
+ exe 'normal! ' . s:c . '|zs' . 16 . '|'
+ normal! 016|
+ exe 'normal! ' . s:c . '|zs' . 16 . '|'
+ normal! 016|
+ exe 'normal! ' . s:c . '|zs' . 16 . '|'
+ normal! 016|
+ exe 'normal! ' . s:c . '|zs' . 8 . '|'
+ normal! 08|
+ exe 'normal! ' . s:c . '|zs' . 8 . '|'
+ normal! 08|
+ exe 'normal! ' . s:c . '|zs' . 16 . '|'
+ normal! 016|
+ exe 'normal! ' . s:c . '|zs' . 16 . '|'
+ normal! 016|
+ exe 'normal! ' . s:c . '|zs' . 16 . '|'
+ normal! 016|
+ exe 'normal! ' . s:c . '|zs' . 16 . '|'
+ normal! 016|]])
+ end)
+end)
diff --git a/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua b/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua
new file mode 100644
index 0000000000..659e716721
--- /dev/null
+++ b/test/functional/legacy/093_mksession_cursor_cols_latin1_spec.lua
@@ -0,0 +1,95 @@
+-- Tests if :mksession saves cursor columns correctly in presence of tab and
+-- multibyte characters when fileencoding=latin1.
+--
+-- Same as legacy test 92 but using Latin-1 file encoding.
+
+local helpers = require('test.functional.helpers')
+local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
+
+describe('store cursor position in session file in Latin-1', function()
+ setup(clear)
+
+ teardown(function()
+ os.remove('test.in')
+ os.remove('test.out')
+ end)
+
+ it('is working', function()
+ insert([[
+ start:
+ no multibyte chAracter
+ one leaDing tab
+ four leadinG spaces
+ two consecutive tabs
+ two tabs in one line
+ one multibyteCharacter
+ a two multiByte characters
+ A three mulTibyte characters]])
+ -- Must write buffer to disk for :mksession. See the comments in
+ -- "092_mksession_cursor_cols_utf8_spec.lua".
+ execute('write! test.in')
+
+ execute('set sessionoptions=buffers splitbelow fileencoding=latin1')
+
+ -- Move the cursor through the buffer lines and position it with "|".
+ execute('/^start:')
+ execute('vsplit')
+ feed('j16|:split<cr>')
+ feed('j16|:split<cr>')
+ feed('j16|:split<cr>')
+ feed('j8|:split<cr>')
+ feed('j8|:split<cr>')
+ feed('j16|:split<cr>')
+ feed('j16|:split<cr>')
+ feed('j16|')
+
+ -- Again move the cursor through the buffer and position it with "|". This
+ -- time also perform a horizontal scroll at every step.
+ execute('wincmd l')
+ execute('/^start:')
+ execute('set nowrap')
+ feed('j16|3zl:split<cr>')
+ feed('j016|3zl:split<cr>')
+ feed('j016|3zl:split<cr>')
+ feed('j08|3zl:split<cr>')
+ feed('j08|3zl:split<cr>')
+ feed('j016|3zl:split<cr>')
+ feed('j016|3zl:split<cr>')
+ feed('j016|3zl:split<cr>')
+
+ -- Create the session file, read it back in, and prepare for verification.
+ execute('mksession! test.out')
+ execute('new test.out')
+ execute([[v/\(^ *normal! 0\|^ *exe 'normal!\)/d]])
+
+ -- Assert buffer contents.
+ expect([[
+ normal! 016|
+ normal! 016|
+ normal! 016|
+ normal! 08|
+ normal! 08|
+ normal! 016|
+ normal! 016|
+ normal! 016|
+ exe 'normal! ' . s:c . '|zs' . 16 . '|'
+ normal! 016|
+ exe 'normal! ' . s:c . '|zs' . 16 . '|'
+ normal! 016|
+ exe 'normal! ' . s:c . '|zs' . 16 . '|'
+ normal! 016|
+ exe 'normal! ' . s:c . '|zs' . 8 . '|'
+ normal! 08|
+ exe 'normal! ' . s:c . '|zs' . 8 . '|'
+ normal! 08|
+ exe 'normal! ' . s:c . '|zs' . 16 . '|'
+ normal! 016|
+ exe 'normal! ' . s:c . '|zs' . 16 . '|'
+ normal! 016|
+ exe 'normal! ' . s:c . '|zs' . 16 . '|'
+ normal! 016|
+ exe 'normal! ' . s:c . '|zs' . 16 . '|'
+ normal! 016|]])
+ end)
+end)