eval: Move remaining get_tv_string* functions to eval/typval.c

This commit is contained in:
ZyX
2016-09-04 02:25:24 +03:00
parent 50ebd1dff5
commit c8e63a8db8
26 changed files with 1244 additions and 1055 deletions

View File

@@ -20,15 +20,13 @@
#define BS '\010' #define BS '\010'
#define TAB '\011' #define TAB '\011'
#define NL '\012' #define NL '\012'
#define NL_STR (char_u *)"\012" #define NL_STR "\012"
#define FF '\014' #define FF '\014'
#define CAR '\015' /* CR is used by Mac OS X */ #define CAR '\015' /* CR is used by Mac OS X */
#define ESC '\033' #define ESC '\033'
#define ESC_STR (char_u *)"\033" #define ESC_STR "\033"
#define ESC_STR_nc "\033"
#define DEL 0x7f #define DEL 0x7f
#define DEL_STR (char_u *)"\177" #define CSI 0x9b // Control Sequence Introducer
#define CSI 0x9b /* Control Sequence Introducer */
#define CSI_STR "\233" #define CSI_STR "\233"
#define DCS 0x90 /* Device Control String */ #define DCS 0x90 /* Device Control String */
#define STERM 0x9c /* String Terminator */ #define STERM 0x9c /* String Terminator */

View File

@@ -90,7 +90,6 @@ int buf_init_chartab(buf_T *buf, int global)
{ {
int c; int c;
int c2; int c2;
char_u *p;
int i; int i;
bool tilde; bool tilde;
bool do_isalpha; bool do_isalpha;
@@ -144,7 +143,8 @@ int buf_init_chartab(buf_T *buf, int global)
// Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint' // Walk through the 'isident', 'iskeyword', 'isfname' and 'isprint'
// options Each option is a list of characters, character numbers or // options Each option is a list of characters, character numbers or
// ranges, separated by commas, e.g.: "200-210,x,#-178,-" // ranges, separated by commas, e.g.: "200-210,x,#-178,-"
for (i = global ? 0 : 3; i <= 3; ++i) { for (i = global ? 0 : 3; i <= 3; i++) {
const char_u *p;
if (i == 0) { if (i == 0) {
// first round: 'isident' // first round: 'isident'
p = p_isi; p = p_isi;
@@ -169,7 +169,7 @@ int buf_init_chartab(buf_T *buf, int global)
} }
if (ascii_isdigit(*p)) { if (ascii_isdigit(*p)) {
c = getdigits_int(&p); c = getdigits_int((char_u **)&p);
} else { } else {
c = mb_ptr2char_adv(&p); c = mb_ptr2char_adv(&p);
} }
@@ -179,7 +179,7 @@ int buf_init_chartab(buf_T *buf, int global)
++p; ++p;
if (ascii_isdigit(*p)) { if (ascii_isdigit(*p)) {
c2 = getdigits_int(&p); c2 = getdigits_int((char_u **)&p);
} else { } else {
c2 = mb_ptr2char_adv(&p); c2 = mb_ptr2char_adv(&p);
} }

View File

@@ -1423,7 +1423,7 @@ static void ins_ctrl_v(void)
edit_putchar('^', TRUE); edit_putchar('^', TRUE);
did_putchar = TRUE; did_putchar = TRUE;
} }
AppendToRedobuff((char_u *)CTRL_V_STR); /* CTRL-V */ AppendToRedobuff(CTRL_V_STR);
add_to_showcmd_c(Ctrl_V); add_to_showcmd_c(Ctrl_V);
@@ -1977,7 +1977,6 @@ static bool ins_compl_accept_char(int c)
*/ */
int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int dir, int flags) int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int dir, int flags)
{ {
char_u *p;
int i, c; int i, c;
int actual_len; /* Take multi-byte characters */ int actual_len; /* Take multi-byte characters */
int actual_compl_length; /* into account. */ int actual_compl_length; /* into account. */
@@ -1987,11 +1986,11 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int
int was_letter = FALSE; int was_letter = FALSE;
if (p_ic && curbuf->b_p_inf && len > 0) { if (p_ic && curbuf->b_p_inf && len > 0) {
/* Infer case of completed part. */ // Infer case of completed part.
/* Find actual length of completion. */ // Find actual length of completion.
if (has_mbyte) { if (has_mbyte) {
p = str; const char_u *p = str;
actual_len = 0; actual_len = 0;
while (*p != NUL) { while (*p != NUL) {
mb_ptr_adv(p); mb_ptr_adv(p);
@@ -2002,7 +2001,7 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int
/* Find actual length of original text. */ /* Find actual length of original text. */
if (has_mbyte) { if (has_mbyte) {
p = compl_orig_text; const char_u *p = compl_orig_text;
actual_compl_length = 0; actual_compl_length = 0;
while (*p != NUL) { while (*p != NUL) {
mb_ptr_adv(p); mb_ptr_adv(p);
@@ -2018,79 +2017,95 @@ int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int
/* Allocate wide character array for the completion and fill it. */ /* Allocate wide character array for the completion and fill it. */
wca = xmalloc(actual_len * sizeof(*wca)); wca = xmalloc(actual_len * sizeof(*wca));
p = str; {
for (i = 0; i < actual_len; ++i) const char_u *p = str;
if (has_mbyte) for (i = 0; i < actual_len; i++) {
if (has_mbyte) {
wca[i] = mb_ptr2char_adv(&p); wca[i] = mb_ptr2char_adv(&p);
else } else {
wca[i] = *(p++); wca[i] = *(p++);
}
}
}
/* Rule 1: Were any chars converted to lower? */ // Rule 1: Were any chars converted to lower?
p = compl_orig_text; {
for (i = 0; i < min_len; ++i) { const char_u *p = compl_orig_text;
if (has_mbyte) for (i = 0; i < min_len; i++) {
if (has_mbyte) {
c = mb_ptr2char_adv(&p); c = mb_ptr2char_adv(&p);
else } else {
c = *(p++); c = *(p++);
}
if (vim_islower(c)) { if (vim_islower(c)) {
has_lower = TRUE; has_lower = true;
if (vim_isupper(wca[i])) { if (vim_isupper(wca[i])) {
/* Rule 1 is satisfied. */ // Rule 1 is satisfied.
for (i = actual_compl_length; i < actual_len; ++i) for (i = actual_compl_length; i < actual_len; i++) {
wca[i] = vim_tolower(wca[i]); wca[i] = vim_tolower(wca[i]);
}
break; break;
} }
} }
} }
}
/* /*
* Rule 2: No lower case, 2nd consecutive letter converted to * Rule 2: No lower case, 2nd consecutive letter converted to
* upper case. * upper case.
*/ */
if (!has_lower) { if (!has_lower) {
p = compl_orig_text; const char_u *p = compl_orig_text;
for (i = 0; i < min_len; ++i) { for (i = 0; i < min_len; i++) {
if (has_mbyte) if (has_mbyte) {
c = mb_ptr2char_adv(&p); c = mb_ptr2char_adv(&p);
else } else {
c = *(p++); c = *(p++);
}
if (was_letter && vim_isupper(c) && vim_islower(wca[i])) { if (was_letter && vim_isupper(c) && vim_islower(wca[i])) {
/* Rule 2 is satisfied. */ // Rule 2 is satisfied.
for (i = actual_compl_length; i < actual_len; ++i) for (i = actual_compl_length; i < actual_len; i++) {
wca[i] = vim_toupper(wca[i]); wca[i] = vim_toupper(wca[i]);
}
break; break;
} }
was_letter = vim_islower(c) || vim_isupper(c); was_letter = vim_islower(c) || vim_isupper(c);
} }
} }
/* Copy the original case of the part we typed. */ // Copy the original case of the part we typed.
p = compl_orig_text; {
for (i = 0; i < min_len; ++i) { const char_u *p = compl_orig_text;
if (has_mbyte) for (i = 0; i < min_len; i++) {
if (has_mbyte) {
c = mb_ptr2char_adv(&p); c = mb_ptr2char_adv(&p);
else } else {
c = *(p++); c = *(p++);
if (vim_islower(c)) }
if (vim_islower(c)) {
wca[i] = vim_tolower(wca[i]); wca[i] = vim_tolower(wca[i]);
else if (vim_isupper(c)) } else if (vim_isupper(c)) {
wca[i] = vim_toupper(wca[i]); wca[i] = vim_toupper(wca[i]);
} }
}
}
/* // Generate encoding specific output from wide character array.
* Generate encoding specific output from wide character array. // Multi-byte characters can occupy up to five bytes more than
* Multi-byte characters can occupy up to five bytes more than // ASCII characters, and we also need one byte for NUL, so stay
* ASCII characters, and we also need one byte for NUL, so stay // six bytes away from the edge of IObuff.
* six bytes away from the edge of IObuff. {
*/ char_u *p = IObuff;
p = IObuff;
i = 0; i = 0;
while (i < actual_len && (p - IObuff + 6) < IOSIZE) while (i < actual_len && (p - IObuff + 6) < IOSIZE) {
if (has_mbyte) if (has_mbyte) {
p += (*mb_char2bytes)(wca[i++], p); p += (*mb_char2bytes)(wca[i++], p);
else } else {
*(p++) = wca[i++]; *(p++) = wca[i++];
}
}
*p = NUL; *p = NUL;
}
xfree(wca); xfree(wca);
@@ -3594,7 +3609,7 @@ int ins_compl_add_tv(typval_T *const tv, const Direction dir)
adup = (bool)tv_dict_get_number(tv->vval.v_dict, "dup"); adup = (bool)tv_dict_get_number(tv->vval.v_dict, "dup");
aempty = (bool)tv_dict_get_number(tv->vval.v_dict, "empty"); aempty = (bool)tv_dict_get_number(tv->vval.v_dict, "empty");
} else { } else {
word = (const char *)get_tv_string_chk(tv); word = (const char *)tv_get_string_chk(tv);
memset(cptext, 0, sizeof(cptext)); memset(cptext, 0, sizeof(cptext));
} }
if (word == NULL || (!aempty && *word == NUL)) { if (word == NULL || (!aempty && *word == NUL)) {
@@ -5785,16 +5800,17 @@ comp_textwidth (
*/ */
static void redo_literal(int c) static void redo_literal(int c)
{ {
char_u buf[10]; char buf[10];
/* Only digits need special treatment. Translate them into a string of // Only digits need special treatment. Translate them into a string of
* three digits. */ // three digits.
if (ascii_isdigit(c)) { if (ascii_isdigit(c)) {
vim_snprintf((char *)buf, sizeof(buf), "%03d", c); vim_snprintf(buf, sizeof(buf), "%03d", c);
AppendToRedobuff(buf); AppendToRedobuff(buf);
} else } else {
AppendCharToRedobuff(c); AppendCharToRedobuff(c);
} }
}
// start_arrow() is called when an arrow key is used in insert mode. // start_arrow() is called when an arrow key is used in insert mode.
// For undo/redo it resembles hitting the <ESC> key. // For undo/redo it resembles hitting the <ESC> key.
@@ -5822,8 +5838,8 @@ static void start_arrow_common(pos_T *end_insert_pos, bool end_change)
{ {
if (!arrow_used && end_change) { // something has been inserted if (!arrow_used && end_change) { // something has been inserted
AppendToRedobuff(ESC_STR); AppendToRedobuff(ESC_STR);
stop_insert(end_insert_pos, FALSE, FALSE); stop_insert(end_insert_pos, false, false);
arrow_used = TRUE; /* this means we stopped the current insert */ arrow_used = true; // This means we stopped the current insert.
} }
check_spell_redraw(); check_spell_redraw();
} }
@@ -5880,7 +5896,7 @@ int stop_arrow(void)
vr_lines_changed = 1; vr_lines_changed = 1;
} }
ResetRedobuff(); ResetRedobuff();
AppendToRedobuff((char_u *)"1i"); /* pretend we start an insertion */ AppendToRedobuff("1i"); // Pretend we start an insertion.
new_insert_skip = 2; new_insert_skip = 2;
} else if (ins_need_undo) { } else if (ins_need_undo) {
if (u_save_cursor() == OK) if (u_save_cursor() == OK)
@@ -6345,12 +6361,13 @@ stuff_inserted (
} }
do { do {
stuffReadbuff(ptr); stuffReadbuff((const char *)ptr);
/* a trailing "0" is inserted as "<C-V>048", "^" as "<C-V>^" */ // A trailing "0" is inserted as "<C-V>048", "^" as "<C-V>^".
if (last) if (last) {
stuffReadbuff((char_u *)(last == '0' stuffReadbuff((last == '0'
? "\026\060\064\070" ? "\026\060\064\070"
: "\026^")); : "\026^"));
}
} while (--count > 0); } while (--count > 0);
if (last) if (last)
@@ -7143,13 +7160,12 @@ static bool ins_esc(long *count, int cmdchar, bool nomove)
disabled_redraw = false; disabled_redraw = false;
} }
if (!arrow_used) { if (!arrow_used) {
/* // Don't append the ESC for "r<CR>" and "grx".
* Don't append the ESC for "r<CR>" and "grx". // When 'insertmode' is set only CTRL-L stops Insert mode. Needed for
* When 'insertmode' is set only CTRL-L stops Insert mode. Needed for // when "count" is non-zero.
* when "count" is non-zero. if (cmdchar != 'r' && cmdchar != 'v') {
*/ AppendToRedobuff(p_im ? "\014" : ESC_STR);
if (cmdchar != 'r' && cmdchar != 'v') }
AppendToRedobuff(p_im ? (char_u *)"\014" : ESC_STR);
/* /*
* Repeating insert may take a long time. Check for * Repeating insert may take a long time. Check for
@@ -7303,7 +7319,8 @@ static bool ins_start_select(int c)
// Execute the key in (insert) Select mode. // Execute the key in (insert) Select mode.
stuffcharReadbuff(Ctrl_O); stuffcharReadbuff(Ctrl_O);
if (mod_mask) { if (mod_mask) {
char_u buf[4] = { K_SPECIAL, KS_MODIFIER, mod_mask, NUL }; const char buf[] = { (char)K_SPECIAL, (char)KS_MODIFIER,
(char)(uint8_t)mod_mask, NUL };
stuffReadbuff(buf); stuffReadbuff(buf);
} }
stuffcharReadbuff(c); stuffcharReadbuff(c);
@@ -8111,11 +8128,11 @@ static bool ins_tab(void)
return true; return true;
} }
did_ai = FALSE; did_ai = false;
did_si = FALSE; did_si = false;
can_si = FALSE; can_si = false;
can_si_back = FALSE; can_si_back = false;
AppendToRedobuff((char_u *)"\t"); AppendToRedobuff("\t");
if (p_sta && ind) { // insert tab in indent, use "shiftwidth" if (p_sta && ind) { // insert tab in indent, use "shiftwidth"
temp = get_sw_value(curbuf); temp = get_sw_value(curbuf);
@@ -8380,8 +8397,8 @@ static int ins_digraph(void)
edit_unputchar(); edit_unputchar();
} }
if (cc != ESC) { if (cc != ESC) {
AppendToRedobuff((char_u *)CTRL_V_STR); AppendToRedobuff(CTRL_V_STR);
c = getdigraph(c, cc, TRUE); c = getdigraph(c, cc, true);
clear_showcmd(); clear_showcmd();
return c; return c;
} }
@@ -8443,12 +8460,13 @@ static int ins_ctrl_ey(int tc)
if (c != NUL) { if (c != NUL) {
long tw_save; long tw_save;
/* The character must be taken literally, insert like it // The character must be taken literally, insert like it
* was typed after a CTRL-V, and pretend 'textwidth' // was typed after a CTRL-V, and pretend 'textwidth'
* wasn't set. Digits, 'o' and 'x' are special after a // wasn't set. Digits, 'o' and 'x' are special after a
* CTRL-V, don't use it for these. */ // CTRL-V, don't use it for these.
if (c < 256 && !isalnum(c)) if (c < 256 && !isalnum(c)) {
AppendToRedobuff((char_u *)CTRL_V_STR); /* CTRL-V */ AppendToRedobuff(CTRL_V_STR);
}
tw_save = curbuf->b_p_tw; tw_save = curbuf->b_p_tw;
curbuf->b_p_tw = -1; curbuf->b_p_tw = -1;
insert_special(c, TRUE, FALSE); insert_special(c, TRUE, FALSE);

File diff suppressed because it is too large Load Diff

View File

@@ -796,7 +796,7 @@ static bool tv_dict_watcher_matches(DictWatcher *watcher, const char *const key)
// of the string means it should match everything up to the '*' instead of the // of the string means it should match everything up to the '*' instead of the
// whole string. // whole string.
const size_t len = strlen(watcher->key_pattern); const size_t len = strlen(watcher->key_pattern);
if (watcher->key_pattern[len - 1] == '*') { if (len && watcher->key_pattern[len - 1] == '*') {
return strncmp(key, watcher->key_pattern, len - 1) == 0; return strncmp(key, watcher->key_pattern, len - 1) == 0;
} else { } else {
return strcmp(key, watcher->key_pattern) == 0; return strcmp(key, watcher->key_pattern) == 0;
@@ -2020,7 +2020,7 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic,
/// ///
/// @return true if everything is OK, false otherwise. /// @return true if everything is OK, false otherwise.
bool tv_check_str_or_nr(const typval_T *const tv) bool tv_check_str_or_nr(const typval_T *const tv)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{ {
switch (tv->v_type) { switch (tv->v_type) {
case VAR_NUMBER: case VAR_NUMBER:
@@ -2072,7 +2072,7 @@ static const char *const num_errors[] = {
/// Check that given value is a number or can be converted to it /// Check that given value is a number or can be converted to it
/// ///
/// Error messages are compatible with tv_get_number() previously used for /// Error messages are compatible with tv_get_number_chk() previously used for
/// the same purpose. /// the same purpose.
/// ///
/// @param[in] tv Value to check. /// @param[in] tv Value to check.
@@ -2101,6 +2101,50 @@ bool tv_check_num(const typval_T *const tv)
return false; return false;
} }
#define FUNC_ERROR "E729: using Funcref as a String"
static const char *const str_errors[] = {
[VAR_PARTIAL]=N_(FUNC_ERROR),
[VAR_FUNC]=N_(FUNC_ERROR),
[VAR_LIST]=N_("E730: using List as a String"),
[VAR_DICT]=N_("E731: using Dictionary as a String"),
[VAR_FLOAT]=((const char *)e_float_as_string),
[VAR_UNKNOWN]=N_("E908: using an invalid value as a String"),
};
#undef FUNC_ERROR
/// Check that given value is a string or can be converted to it
///
/// Error messages are compatible with tv_get_string_chk() previously used for
/// the same purpose.
///
/// @param[in] tv Value to check.
///
/// @return true if everything is OK, false otherwise.
bool tv_check_str(const typval_T *const tv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (tv->v_type) {
case VAR_NUMBER:
case VAR_SPECIAL:
case VAR_STRING: {
return true;
}
case VAR_PARTIAL:
case VAR_FUNC:
case VAR_LIST:
case VAR_DICT:
case VAR_FLOAT:
case VAR_UNKNOWN: {
EMSG(_(str_errors[tv->v_type]));
return false;
}
}
assert(false);
return false;
}
//{{{2 Get //{{{2 Get
/// Get the number value of a VimL object /// Get the number value of a VimL object
@@ -2245,6 +2289,48 @@ float_T tv_get_float(const typval_T *const tv)
return 0; return 0;
} }
/// Get the string value of a VimL object
///
/// @param[in] tv Object to get value of.
/// @param buf Buffer used to hold numbers and special variables converted to
/// string. When function encounters one of these stringified value
/// will be written to buf and buf will be returned.
///
/// Buffer must have NUMBUFLEN size.
///
/// @return Object value if it is VAR_STRING object, number converted to
/// a string for VAR_NUMBER, v: variable name for VAR_SPECIAL or NULL.
const char *tv_get_string_buf_chk(const typval_T *const tv, char *const buf)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
switch (tv->v_type) {
case VAR_NUMBER: {
snprintf(buf, NUMBUFLEN, "%" PRIdVARNUMBER, tv->vval.v_number);
return buf;
}
case VAR_STRING: {
if (tv->vval.v_string != NULL) {
return (const char *)tv->vval.v_string;
}
return "";
}
case VAR_SPECIAL: {
STRCPY(buf, encode_special_var_names[tv->vval.v_special]);
return buf;
}
case VAR_PARTIAL:
case VAR_FUNC:
case VAR_LIST:
case VAR_DICT:
case VAR_FLOAT:
case VAR_UNKNOWN: {
EMSG(_(str_errors[tv->v_type]));
return false;
}
}
return NULL;
}
/// Get the string value of a VimL object /// Get the string value of a VimL object
/// ///
/// @warning For number and special values it uses a single, static buffer. It /// @warning For number and special values it uses a single, static buffer. It
@@ -2252,7 +2338,26 @@ float_T tv_get_float(const typval_T *const tv)
/// tv_get_string_buf() if you need to use tv_get_string() output after /// tv_get_string_buf() if you need to use tv_get_string() output after
/// calling it again. /// calling it again.
/// ///
/// @note get_tv_string_chk() and get_tv_string_buf_chk() are similar, but /// @param[in] tv Object to get value of.
///
/// @return Object value if it is VAR_STRING object, number converted to
/// a string for VAR_NUMBER, v: variable name for VAR_SPECIAL or NULL.
const char *tv_get_string_chk(const typval_T *const tv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
static char mybuf[NUMBUFLEN];
return tv_get_string_buf_chk(tv, mybuf);
}
/// Get the string value of a VimL object
///
/// @warning For number and special values it uses a single, static buffer. It
/// may be used only once, next call to get_tv_string may reuse it. Use
/// tv_get_string_buf() if you need to use tv_get_string() output after
/// calling it again.
///
/// @note tv_get_string_chk() and tv_get_string_buf_chk() are similar, but
/// return NULL on error. /// return NULL on error.
/// ///
/// @param[in] tv Object to get value of. /// @param[in] tv Object to get value of.
@@ -2269,7 +2374,7 @@ const char *tv_get_string(const typval_T *const tv)
/// Get the string value of a VimL object /// Get the string value of a VimL object
/// ///
/// @note get_tv_string_chk() and get_tv_string_buf_chk() are similar, but /// @note tv_get_string_chk() and tv_get_string_buf_chk() are similar, but
/// return NULL on error. /// return NULL on error.
/// ///
/// @param[in] tv Object to get value of. /// @param[in] tv Object to get value of.
@@ -2285,8 +2390,7 @@ const char *tv_get_string(const typval_T *const tv)
const char *tv_get_string_buf(const typval_T *const tv, char *const buf) const char *tv_get_string_buf(const typval_T *const tv, char *const buf)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
{ {
const char *const res = (const char *)get_tv_string_buf_chk( const char *const res = (const char *)tv_get_string_buf_chk(tv, buf);
(typval_T *)tv, (char_u *)buf);
return res != NULL ? res : ""; return res != NULL ? res : "";
} }

View File

@@ -27,6 +27,7 @@ typedef double float_T;
/// Mimimal possible value of varnumber_T variable /// Mimimal possible value of varnumber_T variable
#define VARNUMBER_MIN INT_MIN #define VARNUMBER_MIN INT_MIN
#define PRIdVARNUMBER "d"
/// %d printf format specifier for varnumber_T /// %d printf format specifier for varnumber_T
#define PRIdVARNUMBER "d" #define PRIdVARNUMBER "d"

View File

@@ -1008,8 +1008,8 @@ void do_bang(int addr_count, exarg_T *eap, int forceit, int do_in, int do_out)
AppendToRedobuffLit(cmd, -1); AppendToRedobuffLit(cmd, -1);
xfree(cmd); xfree(cmd);
AppendToRedobuff((char_u *)"\n"); AppendToRedobuff("\n");
bangredo = FALSE; bangredo = false;
} }
/* /*
* Add quotes around the command, for shells that need them. * Add quotes around the command, for shells that need them.

View File

@@ -6794,7 +6794,7 @@ do_exedit (
int ms = msg_scroll; int ms = msg_scroll;
if (eap->nextcmd != NULL) { if (eap->nextcmd != NULL) {
stuffReadbuff(eap->nextcmd); stuffReadbuff((const char *)eap->nextcmd);
eap->nextcmd = NULL; eap->nextcmd = NULL;
} }

View File

@@ -2554,19 +2554,22 @@ void cmdline_paste_str(char_u *s, int literally)
else else
while (*s != NUL) { while (*s != NUL) {
cv = *s; cv = *s;
if (cv == Ctrl_V && s[1]) if (cv == Ctrl_V && s[1]) {
++s; s++;
if (has_mbyte) }
c = mb_cptr2char_adv(&s); if (has_mbyte) {
else c = mb_cptr2char_adv((const char_u **)&s);
} else {
c = *s++; c = *s++;
}
if (cv == Ctrl_V || c == ESC || c == Ctrl_C if (cv == Ctrl_V || c == ESC || c == Ctrl_C
|| c == CAR || c == NL || c == Ctrl_L || c == CAR || c == NL || c == Ctrl_L
#ifdef UNIX #ifdef UNIX
|| c == intr_char || c == intr_char
#endif #endif
|| (c == Ctrl_BSL && *s == Ctrl_N)) || (c == Ctrl_BSL && *s == Ctrl_N)) {
stuffcharReadbuff(Ctrl_V); stuffcharReadbuff(Ctrl_V);
}
stuffcharReadbuff(c); stuffcharReadbuff(c);
} }
} }
@@ -4636,7 +4639,7 @@ in_history (
/// ///
/// @return Any value from HistoryType enum, including HIST_INVALID. May not /// @return Any value from HistoryType enum, including HIST_INVALID. May not
/// return HIST_DEFAULT unless return_default is true. /// return HIST_DEFAULT unless return_default is true.
HistoryType get_histtype(const char_u *const name, const size_t len, HistoryType get_histtype(const char *const name, const size_t len,
const bool return_default) const bool return_default)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{ {
@@ -5029,7 +5032,7 @@ void ex_history(exarg_T *eap)
while (ASCII_ISALPHA(*end) while (ASCII_ISALPHA(*end)
|| vim_strchr((char_u *)":=@>/?", *end) != NULL) || vim_strchr((char_u *)":=@>/?", *end) != NULL)
end++; end++;
histype1 = get_histtype(arg, end - arg, false); histype1 = get_histtype((const char *)arg, end - arg, false);
if (histype1 == HIST_INVALID) { if (histype1 == HIST_INVALID) {
if (STRNICMP(arg, "all", end - arg) == 0) { if (STRNICMP(arg, "all", end - arg) == 0) {
histype1 = 0; histype1 = 0;
@@ -5288,18 +5291,18 @@ static int ex_window(void)
cmdwin_result = Ctrl_C; cmdwin_result = Ctrl_C;
/* Set the new command line from the cmdline buffer. */ /* Set the new command line from the cmdline buffer. */
xfree(ccline.cmdbuff); xfree(ccline.cmdbuff);
if (cmdwin_result == K_XF1 || cmdwin_result == K_XF2) { /* :qa[!] typed */ if (cmdwin_result == K_XF1 || cmdwin_result == K_XF2) { // :qa[!] typed
char *p = (cmdwin_result == K_XF2) ? "qa" : "qa!"; const char *p = (cmdwin_result == K_XF2) ? "qa" : "qa!";
if (histtype == HIST_CMD) { if (histtype == HIST_CMD) {
/* Execute the command directly. */ // Execute the command directly.
ccline.cmdbuff = vim_strsave((char_u *)p); ccline.cmdbuff = (char_u *)xstrdup(p);
cmdwin_result = CAR; cmdwin_result = CAR;
} else { } else {
/* First need to cancel what we were doing. */ // First need to cancel what we were doing.
ccline.cmdbuff = NULL; ccline.cmdbuff = NULL;
stuffcharReadbuff(':'); stuffcharReadbuff(':');
stuffReadbuff((char_u *)p); stuffReadbuff(p);
stuffcharReadbuff(CAR); stuffcharReadbuff(CAR);
} }
} else if (cmdwin_result == K_XF2) { /* :qa typed */ } else if (cmdwin_result == K_XF2) { /* :qa typed */

View File

@@ -614,10 +614,12 @@ readfile (
return FAIL; return FAIL;
} }
#ifdef UNIX #ifdef UNIX
/* Set swap file protection bits after creating it. */ // Set swap file protection bits after creating it.
if (swap_mode > 0 && curbuf->b_ml.ml_mfp != NULL if (swap_mode > 0 && curbuf->b_ml.ml_mfp != NULL
&& curbuf->b_ml.ml_mfp->mf_fname != NULL) && curbuf->b_ml.ml_mfp->mf_fname != NULL) {
(void)os_setperm(curbuf->b_ml.ml_mfp->mf_fname, (long)swap_mode); (void)os_setperm((const char *)curbuf->b_ml.ml_mfp->mf_fname,
(long)swap_mode);
}
#endif #endif
} }
@@ -2870,9 +2872,9 @@ buf_write (
xfree(backup); xfree(backup);
backup = NULL; backup = NULL;
} else { } else {
/* set file protection same as original file, but // set file protection same as original file, but
* strip s-bit */ // strip s-bit.
(void)os_setperm(backup, perm & 0777); (void)os_setperm((const char *)backup, perm & 0777);
#ifdef UNIX #ifdef UNIX
/* /*
@@ -2883,7 +2885,8 @@ buf_write (
*/ */
if (file_info_new.stat.st_gid != file_info_old.stat.st_gid if (file_info_new.stat.st_gid != file_info_old.stat.st_gid
&& os_fchown(bfd, -1, file_info_old.stat.st_gid) != 0) { && os_fchown(bfd, -1, file_info_old.stat.st_gid) != 0) {
os_setperm(backup, (perm & 0707) | ((perm & 07) << 3)); os_setperm((const char *)backup,
(perm & 0707) | ((perm & 07) << 3));
} }
# ifdef HAVE_SELINUX # ifdef HAVE_SELINUX
mch_copy_sec(fname, backup); mch_copy_sec(fname, backup);
@@ -3037,8 +3040,8 @@ nobackup:
&& file_info_old.stat.st_uid == getuid() && file_info_old.stat.st_uid == getuid()
&& vim_strchr(p_cpo, CPO_FWRITE) == NULL) { && vim_strchr(p_cpo, CPO_FWRITE) == NULL) {
perm |= 0200; perm |= 0200;
(void)os_setperm(fname, perm); (void)os_setperm((const char *)fname, perm);
made_writable = TRUE; made_writable = true;
} }
#endif #endif
@@ -3402,8 +3405,9 @@ restore_backup:
|| file_info.stat.st_uid != file_info_old.stat.st_uid || file_info.stat.st_uid != file_info_old.stat.st_uid
|| file_info.stat.st_gid != file_info_old.stat.st_gid) { || file_info.stat.st_gid != file_info_old.stat.st_gid) {
os_fchown(fd, file_info_old.stat.st_uid, file_info_old.stat.st_gid); os_fchown(fd, file_info_old.stat.st_uid, file_info_old.stat.st_gid);
if (perm >= 0) /* set permission again, may have changed */ if (perm >= 0) { // Set permission again, may have changed.
(void)os_setperm(wfname, perm); (void)os_setperm((const char *)wfname, perm);
}
} }
buf_set_file_id(buf); buf_set_file_id(buf);
} else if (!buf->file_id_valid) { } else if (!buf->file_id_valid) {
@@ -3421,8 +3425,9 @@ restore_backup:
if (made_writable) if (made_writable)
perm &= ~0200; /* reset 'w' bit for security reasons */ perm &= ~0200; /* reset 'w' bit for security reasons */
#endif #endif
if (perm >= 0) /* set perm. of new file same as old file */ if (perm >= 0) { // Set perm. of new file same as old file.
(void)os_setperm(wfname, perm); (void)os_setperm((const char *)wfname, perm);
}
#ifdef HAVE_ACL #ifdef HAVE_ACL
/* Probably need to set the ACL before changing the user (can't set the /* Probably need to set the ACL before changing the user (can't set the
* ACL on a file the user doesn't own). */ * ACL on a file the user doesn't own). */
@@ -3628,7 +3633,7 @@ restore_backup:
close(empty_fd); close(empty_fd);
} }
if (org != NULL) { if (org != NULL) {
os_setperm((char_u *)org, os_getperm((const char *)fname) & 0777); os_setperm(org, os_getperm((const char *)fname) & 0777);
xfree(org); xfree(org);
} }
} }
@@ -4690,8 +4695,8 @@ int vim_rename(const char_u *from, const char_u *to)
errmsg = _("E210: Error reading \"%s\""); errmsg = _("E210: Error reading \"%s\"");
to = from; to = from;
} }
#ifndef UNIX /* for Unix os_open() already set the permission */ #ifndef UNIX // For Unix os_open() already set the permission.
os_setperm(to, perm); os_setperm((const char *)to, perm);
#endif #endif
#ifdef HAVE_ACL #ifdef HAVE_ACL
mch_set_acl(to, acl); mch_set_acl(to, acl);

View File

@@ -235,19 +235,18 @@ char_u *get_inserted(void)
return get_buffcont(&redobuff, FALSE); return get_buffcont(&redobuff, FALSE);
} }
/* /// Add string after the current block of the given buffer
* Add string "s" after the current block of buffer "buf". ///
* K_SPECIAL and CSI should have been escaped already. /// K_SPECIAL and CSI should have been escaped already.
*/ ///
static void /// @param[out] buf Buffer to add to.
add_buff ( /// @param[in] s String to add.
buffheader_T *buf, /// @param[in] slen String length or -1 for NUL-terminated string.
char_u *s, static void add_buff(buffheader_T *const buf, const char *const s,
ssize_t slen // length of "s" or -1 ptrdiff_t slen)
)
{ {
if (slen < 0) { if (slen < 0) {
slen = (ssize_t)STRLEN(s); slen = (ptrdiff_t)strlen(s);
} }
if (slen == 0) { // don't add empty strings if (slen == 0) { // don't add empty strings
return; return;
@@ -292,9 +291,8 @@ add_buff (
*/ */
static void add_num_buff(buffheader_T *buf, long n) static void add_num_buff(buffheader_T *buf, long n)
{ {
char_u number[32]; char number[32];
snprintf(number, sizeof(number), "%ld", n);
sprintf((char *)number, "%" PRId64, (int64_t)n);
add_buff(buf, number, -1L); add_buff(buf, number, -1L);
} }
@@ -304,27 +302,29 @@ static void add_num_buff(buffheader_T *buf, long n)
*/ */
static void add_char_buff(buffheader_T *buf, int c) static void add_char_buff(buffheader_T *buf, int c)
{ {
char_u bytes[MB_MAXBYTES + 1]; char bytes[MB_MAXBYTES + 1];
int len; int len;
int i; if (IS_SPECIAL(c)) {
char_u temp[4];
if (IS_SPECIAL(c))
len = 1; len = 1;
else } else {
len = (*mb_char2bytes)(c, bytes); len = (*mb_char2bytes)(c, (char_u *)bytes);
for (i = 0; i < len; ++i) { }
if (!IS_SPECIAL(c))
c = bytes[i];
for (int i = 0; i < len; i++) {
if (!IS_SPECIAL(c)) {
c = bytes[i];
}
char temp[4];
if (IS_SPECIAL(c) || c == K_SPECIAL || c == NUL) { if (IS_SPECIAL(c) || c == K_SPECIAL || c == NUL) {
/* translate special key code into three byte sequence */ // Translate special key code into three byte sequence.
temp[0] = K_SPECIAL; temp[0] = (char)K_SPECIAL;
temp[1] = (char_u)K_SECOND(c); temp[1] = (char)K_SECOND(c);
temp[2] = (char_u)K_THIRD(c); temp[2] = (char)K_THIRD(c);
temp[3] = NUL; temp[3] = NUL;
} else { } else {
temp[0] = (char_u)c; temp[0] = (char)c;
temp[1] = NUL; temp[1] = NUL;
} }
add_buff(buf, temp, -1L); add_buff(buf, temp, -1L);
@@ -479,16 +479,14 @@ static int save_level = 0;
void saveRedobuff(void) void saveRedobuff(void)
{ {
char_u *s;
if (save_level++ == 0) { if (save_level++ == 0) {
save_redobuff = redobuff; save_redobuff = redobuff;
redobuff.bh_first.b_next = NULL; redobuff.bh_first.b_next = NULL;
save_old_redobuff = old_redobuff; save_old_redobuff = old_redobuff;
old_redobuff.bh_first.b_next = NULL; old_redobuff.bh_first.b_next = NULL;
/* Make a copy, so that ":normal ." in a function works. */ // Make a copy, so that ":normal ." in a function works.
s = get_buffcont(&save_redobuff, FALSE); char *const s = (char *)get_buffcont(&save_redobuff, false);
if (s != NULL) { if (s != NULL) {
add_buff(&redobuff, s, -1L); add_buff(&redobuff, s, -1L);
xfree(s); xfree(s);
@@ -514,10 +512,11 @@ void restoreRedobuff(void)
* Append "s" to the redo buffer. * Append "s" to the redo buffer.
* K_SPECIAL and CSI should already have been escaped. * K_SPECIAL and CSI should already have been escaped.
*/ */
void AppendToRedobuff(char_u *s) void AppendToRedobuff(const char *s)
{ {
if (!block_redo) if (!block_redo) {
add_buff(&redobuff, s, -1L); add_buff(&redobuff, (const char *)s, -1L);
}
} }
/* /*
@@ -530,46 +529,49 @@ AppendToRedobuffLit (
int len /* length of "str" or -1 for up to the NUL */ int len /* length of "str" or -1 for up to the NUL */
) )
{ {
char_u *s = str; if (block_redo) {
int c;
char_u *start;
if (block_redo)
return; return;
}
while (len < 0 ? *s != NUL : s - str < len) { const char *s = (const char *)str;
/* Put a string of normal characters in the redo buffer (that's while (len < 0 ? *s != NUL : s - (const char *)str < len) {
* faster). */ // Put a string of normal characters in the redo buffer (that's
start = s; // faster).
while (*s >= ' ' && *s < DEL && (len < 0 || s - str < len)) const char *start = s;
++s; while (*s >= ' ' && *s < DEL && (len < 0 || s - (const char *)str < len)) {
s++;
}
/* Don't put '0' or '^' as last character, just in case a CTRL-D is // Don't put '0' or '^' as last character, just in case a CTRL-D is
* typed next. */ // typed next.
if (*s == NUL && (s[-1] == '0' || s[-1] == '^')) if (*s == NUL && (s[-1] == '0' || s[-1] == '^')) {
--s; s--;
if (s > start) }
if (s > start) {
add_buff(&redobuff, start, (long)(s - start)); add_buff(&redobuff, start, (long)(s - start));
}
if (*s == NUL || (len >= 0 && s - str >= len)) if (*s == NUL || (len >= 0 && s - (const char *)str >= len)) {
break; break;
}
/* Handle a special or multibyte character. */ // Handle a special or multibyte character.
if (has_mbyte) // Composing chars separately are handled separately.
/* Handle composing chars separately. */ const int c = (has_mbyte
c = mb_cptr2char_adv(&s); ? mb_cptr2char_adv((const char_u **)&s)
else : (uint8_t)(*s++));
c = *s++; if (c < ' ' || c == DEL || (*s == NUL && (c == '0' || c == '^'))) {
if (c < ' ' || c == DEL || (*s == NUL && (c == '0' || c == '^')))
add_char_buff(&redobuff, Ctrl_V); add_char_buff(&redobuff, Ctrl_V);
}
/* CTRL-V '0' must be inserted as CTRL-V 048 */ // CTRL-V '0' must be inserted as CTRL-V 048.
if (*s == NUL && c == '0') if (*s == NUL && c == '0') {
add_buff(&redobuff, (char_u *)"048", 3L); add_buff(&redobuff, "048", 3L);
else } else {
add_char_buff(&redobuff, c); add_char_buff(&redobuff, c);
} }
} }
}
/* /*
* Append a character to the redo buffer. * Append a character to the redo buffer.
@@ -594,19 +596,19 @@ void AppendNumberToRedobuff(long n)
* Append string "s" to the stuff buffer. * Append string "s" to the stuff buffer.
* CSI and K_SPECIAL must already have been escaped. * CSI and K_SPECIAL must already have been escaped.
*/ */
void stuffReadbuff(char_u *s) void stuffReadbuff(const char *s)
{ {
add_buff(&readbuf1, s, -1L); add_buff(&readbuf1, s, -1L);
} }
/// Append string "s" to the redo stuff buffer. /// Append string "s" to the redo stuff buffer.
/// @remark CSI and K_SPECIAL must already have been escaped. /// @remark CSI and K_SPECIAL must already have been escaped.
void stuffRedoReadbuff(char_u *s) void stuffRedoReadbuff(const char *s)
{ {
add_buff(&readbuf2, s, -1L); add_buff(&readbuf2, s, -1L);
} }
void stuffReadbuffLen(char_u *s, long len) void stuffReadbuffLen(const char *s, long len)
{ {
add_buff(&readbuf1, s, len); add_buff(&readbuf1, s, len);
} }
@@ -616,19 +618,18 @@ void stuffReadbuffLen(char_u *s, long len)
* escaping other K_SPECIAL and CSI bytes. * escaping other K_SPECIAL and CSI bytes.
* Change CR, LF and ESC into a space. * Change CR, LF and ESC into a space.
*/ */
void stuffReadbuffSpec(char_u *s) void stuffReadbuffSpec(const char *s)
{ {
int c;
while (*s != NUL) { while (*s != NUL) {
if (*s == K_SPECIAL && s[1] != NUL && s[2] != NUL) { if ((uint8_t)(*s) == K_SPECIAL && s[1] != NUL && s[2] != NUL) {
/* Insert special key literally. */ // Insert special key literally.
stuffReadbuffLen(s, 3L); stuffReadbuffLen(s, 3);
s += 3; s += 3;
} else { } else {
c = mb_ptr2char_adv(&s); int c = mb_ptr2char_adv((const char_u **)&s);
if (c == CAR || c == NL || c == ESC) if (c == CAR || c == NL || c == ESC) {
c = ' '; c = ' ';
}
stuffcharReadbuff(c); stuffcharReadbuff(c);
} }
} }
@@ -747,8 +748,8 @@ int start_redo(long count, int old_redo)
/* copy the buffer name, if present */ /* copy the buffer name, if present */
if (c == '"') { if (c == '"') {
add_buff(&readbuf2, (char_u *)"\"", 1L); add_buff(&readbuf2, "\"", 1L);
c = read_redo(FALSE, old_redo); c = read_redo(false, old_redo);
/* if a numbered buffer is used, increment the number */ /* if a numbered buffer is used, increment the number */
if (c >= '1' && c < '9') if (c >= '1' && c < '9')
@@ -1091,21 +1092,19 @@ static void gotchars(char_u *chars, size_t len)
{ {
char_u *s = chars; char_u *s = chars;
int c; int c;
char_u buf[2];
// remember how many chars were last recorded // remember how many chars were last recorded
if (Recording) { if (Recording) {
last_recorded_len += len; last_recorded_len += len;
} }
buf[1] = NUL;
while (len--) { while (len--) {
// Handle one byte at a time; no translation to be done. // Handle one byte at a time; no translation to be done.
c = *s++; c = *s++;
updatescript(c); updatescript(c);
if (Recording) { if (Recording) {
buf[0] = (char_u)c; char buf[2] = { (char)c, NUL };
add_buff(&recordbuff, buf, 1L); add_buff(&recordbuff, buf, 1L);
} }
} }

View File

@@ -1199,6 +1199,7 @@ EXTERN char_u e_dirnotf[] INIT(= N_(
"E919: Directory not found in '%s': \"%s\"")); "E919: Directory not found in '%s': \"%s\""));
EXTERN char_u e_unsupportedoption[] INIT(= N_("E519: Option not supported")); EXTERN char_u e_unsupportedoption[] INIT(= N_("E519: Option not supported"));
EXTERN char_u e_fnametoolong[] INIT(= N_("E856: Filename too long")); EXTERN char_u e_fnametoolong[] INIT(= N_("E856: Filename too long"));
EXTERN char_u e_float_as_string[] INIT(= N_("E806: using Float as a String"));
EXTERN char top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM")); EXTERN char top_bot_msg[] INIT(= N_("search hit TOP, continuing at BOTTOM"));

View File

@@ -625,7 +625,7 @@ static int utf_safe_read_char_adv(const char_u **s, size_t *n)
* Get character at **pp and advance *pp to the next character. * Get character at **pp and advance *pp to the next character.
* Note: composing characters are skipped! * Note: composing characters are skipped!
*/ */
int mb_ptr2char_adv(char_u **pp) int mb_ptr2char_adv(const char_u **const pp)
{ {
int c; int c;
@@ -638,7 +638,7 @@ int mb_ptr2char_adv(char_u **pp)
* Get character at **pp and advance *pp to the next character. * Get character at **pp and advance *pp to the next character.
* Note: composing characters are returned as separate characters. * Note: composing characters are returned as separate characters.
*/ */
int mb_cptr2char_adv(char_u **pp) int mb_cptr2char_adv(const char_u **pp)
{ {
int c; int c;

View File

@@ -1155,7 +1155,7 @@ static void normal_check_stuff_buffer(NormalState *s)
if (need_start_insertmode && goto_im() && !VIsual_active) { if (need_start_insertmode && goto_im() && !VIsual_active) {
need_start_insertmode = false; need_start_insertmode = false;
stuffReadbuff((uint8_t *)"i"); // start insert mode next stuffReadbuff("i"); // start insert mode next
// skip the fileinfo message now, because it would be shown // skip the fileinfo message now, because it would be shown
// after insert mode finishes! // after insert mode finishes!
need_fileinfo = false; need_fileinfo = false;
@@ -1469,8 +1469,9 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
* If 'cpoptions' does not contain 'r', insert the search * If 'cpoptions' does not contain 'r', insert the search
* pattern to really repeat the same command. * pattern to really repeat the same command.
*/ */
if (vim_strchr(p_cpo, CPO_REDO) == NULL) if (vim_strchr(p_cpo, CPO_REDO) == NULL) {
AppendToRedobuffLit(cap->searchbuf, -1); AppendToRedobuffLit(cap->searchbuf, -1);
}
AppendToRedobuff(NL_STR); AppendToRedobuff(NL_STR);
} else if (cap->cmdchar == ':') { } else if (cap->cmdchar == ':') {
/* do_cmdline() has stored the first typed line in /* do_cmdline() has stored the first typed line in
@@ -1853,10 +1854,11 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
break; break;
case OP_FILTER: case OP_FILTER:
if (vim_strchr(p_cpo, CPO_FILTER) != NULL) if (vim_strchr(p_cpo, CPO_FILTER) != NULL) {
AppendToRedobuff((char_u *)"!\r"); /* use any last used !cmd */ AppendToRedobuff("!\r"); // Use any last used !cmd.
else } else {
bangredo = true; /* do_bang() will put cmd in redo buffer */ bangredo = true; // do_bang() will put cmd in redo buffer.
}
case OP_INDENT: case OP_INDENT:
case OP_COLON: case OP_COLON:
@@ -2026,43 +2028,44 @@ void do_pending_operator(cmdarg_T *cap, int old_col, bool gui_yank)
static void op_colon(oparg_T *oap) static void op_colon(oparg_T *oap)
{ {
stuffcharReadbuff(':'); stuffcharReadbuff(':');
if (oap->is_VIsual) if (oap->is_VIsual) {
stuffReadbuff((char_u *)"'<,'>"); stuffReadbuff("'<,'>");
else { } else {
/* // Make the range look nice, so it can be repeated.
* Make the range look nice, so it can be repeated. if (oap->start.lnum == curwin->w_cursor.lnum) {
*/
if (oap->start.lnum == curwin->w_cursor.lnum)
stuffcharReadbuff('.'); stuffcharReadbuff('.');
else } else {
stuffnumReadbuff((long)oap->start.lnum); stuffnumReadbuff((long)oap->start.lnum);
}
if (oap->end.lnum != oap->start.lnum) { if (oap->end.lnum != oap->start.lnum) {
stuffcharReadbuff(','); stuffcharReadbuff(',');
if (oap->end.lnum == curwin->w_cursor.lnum) if (oap->end.lnum == curwin->w_cursor.lnum) {
stuffcharReadbuff('.'); stuffcharReadbuff('.');
else if (oap->end.lnum == curbuf->b_ml.ml_line_count) } else if (oap->end.lnum == curbuf->b_ml.ml_line_count) {
stuffcharReadbuff('$'); stuffcharReadbuff('$');
else if (oap->start.lnum == curwin->w_cursor.lnum) { } else if (oap->start.lnum == curwin->w_cursor.lnum) {
stuffReadbuff((char_u *)".+"); stuffReadbuff(".+");
stuffnumReadbuff(oap->line_count - 1); stuffnumReadbuff(oap->line_count - 1);
} else } else {
stuffnumReadbuff((long)oap->end.lnum); stuffnumReadbuff((long)oap->end.lnum);
} }
} }
if (oap->op_type != OP_COLON) }
stuffReadbuff((char_u *)"!"); if (oap->op_type != OP_COLON) {
stuffReadbuff("!");
}
if (oap->op_type == OP_INDENT) { if (oap->op_type == OP_INDENT) {
stuffReadbuff(get_equalprg()); stuffReadbuff((const char *)get_equalprg());
stuffReadbuff((char_u *)"\n"); stuffReadbuff("\n");
} else if (oap->op_type == OP_FORMAT) { } else if (oap->op_type == OP_FORMAT) {
if (*curbuf->b_p_fp != NUL) { if (*curbuf->b_p_fp != NUL) {
stuffReadbuff(curbuf->b_p_fp); stuffReadbuff((const char *)curbuf->b_p_fp);
} else if (*p_fp != NUL) { } else if (*p_fp != NUL) {
stuffReadbuff(p_fp); stuffReadbuff((const char *)p_fp);
} else { } else {
stuffReadbuff((char_u *)"fmt"); stuffReadbuff("fmt");
} }
stuffReadbuff((char_u *)"\n']"); stuffReadbuff("\n']");
} }
/* /*
@@ -2304,7 +2307,7 @@ do_mouse (
if (VIsual_active) { if (VIsual_active) {
if (VIsual_select) { if (VIsual_select) {
stuffcharReadbuff(Ctrl_G); stuffcharReadbuff(Ctrl_G);
stuffReadbuff((char_u *)"\"+p"); stuffReadbuff("\"+p");
} else { } else {
stuffcharReadbuff('y'); stuffcharReadbuff('y');
stuffcharReadbuff(K_MIDDLEMOUSE); stuffcharReadbuff(K_MIDDLEMOUSE);
@@ -4476,7 +4479,7 @@ static void nv_colon(cmdarg_T *cap)
/* translate "count:" into ":.,.+(count - 1)" */ /* translate "count:" into ":.,.+(count - 1)" */
stuffcharReadbuff('.'); stuffcharReadbuff('.');
if (cap->count0 > 1) { if (cap->count0 > 1) {
stuffReadbuff((char_u *)",.+"); stuffReadbuff(",.+");
stuffnumReadbuff(cap->count0 - 1L); stuffnumReadbuff(cap->count0 - 1L);
} }
} }
@@ -6156,17 +6159,15 @@ static void nv_abbrev(cmdarg_T *cap)
*/ */
static void nv_optrans(cmdarg_T *cap) static void nv_optrans(cmdarg_T *cap)
{ {
static char_u *(ar[8]) = {(char_u *)"dl", (char_u *)"dh", static const char *(ar[]) = { "dl", "dh", "d$", "c$", "cl", "cc", "yy",
(char_u *)"d$", (char_u *)"c$", ":s\r" };
(char_u *)"cl", (char_u *)"cc", static const char *str = "xXDCsSY&";
(char_u *)"yy", (char_u *)":s\r"};
static char_u *str = (char_u *)"xXDCsSY&";
if (!checkclearopq(cap->oap)) { if (!checkclearopq(cap->oap)) {
if (cap->count0) { if (cap->count0) {
stuffnumReadbuff(cap->count0); stuffnumReadbuff(cap->count0);
} }
stuffReadbuff(ar[(int)(vim_strchr(str, cap->cmdchar) - str)]); stuffReadbuff(ar[strchr(str, (char)cap->cmdchar) - str]);
} }
cap->opcount = 0; cap->opcount = 0;
} }

View File

@@ -1109,7 +1109,6 @@ int insert_reg(
) )
{ {
int retval = OK; int retval = OK;
char_u *arg;
int allocated; int allocated;
/* /*
@@ -1125,21 +1124,24 @@ int insert_reg(
if (regname != NUL && !valid_yank_reg(regname, false)) if (regname != NUL && !valid_yank_reg(regname, false))
return FAIL; return FAIL;
if (regname == '.') /* insert last inserted text */ char_u *arg;
retval = stuff_inserted(NUL, 1L, TRUE); if (regname == '.') { // Insert last inserted text.
else if (get_spec_reg(regname, &arg, &allocated, TRUE)) { retval = stuff_inserted(NUL, 1L, true);
if (arg == NULL) } else if (get_spec_reg(regname, &arg, &allocated, true)) {
if (arg == NULL) {
return FAIL; return FAIL;
stuffescaped(arg, literally); }
if (allocated) stuffescaped((const char *)arg, literally);
if (allocated) {
xfree(arg); xfree(arg);
} else { /* name or number register */ }
} else { // Name or number register.
yankreg_T *reg = get_yank_register(regname, YREG_PASTE); yankreg_T *reg = get_yank_register(regname, YREG_PASTE);
if (reg->y_array == NULL) { if (reg->y_array == NULL) {
retval = FAIL; retval = FAIL;
} else { } else {
for (size_t i = 0; i < reg->y_size; i++) { for (size_t i = 0; i < reg->y_size; i++) {
stuffescaped(reg->y_array[i], literally); stuffescaped((const char *)reg->y_array[i], literally);
// Insert a newline between lines and after last line if // Insert a newline between lines and after last line if
// y_type is kMTLineWise. // y_type is kMTLineWise.
if (reg->y_type == kMTLineWise || i < reg->y_size - 1) { if (reg->y_type == kMTLineWise || i < reg->y_size - 1) {
@@ -1156,29 +1158,29 @@ int insert_reg(
* Stuff a string into the typeahead buffer, such that edit() will insert it * Stuff a string into the typeahead buffer, such that edit() will insert it
* literally ("literally" TRUE) or interpret is as typed characters. * literally ("literally" TRUE) or interpret is as typed characters.
*/ */
static void stuffescaped(char_u *arg, int literally) static void stuffescaped(const char *arg, int literally)
{ {
int c;
char_u *start;
while (*arg != NUL) { while (*arg != NUL) {
/* Stuff a sequence of normal ASCII characters, that's fast. Also // Stuff a sequence of normal ASCII characters, that's fast. Also
* stuff K_SPECIAL to get the effect of a special key when "literally" // stuff K_SPECIAL to get the effect of a special key when "literally"
* is TRUE. */ // is TRUE.
start = arg; const char *const start = arg;
while ((*arg >= ' ' && *arg < DEL) || (*arg == K_SPECIAL && !literally)) while ((*arg >= ' ' && *arg < DEL) || ((uint8_t)(*arg) == K_SPECIAL
++arg; && !literally)) {
if (arg > start) arg++;
}
if (arg > start) {
stuffReadbuffLen(start, (long)(arg - start)); stuffReadbuffLen(start, (long)(arg - start));
}
/* stuff a single special character */ /* stuff a single special character */
if (*arg != NUL) { if (*arg != NUL) {
if (has_mbyte) const int c = (has_mbyte
c = mb_cptr2char_adv(&arg); ? mb_cptr2char_adv((const char_u **)&arg)
else : (uint8_t)(*arg++));
c = *arg++; if (literally && ((c < ' ' && c != TAB) || c == DEL)) {
if (literally && ((c < ' ' && c != TAB) || c == DEL))
stuffcharReadbuff(Ctrl_V); stuffcharReadbuff(Ctrl_V);
}
stuffcharReadbuff(c); stuffcharReadbuff(c);
} }
} }
@@ -2663,7 +2665,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
// back to the previous line in the case of 'noautoindent' and // back to the previous line in the case of 'noautoindent' and
// 'backspace' includes "eol". So we insert a dummy space for Ctrl_U // 'backspace' includes "eol". So we insert a dummy space for Ctrl_U
// to consume. // to consume.
stuffReadbuff((char_u *)"\n "); stuffReadbuff("\n ");
stuffcharReadbuff(Ctrl_U); stuffcharReadbuff(Ctrl_U);
} }
} }
@@ -2675,7 +2677,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
// character. Simulate it with motion commands after the insert. // character. Simulate it with motion commands after the insert.
if (flags & PUT_CURSEND) { if (flags & PUT_CURSEND) {
if (flags & PUT_LINE) { if (flags & PUT_LINE) {
stuffReadbuff((char_u *)"j0"); stuffReadbuff("j0");
} else { } else {
// Avoid ringing the bell from attempting to move into the space after // Avoid ringing the bell from attempting to move into the space after
// the current line. We can stuff the readbuffer with "l" if: // the current line. We can stuff the readbuffer with "l" if:
@@ -2705,7 +2707,7 @@ void do_put(int regname, yankreg_T *reg, int dir, long count, int flags)
} }
} }
} else if (flags & PUT_LINE) { } else if (flags & PUT_LINE) {
stuffReadbuff((char_u *)"g'["); stuffReadbuff("g'[");
} }
// So the 'u' command restores cursor position after ".p, save the cursor // So the 'u' command restores cursor position after ".p, save the cursor
@@ -4981,7 +4983,7 @@ void write_reg_contents(int name, const char_u *str, ssize_t len,
write_reg_contents_ex(name, str, len, must_append, kMTUnknown, 0L); write_reg_contents_ex(name, str, len, must_append, kMTUnknown, 0L);
} }
void write_reg_contents_lst(int name, char_u **strings, int maxlen, void write_reg_contents_lst(int name, char_u **strings,
bool must_append, MotionType yank_type, bool must_append, MotionType yank_type,
colnr_T block_len) colnr_T block_len)
{ {

View File

@@ -3419,16 +3419,19 @@ static char_u *set_chars_option(char_u **varp)
&& p[len] == ':' && p[len] == ':'
&& p[len + 1] != NUL) { && p[len + 1] != NUL) {
s = p + len + 1; s = p + len + 1;
c1 = mb_ptr2char_adv(&s); c1 = mb_ptr2char_adv((const char_u **)&s);
if (mb_char2cells(c1) > 1) if (mb_char2cells(c1) > 1) {
continue; continue;
}
if (tab[i].cp == &lcs_tab2) { if (tab[i].cp == &lcs_tab2) {
if (*s == NUL) if (*s == NUL) {
continue; continue;
c2 = mb_ptr2char_adv(&s); }
if (mb_char2cells(c2) > 1) c2 = mb_ptr2char_adv((const char_u **)&s);
if (mb_char2cells(c2) > 1) {
continue; continue;
} }
}
if (*s == ',' || *s == NUL) { if (*s == ',' || *s == NUL) {
if (round) { if (round) {
if (tab[i].cp == &lcs_tab2) { if (tab[i].cp == &lcs_tab2) {
@@ -6887,8 +6890,8 @@ void set_fileformat(int eol_style, int opt_flags)
need_maketitle = true; // Set window title later. need_maketitle = true; // Set window title later.
} }
/// Skip to next part of an option argument: Skip space and comma. /// Skip to next part of an option argument: skip space and comma
char_u *skip_to_option_part(char_u *p) char_u *skip_to_option_part(const char_u *p)
{ {
if (*p == ',') { if (*p == ',') {
p++; p++;
@@ -6896,7 +6899,7 @@ char_u *skip_to_option_part(char_u *p)
while (*p == ' ') { while (*p == ' ') {
p++; p++;
} }
return p; return (char_u *)p;
} }
/// Isolate one part of a string option separated by `sep_chars`. /// Isolate one part of a string option separated by `sep_chars`.

View File

@@ -622,11 +622,11 @@ int32_t os_getperm(const char *name)
/// Set the permission of a file. /// Set the permission of a file.
/// ///
/// @return `OK` for success, `FAIL` for failure. /// @return `OK` for success, `FAIL` for failure.
int os_setperm(const char_u *name, int perm) int os_setperm(const char *const name, int perm)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_ALL
{ {
int r; int r;
RUN_UV_FS_FUNC(r, uv_fs_chmod, (const char *)name, perm, NULL); RUN_UV_FS_FUNC(r, uv_fs_chmod, name, perm, NULL);
return (r == kLibuvSuccess ? OK : FAIL); return (r == kLibuvSuccess ? OK : FAIL);
} }

View File

@@ -2221,11 +2221,12 @@ collection:
if (*regparse == '[') if (*regparse == '[')
endc = get_coll_element(&regparse); endc = get_coll_element(&regparse);
if (endc == 0) { if (endc == 0) {
if (has_mbyte) if (has_mbyte) {
endc = mb_ptr2char_adv(&regparse); endc = mb_ptr2char_adv((const char_u **)&regparse);
else } else {
endc = *regparse++; endc = *regparse++;
} }
}
/* Handle \o40, \x20 and \u20AC style sequences */ /* Handle \o40, \x20 and \u20AC style sequences */
if (endc == '\\' && !reg_cpo_lit) if (endc == '\\' && !reg_cpo_lit)
@@ -6271,8 +6272,8 @@ static int cstrncmp(char_u *s1, char_u *s2, int *n)
str2 = s2; str2 = s2;
c1 = c2 = 0; c1 = c2 = 0;
while ((int)(str1 - s1) < *n) { while ((int)(str1 - s1) < *n) {
c1 = mb_ptr2char_adv(&str1); c1 = mb_ptr2char_adv((const char_u **)&str1);
c2 = mb_ptr2char_adv(&str2); c2 = mb_ptr2char_adv((const char_u **)&str2);
/* decompose the character if necessary, into 'base' characters /* decompose the character if necessary, into 'base' characters
* because I don't care about Arabic, I will hard-code the Hebrew * because I don't care about Arabic, I will hard-code the Hebrew
@@ -6586,7 +6587,6 @@ static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest,
if (expr != NULL) { if (expr != NULL) {
typval_T argv[2]; typval_T argv[2];
int dummy; int dummy;
char_u buf[NUMBUFLEN];
typval_T rettv; typval_T rettv;
staticList10_T matchList; staticList10_T matchList;
@@ -6616,7 +6616,8 @@ static int vim_regsub_both(char_u *source, typval_T *expr, char_u *dest,
clear_submatch_list(&matchList); clear_submatch_list(&matchList);
} }
} }
eval_result = get_tv_string_buf_chk(&rettv, buf); char buf[NUMBUFLEN];
eval_result = (char_u *)tv_get_string_buf_chk(&rettv, buf);
if (eval_result != NULL) { if (eval_result != NULL) {
eval_result = vim_strsave(eval_result); eval_result = vim_strsave(eval_result);
} }

View File

@@ -3141,7 +3141,7 @@ win_line (
p_extra = extra; p_extra = extra;
c = *p_extra; c = *p_extra;
mb_c = mb_ptr2char_adv(&p_extra); mb_c = mb_ptr2char_adv((const char_u **)&p_extra);
mb_utf8 = (c >= 0x80); mb_utf8 = (c >= 0x80);
n_extra = (int)STRLEN(p_extra); n_extra = (int)STRLEN(p_extra);
c_extra = NUL; c_extra = NUL;

View File

@@ -2309,10 +2309,11 @@ int captype(char_u *word, char_u *end)
for (p = word; !spell_iswordp_nmw(p, curwin); mb_ptr_adv(p)) for (p = word; !spell_iswordp_nmw(p, curwin); mb_ptr_adv(p))
if (end == NULL ? *p == NUL : p >= end) if (end == NULL ? *p == NUL : p >= end)
return 0; // only non-word characters, illegal word return 0; // only non-word characters, illegal word
if (has_mbyte) if (has_mbyte) {
c = mb_ptr2char_adv(&p); c = mb_ptr2char_adv((const char_u **)&p);
else } else {
c = *p++; c = *p++;
}
firstcap = allcap = SPELL_ISUPPER(c); firstcap = allcap = SPELL_ISUPPER(c);
// Need to check all letters to find a word with mixed upper/lower. // Need to check all letters to find a word with mixed upper/lower.
@@ -2607,14 +2608,15 @@ static bool spell_iswordp(char_u *p, win_T *wp)
// Returns true if "p" points to a word character. // Returns true if "p" points to a word character.
// Unlike spell_iswordp() this doesn't check for "midword" characters. // Unlike spell_iswordp() this doesn't check for "midword" characters.
bool spell_iswordp_nmw(char_u *p, win_T *wp) bool spell_iswordp_nmw(const char_u *p, win_T *wp)
{ {
int c; int c;
if (has_mbyte) { if (has_mbyte) {
c = mb_ptr2char(p); c = mb_ptr2char(p);
if (c > 255) if (c > 255) {
return spell_mb_isword_class(mb_get_class(p), wp); return spell_mb_isword_class(mb_get_class(p), wp);
}
return spelltab.st_isw[c]; return spelltab.st_isw[c];
} }
return spelltab.st_isw[*p]; return spelltab.st_isw[*p];
@@ -2675,7 +2677,7 @@ int spell_casefold(char_u *str, int len, char_u *buf, int buflen)
buf[outi] = NUL; buf[outi] = NUL;
return FAIL; return FAIL;
} }
c = mb_cptr2char_adv(&p); c = mb_cptr2char_adv((const char_u **)&p);
outi += mb_char2bytes(SPELL_TOFOLD(c), buf + outi); outi += mb_char2bytes(SPELL_TOFOLD(c), buf + outi);
} }
buf[outi] = NUL; buf[outi] = NUL;
@@ -2937,7 +2939,7 @@ void spell_suggest(int count)
// For redo we use a change-word command. // For redo we use a change-word command.
ResetRedobuff(); ResetRedobuff();
AppendToRedobuff((char_u *)"ciw"); AppendToRedobuff("ciw");
AppendToRedobuffLit(p + c, AppendToRedobuffLit(p + c,
stp->st_wordlen + sug.su_badlen - stp->st_orglen); stp->st_wordlen + sug.su_badlen - stp->st_orglen);
AppendCharToRedobuff(ESC); AppendCharToRedobuff(ESC);
@@ -3406,17 +3408,19 @@ void onecap_copy(char_u *word, char_u *wcopy, bool upper)
int l; int l;
p = word; p = word;
if (has_mbyte) if (has_mbyte) {
c = mb_cptr2char_adv(&p); c = mb_cptr2char_adv((const char_u **)&p);
else } else {
c = *p++; c = *p++;
if (upper) }
if (upper) {
c = SPELL_TOUPPER(c); c = SPELL_TOUPPER(c);
else } else {
c = SPELL_TOFOLD(c); c = SPELL_TOFOLD(c);
if (has_mbyte) }
if (has_mbyte) {
l = mb_char2bytes(c, wcopy); l = mb_char2bytes(c, wcopy);
else { } else {
l = 1; l = 1;
wcopy[0] = c; wcopy[0] = c;
} }
@@ -3433,10 +3437,11 @@ static void allcap_copy(char_u *word, char_u *wcopy)
d = wcopy; d = wcopy;
for (s = word; *s != NUL; ) { for (s = word; *s != NUL; ) {
if (has_mbyte) if (has_mbyte) {
c = mb_cptr2char_adv(&s); c = mb_cptr2char_adv((const char_u **)&s);
else } else {
c = *s++; c = *s++;
}
if (c == 0xdf) { if (c == 0xdf) {
c = 'S'; c = 'S';
@@ -5938,12 +5943,12 @@ static void spell_soundfold_sofo(slang_T *slang, char_u *inword, char_u *res)
// The sl_sal_first[] table contains the translation for chars up to // The sl_sal_first[] table contains the translation for chars up to
// 255, sl_sal the rest. // 255, sl_sal the rest.
for (s = inword; *s != NUL; ) { for (s = inword; *s != NUL; ) {
c = mb_cptr2char_adv(&s); c = mb_cptr2char_adv((const char_u **)&s);
if (enc_utf8 ? utf_class(c) == 0 : ascii_iswhite(c)) if (enc_utf8 ? utf_class(c) == 0 : ascii_iswhite(c)) {
c = ' '; c = ' ';
else if (c < 256) } else if (c < 256) {
c = slang->sl_sal_first[c]; c = slang->sl_sal_first[c];
else { } else {
ip = ((int **)slang->sl_sal.ga_data)[c & 0xff]; ip = ((int **)slang->sl_sal.ga_data)[c & 0xff];
if (ip == NULL) // empty list, can't match if (ip == NULL) // empty list, can't match
c = NUL; c = NUL;
@@ -6228,9 +6233,7 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
int word[MAXWLEN]; int word[MAXWLEN];
int wres[MAXWLEN]; int wres[MAXWLEN];
int l; int l;
char_u *s;
int *ws; int *ws;
char_u *t;
int *pf; int *pf;
int i, j, z; int i, j, z;
int reslen; int reslen;
@@ -6250,9 +6253,9 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
// Remove accents, if wanted. We actually remove all non-word characters. // Remove accents, if wanted. We actually remove all non-word characters.
// But keep white space. // But keep white space.
wordlen = 0; wordlen = 0;
for (s = inword; *s != NUL; ) { for (const char_u *s = inword; *s != NUL; ) {
t = s; const char_u *t = s;
c = mb_cptr2char_adv(&s); c = mb_cptr2char_adv((const char_u **)&s);
if (slang->sl_rem_accents) { if (slang->sl_rem_accents) {
if (enc_utf8 ? utf_class(c) == 0 : ascii_iswhite(c)) { if (enc_utf8 ? utf_class(c) == 0 : ascii_iswhite(c)) {
if (did_white) if (did_white)
@@ -6261,10 +6264,11 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
did_white = true; did_white = true;
} else { } else {
did_white = false; did_white = false;
if (!spell_iswordp_nmw(t, curwin)) if (!spell_iswordp_nmw(t, curwin)) {
continue; continue;
} }
} }
}
word[wordlen++] = c; word[wordlen++] = c;
} }
word[wordlen] = NUL; word[wordlen] = NUL;
@@ -6309,7 +6313,7 @@ static void spell_soundfold_wsal(slang_T *slang, char_u *inword, char_u *res)
continue; continue;
++k; ++k;
} }
s = smp[n].sm_rules; char_u *s = smp[n].sm_rules;
pri = 5; // default priority pri = 5; // default priority
p0 = *s; p0 = *s;
@@ -6709,24 +6713,29 @@ soundalike_score (
static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword) static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword)
{ {
int *cnt; int *cnt;
int badlen, goodlen; // lengths including NUL
int j, i; int j, i;
int t; int t;
int bc, gc; int bc, gc;
int pbc, pgc; int pbc, pgc;
char_u *p;
int wbadword[MAXWLEN]; int wbadword[MAXWLEN];
int wgoodword[MAXWLEN]; int wgoodword[MAXWLEN];
const bool l_has_mbyte = has_mbyte; const bool l_has_mbyte = has_mbyte;
// Lengths with NUL.
int badlen;
int goodlen;
if (l_has_mbyte) { if (l_has_mbyte) {
// Get the characters from the multi-byte strings and put them in an // Get the characters from the multi-byte strings and put them in an
// int array for easy access. // int array for easy access.
for (p = badword, badlen = 0; *p != NUL; ) badlen = 0;
for (const char_u *p = badword; *p != NUL; ) {
wbadword[badlen++] = mb_cptr2char_adv(&p); wbadword[badlen++] = mb_cptr2char_adv(&p);
}
wbadword[badlen++] = 0; wbadword[badlen++] = 0;
for (p = goodword, goodlen = 0; *p != NUL; ) goodlen = 0;
for (const char_u *p = goodword; *p != NUL; ) {
wgoodword[goodlen++] = mb_cptr2char_adv(&p); wgoodword[goodlen++] = mb_cptr2char_adv(&p);
}
wgoodword[goodlen++] = 0; wgoodword[goodlen++] = 0;
} else { } else {
badlen = (int)STRLEN(badword) + 1; badlen = (int)STRLEN(badword) + 1;
@@ -6960,19 +6969,20 @@ static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goo
int score_off; int score_off;
int minscore; int minscore;
int round; int round;
char_u *p;
int wbadword[MAXWLEN]; int wbadword[MAXWLEN];
int wgoodword[MAXWLEN]; int wgoodword[MAXWLEN];
// Get the characters from the multi-byte strings and put them in an // Get the characters from the multi-byte strings and put them in an
// int array for easy access. // int array for easy access.
bi = 0; bi = 0;
for (p = badword; *p != NUL; ) for (const char_u *p = badword; *p != NUL; ) {
wbadword[bi++] = mb_cptr2char_adv(&p); wbadword[bi++] = mb_cptr2char_adv(&p);
}
wbadword[bi++] = 0; wbadword[bi++] = 0;
gi = 0; gi = 0;
for (p = goodword; *p != NUL; ) for (const char_u *p = goodword; *p != NUL; ) {
wgoodword[gi++] = mb_cptr2char_adv(&p); wgoodword[gi++] = mb_cptr2char_adv(&p);
}
wgoodword[gi++] = 0; wgoodword[gi++] = 0;
// The idea is to go from start to end over the words. So long as // The idea is to go from start to end over the words. So long as

View File

@@ -1435,7 +1435,7 @@ static int set_sofo(slang_T *lp, char_u *from, char_u *to)
// First count the number of items for each list. Temporarily use // First count the number of items for each list. Temporarily use
// sl_sal_first[] for this. // sl_sal_first[] for this.
for (p = from, s = to; *p != NUL && *s != NUL; ) { for (p = from, s = to; *p != NUL && *s != NUL; ) {
c = mb_cptr2char_adv(&p); c = mb_cptr2char_adv((const char_u **)&p);
mb_cptr_adv(s); mb_cptr_adv(s);
if (c >= 256) if (c >= 256)
++lp->sl_sal_first[c & 0xff]; ++lp->sl_sal_first[c & 0xff];
@@ -1455,8 +1455,8 @@ static int set_sofo(slang_T *lp, char_u *from, char_u *to)
// list. // list.
memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256); memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256);
for (p = from, s = to; *p != NUL && *s != NUL; ) { for (p = from, s = to; *p != NUL && *s != NUL; ) {
c = mb_cptr2char_adv(&p); c = mb_cptr2char_adv((const char_u **)&p);
i = mb_cptr2char_adv(&s); i = mb_cptr2char_adv((const char_u **)&s);
if (c >= 256) { if (c >= 256) {
// Append the from-to chars at the end of the list with // Append the from-to chars at the end of the list with
// the low byte. // the low byte.
@@ -1542,8 +1542,9 @@ static int *mb_str2wide(char_u *s)
int i = 0; int i = 0;
int *res = xmalloc((mb_charlen(s) + 1) * sizeof(int)); int *res = xmalloc((mb_charlen(s) + 1) * sizeof(int));
for (char_u *p = s; *p != NUL; ) for (char_u *p = s; *p != NUL; ) {
res[i++] = mb_ptr2char_adv(&p); res[i++] = mb_ptr2char_adv((const char_u **)&p);
}
res[i] = NUL; res[i] = NUL;
return res; return res;
@@ -2486,14 +2487,15 @@ static afffile_T *spell_read_aff(spellinfo_T *spin, char_u *fname)
// Check that every character appears only once. // Check that every character appears only once.
for (p = items[1]; *p != NUL; ) { for (p = items[1]; *p != NUL; ) {
c = mb_ptr2char_adv(&p); c = mb_ptr2char_adv((const char_u **)&p);
if ((!GA_EMPTY(&spin->si_map) if ((!GA_EMPTY(&spin->si_map)
&& vim_strchr(spin->si_map.ga_data, c) && vim_strchr(spin->si_map.ga_data, c)
!= NULL) != NULL)
|| vim_strchr(p, c) != NULL) || vim_strchr(p, c) != NULL) {
smsg(_("Duplicate character in MAP in %s line %d"), smsg(_("Duplicate character in MAP in %s line %d"),
fname, lnum); fname, lnum);
} }
}
// We simply concatenate all the MAP strings, separated by // We simply concatenate all the MAP strings, separated by
// slashes. // slashes.
@@ -2717,12 +2719,12 @@ static unsigned get_affitem(int flagtype, char_u **pp)
} }
res = getdigits_int(pp); res = getdigits_int(pp);
} else { } else {
res = mb_ptr2char_adv(pp); res = mb_ptr2char_adv((const char_u **)pp);
if (flagtype == AFT_LONG || (flagtype == AFT_CAPLONG if (flagtype == AFT_LONG || (flagtype == AFT_CAPLONG
&& res >= 'A' && res <= 'Z')) { && res >= 'A' && res <= 'Z')) {
if (**pp == NUL) if (**pp == NUL)
return 0; return 0;
res = mb_ptr2char_adv(pp) + (res << 16); res = mb_ptr2char_adv((const char_u **)pp) + (res << 16);
} }
} }
return res; return res;
@@ -2823,13 +2825,15 @@ static bool flag_in_afflist(int flagtype, char_u *afflist, unsigned flag)
case AFT_CAPLONG: case AFT_CAPLONG:
case AFT_LONG: case AFT_LONG:
for (p = afflist; *p != NUL; ) { for (p = afflist; *p != NUL; ) {
n = mb_ptr2char_adv(&p); n = mb_ptr2char_adv((const char_u **)&p);
if ((flagtype == AFT_LONG || (n >= 'A' && n <= 'Z')) if ((flagtype == AFT_LONG || (n >= 'A' && n <= 'Z'))
&& *p != NUL) && *p != NUL) {
n = mb_ptr2char_adv(&p) + (n << 16); n = mb_ptr2char_adv((const char_u **)&p) + (n << 16);
if (n == flag) }
if (n == flag) {
return true; return true;
} }
}
break; break;
case AFT_NUM: case AFT_NUM:
@@ -5436,9 +5440,10 @@ static void init_spellfile(void)
fname = LANGP_ENTRY(curwin->w_s->b_langp, 0) fname = LANGP_ENTRY(curwin->w_s->b_langp, 0)
->lp_slang->sl_fname; ->lp_slang->sl_fname;
vim_snprintf((char *)buf + l, MAXPATHL - l, ".%s.add", vim_snprintf((char *)buf + l, MAXPATHL - l, ".%s.add",
fname != NULL ((fname != NULL
&& strstr((char *)path_tail(fname), ".ascii.") != NULL && strstr((char *)path_tail(fname), ".ascii.") != NULL)
? (char_u *)"ascii" : spell_enc()); ? "ascii"
: (const char *)spell_enc()));
set_option_value("spellfile", 0L, (const char *)buf, OPT_LOCAL); set_option_value("spellfile", 0L, (const char *)buf, OPT_LOCAL);
break; break;
} }
@@ -5465,9 +5470,9 @@ static int set_spell_chartab(char_u *fol, char_u *low, char_u *upp)
EMSG(_(e_affform)); EMSG(_(e_affform));
return FAIL; return FAIL;
} }
f = mb_ptr2char_adv(&pf); f = mb_ptr2char_adv((const char_u **)&pf);
l = mb_ptr2char_adv(&pl); l = mb_ptr2char_adv((const char_u **)&pl);
u = mb_ptr2char_adv(&pu); u = mb_ptr2char_adv((const char_u **)&pu);
// Every character that appears is a word character. // Every character that appears is a word character.
if (f < 256) if (f < 256)
new_st.st_isw[f] = true; new_st.st_isw[f] = true;
@@ -5532,7 +5537,7 @@ set_spell_charflags (
} }
if (*p != NUL) { if (*p != NUL) {
c = mb_ptr2char_adv(&p); c = mb_ptr2char_adv((const char_u **)&p);
new_st.st_fold[i + 128] = c; new_st.st_fold[i + 128] = c;
if (i + 128 != c && new_st.st_isu[i + 128] && c < 256) if (i + 128 != c && new_st.st_isu[i + 128] && c < 256)
new_st.st_upper[c] = i + 128; new_st.st_upper[c] = i + 128;
@@ -5619,12 +5624,13 @@ static void set_map_str(slang_T *lp, char_u *map)
// "aaa/bbb/ccc/". Fill sl_map_array[c] with the character before c and // "aaa/bbb/ccc/". Fill sl_map_array[c] with the character before c and
// before the same slash. For characters above 255 sl_map_hash is used. // before the same slash. For characters above 255 sl_map_hash is used.
for (p = map; *p != NUL; ) { for (p = map; *p != NUL; ) {
c = mb_cptr2char_adv(&p); c = mb_cptr2char_adv((const char_u **)&p);
if (c == '/') if (c == '/') {
headc = 0; headc = 0;
else { } else {
if (headc == 0) if (headc == 0) {
headc = c; headc = c;
}
// Characters above 255 don't fit in sl_map_array[], put them in // Characters above 255 don't fit in sl_map_array[], put them in
// the hash table. Each entry is the char, a NUL the headchar and // the hash table. Each entry is the char, a NUL the headchar and

View File

@@ -598,22 +598,21 @@ static varnumber_T tv_nr(typval_T *tvs, int *idxp)
/// free "*tofree". /// free "*tofree".
/// ///
/// @return String value or NULL in case of error. /// @return String value or NULL in case of error.
static char *tv_str(typval_T *tvs, int *idxp, char ** const tofree) static const char *tv_str(typval_T *tvs, int *idxp, char **const tofree)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{ {
int idx = *idxp - 1; int idx = *idxp - 1;
char *s = NULL; const char *s = NULL;
if (tvs[idx].v_type == VAR_UNKNOWN) { if (tvs[idx].v_type == VAR_UNKNOWN) {
EMSG(_(e_printf)); EMSG(_(e_printf));
} else { } else {
(*idxp)++; (*idxp)++;
if (tvs[idx].v_type == VAR_STRING || tvs[idx].v_type == VAR_NUMBER) { if (tvs[idx].v_type == VAR_STRING || tvs[idx].v_type == VAR_NUMBER) {
s = (char *)get_tv_string_chk(&tvs[idx]); s = tv_get_string_chk(&tvs[idx]);
*tofree = NULL; *tofree = NULL;
} else { } else {
s = encode_tv2echo(&tvs[idx], NULL); s = *tofree = encode_tv2echo(&tvs[idx], NULL);
*tofree = s;
} }
} }
return s; return s;
@@ -953,7 +952,7 @@ int vim_vsnprintf(char *str, size_t str_m, const char *fmt, va_list ap,
case 's': case 's':
case 'S': case 'S':
str_arg = tvs ? tv_str(tvs, &arg_idx, &tofree) str_arg = tvs ? tv_str(tvs, &arg_idx, &tofree)
: va_arg(ap, char *); : va_arg(ap, const char *);
if (!str_arg) { if (!str_arg) {
str_arg = "[NULL]"; str_arg = "[NULL]";
str_arg_l = 6; str_arg_l = 6;

View File

@@ -1140,7 +1140,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
EMSG2(_(e_not_open), file_name); EMSG2(_(e_not_open), file_name);
goto theend; goto theend;
} }
(void)os_setperm((char_u *)file_name, perm); (void)os_setperm(file_name, perm);
if (p_verbose > 0) { if (p_verbose > 0) {
verbose_enter(); verbose_enter();
smsg(_("Writing undo file: %s"), file_name); smsg(_("Writing undo file: %s"), file_name);
@@ -1165,7 +1165,7 @@ void u_write_undo(const char *const name, const bool forceit, buf_T *const buf,
&& os_fileinfo(file_name, &file_info_new) && os_fileinfo(file_name, &file_info_new)
&& file_info_old.stat.st_gid != file_info_new.stat.st_gid && file_info_old.stat.st_gid != file_info_new.stat.st_gid
&& os_fchown(fd, (uv_uid_t)-1, (uv_gid_t)file_info_old.stat.st_gid)) { && os_fchown(fd, (uv_uid_t)-1, (uv_gid_t)file_info_old.stat.st_gid)) {
os_setperm((char_u *)file_name, (perm & 0707) | ((perm & 07) << 3)); os_setperm(file_name, (perm & 0707) | ((perm & 07) << 3));
} }
# ifdef HAVE_SELINUX # ifdef HAVE_SELINUX
if (buf->b_ffname != NULL) if (buf->b_ffname != NULL)

View File

@@ -0,0 +1,38 @@
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local feed = helpers.feed
local clear = helpers.clear
local command = helpers.command
local screen
before_each(function()
clear()
screen = Screen.new(25, 5)
screen:attach()
end)
describe('input()', function()
it('works correctly with multiline prompts', function()
feed([[:call input("Test\nFoo")<CR>]])
screen:expect([[
{1:~ }|
{1:~ }|
{1:~ }|
Test |
Foo^ |
]], {{bold=true, foreground=Screen.colors.Blue}})
end)
it('works correctly with multiline prompts and :echohl', function()
command('hi Test ctermfg=Red guifg=Red term=bold')
feed([[:echohl Test | call input("Test\nFoo")<CR>]])
screen:expect([[
{1:~ }|
{1:~ }|
{1:~ }|
{2:Test} |
{2:Foo}^ |
]], {{bold=true, foreground=Screen.colors.Blue}, {foreground=Screen.colors.Red}})
end)
end)

View File

@@ -44,3 +44,18 @@ describe('setmatches()', function()
eq({}, funcs.getmatches()) eq({}, funcs.getmatches())
end) end)
end) end)
describe('matchadd()', function()
it('correctly works when first two arguments and conceal are numbers at once',
function()
command('hi def link 1 PreProc')
eq(4, funcs.matchadd(1, 2, 3, 4, {conceal=5}))
eq({{
group='1',
pattern='2',
priority=3,
id=4,
conceal='5',
}}, funcs.getmatches())
end)
end)

View File

@@ -9,7 +9,7 @@ local eval = helpers.eval
describe('dictionary change notifications', function() describe('dictionary change notifications', function()
local channel local channel
setup(function() before_each(function()
clear() clear()
channel = nvim('get_api_info')[1] channel = nvim('get_api_info')[1]
nvim('set_var', 'channel', channel) nvim('set_var', 'channel', channel)
@@ -18,19 +18,15 @@ describe('dictionary change notifications', function()
-- the same set of tests are applied to top-level dictionaries(g:, b:, w: and -- the same set of tests are applied to top-level dictionaries(g:, b:, w: and
-- t:) and a dictionary variable, so we generate them in the following -- t:) and a dictionary variable, so we generate them in the following
-- function. -- function.
local function gentests(dict_expr, dict_expr_suffix, dict_init) local function gentests(dict_expr, dict_init)
if not dict_expr_suffix then
dict_expr_suffix = ''
end
local function update(opval, key) local function update(opval, key)
if not key then if not key then
key = 'watched' key = 'watched'
end end
if opval == '' then if opval == '' then
nvim('command', "unlet "..dict_expr..dict_expr_suffix..key) command(('unlet %s[\'%s\']'):format(dict_expr, key))
else else
nvim('command', "let "..dict_expr..dict_expr_suffix..key.." "..opval) command(('let %s[\'%s\'] %s'):format(dict_expr, key, opval))
end end
end end
@@ -50,7 +46,7 @@ describe('dictionary change notifications', function()
describe(dict_expr .. ' watcher', function() describe(dict_expr .. ' watcher', function()
if dict_init then if dict_init then
setup(function() before_each(function()
source(dict_init) source(dict_init)
end) end)
end end
@@ -143,6 +139,32 @@ describe('dictionary change notifications', function()
]]) ]])
end) end)
it('is triggered for empty keys', function()
command([[
call dictwatcheradd(]]..dict_expr..[[, "", "g:Changed")
]])
update('= 1', '')
verify_value({new = 1}, '')
update('= 2', '')
verify_value({old = 1, new = 2}, '')
command([[
call dictwatcherdel(]]..dict_expr..[[, "", "g:Changed")
]])
end)
it('is triggered for empty keys when using catch-all *', function()
command([[
call dictwatcheradd(]]..dict_expr..[[, "*", "g:Changed")
]])
update('= 1', '')
verify_value({new = 1}, '')
update('= 2', '')
verify_value({old = 1, new = 2}, '')
command([[
call dictwatcherdel(]]..dict_expr..[[, "*", "g:Changed")
]])
end)
-- test a sequence of updates of different types to ensure proper memory -- test a sequence of updates of different types to ensure proper memory
-- management(with ASAN) -- management(with ASAN)
local function test_updates(tests) local function test_updates(tests)
@@ -190,10 +212,10 @@ describe('dictionary change notifications', function()
gentests('b:') gentests('b:')
gentests('w:') gentests('w:')
gentests('t:') gentests('t:')
gentests('g:dict_var', '.', 'let g:dict_var = {}') gentests('g:dict_var', 'let g:dict_var = {}')
describe('multiple watchers on the same dict/key', function() describe('multiple watchers on the same dict/key', function()
setup(function() before_each(function()
source([[ source([[
function! g:Watcher1(dict, key, value) function! g:Watcher1(dict, key, value)
call rpcnotify(g:channel, '1', a:key, a:value) call rpcnotify(g:channel, '1', a:key, a:value)
@@ -213,6 +235,9 @@ describe('dictionary change notifications', function()
end) end)
it('only removes watchers that fully match dict, key and callback', function() it('only removes watchers that fully match dict, key and callback', function()
nvim('command', 'let g:key = "value"')
eq({'notification', '1', {'key', {new = 'value'}}}, next_msg())
eq({'notification', '2', {'key', {new = 'value'}}}, next_msg())
nvim('command', 'call dictwatcherdel(g:, "key", "g:Watcher1")') nvim('command', 'call dictwatcherdel(g:, "key", "g:Watcher1")')
nvim('command', 'let g:key = "v2"') nvim('command', 'let g:key = "v2"')
eq({'notification', '2', {'key', {old = 'value', new = 'v2'}}}, next_msg()) eq({'notification', '2', {'key', {old = 'value', new = 'v2'}}}, next_msg())
@@ -220,6 +245,17 @@ describe('dictionary change notifications', function()
end) end)
describe('errors', function() describe('errors', function()
before_each(function()
source([[
function! g:Watcher1(dict, key, value)
call rpcnotify(g:channel, '1', a:key, a:value)
endfunction
function! g:Watcher2(dict, key, value)
call rpcnotify(g:channel, '2', a:key, a:value)
endfunction
]])
end)
-- WARNING: This suite depends on the above tests -- WARNING: This suite depends on the above tests
it('fails to remove if no watcher with matching callback is found', function() it('fails to remove if no watcher with matching callback is found', function()
eq("Vim(call):Couldn't find a watcher matching key and callback", eq("Vim(call):Couldn't find a watcher matching key and callback",
@@ -236,15 +272,10 @@ describe('dictionary change notifications', function()
command('call dictwatcherdel(g:, "key", "g:InvalidCb")') command('call dictwatcherdel(g:, "key", "g:InvalidCb")')
end) end)
it('fails with empty keys', function()
eq("Vim(call):E713: Cannot use empty key for Dictionary",
exc_exec('call dictwatcheradd(g:, "", "g:Watcher1")'))
eq("Vim(call):E713: Cannot use empty key for Dictionary",
exc_exec('call dictwatcherdel(g:, "", "g:Watcher1")'))
end)
it('does not fail to replace a watcher function', function() it('does not fail to replace a watcher function', function()
source([[ source([[
let g:key = 'v2'
call dictwatcheradd(g:, "key", "g:Watcher2")
function! g:ReplaceWatcher2() function! g:ReplaceWatcher2()
function! g:Watcher2(dict, key, value) function! g:Watcher2(dict, key, value)
call rpcnotify(g:channel, '2b', a:key, a:value) call rpcnotify(g:channel, '2b', a:key, a:value)