diff --git a/src/nvim/charset.c b/src/nvim/charset.c index 4d150c3230..e33e002787 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1373,17 +1373,17 @@ void getvcols(win_T *wp, pos_T *pos1, pos_T *pos2, colnr_T *left, /// skipwhite: skip over ' ' and '\t'. /// -/// @param q +/// @param[in] q String to skip in. /// /// @return Pointer to character after the skipped whitespace. -char_u* skipwhite(char_u *q) +char_u *skipwhite(const char_u *q) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { - char_u *p = q; + const char_u *p = q; while (ascii_iswhite(*p)) { - // skip to next non-white p++; } - return p; + return (char_u *)p; } /// skip over digits diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 53540d21d4..9a8ff21263 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -1859,8 +1859,9 @@ static bool check_compl_option(bool dict_opt) : (*curbuf->b_p_tsr == NUL && *p_tsr == NUL)) { ctrl_x_mode = 0; edit_submode = NULL; - msg_attr(dict_opt ? (char_u *)_("'dictionary' option is empty") - : (char_u *)_("'thesaurus' option is empty"), hl_attr(HLF_E)); + msg_attr((dict_opt + ? _("'dictionary' option is empty") + : _("'thesaurus' option is empty")), hl_attr(HLF_E)); if (emsg_silent == 0) { vim_beep(BO_COMPL); setcursor(); @@ -4801,9 +4802,9 @@ static int ins_complete(int c, bool enable_pum) if (!shortmess(SHM_COMPLETIONMENU)) { if (edit_submode_extra != NULL) { if (!p_smd) { - msg_attr(edit_submode_extra, - edit_submode_highl < HLF_COUNT - ? hl_attr(edit_submode_highl) : 0); + msg_attr((const char *)edit_submode_extra, + (edit_submode_highl < HLF_COUNT + ? hl_attr(edit_submode_highl) : 0)); } } else { msg_clr_cmdline(); // necessary for "noshowmode" diff --git a/src/nvim/eval.c b/src/nvim/eval.c index bbb6565509..eeb9f45bbc 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -1454,13 +1454,13 @@ void ex_let(exarg_T *eap) if (*expr != '=' && !(vim_strchr((char_u *)"+-.", *expr) != NULL && expr[1] == '=')) { // ":let" without "=": list variables - if (*arg == '[') + if (*arg == '[') { EMSG(_(e_invarg)); - else if (!ends_excmd(*arg)) - /* ":let var1 var2" */ - arg = list_arg_vars(eap, arg, &first); - else if (!eap->skip) { - /* ":let" */ + } else if (!ends_excmd(*arg)) { + // ":let var1 var2" + arg = (char_u *)list_arg_vars(eap, (const char *)arg, &first); + } else if (!eap->skip) { + // ":let" list_glob_vars(&first); list_buf_vars(&first); list_win_vars(&first); @@ -1644,7 +1644,8 @@ static char_u *skip_var_one(char_u *arg) * List variables for hashtab "ht" with prefix "prefix". * If "empty" is TRUE also list NULL strings as empty strings. */ -static void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *first) +static void list_hashtable_vars(hashtab_T *ht, const char *prefix, int empty, + int *first) { hashitem_T *hi; dictitem_T *di; @@ -1653,11 +1654,12 @@ static void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *f todo = (int)ht->ht_used; for (hi = ht->ht_array; todo > 0 && !got_int; ++hi) { if (!HASHITEM_EMPTY(hi)) { - --todo; + todo--; di = HI2DI(hi); if (empty || di->di_tv.v_type != VAR_STRING - || di->di_tv.vval.v_string != NULL) + || di->di_tv.vval.v_string != NULL) { list_one_var(di, prefix, first); + } } } } @@ -1667,7 +1669,7 @@ static void list_hashtable_vars(hashtab_T *ht, char_u *prefix, int empty, int *f */ static void list_glob_vars(int *first) { - list_hashtable_vars(&globvarht, (char_u *)"", TRUE, first); + list_hashtable_vars(&globvarht, "", true, first); } /* @@ -1675,14 +1677,13 @@ static void list_glob_vars(int *first) */ static void list_buf_vars(int *first) { - char_u numbuf[NUMBUFLEN]; + char numbuf[NUMBUFLEN]; - list_hashtable_vars(&curbuf->b_vars->dv_hashtab, (char_u *)"b:", - TRUE, first); + list_hashtable_vars(&curbuf->b_vars->dv_hashtab, "b:", true, first); - sprintf((char *)numbuf, "%" PRId64, (int64_t)curbuf->b_changedtick); - list_one_var_a((char_u *)"b:", (char_u *)"changedtick", VAR_NUMBER, - numbuf, first); + snprintf(numbuf, sizeof(numbuf), "%d", curbuf->b_changedtick); + list_one_var_a("b:", "changedtick", sizeof("changedtick") - 1, VAR_NUMBER, + numbuf, first); } /* @@ -1690,8 +1691,7 @@ static void list_buf_vars(int *first) */ static void list_win_vars(int *first) { - list_hashtable_vars(&curwin->w_vars->dv_hashtab, - (char_u *)"w:", TRUE, first); + list_hashtable_vars(&curwin->w_vars->dv_hashtab, "w:", true, first); } /* @@ -1699,8 +1699,7 @@ static void list_win_vars(int *first) */ static void list_tab_vars(int *first) { - list_hashtable_vars(&curtab->tp_vars->dv_hashtab, - (char_u *)"t:", TRUE, first); + list_hashtable_vars(&curtab->tp_vars->dv_hashtab, "t:", true, first); } /* @@ -1708,7 +1707,7 @@ static void list_tab_vars(int *first) */ static void list_vim_vars(int *first) { - list_hashtable_vars(&vimvarht, (char_u *)"v:", FALSE, first); + list_hashtable_vars(&vimvarht, "v:", false, first); } /* @@ -1716,9 +1715,9 @@ static void list_vim_vars(int *first) */ static void list_script_vars(int *first) { - if (current_SID > 0 && current_SID <= ga_scripts.ga_len) - list_hashtable_vars(&SCRIPT_VARS(current_SID), - (char_u *)"s:", FALSE, first); + if (current_SID > 0 && current_SID <= ga_scripts.ga_len) { + list_hashtable_vars(&SCRIPT_VARS(current_SID), "s:", false, first); + } } /* @@ -1726,35 +1725,36 @@ static void list_script_vars(int *first) */ static void list_func_vars(int *first) { - if (current_funccal != NULL) - list_hashtable_vars(¤t_funccal->l_vars.dv_hashtab, - (char_u *)"l:", FALSE, first); + if (current_funccal != NULL) { + list_hashtable_vars(¤t_funccal->l_vars.dv_hashtab, "l:", false, + first); + } } /* * List variables in "arg". */ -static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first) +static const char *list_arg_vars(exarg_T *eap, const char *arg, int *first) { int error = FALSE; int len; - char_u *name; - char_u *name_start; - char_u *arg_subsc; - char_u *tofree; + const char *name; + const char *name_start; typval_T tv; while (!ends_excmd(*arg) && !got_int) { if (error || eap->skip) { - arg = find_name_end(arg, NULL, NULL, FNE_INCL_BR | FNE_CHECK_START); + arg = (const char *)find_name_end((char_u *)arg, NULL, NULL, + FNE_INCL_BR | FNE_CHECK_START); if (!ascii_iswhite(*arg) && !ends_excmd(*arg)) { emsg_severe = TRUE; EMSG(_(e_trailing)); break; } } else { - /* get_name_len() takes care of expanding curly braces */ + // get_name_len() takes care of expanding curly braces name_start = name = arg; + char *tofree; len = get_name_len(&arg, &tofree, TRUE, TRUE); if (len <= 0) { /* This is mainly to keep test 49 working: when expanding @@ -1769,14 +1769,15 @@ static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first) if (tofree != NULL) { name = tofree; } - if (get_var_tv(name, len, &tv, NULL, true, false) == FAIL) { + if (get_var_tv((const char *)name, len, &tv, NULL, true, false) + == FAIL) { error = true; } else { // handle d.key, l[idx], f(expr) - arg_subsc = arg; - if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) - error = TRUE; - else { + const char *const arg_subsc = arg; + if (handle_subscript(&arg, &tv, TRUE, TRUE) == FAIL) { + error = true; + } else { if (arg == arg_subsc && len == 2 && name[1] == ':') { switch (*name) { case 'g': list_glob_vars(first); break; @@ -1790,17 +1791,15 @@ static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first) EMSG2(_("E738: Can't list variables for %s"), name); } } else { - int c; - - char_u *s = (char_u *) encode_tv2echo(&tv, NULL); - c = *arg; - *arg = NUL; - list_one_var_a((char_u *)"", - arg == arg_subsc ? name : name_start, - tv.v_type, - s == NULL ? (char_u *)"" : s, - first); - *arg = c; + char *const s = encode_tv2echo(&tv, NULL); + const char *const used_name = (arg == arg_subsc + ? name + : name_start); + const ptrdiff_t name_size = (used_name == tofree + ? (ptrdiff_t)strlen(used_name) + : (arg - used_name)); + list_one_var_a("", used_name, name_size, + tv.v_type, s == NULL ? "" : s, first); xfree(s); } clear_tv(&tv); @@ -1811,7 +1810,7 @@ static char_u *list_arg_vars(exarg_T *eap, char_u *arg, int *first) xfree(tofree); } - arg = skipwhite(arg); + arg = (const char *)skipwhite((const char_u *)arg); } return arg; @@ -1831,9 +1830,7 @@ ex_let_one ( char_u *op /* "+", "-", "." or NULL*/ ) { - int c1; char_u *name; - char_u *p; char_u *arg_end = NULL; int len; int opt_flags; @@ -1856,9 +1853,9 @@ ex_let_one ( && vim_strchr(endchars, *skipwhite(arg)) == NULL) EMSG(_(e_letunexp)); else if (!check_secure()) { - c1 = name[len]; + const char_u c1 = name[len]; name[len] = NUL; - p = get_tv_string_chk(tv); + char_u *p = get_tv_string_chk(tv); if (p != NULL && op != NULL && *op == '.') { char *s = vim_getenv((char *)name); @@ -1882,33 +1879,30 @@ ex_let_one ( xfree(tofree); } } - } - /* - * ":let &option = expr": Set option value. - * ":let &l:option = expr": Set local option value. - * ":let &g:option = expr": Set global option value. - */ - else if (*arg == '&') { - /* Find the end of the name. */ - p = find_option_end(&arg, &opt_flags); - if (p == NULL || (endchars != NULL - && vim_strchr(endchars, *skipwhite(p)) == NULL)) + // ":let &option = expr": Set option value. + // ":let &l:option = expr": Set local option value. + // ":let &g:option = expr": Set global option value. + } else if (*arg == '&') { + // Find the end of the name. + char *const p = (char *)find_option_end((const char **)&arg, &opt_flags); + if (p == NULL + || (endchars != NULL + && vim_strchr(endchars, *skipwhite((const char_u *)p)) == NULL)) { EMSG(_(e_letunexp)); - else { + } else { long n; int opt_type; long numval; - char_u *stringval = NULL; - char_u *s; + char_u *stringval = NULL; + char_u *s; - c1 = *p; + const char c1 = *p; *p = NUL; n = get_tv_number(tv); s = get_tv_string_chk(tv); /* != NULL if number or string */ if (s != NULL && op != NULL && *op != '=') { - opt_type = get_option_value(arg, &numval, - &stringval, opt_flags); + opt_type = get_option_value(arg, &numval, &stringval, opt_flags); if ((opt_type == 1 && *op == '.') || (opt_type == 0 && *op != '.')) EMSG2(_(e_letwrong), op); @@ -1927,7 +1921,7 @@ ex_let_one ( } if (s != NULL) { set_option_value(arg, n, s, opt_flags); - arg_end = p; + arg_end = (char_u *)p; } *p = c1; xfree(stringval); @@ -1947,7 +1941,7 @@ ex_let_one ( char_u *ptofree = NULL; char_u *s; - p = get_tv_string_chk(tv); + char_u *p = get_tv_string_chk(tv); if (p != NULL && op != NULL && *op == '.') { s = get_reg_contents(*arg == '@' ? '"' : *arg, kGRegExprSrc); if (s != NULL) { @@ -1969,7 +1963,7 @@ ex_let_one ( else if (eval_isnamec1(*arg) || *arg == '{') { lval_T lv; - p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START); + char_u *const p = get_lval(arg, tv, &lv, FALSE, FALSE, 0, FNE_CHECK_START); if (p != NULL && lv.ll_name != NULL) { if (endchars != NULL && vim_strchr(endchars, *skipwhite(p)) == NULL) EMSG(_(e_letunexp)); @@ -2079,7 +2073,8 @@ get_lval ( cc = *p; *p = NUL; - v = find_var(lp->ll_name, &ht, flags & GLV_NO_AUTOLOAD); + v = find_var((const char *)lp->ll_name, STRLEN(lp->ll_name), &ht, + flags & GLV_NO_AUTOLOAD); if (v == NULL && !quiet) EMSG2(_(e_undefvar), lp->ll_name); *p = cc; @@ -2341,7 +2336,7 @@ static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, ch // handle +=, -= and .= di = NULL; - if (get_var_tv(lp->ll_name, (int)STRLEN(lp->ll_name), + if (get_var_tv((const char *)lp->ll_name, (int)STRLEN(lp->ll_name), &tv, &di, true, false) == OK) { if ((di == NULL || (!var_check_ro(di->di_flags, lp->ll_name, false) @@ -2817,7 +2812,7 @@ void ex_call(exarg_T *eap) // contents. For VAR_PARTIAL get its partial, unless we already have one // from trans_function_name(). len = (int)STRLEN(tofree); - name = deref_func_name(tofree, &len, + name = deref_func_name((const char *)tofree, &len, partial != NULL ? NULL : &partial, false); /* Skip white space to allow ":call func ()". Not good, but required for @@ -2856,7 +2851,7 @@ void ex_call(exarg_T *eap) } /* Handle a function returning a Funcref, Dictionary or List. */ - if (handle_subscript(&arg, &rettv, !eap->skip, TRUE) == FAIL) { + if (handle_subscript((const char **)&arg, &rettv, !eap->skip, TRUE) == FAIL) { failed = TRUE; break; } @@ -3046,7 +3041,8 @@ int do_unlet(char_u *name, int forceit) dict_T *d; dictitem_T *di; dict_T *dict; - ht = find_var_ht_dict(name, &varname, &dict); + ht = find_var_ht_dict((const char *)name, STRLEN(name), + (const char **)&varname, &dict); if (ht != NULL && *varname != NUL) { if (ht == &globvarht) { @@ -3057,7 +3053,7 @@ int do_unlet(char_u *name, int forceit) } else if (ht == &compat_hashtab) { d = &vimvardict; } else { - di = find_var_in_ht(ht, *name, (char_u *)"", false); + di = find_var_in_ht(ht, *name, "", 0, false); d = di->di_tv.vval.v_dict; } if (d == NULL) { @@ -3121,7 +3117,7 @@ static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock) if (check_changedtick(lp->ll_name)) ret = FAIL; else { - di = find_var(lp->ll_name, NULL, TRUE); + di = find_var((const char *)lp->ll_name, STRLEN(lp->ll_name), NULL, true); if (di == NULL) ret = FAIL; else { @@ -4305,9 +4301,10 @@ static int eval7( break; // Option value: &name - case '&': ret = get_option_tv(arg, rettv, evaluate); + case '&': { + ret = get_option_tv((const char **)arg, rettv, evaluate); break; - + } // Environment variable: $VAR. case '$': ret = get_env_tv(arg, rettv, evaluate); break; @@ -4343,7 +4340,7 @@ static int eval7( // Must be a variable or function name. // Can also be a curly-braces kind of name: {expr}. s = *arg; - len = get_name_len(arg, &alias, evaluate, true); + len = get_name_len((const char **)arg, (char **)&alias, evaluate, true); if (alias != NULL) { s = alias; } @@ -4355,7 +4352,7 @@ static int eval7( partial_T *partial; // If "s" is the name of a variable of type VAR_FUNC // use its contents. - s = deref_func_name(s, &len, &partial, !evaluate); + s = deref_func_name((const char *)s, &len, &partial, !evaluate); // Invoke the function. ret = get_func_tv(s, len, rettv, arg, @@ -4380,7 +4377,7 @@ static int eval7( ret = FAIL; } } else if (evaluate) { - ret = get_var_tv(s, len, rettv, NULL, true, false); + ret = get_var_tv((const char *)s, len, rettv, NULL, true, false); } else { ret = OK; } @@ -4393,7 +4390,7 @@ static int eval7( // Handle following '[', '(' and '.' for expr[expr], expr.name, // expr(expr). if (ret == OK) { - ret = handle_subscript(arg, rettv, evaluate, true); + ret = handle_subscript((const char **)arg, rettv, evaluate, true); } // Apply logical NOT and unary '-', from right to left, ignore '+'. @@ -4694,35 +4691,32 @@ eval_index ( return OK; } -/* - * Get an option value. - * "arg" points to the '&' or '+' before the option name. - * "arg" is advanced to character after the option name. - * Return OK or FAIL. - */ -static int -get_option_tv ( - char_u **arg, - typval_T *rettv, /* when NULL, only check if option exists */ - int evaluate -) +/// Get an option value +/// +/// @param[in,out] arg Points to the '&' or '+' before the option name. Is +/// advanced to the character after the option name. +/// @param[out] rettv Location where result is saved. +/// @param[in] evaluate If not true, rettv is not populated. +/// +/// @return OK or FAIL. +static int get_option_tv(const char **const arg, typval_T *const rettv, + const bool evaluate) + FUNC_ATTR_NONNULL_ARG(1) { - char_u *option_end; long numval; char_u *stringval; int opt_type; int c; - int working = (**arg == '+'); /* has("+option") */ + bool working = (**arg == '+'); // has("+option") int ret = OK; int opt_flags; - /* - * Isolate the option name and find its value. - */ - option_end = find_option_end(arg, &opt_flags); + // Isolate the option name and find its value. + char *option_end = (char *)find_option_end(arg, &opt_flags); if (option_end == NULL) { - if (rettv != NULL) + if (rettv != NULL) { EMSG2(_("E112: Option name missing: %s"), *arg); + } return FAIL; } @@ -4733,8 +4727,8 @@ get_option_tv ( c = *option_end; *option_end = NUL; - opt_type = get_option_value(*arg, &numval, - rettv == NULL ? NULL : &stringval, opt_flags); + opt_type = get_option_value((char_u *)*arg, &numval, + rettv == NULL ? NULL : &stringval, opt_flags); if (opt_type == -3) { /* invalid name */ if (rettv != NULL) @@ -6994,40 +6988,45 @@ static VimLFuncDef *find_internal_func(const char *const name) return find_internal_func_gperf(name, len); } -/// Check if "name" is a variable of type VAR_FUNC. If so, return the function -/// name it contains, otherwise return "name". -/// If "partialp" is not NULL, and "name" is of type VAR_PARTIAL also set -/// "partialp". -static char_u *deref_func_name( - char_u *name, int *lenp, - partial_T **partialp, bool no_autoload -) +/// Return name of the function corresponding to `name` +/// +/// If `name` points to variable that is either a function or partial then +/// corresponding function name is returned. Otherwise it returns `name` itself. +/// +/// @param[in] name Function name to check. +/// @param[in,out] lenp Location where length of the returned name is stored. +/// Must be set to the length of the `name` argument. +/// @param[out] partialp Location where partial will be stored if found +/// function appears to be a partial. May be NULL if this +/// is not needed. +/// @param[in] no_autoload If true, do not source autoload scripts if function +/// was not found. +/// +/// @return name of the function. +static char_u *deref_func_name(const char *name, int *lenp, + partial_T **const partialp, bool no_autoload) + FUNC_ATTR_NONNULL_ARG(1, 2) { - dictitem_T *v; - int cc; if (partialp != NULL) { *partialp = NULL; } - cc = name[*lenp]; - name[*lenp] = NUL; - v = find_var(name, NULL, no_autoload); - name[*lenp] = cc; + dictitem_T *const v = find_var(name, (size_t)*lenp, NULL, no_autoload); if (v != NULL && v->di_tv.v_type == VAR_FUNC) { - if (v->di_tv.vval.v_string == NULL) { + if (v->di_tv.vval.v_string == NULL) { // just in case *lenp = 0; - return (char_u *)""; /* just in case */ + return (char_u *)""; } *lenp = (int)STRLEN(v->di_tv.vval.v_string); return v->di_tv.vval.v_string; } if (v != NULL && v->di_tv.v_type == VAR_PARTIAL) { - partial_T *pt = v->di_tv.vval.v_partial; + partial_T *const pt = v->di_tv.vval.v_partial; - if (pt == NULL) { + if (pt == NULL) { // just in case *lenp = 0; - return (char_u *)""; // just in case + return (char_u *)""; } if (partialp != NULL) { *partialp = pt; @@ -7036,7 +7035,7 @@ static char_u *deref_func_name( return pt->pt_name; } - return name; + return (char_u *)name; } /* @@ -7103,33 +7102,48 @@ get_func_tv ( return ret; } -#define ERROR_UNKNOWN 0 -#define ERROR_TOOMANY 1 -#define ERROR_TOOFEW 2 -#define ERROR_SCRIPT 3 -#define ERROR_DICT 4 -#define ERROR_NONE 5 -#define ERROR_OTHER 6 -#define ERROR_BOTH 7 +typedef enum { + ERROR_UNKNOWN = 0, + ERROR_TOOMANY, + ERROR_TOOFEW, + ERROR_SCRIPT, + ERROR_DICT, + ERROR_NONE, + ERROR_OTHER, + ERROR_BOTH, +} FnameTransError; + #define FLEN_FIXED 40 -/// In a script change name() and s:name() to K_SNR 123_name(). -/// Change 123_name() to K_SNR 123_name(). -/// Use "fname_buf[FLEN_FIXED + 1]" when it fits, otherwise allocate memory -/// (slow). -static char_u * -fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error) { - int llen; +/// In a script transform script-local names into actually used names +/// +/// Transforms "" and "s:" prefixes to `K_SNR {N}` (e.g. K_SNR "123") and +/// "" prefix to `K_SNR`. Uses `fname_buf` buffer that is supposed to have +/// #FLEN_FIXED + 1 length when it fits, otherwise it allocates memory. +/// +/// @param[in] name Name to transform. +/// @param fname_buf Buffer to save resulting function name to, if it fits. +/// Must have at least #FLEN_FIXED + 1 length. +/// @param[out] tofree Location where pointer to an allocated memory is saved +/// in case result does not fit into fname_buf. +/// @param[out] error Location where error type is saved, @see +/// FnameTransError. +/// +/// @return transformed name: either `fname_buf` or a pointer to an allocated +/// memory. +static char_u *fname_trans_sid(const char_u *const name, + char_u *const fname_buf, + char_u **const tofree, int *const error) + FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +{ char_u *fname; - int i; - - llen = eval_fname_script(name); + const int llen = eval_fname_script((const char *)name); if (llen > 0) { fname_buf[0] = K_SPECIAL; fname_buf[1] = KS_EXTRA; fname_buf[2] = (int)KE_SNR; - i = 3; - if (eval_fname_sid(name)) { // "" or "s:" + int i = 3; + if (eval_fname_sid((const char *)name)) { // "" or "s:" if (current_SID <= 0) { *error = ERROR_SCRIPT; } else { @@ -7152,7 +7166,7 @@ fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error) { } } } else { - fname = name; + fname = (char_u *)name; } return fname; @@ -7235,7 +7249,7 @@ call_func( rettv->vval.v_number = 0; error = ERROR_UNKNOWN; - if (!builtin_function(rfname, -1)) { + if (!builtin_function((const char *)rfname, -1)) { /* * User defined function. */ @@ -7248,8 +7262,9 @@ call_func( /* executed an autocommand, search for the function again */ fp = find_func(rfname); } - /* Try loading a package. */ - if (fp == NULL && script_autoload(rfname, TRUE) && !aborting()) { + // Try loading a package. + if (fp == NULL && script_autoload((const char *)rfname, STRLEN(rfname), + true) && !aborting()) { /* loaded a package, search for the function again */ fp = find_func(rfname); } @@ -7272,7 +7287,7 @@ call_func( } } else { // Find the function name in the table, call its implementation. - VimLFuncDef *const fdef = find_internal_func((char *)fname); + VimLFuncDef *const fdef = find_internal_func((const char *)fname); if (fdef != NULL) { if (argcount < fdef->min_argc) { error = ERROR_TOOFEW; @@ -7952,17 +7967,17 @@ static buf_T *get_buf_tv(typval_T *tv, int curtab_only) */ static void f_bufname(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - buf_T *buf; - - (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ - ++emsg_off; - buf = get_buf_tv(&argvars[0], FALSE); rettv->v_type = VAR_STRING; - if (buf != NULL && buf->b_fname != NULL) - rettv->vval.v_string = vim_strsave(buf->b_fname); - else - rettv->vval.v_string = NULL; - --emsg_off; + rettv->vval.v_string = NULL; + if (!tv_check_str_or_nr(&argvars[0])) { + return; + } + emsg_off++; + const buf_T *const buf = get_buf_tv(&argvars[0], false); + emsg_off--; + if (buf != NULL && buf->b_fname != NULL) { + rettv->vval.v_string = (char_u *)xstrdup((char *)buf->b_fname); + } } /* @@ -7970,36 +7985,36 @@ static void f_bufname(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_bufnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - buf_T *buf; - int error = FALSE; - char_u *name; + int error = false; + char_u *name; - (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ - ++emsg_off; - buf = get_buf_tv(&argvars[0], FALSE); - --emsg_off; + rettv->vval.v_number = -1; + if (!tv_check_str_or_nr(&argvars[0])) { + return; + } + emsg_off++; + const buf_T *buf = get_buf_tv(&argvars[0], false); + emsg_off--; - /* If the buffer isn't found and the second argument is not zero create a - * new buffer. */ + // If the buffer isn't found and the second argument is not zero create a + // new buffer. if (buf == NULL && argvars[1].v_type != VAR_UNKNOWN && get_tv_number_chk(&argvars[1], &error) != 0 && !error && (name = get_tv_string_chk(&argvars[0])) != NULL - && !error) + && !error) { buf = buflist_new(name, NULL, (linenr_T)1, 0); + } - if (buf != NULL) + if (buf != NULL) { rettv->vval.v_number = buf->b_fnum; - else - rettv->vval.v_number = -1; + } } static void buf_win_common(typval_T *argvars, typval_T *rettv, bool get_nr) { - int error = false; - (void)get_tv_number_chk(&argvars[0], &error); // issue errmsg if type error - if (error) { // the argument has an invalid type + if (!tv_check_str_or_nr(&argvars[0])) { rettv->vval.v_number = -1; return; } @@ -8043,14 +8058,13 @@ static void f_bufwinnr(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_byte2line(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - long boff = 0; - - boff = get_tv_number(&argvars[0]) - 1; /* boff gets -1 on type error */ - if (boff < 0) + long boff = get_tv_number(&argvars[0]) - 1; + if (boff < 0) { rettv->vval.v_number = -1; - else - rettv->vval.v_number = ml_find_line_or_offset(curbuf, - (linenr_T)0, &boff); + } else { + rettv->vval.v_number = (varnumber_T)ml_find_line_or_offset(curbuf, 0, + &boff); + } } static void byteidx(typval_T *argvars, typval_T *rettv, int comp) @@ -8914,53 +8928,55 @@ static void f_exepath(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_exists(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - char_u *p; - char_u *name; - int n = FALSE; + int n = false; int len = 0; - p = get_tv_string(&argvars[0]); - if (*p == '$') { /* environment variable */ - /* first try "normal" environment variables (fast) */ - if (os_getenv((char *)(p + 1)) != NULL) - n = TRUE; - else { - /* try expanding things like $VIM and ${HOME} */ - p = expand_env_save(p); - if (p != NULL && *p != '$') - n = TRUE; + char *p = (char *)get_tv_string(&argvars[0]); + if (*p == '$') { // Environment variable. + // First try "normal" environment variables (fast). + if (os_getenv(p + 1) != NULL) { + n = true; + } else { + // Try expanding things like $VIM and ${HOME}. + p = (char *)expand_env_save((char_u *)p); + if (p != NULL && *p != '$') { + n = true; + } xfree(p); } - } else if (*p == '&' || *p == '+') { /* option */ - n = (get_option_tv(&p, NULL, TRUE) == OK); - if (*skipwhite(p) != NUL) - n = FALSE; /* trailing garbage */ - } else if (*p == '*') { /* internal or user defined function */ + } else if (*p == '&' || *p == '+') { // Option. + n = (get_option_tv((const char **)&p, NULL, true) == OK); + if (*skipwhite((const char_u *)p) != NUL) { + n = false; // Trailing garbage. + } + } else if (*p == '*') { // Internal or user defined function. n = function_exists(p + 1); } else if (*p == ':') { n = cmd_exists(p + 1); } else if (*p == '#') { - if (p[1] == '#') + if (p[1] == '#') { n = autocmd_supported(p + 2); - else + } else { n = au_exists(p + 1); - } else { /* internal variable */ - char_u *tofree; + } + } else { // Internal variable. typval_T tv; - /* get_name_len() takes care of expanding curly braces */ - name = p; - len = get_name_len(&p, &tofree, TRUE, FALSE); + // get_name_len() takes care of expanding curly braces + const char *name = p; + char *tofree; + len = get_name_len((const char **)&p, &tofree, TRUE, FALSE); if (len > 0) { if (tofree != NULL) { name = tofree; } n = (get_var_tv(name, len, &tv, NULL, false, true) == OK); if (n) { - /* handle d.key, l[idx], f(expr) */ - n = (handle_subscript(&p, &tv, TRUE, FALSE) == OK); - if (n) + // Handle d.key, l[idx], f(expr). + n = (handle_subscript((const char **)&p, &tv, true, false) == OK); + if (n) { clear_tv(&tv); + } } } if (*p != NUL) @@ -9683,7 +9699,7 @@ static void f_function(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (s == NULL || *s == NUL || (use_string && ascii_isdigit(*s))) { EMSG2(_(e_invarg2), s); } else if (use_string && vim_strchr(s, AUTOLOAD_CHAR) == NULL - && !function_exists(s)) { + && !function_exists((const char *)s)) { // Don't check an autoload name for existence here. EMSG2(_("E700: Unknown function: %s"), s); } else { @@ -10052,20 +10068,22 @@ static void f_getbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) { linenr_T lnum; linenr_T end; - buf_T *buf; + buf_T *buf = NULL; - (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ - ++emsg_off; - buf = get_buf_tv(&argvars[0], FALSE); - --emsg_off; + if (tv_check_str_or_nr(&argvars[0])) { + emsg_off++; + buf = get_buf_tv(&argvars[0], false); + emsg_off--; + } lnum = get_tv_lnum_buf(&argvars[1], buf); - if (argvars[2].v_type == VAR_UNKNOWN) + if (argvars[2].v_type == VAR_UNKNOWN) { end = lnum; - else + } else { end = get_tv_lnum_buf(&argvars[2], buf); + } - get_buffer_lines(buf, lnum, end, TRUE, rettv); + get_buffer_lines(buf, lnum, end, true, rettv); } /* @@ -10073,26 +10091,25 @@ static void f_getbufline(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - buf_T *buf; - buf_T *save_curbuf; - char_u *varname; - dictitem_T *v; - int done = FALSE; - - (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ - varname = get_tv_string_chk(&argvars[1]); - ++emsg_off; - buf = get_buf_tv(&argvars[0], FALSE); + bool done = false; rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; + if (!tv_check_str_or_nr(&argvars[0])) { + goto f_getbufvar_end; + } + + const char *varname = (const char *)get_tv_string_chk(&argvars[1]); + emsg_off++; + buf_T *const buf = get_buf_tv(&argvars[0], false); + if (buf != NULL && varname != NULL) { - /* set curbuf to be our buf, temporarily */ - save_curbuf = curbuf; + // set curbuf to be our buf, temporarily + buf_T *const save_curbuf = curbuf; curbuf = buf; - if (*varname == '&') { // buffer-local-option + if (*varname == '&') { // buffer-local-option if (varname[1] == NUL) { // get all buffer-local options in a dict dict_T *opts = get_winbuf_options(true); @@ -10112,25 +10129,26 @@ static void f_getbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) rettv->vval.v_number = curbuf->b_changedtick; done = true; } else { - /* Look up the variable. */ - /* Let getbufvar({nr}, "") return the "b:" dictionary. */ - v = find_var_in_ht(&curbuf->b_vars->dv_hashtab, - 'b', varname, FALSE); + // Look up the variable. + // Let getbufvar({nr}, "") return the "b:" dictionary. + dictitem_T *const v = find_var_in_ht(&curbuf->b_vars->dv_hashtab, 'b', + varname, strlen(varname), false); if (v != NULL) { copy_tv(&v->di_tv, rettv); - done = TRUE; + done = true; } } - /* restore previous notion of curbuf */ + // restore previous notion of curbuf curbuf = save_curbuf; } + emsg_off--; - if (!done && argvars[2].v_type != VAR_UNKNOWN) - /* use the default value */ +f_getbufvar_end: + if (!done && argvars[2].v_type != VAR_UNKNOWN) { + // use the default value copy_tv(&argvars[2], rettv); - - --emsg_off; + } } /* @@ -10898,13 +10916,12 @@ static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) win_T *oldcurwin; tabpage_T *tp, *oldtabpage; dictitem_T *v; - char_u *varname; bool done = false; rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; - varname = get_tv_string_chk(&argvars[1]); + const char *const varname = (const char *)get_tv_string_chk(&argvars[1]); tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); if (tp != NULL && varname != NULL) { // Set tp to be our tabpage, temporarily. Also set the window to the @@ -10913,7 +10930,8 @@ static void f_gettabvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) if (switch_win(&oldcurwin, &oldtabpage, window, tp, true) == OK) { // look up the variable // Let gettabvar({nr}, "") return the "t:" dictionary. - v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', varname, FALSE); + v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', + varname, strlen(varname), false); if (v != NULL) { copy_tv(&v->di_tv, rettv); done = true; @@ -11092,7 +11110,6 @@ getwinvar ( ) { win_T *win, *oldcurwin; - char_u *varname; dictitem_T *v; tabpage_T *tp = NULL; tabpage_T *oldtabpage = NULL; @@ -11103,12 +11120,13 @@ getwinvar ( else tp = curtab; win = find_win_by_nr(&argvars[off], tp); - varname = get_tv_string_chk(&argvars[off + 1]); - ++emsg_off; + const char *varname = (const char *)get_tv_string_chk( + &argvars[off + 1]); rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; + emsg_off++; if (win != NULL && varname != NULL) { // Set curwin to be our win, temporarily. Also set the tabpage, // otherwise the window is not valid. Only do this when needed, @@ -11134,7 +11152,8 @@ getwinvar ( } else { // Look up the variable. // Let getwinvar({nr}, "") return the "w:" dictionary. - v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w', varname, FALSE); + v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w', varname, + strlen(varname), false); if (v != NULL) { copy_tv(&v->di_tv, rettv); done = true; @@ -11147,12 +11166,12 @@ getwinvar ( restore_win(oldcurwin, oldtabpage, true); } } + emsg_off--; - if (!done && argvars[off + 2].v_type != VAR_UNKNOWN) - /* use the default return value */ + if (!done && argvars[off + 2].v_type != VAR_UNKNOWN) { + // use the default return value copy_tv(&argvars[off + 2], rettv); - - --emsg_off; + } } /* @@ -11817,7 +11836,7 @@ static void get_user_input(typval_T *argvars, typval_T *rettv, int inputdialog) *p = NUL; msg_start(); msg_clr_eos(); - msg_puts_attr(prompt, echo_attr); + msg_puts_attr((const char *)prompt, echo_attr); msg_didout = FALSE; msg_starthere(); *p = c; @@ -11910,7 +11929,7 @@ static void f_inputlist(typval_T *argvars, typval_T *rettv, FunPtr fptr) msg_clr_eos(); for (li = argvars[0].vval.v_list->lv_first; li != NULL; li = li->li_next) { - msg_puts(get_tv_string(&li->li_tv)); + msg_puts((const char *)get_tv_string(&li->li_tv)); msg_putchar('\n'); } @@ -12035,10 +12054,11 @@ static void f_islocked(typval_T *argvars, typval_T *rettv, FunPtr fptr) EMSG(_(e_trailing)); else { if (lv.ll_tv == NULL) { - if (check_changedtick(lv.ll_name)) - rettv->vval.v_number = 1; /* always locked */ - else { - di = find_var(lv.ll_name, NULL, TRUE); + if (check_changedtick(lv.ll_name)) { + rettv->vval.v_number = 1; // Always locked. + } else { + di = find_var((const char *)lv.ll_name, STRLEN(lv.ll_name), NULL, + true); if (di != NULL) { /* Consider a variable locked when: * 1. the variable itself is locked @@ -12880,7 +12900,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) if (rhs != NULL) { // Return a dictionary. char_u *lhs = str2special_save(mp->m_keys, TRUE); - char_u *mapmode = map_mode_to_chars(mp->m_mode); + char *const mapmode = map_mode_to_chars(mp->m_mode); dict_T *dict = rettv->vval.v_dict; dict_add_nr_str(dict, "lhs", 0L, lhs); @@ -12891,7 +12911,7 @@ static void get_maparg(typval_T *argvars, typval_T *rettv, int exact) dict_add_nr_str(dict, "sid", (long)mp->m_script_ID, NULL); dict_add_nr_str(dict, "buffer", (long)buffer_local, NULL); dict_add_nr_str(dict, "nowait", mp->m_nowait ? 1L : 0L, NULL); - dict_add_nr_str(dict, "mode", 0L, mapmode); + dict_add_nr_str(dict, "mode", 0L, (char_u *)mapmode); xfree(lhs); xfree(mapmode); @@ -15108,44 +15128,45 @@ static void f_serverstop(typval_T *argvars, typval_T *rettv, FunPtr fptr) */ static void f_setbufvar(typval_T *argvars, typval_T *rettv, FunPtr fptr) { - buf_T *buf; - char_u *varname, *bufvarname; - typval_T *varp; char_u nbuf[NUMBUFLEN]; - if (check_restricted() || check_secure()) + if (check_restricted() + || check_secure() + || !tv_check_str_or_nr(&argvars[0])) { return; - (void)get_tv_number(&argvars[0]); /* issue errmsg if type error */ - varname = get_tv_string_chk(&argvars[1]); - buf = get_buf_tv(&argvars[0], FALSE); - varp = &argvars[2]; + } + const char *varname = (const char *)get_tv_string_chk(&argvars[1]); + buf_T *const buf = get_buf_tv(&argvars[0], false); + typval_T *varp = &argvars[2]; if (buf != NULL && varname != NULL && varp != NULL) { if (*varname == '&') { long numval; - char_u *strval; + char_u *strval; int error = false; - aco_save_T aco; + aco_save_T aco; // set curbuf to be our buf, temporarily aucmd_prepbuf(&aco, buf); - ++varname; + varname++; numval = get_tv_number_chk(varp, &error); strval = get_tv_string_buf_chk(varp, nbuf); - if (!error && strval != NULL) - set_option_value(varname, numval, strval, OPT_LOCAL); + if (!error && strval != NULL) { + set_option_value((char_u *)varname, numval, strval, OPT_LOCAL); + } // reset notion of buffer aucmd_restbuf(&aco); } else { buf_T *save_curbuf = curbuf; - bufvarname = xmalloc(STRLEN(varname) + 3); + const size_t varname_len = STRLEN(varname); + char_u *const bufvarname = xmalloc(STRLEN(varname) + 3); curbuf = buf; - STRCPY(bufvarname, "b:"); - STRCPY(bufvarname + 2, varname); - set_var(bufvarname, varp, TRUE); + memcpy(bufvarname, "b:", 2); + memcpy(bufvarname + 2, varname, varname_len + 1); + set_var(bufvarname, varp, true); xfree(bufvarname); curbuf = save_curbuf; } @@ -16821,7 +16842,7 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr) break; case 'n': /* name */ - p = get_highlight_name(NULL, id - 1); + p = (char_u *)get_highlight_name(NULL, id - 1); break; case 'r': /* reverse */ @@ -18353,11 +18374,12 @@ static int get_env_len(char_u **arg) // Get the length of the name of a function or internal variable. // "arg" is advanced to the first non-white character after the name. // Return 0 if something is wrong. -static int get_id_len(char_u **arg) { - char_u *p; +static int get_id_len(const char **const arg) +{ int len; // Find the end of the name. + const char *p; for (p = *arg; eval_isnamec(*p); p++) { if (*p == ':') { // "s:" is start of "s:var", but "n:" is not and can be used in @@ -18374,7 +18396,7 @@ static int get_id_len(char_u **arg) { } len = (int)(p - *arg); - *arg = skipwhite(p); + *arg = (const char *)skipwhite((const char_u *)p); return len; } @@ -18388,17 +18410,19 @@ static int get_id_len(char_u **arg) { * If the name contains 'magic' {}'s, expand them and return the * expanded name in an allocated string via 'alias' - caller must free. */ -static int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose) +static int get_name_len(const char **const arg, + char **alias, + int evaluate, + int verbose) { int len; - char_u *p; char_u *expr_start; char_u *expr_end; *alias = NULL; /* default to no alias */ - if ((*arg)[0] == K_SPECIAL && (*arg)[1] == KS_EXTRA - && (*arg)[2] == (int)KE_SNR) { + if ((*arg)[0] == (char)K_SPECIAL && (*arg)[1] == (char)KS_EXTRA + && (*arg)[2] == (char)KE_SNR) { /* hard coded , already translated */ *arg += 3; return get_id_len(arg) + 3; @@ -18412,14 +18436,14 @@ static int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose) /* * Find the end of the name; check for {} construction. */ - p = find_name_end(*arg, &expr_start, &expr_end, - len > 0 ? 0 : FNE_CHECK_START); + const char *p = (const char *)find_name_end((char_u *)*arg, + &expr_start, + &expr_end, + len > 0 ? 0 : FNE_CHECK_START); if (expr_start != NULL) { - char_u *temp_string; - if (!evaluate) { len += (int)(p - *arg); - *arg = skipwhite(p); + *arg = (const char *)skipwhite((const char_u *)p); return len; } @@ -18427,11 +18451,13 @@ static int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose) * Include any etc in the expanded string: * Thus the -len here. */ - temp_string = make_expanded_name(*arg - len, expr_start, expr_end, p); - if (temp_string == NULL) + char_u *temp_string = make_expanded_name((char_u *)*arg - len, expr_start, + expr_end, (char_u *)p); + if (temp_string == NULL) { return -1; - *alias = temp_string; - *arg = skipwhite(p); + } + *alias = (char *)temp_string; + *arg = (const char *)skipwhite((const char_u *)p); return (int)STRLEN(temp_string); } @@ -18845,9 +18871,8 @@ char_u *set_cmdarg(exarg_T *eap, char_u *oldarg) * Get the value of internal variable "name". * Return OK or FAIL. */ -static int -get_var_tv ( - char_u *name, +static int get_var_tv( + const char *name, int len, // length of "name" typval_T *rettv, // NULL when only checking existence dictitem_T **dip, // non-NULL when typval's dict item is needed @@ -18859,25 +18884,16 @@ get_var_tv ( typval_T *tv = NULL; typval_T atv; dictitem_T *v; - int cc; - /* truncate the name, so that we can use strcmp() */ - cc = name[len]; - name[len] = NUL; - - /* - * Check for "b:changedtick". - */ - if (STRCMP(name, "b:changedtick") == 0) { + // Check for "b:changedtick". + if (sizeof("b:changedtick") - 1 == len + && STRNCMP(name, "b:changedtick", len) == 0) { atv.v_type = VAR_NUMBER; atv.vval.v_number = curbuf->b_changedtick; tv = &atv; - } - /* - * Check for user-defined variables. - */ - else { - v = find_var(name, NULL, no_autoload); + } else { + // Check for user-defined variables. + v = find_var(name, (size_t)len, NULL, no_autoload); if (v != NULL) { tv = &v->di_tv; if (dip != NULL) { @@ -18887,13 +18903,13 @@ get_var_tv ( } if (tv == NULL) { - if (rettv != NULL && verbose) - EMSG2(_(e_undefvar), name); + if (rettv != NULL && verbose) { + emsgf(_("E121: Undefined variable: %.*s"), len, name); + } ret = FAIL; - } else if (rettv != NULL) + } else if (rettv != NULL) { copy_tv(tv, rettv); - - name[len] = cc; + } return ret; } @@ -18905,7 +18921,7 @@ get_var_tv ( */ static int handle_subscript ( - char_u **arg, + const char **const arg, typval_T *rettv, int evaluate, /* do more than finding the end */ int verbose /* give error messages */ @@ -18940,7 +18956,7 @@ handle_subscript ( } else { s = (char_u *)""; } - ret = get_func_tv(s, (int)STRLEN(s), rettv, arg, + ret = get_func_tv(s, (int)STRLEN(s), rettv, (char_u **)arg, curwin->w_cursor.lnum, curwin->w_cursor.lnum, &len, evaluate, pt, selfdict); @@ -18967,7 +18983,7 @@ handle_subscript ( ++selfdict->dv_refcount; } else selfdict = NULL; - if (eval_index(arg, rettv, evaluate, verbose) == FAIL) { + if (eval_index((char_u **)arg, rettv, evaluate, verbose) == FAIL) { clear_tv(rettv); ret = FAIL; } @@ -19331,6 +19347,53 @@ static void init_tv(typval_T *varp) memset(varp, 0, sizeof(typval_T)); } +/// Check that given value is a number or string +/// +/// Error messages are compatible with get_tv_number() previously used for the +/// same purpose in buf*() functions. Special values are not accepted (previous +/// behaviour: silently fail to find buffer). +/// +/// @param[in] tv Value to check. +/// +/// @return true if everything is OK, false otherwise. +bool tv_check_str_or_nr(const typval_T *const tv) + FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE +{ + switch (tv->v_type) { + case VAR_NUMBER: + case VAR_STRING: { + return true; + } + case VAR_FLOAT: { + EMSG(_("E805: Expected a Number or a String, Float found")); + return false; + } + case VAR_PARTIAL: + case VAR_FUNC: { + EMSG(_("E703: Expected a Number or a String, Funcref found")); + return false; + } + case VAR_LIST: { + EMSG(_("E745: Expected a Number or a String, List found")); + return false; + } + case VAR_DICT: { + EMSG(_("E728: Expected a Number or a String, Dictionary found")); + return false; + } + case VAR_SPECIAL: { + EMSG(_("E5300: Expected a Number or a String")); + return false; + } + case VAR_UNKNOWN: { + EMSG2(_(e_intern2), "tv_check_str_or_nr(UNKNOWN)"); + return false; + } + } + assert(false); + return false; +} + /* * Get the number value of a variable. * If it is a String variable, uses vim_str2nr(). @@ -19535,58 +19598,76 @@ static char_u *get_tv_string_buf_chk(const typval_T *varp, char_u *buf) * When "htp" is not NULL we are writing to the variable, set "htp" to the * hashtab_T used. */ -static dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload) +static dictitem_T *find_var(const char *const name, const size_t name_len, + hashtab_T **htp, int no_autoload) { - char_u *varname; - hashtab_T *ht; - - ht = find_var_ht(name, &varname); - if (htp != NULL) + const char *varname; + hashtab_T *ht = find_var_ht(name, name_len, &varname); + if (htp != NULL) { *htp = ht; - if (ht == NULL) + } + if (ht == NULL) { return NULL; - return find_var_in_ht(ht, *name, varname, no_autoload || htp != NULL); + } + return find_var_in_ht(ht, *name, + varname, name_len - (size_t)(varname - name), + no_autoload || htp != NULL); } -/// Find variable "varname" in hashtab "ht" with name "htname". -/// Returns NULL if not found. -static dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, - char_u *varname, bool no_autoload) +/// Find variable in hashtab +/// +/// @param[in] ht Hashtab to find variable in. +/// @param[in] htname Hashtab name (first character). +/// @param[in] varname Variable name. +/// @param[in] varname_len Variable name length. +/// @param[in] no_autoload If true then autoload scripts will not be sourced +/// if autoload variable was not found. +/// +/// @return pointer to the dictionary item with the found variable or NULL if it +/// was not found. +static dictitem_T *find_var_in_ht(hashtab_T *const ht, + int htname, + const char *const varname, + const size_t varname_len, + int no_autoload) + FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL { hashitem_T *hi; - if (*varname == NUL) { - /* Must be something like "s:", otherwise "ht" would be NULL. */ + if (varname_len == 0) { + // Must be something like "s:", otherwise "ht" would be NULL. switch (htname) { - case 's': return &SCRIPT_SV(current_SID)->sv_var; - case 'g': return &globvars_var; - case 'v': return &vimvars_var; - case 'b': return &curbuf->b_bufvar; - case 'w': return &curwin->w_winvar; - case 't': return &curtab->tp_winvar; - case 'l': return current_funccal == NULL - ? NULL : ¤t_funccal->l_vars_var; - case 'a': return current_funccal == NULL - ? NULL : ¤t_funccal->l_avars_var; + case 's': return (dictitem_T *)&SCRIPT_SV(current_SID)->sv_var; + case 'g': return (dictitem_T *)&globvars_var; + case 'v': return (dictitem_T *)&vimvars_var; + case 'b': return (dictitem_T *)&curbuf->b_bufvar; + case 'w': return (dictitem_T *)&curwin->w_winvar; + case 't': return (dictitem_T *)&curtab->tp_winvar; + case 'l': return (current_funccal == NULL + ? NULL : (dictitem_T *)¤t_funccal->l_vars_var); + case 'a': return (current_funccal == NULL + ? NULL : (dictitem_T *)¤t_funccal->l_avars_var); } return NULL; } - hi = hash_find(ht, varname); + hi = hash_find_len(ht, varname, varname_len); if (HASHITEM_EMPTY(hi)) { - /* For global variables we may try auto-loading the script. If it - * worked find the variable again. Don't auto-load a script if it was - * loaded already, otherwise it would be loaded every time when - * checking if a function name is a Funcref variable. */ + // For global variables we may try auto-loading the script. If it + // worked find the variable again. Don't auto-load a script if it was + // loaded already, otherwise it would be loaded every time when + // checking if a function name is a Funcref variable. if (ht == &globvarht && !no_autoload) { - /* Note: script_autoload() may make "hi" invalid. It must either - * be obtained again or not used. */ - if (!script_autoload(varname, FALSE) || aborting()) + // Note: script_autoload() may make "hi" invalid. It must either + // be obtained again or not used. + if (!script_autoload(varname, varname_len, false) || aborting()) { return NULL; - hi = hash_find(ht, varname); + } + hi = hash_find_len(ht, varname, varname_len); } - if (HASHITEM_EMPTY(hi)) + if (HASHITEM_EMPTY(hi)) { return NULL; + } } return HI2DI(hi); } @@ -19610,17 +19691,25 @@ static funccall_T *get_funccal(void) return funccal; } -// Find the dict and hashtable used for a variable name. Set "varname" to the -// start of name without ':'. -static hashtab_T *find_var_ht_dict(char_u *name, uint8_t **varname, dict_T **d) +/// Find the dict and hashtable used for a variable +/// +/// @param[in] name Variable name, possibly with scope prefix. +/// @param[in] name_len Variable name length. +/// @param[out] varname Will be set to the start of the name without scope +/// prefix. +/// @param[out] d Scope dictionary. +/// +/// @return Scope hashtab, NULL if name is not valid. +static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len, + const char **varname, dict_T **d) { - hashitem_T *hi; + hashitem_T *hi; *d = NULL; - if (name[0] == NUL) { + if (name_len == 0) { return NULL; } - if (name[1] != ':') { + if (name_len == 1 || (name_len >= 2 && name[1] != ':')) { // name has implicit scope if (name[0] == ':' || name[0] == AUTOLOAD_CHAR) { // The name must not start with a colon or #. @@ -19629,7 +19718,7 @@ static hashtab_T *find_var_ht_dict(char_u *name, uint8_t **varname, dict_T **d) *varname = name; // "version" is "v:version" in all scopes - hi = hash_find(&compat_hashtab, name); + hi = hash_find_len(&compat_hashtab, name, name_len); if (!HASHITEM_EMPTY(hi)) { return &compat_hashtab; } @@ -19645,26 +19734,27 @@ static hashtab_T *find_var_ht_dict(char_u *name, uint8_t **varname, dict_T **d) *varname = name + 2; if (*name == 'g') { // global variable *d = &globvardict; - } else if (vim_strchr(name + 2, ':') != NULL - || vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL) { + } else if (name_len > 2 + && (memchr(name + 2, ':', name_len - 2) != NULL + || memchr(name + 2, AUTOLOAD_CHAR, name_len - 2) != NULL)) { // There must be no ':' or '#' in the rest of the name if g: was not used return NULL; } - if (*name == 'b') { // buffer variable + if (*name == 'b') { // buffer variable *d = curbuf->b_vars; - } else if (*name == 'w') { // window variable + } else if (*name == 'w') { // window variable *d = curwin->w_vars; - } else if (*name == 't') { // tab page variable + } else if (*name == 't') { // tab page variable *d = curtab->tp_vars; - } else if (*name == 'v') { // v: variable + } else if (*name == 'v') { // v: variable *d = &vimvardict; } else if (*name == 'a' && current_funccal != NULL) { // function argument *d = &get_funccal()->l_avars; } else if (*name == 'l' && current_funccal != NULL) { // local variable *d = &get_funccal()->l_vars; - } else if (*name == 's' // script variable - && current_SID > 0 && current_SID <= ga_scripts.ga_len) { + } else if (*name == 's' // script variable + && current_SID > 0 && current_SID <= ga_scripts.ga_len) { *d = &SCRIPT_SV(current_SID)->sv_dict; } @@ -19672,13 +19762,19 @@ end: return *d ? &(*d)->dv_hashtab : NULL; } -// Find the hashtab used for a variable name. -// Return NULL if the name is not valid. -// Set "varname" to the start of name without ':'. -static hashtab_T *find_var_ht(uint8_t *name, uint8_t **varname) +/// Find the hashtable used for a variable +/// +/// @param[in] name Variable name, possibly with scope prefix. +/// @param[in] name_len Variable name length. +/// @param[out] varname Will be set to the start of the name without scope +/// prefix. +/// +/// @return Scope hashtab, NULL if name is not valid. +static hashtab_T *find_var_ht(const char *name, const size_t name_len, + const char **varname) { dict_T *d; - return find_var_ht_dict(name, varname, &d); + return find_var_ht_dict(name, name_len, varname, &d); } /* @@ -19686,13 +19782,14 @@ static hashtab_T *find_var_ht(uint8_t *name, uint8_t **varname) * Note: see get_tv_string() for how long the pointer remains valid. * Returns NULL when it doesn't exist. */ -char_u *get_var_value(char_u *name) +char_u *get_var_value(const char *const name) { dictitem_T *v; - v = find_var(name, NULL, FALSE); - if (v == NULL) + v = find_var(name, strlen(name), NULL, FALSE); + if (v == NULL) { return NULL; + } return get_tv_string(&v->di_tv); } @@ -19813,28 +19910,27 @@ static void delete_var(hashtab_T *ht, hashitem_T *hi) /* * List the value of one internal variable. */ -static void list_one_var(dictitem_T *v, char_u *prefix, int *first) +static void list_one_var(dictitem_T *v, const char *prefix, int *first) { - char_u *s = (char_u *) encode_tv2echo(&v->di_tv, NULL); - list_one_var_a(prefix, v->di_key, v->di_tv.v_type, - s == NULL ? (char_u *)"" : s, first); + char *const s = encode_tv2echo(&v->di_tv, NULL); + list_one_var_a(prefix, (const char *)v->di_key, STRLEN(v->di_key), + v->di_tv.v_type, (s == NULL ? "" : s), first); xfree(s); } -static void -list_one_var_a ( - char_u *prefix, - char_u *name, - int type, - char_u *string, - int *first /* when TRUE clear rest of screen and set to FALSE */ -) +/// @param[in] name_len Length of the name. May be -1, in this case strlen() +/// will be used. +/// @param[in,out] first When true clear rest of screen and set to false. +static void list_one_var_a(const char *prefix, const char *name, + const ptrdiff_t name_len, const int type, + const char *string, int *first) { - /* don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" */ + // don't use msg() or msg_attr() to avoid overwriting "v:statusmsg" msg_start(); msg_puts(prefix); - if (name != NULL) /* "a:" vars don't have a name stored */ - msg_puts(name); + if (name != NULL) { // "a:" vars don't have a name stored + msg_puts_attr_len(name, name_len, 0); + } msg_putchar(' '); msg_advance(22); if (type == VAR_NUMBER) { @@ -19852,10 +19948,10 @@ list_one_var_a ( } else msg_putchar(' '); - msg_outtrans(string); + msg_outtrans((char_u *)string); if (type == VAR_FUNC || type == VAR_PARTIAL) { - msg_puts((char_u *)"()"); + msg_puts("()"); } if (*first) { msg_clr_eos(); @@ -19876,12 +19972,14 @@ set_var ( ) { dictitem_T *v; - char_u *varname; hashtab_T *ht; typval_T oldtv; dict_T *dict; - ht = find_var_ht_dict(name, &varname, &dict); + const size_t name_len = STRLEN(name); + char_u *varname; + ht = find_var_ht_dict((const char *)name, name_len, (const char **)&varname, + &dict); bool watched = is_watched(dict); if (watched) { @@ -19892,7 +19990,9 @@ set_var ( EMSG2(_(e_illvar), name); return; } - v = find_var_in_ht(ht, 0, varname, TRUE); + v = find_var_in_ht(ht, 0, + (const char *)varname, name_len - (size_t)(varname - name), + true); if ((tv->v_type == VAR_FUNC || tv->v_type == VAR_PARTIAL) && var_check_func_name(name, v == NULL)) { @@ -20019,15 +20119,15 @@ var_check_func_name ( EMSG2(_("E704: Funcref variable name must start with a capital: %s"), name); return TRUE; } - /* Don't allow hiding a function. When "v" is not NULL we might be - * assigning another function to the same var, the type is checked - * below. */ - if (new_var && function_exists(name)) { + // Don't allow hiding a function. When "v" is not NULL we might be + // assigning another function to the same var, the type is checked + // below. + if (new_var && function_exists((const char *)name)) { EMSG2(_("E705: Variable name conflicts with existing function: %s"), - name); - return TRUE; + name); + return true; } - return FALSE; + return false; } /* @@ -20222,7 +20322,6 @@ void ex_echo(exarg_T *eap) { char_u *arg = eap->arg; typval_T rettv; - char_u *p; bool needclr = true; bool atstart = true; @@ -20233,19 +20332,20 @@ void ex_echo(exarg_T *eap) * still need to be cleared. E.g., "echo 22,44". */ need_clr_eos = needclr; - p = arg; - if (eval1(&arg, &rettv, !eap->skip) == FAIL) { - /* - * Report the invalid expression unless the expression evaluation - * has been cancelled due to an aborting error, an interrupt, or an - * exception. - */ - if (!aborting()) - EMSG2(_(e_invexpr2), p); - need_clr_eos = FALSE; - break; + { + char_u *p = arg; + if (eval1(&arg, &rettv, !eap->skip) == FAIL) { + // Report the invalid expression unless the expression evaluation + // has been cancelled due to an aborting error, an interrupt, or an + // exception. + if (!aborting()) { + EMSG2(_(e_invexpr2), p); + } + need_clr_eos = FALSE; + break; + } + need_clr_eos = false; } - need_clr_eos = FALSE; if (!eap->skip) { if (atstart) { @@ -20259,9 +20359,11 @@ void ex_echo(exarg_T *eap) msg_sb_eol(); msg_start(); } - } else if (eap->cmdidx == CMD_echo) - msg_puts_attr((char_u *)" ", echo_attr); - char_u *tofree = p = (char_u *) encode_tv2echo(&rettv, NULL); + } else if (eap->cmdidx == CMD_echo) { + msg_puts_attr(" ", echo_attr); + } + char *tofree = encode_tv2echo(&rettv, NULL); + const char *p = tofree; if (p != NULL) { for (; *p != NUL && !got_int; ++p) { if (*p == '\n' || *p == '\r' || *p == TAB) { @@ -20270,15 +20372,15 @@ void ex_echo(exarg_T *eap) msg_clr_eos(); needclr = false; } - msg_putchar_attr(*p, echo_attr); + msg_putchar_attr((uint8_t)*p, echo_attr); } else { if (has_mbyte) { - int i = (*mb_ptr2len)(p); + int i = (*mb_ptr2len)((const char_u *)p); - (void)msg_outtrans_len_attr(p, i, echo_attr); + (void)msg_outtrans_len_attr((char_u *)p, i, echo_attr); p += i - 1; } else - (void)msg_outtrans_len_attr(p, 1, echo_attr); + (void)msg_outtrans_len_attr((char_u *)p, 1, echo_attr); } } } @@ -20392,9 +20494,9 @@ void ex_execute(exarg_T *eap) * Returns NULL when no option name found. Otherwise pointer to the char * after the option name. */ -static char_u *find_option_end(char_u **arg, int *opt_flags) +static const char *find_option_end(const char **const arg, int *const opt_flags) { - char_u *p = *arg; + const char *p = *arg; ++p; if (*p == 'g' && p[1] == ':') { @@ -20569,7 +20671,7 @@ void ex_function(exarg_T *eap) } if (!got_int) { msg_putchar('\n'); - msg_puts((char_u *)" endfunction"); + msg_puts(" endfunction"); } } else emsg_funcname(N_("E123: Undefined function: %s"), name); @@ -20784,7 +20886,7 @@ void ex_function(exarg_T *eap) if (*p == '!') { p = skipwhite(p + 1); } - p += eval_fname_script(p); + p += eval_fname_script((const char *)p); xfree(trans_function_name(&p, true, 0, NULL, NULL)); if (*skipwhite(p) == '(') { nesting++; @@ -20859,7 +20961,7 @@ void ex_function(exarg_T *eap) * If there are no errors, add the function */ if (fudi.fd_dict == NULL) { - v = find_var(name, &ht, FALSE); + v = find_var((const char *)name, STRLEN(name), &ht, FALSE); if (v != NULL && v->di_tv.v_type == VAR_FUNC) { emsg_funcname(N_("E707: Function name conflicts with variable: %s"), name); @@ -20916,7 +21018,7 @@ void ex_function(exarg_T *eap) /* Check that the autoload name matches the script name. */ int j = FAIL; if (sourcing_name != NULL) { - scriptname = autoload_name(name); + scriptname = (char_u *)autoload_name((const char *)name, STRLEN(name)); p = vim_strchr(scriptname, '/'); plen = (int)STRLEN(p); slen = (int)STRLEN(sourcing_name); @@ -21024,15 +21126,16 @@ trans_function_name ( if ((*pp)[0] == K_SPECIAL && (*pp)[1] == KS_EXTRA && (*pp)[2] == (int)KE_SNR) { *pp += 3; - len = get_id_len(pp) + 3; - return vim_strnsave(start, len); + len = get_id_len((const char **)pp) + 3; + return (char_u *)xmemdupz(start, len); } /* A name starting with "" or "" is local to a script. But * don't skip over "s:", get_lval() needs it for "s:dict.func". */ - lead = eval_fname_script(start); - if (lead > 2) + lead = eval_fname_script((const char *)start); + if (lead > 2) { start += lead; + } /* Note that TFN_ flags use the same values as GLV_ flags. */ end = get_lval(start, NULL, &lv, FALSE, skip, flags, @@ -21095,14 +21198,15 @@ trans_function_name ( /* Check if the name is a Funcref. If so, use the value. */ if (lv.ll_exp_name != NULL) { len = (int)STRLEN(lv.ll_exp_name); - name = deref_func_name(lv.ll_exp_name, &len, partial, + name = deref_func_name((const char *)lv.ll_exp_name, &len, partial, flags & TFN_NO_AUTOLOAD); if (name == lv.ll_exp_name) { name = NULL; } } else { len = (int)(end - *pp); - name = deref_func_name(*pp, &len, partial, flags & TFN_NO_AUTOLOAD); + name = deref_func_name((const char *)*pp, &len, partial, + flags & TFN_NO_AUTOLOAD); if (name == *pp) { name = NULL; } @@ -21147,9 +21251,9 @@ trans_function_name ( lead = 0; /* do nothing */ else if (lead > 0) { lead = 3; - if ((lv.ll_exp_name != NULL && eval_fname_sid(lv.ll_exp_name)) - || eval_fname_sid(*pp)) { - /* It's "s:" or "" */ + if ((lv.ll_exp_name != NULL && eval_fname_sid((const char *)lv.ll_exp_name)) + || eval_fname_sid((const char *)*pp)) { + // It's "s:" or "". if (current_SID <= 0) { EMSG(_(e_usingsid)); goto theend; @@ -21157,7 +21261,8 @@ trans_function_name ( sprintf((char *)sid_buf, "%" PRId64 "_", (int64_t)current_SID); lead += (int)STRLEN(sid_buf); } - } else if (!(flags & TFN_INT) && builtin_function(lv.ll_name, len)) { + } else if (!(flags & TFN_INT) + && builtin_function((const char *)lv.ll_name, len)) { EMSG2(_("E128: Function name must start with a capital or \"s:\": %s"), start); goto theend; @@ -21194,12 +21299,13 @@ theend: * Return 2 if "p" starts with "s:". * Return 0 otherwise. */ -static int eval_fname_script(char_u *p) +static int eval_fname_script(const char *const p) { // Use mb_stricmp() because in Turkish comparing the "I" may not work with // the standard library function. - if (p[0] == '<' && (mb_strnicmp(p + 1, (char_u *)"SID>", 4) == 0 - || mb_strnicmp(p + 1, (char_u *)"SNR>", 4) == 0)) { + if (p[0] == '<' + && (mb_strnicmp((char_u *)p + 1, (char_u *)"SID>", 4) == 0 + || mb_strnicmp((char_u *)p + 1, (char_u *)"SNR>", 4) == 0)) { return 5; } if (p[0] == 's' && p[1] == ':') { @@ -21208,13 +21314,19 @@ static int eval_fname_script(char_u *p) return 0; } -/* - * Return TRUE if "p" starts with "" or "s:". - * Only works if eval_fname_script() returned non-zero for "p"! - */ -static int eval_fname_sid(char_u *p) +/// Check whether function name starts with or s: +/// +/// Only works for names previously checked by eval_fname_script(), if it +/// returned non-zero. +/// +/// @param[in] name Name to check. +/// +/// @return true if it starts with or s:, false otherwise. +static inline bool eval_fname_sid(const char *const name) + FUNC_ATTR_PURE FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_WARN_UNUSED_RESULT + FUNC_ATTR_NONNULL_ALL { - return *p == 's' || TOUPPER_ASC(p[2]) == 'I'; + return *name == 's' || TOUPPER_ASC(name[2]) == 'I'; } /* @@ -21228,28 +21340,34 @@ static void list_func_head(ufunc_T *fp, int indent) MSG_PUTS("function "); if (fp->uf_name[0] == K_SPECIAL) { MSG_PUTS_ATTR("", hl_attr(HLF_8)); - msg_puts(fp->uf_name + 3); - } else - msg_puts(fp->uf_name); + msg_puts((const char *)fp->uf_name + 3); + } else { + msg_puts((const char *)fp->uf_name); + } msg_putchar('('); int j; for (j = 0; j < fp->uf_args.ga_len; ++j) { - if (j) - MSG_PUTS(", "); - msg_puts(FUNCARG(fp, j)); + if (j) { + msg_puts(", "); + } + msg_puts((const char *)FUNCARG(fp, j)); } if (fp->uf_varargs) { - if (j) - MSG_PUTS(", "); - MSG_PUTS("..."); + if (j) { + msg_puts(", "); + } + msg_puts("..."); } msg_putchar(')'); - if (fp->uf_flags & FC_ABORT) - MSG_PUTS(" abort"); - if (fp->uf_flags & FC_RANGE) - MSG_PUTS(" range"); - if (fp->uf_flags & FC_DICT) - MSG_PUTS(" dict"); + if (fp->uf_flags & FC_ABORT) { + msg_puts(" abort"); + } + if (fp->uf_flags & FC_RANGE) { + msg_puts(" range"); + } + if (fp->uf_flags & FC_DICT) { + msg_puts(" dict"); + } msg_clr_eos(); if (p_verbose > 0) last_set_msg(fp->uf_script_ID); @@ -21259,7 +21377,7 @@ static void list_func_head(ufunc_T *fp, int indent) * Find a function by name, return pointer to it in ufuncs. * Return NULL for unknown function. */ -static ufunc_T *find_func(char_u *name) +static ufunc_T *find_func(const char_u *name) { hashitem_T *hi; @@ -21286,31 +21404,34 @@ void free_all_functions(void) #endif -int translated_function_exists(char_u *name) +bool translated_function_exists(const char *name) { if (builtin_function(name, -1)) { return find_internal_func((char *)name) != NULL; } - return find_func(name) != NULL; + return find_func((const char_u *)name) != NULL; } -/* - * Return TRUE if a function "name" exists. - */ -static int function_exists(char_u *name) +/// Check whether function with the given name exists +/// +/// @param[in] name Function name. +/// +/// @return True if it exists, false otherwise. +static bool function_exists(const char *const name) { - char_u *nm = name; - char_u *p; - int n = FALSE; + char_u *nm = (char_u *)name; + bool n = false; - p = trans_function_name(&nm, false, TFN_INT|TFN_QUIET|TFN_NO_AUTOLOAD, - NULL, NULL); + char *const p = (char *)trans_function_name(&nm, false, + TFN_INT|TFN_QUIET|TFN_NO_AUTOLOAD, + NULL, NULL); nm = skipwhite(nm); /* Only accept "funcname", "funcname ", "funcname (..." and * "funcname(...", not "funcname!...". */ - if (p != NULL && (*nm == NUL || *nm == '(')) + if (p != NULL && (*nm == NUL || *nm == '(')) { n = translated_function_exists(p); + } xfree(p); return n; } @@ -21318,16 +21439,17 @@ static int function_exists(char_u *name) /// Return TRUE if "name" looks like a builtin function name: starts with a /// lower case letter and doesn't contain AUTOLOAD_CHAR. /// "len" is the length of "name", or -1 for NUL terminated. -static bool builtin_function(char_u *name, int len) +static bool builtin_function(const char *name, int len) { if (!ASCII_ISLOWER(name[0])) { - return FALSE; + return false; } - char_u *p = vim_strchr(name, AUTOLOAD_CHAR); + const char *p = (len == -1 + ? strchr(name, AUTOLOAD_CHAR) + : memchr(name, AUTOLOAD_CHAR, (size_t)len)); - return p == NULL - || (len > 0 && p > name + len); + return p == NULL; } /* @@ -21493,44 +21615,45 @@ static int prof_self_cmp(const void *s1, const void *s2) } -/* - * If "name" has a package name try autoloading the script for it. - * Return TRUE if a package was loaded. - */ -static int -script_autoload ( - char_u *name, - int reload /* load script again when already loaded */ -) +/// If name has a package name try autoloading the script for it +/// +/// @param[in] name Variable/function name. +/// @param[in] name_len Name length. +/// @param[in] reload If true, load script again when already loaded. +/// +/// @return true if a package was loaded. +static bool script_autoload(const char *const name, const size_t name_len, + const bool reload) { - char_u *p; - char_u *scriptname, *tofree; - int ret = FALSE; - int i; + // If there is no '#' after name[0] there is no package name. + const char *p = memchr(name, AUTOLOAD_CHAR, name_len); + if (p == NULL || p == name) { + return false; + } - /* If there is no '#' after name[0] there is no package name. */ - p = vim_strchr(name, AUTOLOAD_CHAR); - if (p == NULL || p == name) - return FALSE; + bool ret = false; + char *tofree = autoload_name(name, name_len); + char *scriptname = tofree; - tofree = scriptname = autoload_name(name); - - /* Find the name in the list of previously loaded package names. Skip - * "autoload/", it's always the same. */ - for (i = 0; i < ga_loaded.ga_len; ++i) - if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) + // Find the name in the list of previously loaded package names. Skip + // "autoload/", it's always the same. + int i = 0; + for (; i < ga_loaded.ga_len; i++) { + if (STRCMP(((char **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0) { break; - if (!reload && i < ga_loaded.ga_len) - ret = FALSE; /* was loaded already */ - else { - /* Remember the name if it wasn't loaded already. */ + } + } + if (!reload && i < ga_loaded.ga_len) { + ret = false; // Was loaded already. + } else { + // Remember the name if it wasn't loaded already. if (i == ga_loaded.ga_len) { - GA_APPEND(char_u *, &ga_loaded, scriptname); + GA_APPEND(char *, &ga_loaded, scriptname); tofree = NULL; } // Try loading the package from $VIMRUNTIME/autoload/.vim - if (source_runtime(scriptname, 0) == OK) { + if (source_runtime((char_u *)scriptname, 0) == OK) { ret = true; } } @@ -21539,21 +21662,29 @@ script_autoload ( return ret; } -/* - * Return the autoload script name for a function or variable name. - */ -static char_u *autoload_name(char_u *name) +/// Return the autoload script name for a function or variable name +/// +/// @param[in] name Variable/function name. +/// @param[in] name_len Name length. +/// +/// @return [allocated] autoload script name. +static char *autoload_name(const char *const name, const size_t name_len) + FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT { - /* Get the script file name: replace '#' with '/', append ".vim". */ - char_u *scriptname = xmalloc(STRLEN(name) + 14); - STRCPY(scriptname, "autoload/"); - STRCAT(scriptname, name); - *vim_strrchr(scriptname, AUTOLOAD_CHAR) = NUL; - STRCAT(scriptname, ".vim"); - - char_u *p; - while ((p = vim_strchr(scriptname, AUTOLOAD_CHAR)) != NULL) - *p = '/'; + // Get the script file name: replace '#' with '/', append ".vim". + char *const scriptname = xmalloc(name_len + sizeof("autoload/.vim")); + memcpy(scriptname, "autoload/", sizeof("autoload/") - 1); + memcpy(scriptname + sizeof("autoload/") - 1, name, name_len); + size_t auchar_idx = 0; + for (size_t i = sizeof("autoload/") - 1; + i - sizeof("autoload/") + 1 < name_len; + i++) { + if (scriptname[i] == AUTOLOAD_CHAR) { + scriptname[i] = '/'; + auchar_idx = i; + } + } + memcpy(scriptname + auchar_idx, ".vim", sizeof(".vim")); return scriptname; } @@ -21927,24 +22058,24 @@ call_user_func ( smsg(_("calling %s"), sourcing_name); if (p_verbose >= 14) { - char_u buf[MSG_BUF_LEN]; - - msg_puts((char_u *)"("); + msg_puts("("); for (int i = 0; i < argcount; ++i) { if (i > 0) { - msg_puts((char_u *)", "); + msg_puts(", "); } if (argvars[i].v_type == VAR_NUMBER) { msg_outnum((long)argvars[i].vval.v_number); } else { // Do not want errors such as E724 here. emsg_off++; - char_u *s = (char_u *) encode_tv2string(&argvars[i], NULL); - char_u *tofree = s; + char *tofree = encode_tv2string(&argvars[i], NULL); + char *s = tofree; emsg_off--; if (s != NULL) { - if (vim_strsize(s) > MSG_BUF_CLEN) { - trunc_string(s, buf, MSG_BUF_CLEN, MSG_BUF_LEN); + if (vim_strsize((char_u *)s) > MSG_BUF_CLEN) { + char buf[MSG_BUF_LEN]; + trunc_string((char_u *)s, (char_u *)buf, MSG_BUF_CLEN, + sizeof(buf)); s = buf; } msg_puts(s); @@ -21952,9 +22083,9 @@ call_user_func ( } } } - msg_puts((char_u *)")"); + msg_puts(")"); } - msg_puts((char_u *)"\n"); /* don't overwrite this either */ + msg_puts("\n"); // don't overwrite this either verbose_leave_scroll(); --no_wait_return; @@ -22045,7 +22176,7 @@ call_user_func ( xfree(tofree); } } - msg_puts((char_u *)"\n"); /* don't overwrite this either */ + msg_puts("\n"); // don't overwrite this either verbose_leave_scroll(); --no_wait_return; @@ -22063,7 +22194,7 @@ call_user_func ( verbose_enter_scroll(); smsg(_("continuing in %s"), sourcing_name); - msg_puts((char_u *)"\n"); /* don't overwrite this either */ + msg_puts("\n"); // don't overwrite this either verbose_leave_scroll(); --no_wait_return; @@ -23369,10 +23500,12 @@ bool eval_has_provider(char *name) { #define check_provider(name) \ if (has_##name == -1) { \ - has_##name = !!find_func((uint8_t *)"provider#" #name "#Call"); \ + has_##name = !!find_func((char_u *)"provider#" #name "#Call"); \ if (!has_##name) { \ - script_autoload((uint8_t *)"provider#" #name "#Call", false); \ - has_##name = !!find_func((uint8_t *)"provider#" #name "#Call"); \ + script_autoload("provider#" #name "#Call", \ + sizeof("provider#" #name "#Call") - 1, \ + false); \ + has_##name = !!find_func((char_u *)"provider#" #name "#Call"); \ } \ } diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 4b3798794c..a03878dec2 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -1474,12 +1474,12 @@ void append_redir(char *const buf, const size_t buflen, void print_line_no_prefix(linenr_T lnum, int use_number, int list) { - char_u numbuf[30]; + char numbuf[30]; if (curwin->w_p_nu || use_number) { - vim_snprintf((char *)numbuf, sizeof(numbuf), - "%*ld ", number_width(curwin), (long)lnum); - msg_puts_attr(numbuf, hl_attr(HLF_N)); /* Highlight line nrs */ + vim_snprintf(numbuf, sizeof(numbuf), "%*" PRIdLINENR " ", + number_width(curwin), lnum); + msg_puts_attr(numbuf, hl_attr(HLF_N)); // Highlight line nrs. } msg_prt_line(ml_get(lnum), list); } @@ -5720,33 +5720,33 @@ void ex_sign(exarg_T *eap) */ static void sign_list_defined(sign_T *sp) { - char_u *p; - smsg("sign %s", sp->sn_name); if (sp->sn_icon != NULL) { - MSG_PUTS(" icon="); + msg_puts(" icon="); msg_outtrans(sp->sn_icon); - MSG_PUTS(_(" (not supported)")); + msg_puts(_(" (not supported)")); } if (sp->sn_text != NULL) { - MSG_PUTS(" text="); + msg_puts(" text="); msg_outtrans(sp->sn_text); } if (sp->sn_line_hl > 0) { - MSG_PUTS(" linehl="); - p = get_highlight_name(NULL, sp->sn_line_hl - 1); - if (p == NULL) - MSG_PUTS("NONE"); - else + msg_puts(" linehl="); + const char *const p = get_highlight_name(NULL, sp->sn_line_hl - 1); + if (p == NULL) { + msg_puts("NONE"); + } else { msg_puts(p); + } } if (sp->sn_text_hl > 0) { - MSG_PUTS(" texthl="); - p = get_highlight_name(NULL, sp->sn_text_hl - 1); - if (p == NULL) - MSG_PUTS("NONE"); - else + msg_puts(" texthl="); + const char *const p = get_highlight_name(NULL, sp->sn_text_hl - 1); + if (p == NULL) { + msg_puts("NONE"); + } else { msg_puts(p); + } } } diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index b4e57bc916..048323b137 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -2250,7 +2250,7 @@ void ex_compiler(exarg_T *eap) // plugin will then skip the settings. Afterwards set // "b:current_compiler" and restore "current_compiler". // Explicitly prepend "g:" to make it work in a function. - old_cur_comp = get_var_value((char_u *)"g:current_compiler"); + old_cur_comp = get_var_value("g:current_compiler"); if (old_cur_comp != NULL) { old_cur_comp = vim_strsave(old_cur_comp); } @@ -2268,7 +2268,7 @@ void ex_compiler(exarg_T *eap) do_cmdline_cmd(":delcommand CompilerSet"); // Set "b:current_compiler" from "current_compiler". - p = get_var_value((char_u *)"g:current_compiler"); + p = get_var_value("g:current_compiler"); if (p != NULL) { set_internal_string_var((char_u *)"b:current_compiler", p); } diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index c5625d7882..d1c063ecce 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -585,8 +585,9 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline, smsg(_("line %" PRId64 ": %s"), (int64_t)sourcing_lnum, cmdline_copy); - if (msg_silent == 0) - msg_puts((char_u *)"\n"); /* don't overwrite this */ + if (msg_silent == 0) { + msg_puts("\n"); // don't overwrite this either + } verbose_leave_scroll(); --no_wait_return; @@ -2582,7 +2583,7 @@ int modifier_len(char_u *cmd) * Return 2 if there is an exact match. * Return 3 if there is an ambiguous match. */ -int cmd_exists(char_u *name) +int cmd_exists(const char *const name) { exarg_T ea; int full = FALSE; @@ -2591,17 +2592,20 @@ int cmd_exists(char_u *name) char_u *p; /* Check command modifiers. */ - for (i = 0; i < (int)ARRAY_SIZE(cmdmods); ++i) { - for (j = 0; name[j] != NUL; ++j) - if (name[j] != cmdmods[i].name[j]) + for (i = 0; i < (int)ARRAY_SIZE(cmdmods); i++) { + for (j = 0; name[j] != NUL; j++) { + if (name[j] != (char)cmdmods[i].name[j]) { break; - if (name[j] == NUL && j >= cmdmods[i].minlen) + } + } + if (name[j] == NUL && j >= cmdmods[i].minlen) { return cmdmods[i].name[j] == NUL ? 2 : 1; + } } /* Check built-in commands and user defined commands. * For ":2match" and ":3match" we need to skip the number. */ - ea.cmd = (*name == '2' || *name == '3') ? name + 1 : name; + ea.cmd = (char_u *)((*name == '2' || *name == '3') ? name + 1 : name); ea.cmdidx = (cmdidx_T)0; p = find_command(&ea, &full); if (p == NULL) diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c index f518fa0d66..ab8118e491 100644 --- a/src/nvim/ex_eval.c +++ b/src/nvim/ex_eval.c @@ -482,7 +482,7 @@ static int throw_exception(void *value, int type, char_u *cmdname) msg_scroll = TRUE; /* always scroll up, don't overwrite */ smsg(_("Exception thrown: %s"), excp->value); - msg_puts((char_u *)"\n"); /* don't overwrite this either */ + msg_puts("\n"); // don't overwrite this either if (debug_break_level > 0 || *p_vfile == NUL) cmdline_row = msg_row; @@ -532,15 +532,17 @@ static void discard_exception(except_T *excp, int was_finished) smsg(was_finished ? _("Exception finished: %s") : _("Exception discarded: %s"), excp->value); - msg_puts((char_u *)"\n"); /* don't overwrite this either */ - if (debug_break_level > 0 || *p_vfile == NUL) + msg_puts("\n"); // don't overwrite this either + if (debug_break_level > 0 || *p_vfile == NUL) { cmdline_row = msg_row; - --no_wait_return; - if (debug_break_level > 0) + } + no_wait_return--; + if (debug_break_level > 0) { msg_silent = save_msg_silent; - else + } else { verbose_leave(); - STRCPY(IObuff, saved_IObuff); + } + STRNCPY(IObuff, saved_IObuff, IOSIZE); xfree(saved_IObuff); } if (excp->type != ET_INTERRUPT) @@ -595,7 +597,7 @@ static void catch_exception(except_T *excp) msg_scroll = TRUE; /* always scroll up, don't overwrite */ smsg(_("Exception caught: %s"), excp->value); - msg_puts((char_u *)"\n"); /* don't overwrite this either */ + msg_puts("\n"); // don't overwrite this either if (debug_break_level > 0 || *p_vfile == NUL) cmdline_row = msg_row; @@ -714,7 +716,7 @@ static void report_pending(int action, int pending, void *value) ++no_wait_return; msg_scroll = TRUE; /* always scroll up, don't overwrite */ smsg(mesg, s); - msg_puts((char_u *)"\n"); /* don't overwrite this either */ + msg_puts("\n"); // don't overwrite this either cmdline_row = msg_row; --no_wait_return; if (debug_break_level > 0) diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 2555b64dfd..9eea721463 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -1879,7 +1879,7 @@ getexmodeline ( vcol = indent; while (indent >= 8) { ga_append(&line_ga, TAB); - msg_puts((char_u *)" "); + msg_puts(" "); indent -= 8; } while (indent-- > 0) { @@ -2608,7 +2608,7 @@ static void redrawcmdprompt(void) if (ccline.cmdfirstc != NUL) msg_putchar(ccline.cmdfirstc); if (ccline.cmdprompt != NULL) { - msg_puts_attr(ccline.cmdprompt, ccline.cmdattr); + msg_puts_attr((const char *)ccline.cmdprompt, ccline.cmdattr); ccline.cmdindent = msg_col + (msg_row - cmdline_row) * Columns; /* do the reverse of set_cmdspos() */ if (ccline.cmdfirstc != NUL) @@ -3317,7 +3317,7 @@ static int showmatches(expand_T *xp, int wildmenu) msg_outtrans_attr(files_found[k], hl_attr(HLF_D)); p = files_found[k] + STRLEN(files_found[k]) + 1; msg_advance(maxlen + 1); - msg_puts(p); + msg_puts((const char *)p); msg_advance(maxlen + 3); msg_puts_long_attr(p + 2, hl_attr(HLF_D)); break; @@ -3759,6 +3759,8 @@ static void cleanup_help_tags(int num_file, char_u **file) } } +typedef char_u *(*ExpandFunc)(expand_T *, int); + /* * Do the expansion based on xp->xp_context and "pat". */ @@ -3898,7 +3900,7 @@ ExpandFromContext ( else { static struct expgen { int context; - char_u *((*func)(expand_T *, int)); + ExpandFunc func; int ic; int escaped; } tab[] = @@ -3919,7 +3921,7 @@ ExpandFromContext ( {EXPAND_MENUNAMES, get_menu_names, FALSE, TRUE}, {EXPAND_SYNTAX, get_syntax_name, TRUE, TRUE}, {EXPAND_SYNTIME, get_syntime_arg, TRUE, TRUE}, - {EXPAND_HIGHLIGHT, get_highlight_name, TRUE, TRUE}, + {EXPAND_HIGHLIGHT, (ExpandFunc)get_highlight_name, TRUE, TRUE}, {EXPAND_EVENTS, get_event_name, TRUE, TRUE}, {EXPAND_AUGROUP, get_augroup_name, TRUE, TRUE}, {EXPAND_CSCOPE, get_cscope_name, TRUE, TRUE}, diff --git a/src/nvim/farsi.c b/src/nvim/farsi.c index eb22ad1428..678e6d2e14 100644 --- a/src/nvim/farsi.c +++ b/src/nvim/farsi.c @@ -1593,7 +1593,7 @@ void conv_to_pvim(void) // Assume the screen has been messed up: clear it and redraw. redraw_later(CLEAR); - MSG_ATTR(farsi_text_1, hl_attr(HLF_S)); + MSG_ATTR((const char *)farsi_text_1, hl_attr(HLF_S)); } /// Convert the Farsi VIM into Farsi 3342 standard. @@ -1614,7 +1614,7 @@ void conv_to_pstd(void) // Assume the screen has been messed up: clear it and redraw. redraw_later(CLEAR); - MSG_ATTR(farsi_text_2, hl_attr(HLF_S)); + msg_attr((const char *)farsi_text_2, hl_attr(HLF_S)); } /// left-right swap the characters in buf[len]. diff --git a/src/nvim/file_search.c b/src/nvim/file_search.c index d733ba311a..79a39c6503 100644 --- a/src/nvim/file_search.c +++ b/src/nvim/file_search.c @@ -636,9 +636,8 @@ char_u *vim_findfile(void *search_ctx_arg) if (p_verbose >= 5) { verbose_enter_scroll(); smsg("Already Searched: %s (%s)", - stackp->ffs_fix_path, stackp->ffs_wc_path); - /* don't overwrite this either */ - msg_puts((char_u *)"\n"); + stackp->ffs_fix_path, stackp->ffs_wc_path); + msg_puts("\n"); // don't overwrite this either verbose_leave_scroll(); } #endif @@ -650,8 +649,7 @@ char_u *vim_findfile(void *search_ctx_arg) verbose_enter_scroll(); smsg("Searching: %s (%s)", stackp->ffs_fix_path, stackp->ffs_wc_path); - /* don't overwrite this either */ - msg_puts((char_u *)"\n"); + msg_puts("\n"); // don't overwrite this either verbose_leave_scroll(); } #endif @@ -809,10 +807,8 @@ char_u *vim_findfile(void *search_ctx_arg) ) == FAIL) { if (p_verbose >= 5) { verbose_enter_scroll(); - smsg("Already: %s", - file_path); - /* don't overwrite this either */ - msg_puts((char_u *)"\n"); + smsg("Already: %s", file_path); + msg_puts("\n"); // don't overwrite this either verbose_leave_scroll(); } continue; @@ -837,8 +833,7 @@ char_u *vim_findfile(void *search_ctx_arg) if (p_verbose >= 5) { verbose_enter_scroll(); smsg("HIT: %s", file_path); - /* don't overwrite this either */ - msg_puts((char_u *)"\n"); + msg_puts("\n"); // don't overwrite this either verbose_leave_scroll(); } #endif @@ -999,10 +994,8 @@ static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename, ff_visited_l #ifdef FF_VERBOSE if (p_verbose >= 5) { verbose_enter_scroll(); - smsg("ff_get_visited_list: FOUND list for %s", - filename); - /* don't overwrite this either */ - msg_puts((char_u *)"\n"); + smsg("ff_get_visited_list: FOUND list for %s", filename); + msg_puts("\n"); // don't overwrite this either verbose_leave_scroll(); } #endif @@ -1016,8 +1009,7 @@ static ff_visited_list_hdr_T *ff_get_visited_list(char_u *filename, ff_visited_l if (p_verbose >= 5) { verbose_enter_scroll(); smsg("ff_get_visited_list: new list for %s", filename); - /* don't overwrite this either */ - msg_puts((char_u *)"\n"); + msg_puts("\n"); // don't overwrite this either verbose_leave_scroll(); } #endif diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index cdb912ca94..efb16e880e 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -3897,8 +3897,8 @@ static int check_mtime(buf_T *buf, FileInfo *file_info) buf->b_mtime_read)) { msg_scroll = TRUE; /* don't overwrite messages here */ msg_silent = 0; /* must give this prompt */ - /* don't use emsg() here, don't want to flush the buffers */ - MSG_ATTR(_("WARNING: The file has been changed since reading it!!!"), + // Don't use emsg() here, don't want to flush the buffers. + msg_attr(_("WARNING: The file has been changed since reading it!!!"), hl_attr(HLF_E)); if (ask_yesno((char_u *)_("Do you really want to write to it"), TRUE) == 'n') @@ -4778,8 +4778,8 @@ check_timestamps ( --no_wait_return; need_check_timestamps = FALSE; if (need_wait_return && didit == 2) { - /* make sure msg isn't overwritten */ - msg_puts((char_u *)"\n"); + // make sure msg isn't overwritten + msg_puts("\n"); ui_flush(); } } @@ -5006,10 +5006,9 @@ buf_check_timestamp ( } else { if (!autocmd_busy) { msg_start(); - msg_puts_attr((char_u *) tbuf, hl_attr(HLF_E) + MSG_HIST); + msg_puts_attr(tbuf, hl_attr(HLF_E) + MSG_HIST); if (*mesg2 != NUL) { - msg_puts_attr((char_u *)mesg2, - hl_attr(HLF_W) + MSG_HIST); + msg_puts_attr(mesg2, hl_attr(HLF_W) + MSG_HIST); } msg_clr_eos(); (void)msg_end(); @@ -5389,9 +5388,7 @@ static AutoPatCmd *active_apc_list = NULL; /* stack of active autocommands */ * augroups stores a list of autocmd group names. */ static garray_T augroups = {0, 0, sizeof(char_u *), 10, NULL}; -#define AUGROUP_NAME(i) (((char_u **)augroups.ga_data)[i]) -// use get_deleted_augroup() to get this -static char_u *deleted_augroup = NULL; +#define AUGROUP_NAME(i) (((char **)augroups.ga_data)[i]) /* * The ID of the current group. Group 0 is the default one. @@ -5406,10 +5403,14 @@ static event_T last_event; static int last_group; static int autocmd_blocked = 0; /* block all autocmds */ -static char_u *get_deleted_augroup(void) +// use get_deleted_augroup() to get this +static const char *deleted_augroup = NULL; + +static inline const char *get_deleted_augroup(void) + FUNC_ATTR_ALWAYS_INLINE { if (deleted_augroup == NULL) { - deleted_augroup = (char_u *)_("--Deleted--"); + deleted_augroup = _("--Deleted--"); } return deleted_augroup; } @@ -5438,7 +5439,7 @@ static void show_autocmd(AutoPat *ap, event_T event) } else { msg_puts_attr(AUGROUP_NAME(ap->group), hl_attr(HLF_T)); } - msg_puts((char_u *)" "); + msg_puts(" "); } msg_puts_attr(event_nr2name(event), hl_attr(HLF_T)); last_event = event; @@ -5567,7 +5568,7 @@ void aubuflocal_remove(buf_T *buf) if (p_verbose >= 6) { verbose_enter(); smsg(_("auto-removing autocommand: %s "), - event_nr2name(event), buf->b_fnum); + event_nr2name(event), buf->b_fnum); verbose_leave(); } } @@ -5590,7 +5591,7 @@ static int au_new_group(char_u *name) ga_grow(&augroups, 1); } - AUGROUP_NAME(i) = vim_strsave(name); + AUGROUP_NAME(i) = xstrdup((char *)name); if (i == augroups.ga_len) ++augroups.ga_len; } @@ -5626,7 +5627,7 @@ static void au_del_group(char_u *name) } xfree(AUGROUP_NAME(i)); if (in_use) { - AUGROUP_NAME(i) = get_deleted_augroup(); + AUGROUP_NAME(i) = (char *)get_deleted_augroup(); } else { AUGROUP_NAME(i) = NULL; } @@ -5680,7 +5681,7 @@ void do_augroup(char_u *arg, int del_group) for (int i = 0; i < augroups.ga_len; ++i) { if (AUGROUP_NAME(i) != NULL) { msg_puts(AUGROUP_NAME(i)); - msg_puts((char_u *)" "); + msg_puts(" "); } } msg_clr_eos(); @@ -5691,23 +5692,19 @@ void do_augroup(char_u *arg, int del_group) #if defined(EXITFREE) void free_all_autocmds(void) { - int i; - char_u *s; - for (current_augroup = -1; current_augroup < augroups.ga_len; current_augroup++) { do_autocmd((char_u *)"", true); } - for (i = 0; i < augroups.ga_len; i++) { - s = ((char_u **)(augroups.ga_data))[i]; - if (s != get_deleted_augroup()) { - xfree(s); - } + for (int i = 0; i < augroups.ga_len; i++) { + char *const s = ((char **)(augroups.ga_data))[i]; + if ((const char *)s != get_deleted_augroup()) { + xfree(s); + } } ga_clear(&augroups); } - #endif /* @@ -5715,13 +5712,13 @@ void free_all_autocmds(void) * Return NUM_EVENTS if the event name was not found. * Return a pointer to the next event name in "end". */ -static event_T event_name2nr(char_u *start, char_u **end) +static event_T event_name2nr(const char_u *start, char_u **end) { - char_u *p; + const char_u *p; int i; int len; - // the event name ends with end of line, '|', a blank or a comma */ + // the event name ends with end of line, '|', a blank or a comma for (p = start; *p && !ascii_iswhite(*p) && *p != ',' && *p != '|'; p++) { } for (i = 0; event_names[i].name != NULL; i++) { @@ -5730,25 +5727,32 @@ static event_T event_name2nr(char_u *start, char_u **end) break; } } - if (*p == ',') - ++p; - *end = p; - if (event_names[i].name == NULL) + if (*p == ',') { + p++; + } + *end = (char_u *)p; + if (event_names[i].name == NULL) { return NUM_EVENTS; + } return event_names[i].event; } -/* - * Return the name for event "event". - */ -static char_u *event_nr2name(event_T event) +/// Return the name for event +/// +/// @param[in] event Event to return name for. +/// +/// @return Event name, static string. Returns "Unknown" for unknown events. +static const char *event_nr2name(event_T event) + FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_CONST { int i; - for (i = 0; event_names[i].name != NULL; ++i) - if (event_names[i].event == event) - return (char_u *)event_names[i].name; - return (char_u *)"Unknown"; + for (i = 0; event_names[i].name != NULL; i++) { + if (event_names[i].event == event) { + return event_names[i].name; + } + } + return "Unknown"; } /* @@ -7013,7 +7017,6 @@ auto_next_pat ( { AutoPat *ap; AutoCmd *cp; - char_u *name; char *s; xfree(sourcing_name); @@ -7032,11 +7035,13 @@ auto_next_pat ( ? match_file_pat(NULL, &ap->reg_prog, apc->fname, apc->sfname, apc->tail, ap->allow_dirs) : ap->buflocal_nr == apc->arg_bufnr) { - name = event_nr2name(apc->event); + const char *const name = event_nr2name(apc->event); s = _("%s Auto commands for \"%s\""); - sourcing_name = xmalloc(STRLEN(s) + STRLEN(name) + ap->patlen + 1); - sprintf((char *)sourcing_name, s, - (char *)name, (char *)ap->pat); + const size_t sourcing_name_len = (STRLEN(s) + strlen(name) + ap->patlen + + 1); + sourcing_name = xmalloc(sourcing_name_len); + snprintf((char *)sourcing_name, sourcing_name_len, s, name, + (char *)ap->pat); if (p_verbose >= 8) { verbose_enter(); smsg(_("Executing %s"), sourcing_name); @@ -7102,7 +7107,7 @@ char_u *getnextac(int c, void *cookie, int indent) if (p_verbose >= 9) { verbose_enter_scroll(); smsg(_("autocommand %s"), ac->cmd); - msg_puts((char_u *)"\n"); /* don't overwrite this either */ + msg_puts("\n"); // don't overwrite this either verbose_leave_scroll(); } retval = vim_strsave(ac->cmd); @@ -7168,15 +7173,17 @@ bool has_autocmd(event_T event, char_u *sfname, buf_T *buf) */ char_u *get_augroup_name(expand_T *xp, int idx) { - if (idx == augroups.ga_len) /* add "END" add the end */ + if (idx == augroups.ga_len) { // add "END" add the end return (char_u *)"END"; - if (idx >= augroups.ga_len) /* end of list */ + } + if (idx >= augroups.ga_len) { // end of list return NULL; + } if (AUGROUP_NAME(idx) == NULL || AUGROUP_NAME(idx) == get_deleted_augroup()) { // skip deleted entries return (char_u *)""; } - return AUGROUP_NAME(idx); // return a name + return (char_u *)AUGROUP_NAME(idx); } static int include_groups = FALSE; @@ -7238,18 +7245,22 @@ char_u *get_event_name(expand_T *xp, int idx) || AUGROUP_NAME(idx) == get_deleted_augroup()) { return (char_u *)""; // skip deleted entries } - return AUGROUP_NAME(idx); // return a name + return (char_u *)AUGROUP_NAME(idx); } return (char_u *)event_names[idx - augroups.ga_len].name; } -/// Return true if autocmd "event" is supported. -bool autocmd_supported(char_u *event) +/// Check whether given autocommand is supported +/// +/// @param[in] event Event to check. +/// +/// @return True if it is, false otherwise. +bool autocmd_supported(const char *const event) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { char_u *p; - - return event_name2nr(event, &p) != NUM_EVENTS; + return event_name2nr((const char_u *)event, &p) != NUM_EVENTS; } /// Return true if an autocommand is defined for a group, event and @@ -7264,26 +7275,24 @@ bool autocmd_supported(char_u *event) /// exists("#Event#pat") /// /// @param arg autocommand string -bool au_exists(const char_u *arg) FUNC_ATTR_WARN_UNUSED_RESULT +bool au_exists(const char *const arg) FUNC_ATTR_WARN_UNUSED_RESULT { - char_u *arg_save; - char_u *pattern = NULL; - char_u *event_name; - char_u *p; event_T event; AutoPat *ap; buf_T *buflocal_buf = NULL; int group; bool retval = false; - /* Make a copy so that we can change the '#' chars to a NUL. */ - arg_save = vim_strsave(arg); - p = vim_strchr(arg_save, '#'); - if (p != NULL) + // Make a copy so that we can change the '#' chars to a NUL. + char *const arg_save = xstrdup(arg); + char *p = strchr(arg_save, '#'); + if (p != NULL) { *p++ = NUL; + } - /* First, look for an autocmd group name */ - group = au_find_group(arg_save); + // First, look for an autocmd group name. + group = au_find_group((char_u *)arg_save); + char *event_name; if (group == AUGROUP_ERROR) { /* Didn't match a group name, assume the first argument is an event. */ group = AUGROUP_ALL; @@ -7295,17 +7304,18 @@ bool au_exists(const char_u *arg) FUNC_ATTR_WARN_UNUSED_RESULT goto theend; } - /* Must be "Group#Event" or "Group#Event#pat". */ + // Must be "Group#Event" or "Group#Event#pat". event_name = p; - p = vim_strchr(event_name, '#'); - if (p != NULL) - *p++ = NUL; /* "Group#Event#pat" */ + p = strchr(event_name, '#'); + if (p != NULL) { + *p++ = NUL; // "Group#Event#pat" + } } - pattern = p; /* "pattern" is NULL when there is no pattern */ + char *pattern = p; // "pattern" is NULL when there is no pattern. - /* find the index (enum) for the event name */ - event = event_name2nr(event_name, &p); + // Find the index (enum) for the event name. + event = event_name2nr((char_u *)event_name, (char_u **)&p); /* return FALSE if the event name is not recognized */ if (event == NUM_EVENTS) @@ -7331,7 +7341,7 @@ bool au_exists(const char_u *arg) FUNC_ATTR_WARN_UNUSED_RESULT && (group == AUGROUP_ALL || ap->group == group) && (pattern == NULL || (buflocal_buf == NULL - ? fnamecmp(ap->pat, pattern) == 0 + ? fnamecmp(ap->pat, (char_u *)pattern) == 0 : ap->buflocal_nr == buflocal_buf->b_fnum))) { retval = true; break; diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index fccbd69dbf..ae890d46bc 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -3163,11 +3163,11 @@ map_clear_int ( } } -/* - * Return characters to represent the map mode in an allocated string. - * Returns NULL when out of memory. - */ -char_u *map_mode_to_chars(int mode) +/// Return characters to represent the map mode in an allocated string +/// +/// @return [allocated] NUL-terminated string with characters. +char *map_mode_to_chars(int mode) + FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_RET { garray_T mapmode; @@ -3200,7 +3200,7 @@ char_u *map_mode_to_chars(int mode) } ga_append(&mapmode, NUL); - return (char_u *)mapmode.ga_data; + return (char *)mapmode.ga_data; } static void @@ -3209,8 +3209,7 @@ showmap ( int local /* TRUE for buffer-local map */ ) { - int len = 1; - char_u *mapchars; + size_t len = 1; if (msg_didout || msg_silent != 0) { msg_putchar('\n'); @@ -3218,10 +3217,10 @@ showmap ( return; } - mapchars = map_mode_to_chars(mp->m_mode); - if (mapchars != NULL) { + { + char *const mapchars = map_mode_to_chars(mp->m_mode); msg_puts(mapchars); - len = (int)STRLEN(mapchars); + len = strlen(mapchars); xfree(mapchars); } @@ -3229,18 +3228,19 @@ showmap ( msg_putchar(' '); /* Display the LHS. Get length of what we write. */ - len = msg_outtrans_special(mp->m_keys, TRUE); + len = (size_t)msg_outtrans_special(mp->m_keys, true); do { msg_putchar(' '); /* padd with blanks */ ++len; } while (len < 12); - if (mp->m_noremap == REMAP_NONE) - msg_puts_attr((char_u *)"*", hl_attr(HLF_8)); - else if (mp->m_noremap == REMAP_SCRIPT) - msg_puts_attr((char_u *)"&", hl_attr(HLF_8)); - else + if (mp->m_noremap == REMAP_NONE) { + msg_puts_attr("*", hl_attr(HLF_8)); + } else if (mp->m_noremap == REMAP_SCRIPT) { + msg_puts_attr("&", hl_attr(HLF_8)); + } else { msg_putchar(' '); + } if (local) msg_putchar('@'); @@ -3249,9 +3249,9 @@ showmap ( /* Use FALSE below if we only want things like to show up as such on * the rhs, and not M-x etc, TRUE gets both -- webb */ - if (*mp->m_str == NUL) - msg_puts_attr((char_u *)"", hl_attr(HLF_8)); - else { + if (*mp->m_str == NUL) { + msg_puts_attr("", hl_attr(HLF_8)); + } else { /* Remove escaping of CSI, because "m_str" is in a format to be used * as typeahead. */ char_u *s = vim_strsave(mp->m_str); diff --git a/src/nvim/hashtab.c b/src/nvim/hashtab.c index 376f33e23e..b14bb01c0e 100644 --- a/src/nvim/hashtab.c +++ b/src/nvim/hashtab.c @@ -82,22 +82,42 @@ void hash_clear_all(hashtab_T *ht, unsigned int off) /// used for that key. /// WARNING: Returned pointer becomes invalid as soon as the hash table /// is changed in any way. -hashitem_T* hash_find(hashtab_T *ht, char_u *key) +hashitem_T *hash_find(hashtab_T *ht, const char_u *key) { - return hash_lookup(ht, key, hash_hash(key)); + return hash_lookup(ht, (const char *)key, STRLEN(key), hash_hash(key)); +} + +/// Like hash_find, but key is not NUL-terminated +/// +/// @param[in] ht Hashtab to look in. +/// @param[in] key Key of the looked-for item. Must not be NULL. +/// @param[in] len Key length. +/// +/// @return Pointer to the hash item corresponding to the given key. +/// If not found, then return pointer to the empty item that would be +/// used for that key. +/// +/// @warning Returned pointer becomes invalid as soon as the hash table +/// is changed in any way. +hashitem_T *hash_find_len(hashtab_T *ht, const char *key, const size_t len) +{ + return hash_lookup(ht, key, len, hash_hash_len(key, len)); } /// Like hash_find(), but caller computes "hash". /// -/// @param key The key of the looked-for item. Must not be NULL. -/// @param hash The precomputed hash for the key. +/// @param[in] key The key of the looked-for item. Must not be NULL. +/// @param[in] key_len Key length. +/// @param[in] hash The precomputed hash for the key. /// /// @return Pointer to the hashitem corresponding to the given key. /// If not found, then return pointer to the empty item that would be /// used for that key. /// WARNING: Returned pointer becomes invalid as soon as the hash table /// is changed in any way. -hashitem_T* hash_lookup(hashtab_T *ht, char_u *key, hash_T hash) +hashitem_T *hash_lookup(hashtab_T *const ht, + const char *const key, const size_t key_len, + const hash_T hash) { #ifdef HT_DEBUG hash_count_lookup++; @@ -117,7 +137,9 @@ hashitem_T* hash_lookup(hashtab_T *ht, char_u *key, hash_T hash) hashitem_T *freeitem = NULL; if (hi->hi_key == HI_KEY_REMOVED) { freeitem = hi; - } else if ((hi->hi_hash == hash) && (STRCMP(hi->hi_key, key) == 0)) { + } else if ((hi->hi_hash == hash) + && (STRNCMP(hi->hi_key, key, key_len) == 0) + && hi->hi_key[key_len] == NUL) { return hi; } @@ -142,7 +164,8 @@ hashitem_T* hash_lookup(hashtab_T *ht, char_u *key, hash_T hash) if ((hi->hi_hash == hash) && (hi->hi_key != HI_KEY_REMOVED) - && (STRCMP(hi->hi_key, key) == 0)) { + && (STRNCMP(hi->hi_key, key, key_len) == 0) + && hi->hi_key[key_len] == NUL) { return hi; } @@ -179,7 +202,7 @@ void hash_debug_results(void) int hash_add(hashtab_T *ht, char_u *key) { hash_T hash = hash_hash(key); - hashitem_T *hi = hash_lookup(ht, key, hash); + hashitem_T *hi = hash_lookup(ht, (const char *)key, STRLEN(key), hash); if (!HASHITEM_EMPTY(hi)) { EMSG2(_(e_intern2), "hash_add()"); return FAIL; @@ -359,13 +382,16 @@ static void hash_may_resize(hashtab_T *ht, size_t minitems) ht->ht_filled = ht->ht_used; } +#define HASH_CYCLE_BODY(hash, p) \ + hash = hash * 101 + *p++ + /// Get the hash number for a key. /// /// If you think you know a better hash function: Compile with HT_DEBUG set and /// run a script that uses hashtables a lot. Vim will then print statistics /// when exiting. Try that with the current hash algorithm and yours. The /// lower the percentage the better. -hash_T hash_hash(char_u *key) +hash_T hash_hash(const char_u *key) { hash_T hash = *key; @@ -375,14 +401,43 @@ hash_T hash_hash(char_u *key) // A simplistic algorithm that appears to do very well. // Suggested by George Reilly. - char_u *p = key + 1; + const uint8_t *p = key + 1; while (*p != NUL) { - hash = hash * 101 + *p++; + HASH_CYCLE_BODY(hash, p); } return hash; } +/// Get the hash number for a key that is not a NUL-terminated string +/// +/// @warning Function does not check whether key contains NUL. But you will not +/// be able to get hash entry in this case. +/// +/// @param[in] key Key. +/// @param[in] len Key length. +/// +/// @return Key hash. +hash_T hash_hash_len(const char *key, const size_t len) + FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT +{ + if (len == 0) { + return 0; + } + + hash_T hash = *(uint8_t *)key; + const uint8_t *end = (uint8_t *)key + len; + + const uint8_t *p = (const uint8_t *)key + 1; + while (p < end) { + HASH_CYCLE_BODY(hash, p); + } + + return hash; +} + +#undef HASH_CYCLE_BODY + /// Function to get HI_KEY_REMOVED value /// /// Used for testing because luajit ffi does not allow getting addresses of diff --git a/src/nvim/if_cscope.c b/src/nvim/if_cscope.c index 9d50058257..a05ac5f877 100644 --- a/src/nvim/if_cscope.c +++ b/src/nvim/if_cscope.c @@ -2008,8 +2008,9 @@ static int cs_reset(exarg_T *eap) xfree(pplist); xfree(fllist); - if (p_csverbose) - MSG_ATTR(_("All cscope databases reset"), hl_attr(HLF_R) | MSG_HIST); + if (p_csverbose) { + msg_attr(_("All cscope databases reset"), hl_attr(HLF_R) | MSG_HIST); + } return CSCOPE_SUCCESS; } /* cs_reset */ diff --git a/src/nvim/keymap.c b/src/nvim/keymap.c index 94bbaf4239..72b0d0aa40 100644 --- a/src/nvim/keymap.c +++ b/src/nvim/keymap.c @@ -843,10 +843,10 @@ char_u *replace_termcodes(const char_u *from, const size_t from_len, // If "mapleader" or "maplocalleader" isn't set use a backslash. if (end - src >= 7 && STRNICMP(src, "", 8) == 0) { len = 8; - p = get_var_value((char_u *)"g:mapleader"); + p = get_var_value("g:mapleader"); } else if (end - src >= 12 && STRNICMP(src, "", 13) == 0) { len = 13; - p = get_var_value((char_u *)"g:maplocalleader"); + p = get_var_value("g:maplocalleader"); } else { len = 0; p = NULL; diff --git a/src/nvim/memline.c b/src/nvim/memline.c index b8891f6560..91dab16e27 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -1410,8 +1410,8 @@ recover_names ( for (int i = 0; i < num_files; ++i) { /* print the swap file name */ msg_outnum((long)++file_count); - MSG_PUTS(". "); - msg_puts(path_tail(files[i])); + msg_puts(". "); + msg_puts((const char *)path_tail(files[i])); msg_putchar('\n'); (void)swapfile_info(files[i]); } diff --git a/src/nvim/menu.c b/src/nvim/menu.c index 7c0eee64dd..cbaddb00d0 100644 --- a/src/nvim/menu.c +++ b/src/nvim/menu.c @@ -755,10 +755,11 @@ static void show_menus_recursive(vimmenu_T *menu, int modes, int depth) else msg_putchar(' '); MSG_PUTS(" "); - if (*menu->strings[bit] == NUL) - msg_puts_attr((char_u *)"", hl_attr(HLF_8)); - else + if (*menu->strings[bit] == NUL) { + msg_puts_attr("", hl_attr(HLF_8)); + } else { msg_outtrans_special(menu->strings[bit], FALSE); + } } } else { if (menu == NULL) { diff --git a/src/nvim/message.c b/src/nvim/message.c index ad1c63eeac..4cc1350938 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -129,9 +129,9 @@ int verb_msg(char_u *s) return n; } -int msg_attr(char_u *s, int attr) FUNC_ATTR_NONNULL_ARG(1) +int msg_attr(const char *s, const int attr) FUNC_ATTR_NONNULL_ARG(1) { - return msg_attr_keep(s, attr, FALSE); + return msg_attr_keep((char_u *)s, attr, false); } int @@ -165,8 +165,9 @@ msg_attr_keep ( || (*s != '<' && last_msg_hist != NULL && last_msg_hist->msg != NULL - && STRCMP(s, last_msg_hist->msg))) - add_msg_hist(s, -1, attr); + && STRCMP(s, last_msg_hist->msg))) { + add_msg_hist((const char *)s, -1, attr); + } /* When displaying keep_msg, don't let msg_start() free it, caller must do * that. */ @@ -348,7 +349,7 @@ int smsg_attr(int attr, char *s, ...) va_start(arglist, s); vim_vsnprintf((char *)IObuff, IOSIZE, s, arglist, NULL); va_end(arglist); - return msg_attr(IObuff, attr); + return msg_attr((const char *)IObuff, attr); } /* @@ -382,39 +383,40 @@ static int other_sourcing_name(void) return FALSE; } -/// Get the message about the source, as used for an error message. -/// Returns an allocated string with room for one more character. -/// Returns NULL when no message is to be given. -static char_u *get_emsg_source(void) +/// Get the message about the source, as used for an error message +/// +/// @return [allocated] String with room for one more characters. NULL when no +/// message is to be given. +static char *get_emsg_source(void) + FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT { if (sourcing_name != NULL && other_sourcing_name()) { - char_u *p = (char_u *)_("Error detected while processing %s:"); - size_t len = STRLEN(sourcing_name) + STRLEN(p) + 1; - char_u *buf = xmalloc(len); - snprintf((char *)buf, len, (char *)p, sourcing_name); + const char *const p = _("Error detected while processing %s:"); + const size_t buf_len = STRLEN(sourcing_name) + strlen(p) + 1; + char *const buf = xmalloc(buf_len); + snprintf(buf, buf_len, p, sourcing_name); return buf; } return NULL; } -/* - * Get the message about the source lnum, as used for an error message. - * Returns an allocated string with room for one more character. - * Returns NULL when no message is to be given. - */ -static char_u *get_emsg_lnum(void) +/// Get the message about the source lnum, as used for an error message. +/// +/// @return [allocated] String with room for one more characters. NULL when no +/// message is to be given. +static char *get_emsg_lnum(void) + FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT { - char_u *Buf, *p; - - /* lnum is 0 when executing a command from the command line - * argument, we don't want a line number then */ + // lnum is 0 when executing a command from the command line + // argument, we don't want a line number then if (sourcing_name != NULL && (other_sourcing_name() || sourcing_lnum != last_sourcing_lnum) && sourcing_lnum != 0) { - p = (char_u *)_("line %4ld:"); - Buf = xmalloc(STRLEN(p) + 20); - sprintf((char *)Buf, (char *)p, (long)sourcing_lnum); - return Buf; + const char *const p = _("line %4ld:"); + const size_t buf_len = 20 + strlen(p); + char *const buf = xmalloc(buf_len); + snprintf(buf, buf_len, p, (long)sourcing_lnum); + return buf; } return NULL; } @@ -426,10 +428,8 @@ static char_u *get_emsg_lnum(void) */ void msg_source(int attr) { - char_u *p; - - ++no_wait_return; - p = get_emsg_source(); + no_wait_return++; + char *p = get_emsg_source(); if (p != NULL) { msg_attr(p, attr); xfree(p); @@ -476,10 +476,10 @@ int emsg_not_now(void) * * return TRUE if wait_return not called */ -int emsg(char_u *s) +int emsg(const char_u *s_) { + const char *s = (const char *)s_; int attr; - char_u *p; int ignore = false; int severe; @@ -506,7 +506,7 @@ int emsg(char_u *s) * when the message should be ignored completely (used for the * interrupt message). */ - if (cause_errthrow(s, severe, &ignore) == true) { + if (cause_errthrow((char_u *)s, severe, &ignore) == true) { if (!ignore) { did_emsg = true; } @@ -514,7 +514,7 @@ int emsg(char_u *s) } // set "v:errmsg", also when using ":silent! cmd" - set_vim_var_string(VV_ERRMSG, (char *) s, -1); + set_vim_var_string(VV_ERRMSG, s, -1); /* * When using ":silent! cmd" ignore error messages. @@ -523,19 +523,21 @@ int emsg(char_u *s) if (emsg_silent != 0) { if (!emsg_noredir) { msg_start(); - p = get_emsg_source(); + char *p = get_emsg_source(); if (p != NULL) { - STRCAT(p, "\n"); - redir_write(p, STRLEN(p)); + const size_t p_len = strlen(p); + p[p_len] = '\n'; + redir_write(p, p_len + 1); xfree(p); } p = get_emsg_lnum(); if (p != NULL) { - STRCAT(p, "\n"); - redir_write(p, STRLEN(p)); + const size_t p_len = strlen(p); + p[p_len] = '\n'; + redir_write(p, p_len + 1); xfree(p); } - redir_write(s, STRLEN(s)); + redir_write(s, strlen(s)); } return true; } @@ -570,10 +572,8 @@ int emsg(char_u *s) */ msg_source(attr); - /* - * Display the error message itself. - */ - msg_nowait = FALSE; /* wait for this msg */ + // Display the error message itself. + msg_nowait = false; // Wait for this msg. return msg_attr(s, attr); } @@ -625,14 +625,14 @@ char_u *msg_trunc_attr(char_u *s, int force, int attr) { int n; - /* Add message to history before truncating */ - add_msg_hist(s, -1, attr); + // Add message to history before truncating. + add_msg_hist((const char *)s, -1, attr); s = msg_may_trunc(force, s); - msg_hist_off = TRUE; - n = msg_attr(s, attr); - msg_hist_off = FALSE; + msg_hist_off = true; + n = msg_attr((const char *)s, attr); + msg_hist_off = false; if (n) return s; @@ -671,12 +671,8 @@ char_u *msg_may_trunc(int force, char_u *s) return s; } -static void -add_msg_hist ( - char_u *s, - int len, /* -1 for undetermined length */ - int attr -) +/// @param[in] len Length of s or -1. +static void add_msg_hist(const char *s, int len, int attr) { if (msg_hist_off || msg_silent != 0) return; @@ -694,9 +690,10 @@ add_msg_hist ( ++s; --len; } - while (len > 0 && s[len - 1] == '\n') - --len; - p->msg = vim_strnsave(s, len); + while (len > 0 && s[len - 1] == '\n') { + len--; + } + p->msg = (char_u *)xmemdupz(s, (size_t)len); p->next = NULL; p->attr = attr; if (last_msg_hist != NULL) @@ -771,7 +768,7 @@ void ex_messages(exarg_T *eap) // Display what was not skipped. for (; p != NULL && !got_int; p = p->next) { if (p->msg != NULL) { - msg_attr(p->msg, p->attr); + msg_attr((const char *)p->msg, p->attr); } } @@ -1055,9 +1052,10 @@ void msg_start(void) msg_didout = FALSE; /* no output on current line yet */ } - /* when redirecting, may need to start a new line. */ - if (!did_return) - redir_write((char_u *)"\n", -1); + // When redirecting, may need to start a new line. + if (!did_return) { + redir_write("\n", 1); + } } /* @@ -1076,24 +1074,24 @@ void msg_putchar(int c) void msg_putchar_attr(int c, int attr) { - char_u buf[MB_MAXBYTES + 1]; + char buf[MB_MAXBYTES + 1]; if (IS_SPECIAL(c)) { - buf[0] = K_SPECIAL; - buf[1] = K_SECOND(c); - buf[2] = K_THIRD(c); + buf[0] = (char)K_SPECIAL; + buf[1] = (char)K_SECOND(c); + buf[2] = (char)K_THIRD(c); buf[3] = NUL; } else { - buf[(*mb_char2bytes)(c, buf)] = NUL; + buf[(*mb_char2bytes)(c, (char_u *)buf)] = NUL; } msg_puts_attr(buf, attr); } void msg_outnum(long n) { - char_u buf[20]; + char buf[20]; - sprintf((char *)buf, "%" PRId64, (int64_t)n); + snprintf(buf, sizeof(buf), "%ld", n); msg_puts(buf); } @@ -1149,16 +1147,16 @@ char_u *msg_outtrans_one(char_u *p, int attr) msg_outtrans_len_attr(p, l, attr); return p + l; } - msg_puts_attr(transchar_byte(*p), attr); + msg_puts_attr((const char *)transchar_byte(*p), attr); return p + 1; } int msg_outtrans_len_attr(char_u *msgstr, int len, int attr) { int retval = 0; - char_u *str = msgstr; - char_u *plain_start = msgstr; - char_u *s; + const char *str = (const char *)msgstr; + const char *plain_start = (const char *)msgstr; + char_u *s; int mb_l; int c; @@ -1168,10 +1166,11 @@ int msg_outtrans_len_attr(char_u *msgstr, int len, int attr) attr &= ~MSG_HIST; } - /* If the string starts with a composing character first draw a space on - * which the composing char can be drawn. */ - if (enc_utf8 && utf_iscomposing(utf_ptr2char(msgstr))) - msg_puts_attr((char_u *)" ", attr); + // If the string starts with a composing character first draw a space on + // which the composing char can be drawn. + if (enc_utf8 && utf_iscomposing(utf_ptr2char(msgstr))) { + msg_puts_attr(" ", attr); + } /* * Go over the string. Special characters are translated and printed. @@ -1180,24 +1179,25 @@ int msg_outtrans_len_attr(char_u *msgstr, int len, int attr) while (--len >= 0) { if (enc_utf8) /* Don't include composing chars after the end. */ - mb_l = utfc_ptr2len_len(str, len + 1); + mb_l = utfc_ptr2len_len((char_u *)str, len + 1); else if (has_mbyte) - mb_l = (*mb_ptr2len)(str); + mb_l = (*mb_ptr2len)((char_u *)str); else mb_l = 1; if (has_mbyte && mb_l > 1) { - c = (*mb_ptr2char)(str); - if (vim_isprintc(c)) - /* printable multi-byte char: count the cells. */ - retval += (*mb_ptr2cells)(str); - else { - /* unprintable multi-byte char: print the printable chars so - * far and the translation of the unprintable char. */ - if (str > plain_start) - msg_puts_attr_len(plain_start, (int)(str - plain_start), - attr); + c = (*mb_ptr2char)((char_u *)str); + if (vim_isprintc(c)) { + // Printable multi-byte char: count the cells. + retval += (*mb_ptr2cells)((char_u *)str); + } else { + // Unprintable multi-byte char: print the printable chars so + // far and the translation of the unprintable char. + if (str > plain_start) { + msg_puts_attr_len(plain_start, str - plain_start, attr); + } plain_start = str + mb_l; - msg_puts_attr(transchar(c), attr == 0 ? hl_attr(HLF_8) : attr); + msg_puts_attr((const char *)transchar(c), + (attr == 0 ? hl_attr(HLF_8) : attr)); retval += char2cells(c); } len -= mb_l - 1; @@ -1205,23 +1205,25 @@ int msg_outtrans_len_attr(char_u *msgstr, int len, int attr) } else { s = transchar_byte(*str); if (s[1] != NUL) { - /* unprintable char: print the printable chars so far and the - * translation of the unprintable char. */ - if (str > plain_start) - msg_puts_attr_len(plain_start, (int)(str - plain_start), - attr); + // Unprintable char: print the printable chars so far and the + // translation of the unprintable char. + if (str > plain_start) { + msg_puts_attr_len(plain_start, str - plain_start, attr); + } plain_start = str + 1; - msg_puts_attr(s, attr == 0 ? hl_attr(HLF_8) : attr); + msg_puts_attr((const char *)s, attr == 0 ? hl_attr(HLF_8) : attr); retval += (int)STRLEN(s); - } else - ++retval; - ++str; + } else { + retval++; + } + str++; } } - if (str > plain_start) - /* print the printable chars at the end */ - msg_puts_attr_len(plain_start, (int)(str - plain_start), attr); + if (str > plain_start) { + // Print the printable chars at the end. + msg_puts_attr_len(plain_start, str - plain_start, attr); + } return retval; } @@ -1264,23 +1266,23 @@ msg_outtrans_special ( { char_u *str = strstart; int retval = 0; - char_u *string; int attr; - int len; attr = hl_attr(HLF_8); while (*str != NUL) { - /* Leading and trailing spaces need to be displayed in <> form. */ + const char *string; + // Leading and trailing spaces need to be displayed in <> form. if ((str == strstart || str[1] == NUL) && *str == ' ') { - string = (char_u *)""; - ++str; - } else - string = str2special(&str, from); - len = vim_strsize(string); - /* Highlight special keys */ - msg_puts_attr(string, len > 1 - && (*mb_ptr2len)(string) <= 1 - ? attr : 0); + string = ""; + str++; + } else { + string = (const char *)str2special((char_u **)&str, from); + } + const int len = vim_strsize((char_u *)string); + // Highlight special keys + msg_puts_attr(string, (len > 1 + && (*mb_ptr2len)((char_u *)string) <= 1 + ? attr : 0)); retval += len; } return retval; @@ -1404,7 +1406,6 @@ void msg_prt_line(char_u *s, int list) int attr = 0; char_u *trail = NULL; int l; - char_u buf[MB_MAXBYTES + 1]; if (curwin->w_p_list) list = TRUE; @@ -1430,10 +1431,11 @@ void msg_prt_line(char_u *s, int list) c = *p_extra++; } else if (has_mbyte && (l = (*mb_ptr2len)(s)) > 1) { col += (*mb_ptr2cells)(s); + char buf[MB_MAXBYTES + 1]; if (lcs_nbsp != NUL && list && (mb_ptr2char(s) == 160 || mb_ptr2char(s) == 0x202f)) { - mb_char2bytes(lcs_nbsp, buf); - buf[(*mb_ptr2len)(buf)] = NUL; + mb_char2bytes(lcs_nbsp, (char_u *)buf); + buf[(*mb_ptr2len)((char_u *)buf)] = NUL; } else { memmove(buf, s, (size_t)l); buf[l] = NUL; @@ -1530,12 +1532,12 @@ static char_u *screen_puts_mbyte(char_u *s, int l, int attr) * Output a string to the screen at position msg_row, msg_col. * Update msg_row and msg_col for the next message. */ -void msg_puts(char_u *s) +void msg_puts(const char *s) { msg_puts_attr(s, 0); } -void msg_puts_title(char_u *s) +void msg_puts_title(const char *s) { msg_puts_attr(s, hl_attr(HLF_T)); } @@ -1559,7 +1561,7 @@ void msg_puts_long_len_attr(char_u *longstr, int len, int attr) if (len > room && room >= 20) { slen = (room - 3) / 2; msg_outtrans_len_attr(longstr, slen, attr); - msg_puts_attr((char_u *)"...", hl_attr(HLF_8)); + msg_puts_attr("...", hl_attr(HLF_8)); } msg_outtrans_len_attr(longstr + len - slen, slen, attr); } @@ -1567,7 +1569,7 @@ void msg_puts_long_len_attr(char_u *longstr, int len, int attr) /* * Basic function for writing a message with highlight attributes. */ -void msg_puts_attr(char_u *s, int attr) +void msg_puts_attr(const char *const s, const int attr) { msg_puts_attr_len(s, -1, attr); } @@ -1575,7 +1577,7 @@ void msg_puts_attr(char_u *s, int attr) /// Like msg_puts_attr(), but with a maximum length "maxlen" (in bytes). /// When "maxlen" is -1 there is no maximum length. /// When "maxlen" is >= 0 the message is not put in the history. -static void msg_puts_attr_len(char_u *str, int maxlen, int attr) +void msg_puts_attr_len(const char *str, const ptrdiff_t maxlen, int attr) { // If redirection is on, also write to the redirection file. redir_write(str, maxlen); @@ -1606,9 +1608,9 @@ static void msg_puts_attr_len(char_u *str, int maxlen, int attr) // different, e.g. for Win32 console) or we just don't know where the // cursor is. if (msg_use_printf()) { - msg_puts_printf((char *)str, maxlen); + msg_puts_printf(str, maxlen); } else { - msg_puts_display(str, maxlen, attr, false); + msg_puts_display((const char_u *)str, maxlen, attr, false); } } @@ -1616,14 +1618,15 @@ static void msg_puts_attr_len(char_u *str, int maxlen, int attr) * The display part of msg_puts_attr_len(). * May be called recursively to display scroll-back text. */ -static void msg_puts_display(char_u *str, int maxlen, int attr, int recurse) +static void msg_puts_display(const char_u *str, int maxlen, int attr, + int recurse) { - char_u *s = str; - char_u *t_s = str; /* string from "t_s" to "s" is still todo */ - int t_col = 0; /* screen cells todo, 0 when "t_s" not used */ + const char_u *s = str; + const char_u *t_s = str; // String from "t_s" to "s" is still todo. + int t_col = 0; // Screen cells todo, 0 when "t_s" not used. int l; int cw; - char_u *sb_str = str; + const char_u *sb_str = str; int sb_col = msg_col; int wrap; int did_last_char; @@ -1665,26 +1668,26 @@ static void msg_puts_display(char_u *str, int maxlen, int attr, int recurse) if (msg_col >= Columns) /* can happen after screen resize */ msg_col = Columns - 1; - /* Display char in last column before showing more-prompt. */ - if (*s >= ' ' - && !cmdmsg_rl - ) { + // Display char in last column before showing more-prompt. + if (*s >= ' ' && !cmdmsg_rl) { if (has_mbyte) { if (enc_utf8 && maxlen >= 0) /* avoid including composing chars after the end */ l = utfc_ptr2len_len(s, (int)((str + maxlen) - s)); else l = (*mb_ptr2len)(s); - s = screen_puts_mbyte(s, l, attr); - } else + s = screen_puts_mbyte((char_u *)s, l, attr); + } else { msg_screen_putchar(*s++, attr); + } did_last_char = TRUE; } else did_last_char = FALSE; - if (p_more) - /* store text for scrolling back */ - store_sb_text(&sb_str, s, attr, &sb_col, TRUE); + if (p_more) { + // Store text for scrolling back. + store_sb_text((char_u **)&sb_str, (char_u *)s, attr, &sb_col, true); + } inc_msg_scrolled(); need_wait_return = TRUE; /* may need wait_return in main() */ @@ -1720,13 +1723,15 @@ static void msg_puts_display(char_u *str, int maxlen, int attr, int recurse) && msg_col + t_col >= Columns - 1) ; if (t_col > 0 && (wrap || *s == '\r' || *s == '\b' - || *s == '\t' || *s == BELL)) - /* output any postponed text */ + || *s == '\t' || *s == BELL)) { + // Output any postponed text. t_puts(&t_col, t_s, s, attr); + } - if (wrap && p_more && !recurse) - /* store text for scrolling back */ - store_sb_text(&sb_str, s, attr, &sb_col, TRUE); + if (wrap && p_more && !recurse) { + // Store text for scrolling back. + store_sb_text((char_u **)&sb_str, (char_u *)s, attr, &sb_col, true); + } if (*s == '\n') { /* go to next line */ msg_didout = FALSE; /* remember that line is empty */ @@ -1764,7 +1769,7 @@ static void msg_puts_display(char_u *str, int maxlen, int attr, int recurse) // characters and draw them all at once later. if (cmdmsg_rl || (cw > 1 && msg_col + t_col >= Columns - 1)) { if (l > 1) { - s = screen_puts_mbyte(s, l, attr) - 1; + s = screen_puts_mbyte((char_u *)s, l, attr) - 1; } else { msg_screen_putchar(*s, attr); } @@ -1780,10 +1785,12 @@ static void msg_puts_display(char_u *str, int maxlen, int attr, int recurse) } /* output any postponed text */ - if (t_col > 0) + if (t_col > 0) { t_puts(&t_col, t_s, s, attr); - if (p_more && !recurse) - store_sb_text(&sb_str, s, attr, &sb_col, FALSE); + } + if (p_more && !recurse) { + store_sb_text((char_u **)&sb_str, (char_u *)s, attr, &sb_col, false); + } msg_check(); } @@ -1959,11 +1966,11 @@ static msgchunk_T *disp_sb_line(int row, msgchunk_T *smp) /* * Output any postponed text for msg_puts_attr_len(). */ -static void t_puts(int *t_col, char_u *t_s, char_u *s, int attr) +static void t_puts(int *t_col, const char_u *t_s, const char_u *s, int attr) { /* output postponed text */ msg_didout = TRUE; /* remember that line is not empty */ - screen_puts_len(t_s, (int)(s - t_s), msg_row, msg_col, attr); + screen_puts_len((char_u *)t_s, (int)(s - t_s), msg_row, msg_col, attr); msg_col += *t_col; *t_col = 0; /* If the string starts with a composing character don't increment the @@ -1984,13 +1991,13 @@ int msg_use_printf(void) } /// Print a message when there is no valid screen. -static void msg_puts_printf(char *str, int maxlen) +static void msg_puts_printf(const char *str, const ptrdiff_t maxlen) { - char *s = str; + const char *s = str; char buf[4]; char *p; - while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen)) { + while (*s != NUL && (maxlen < 0 || s - str < maxlen)) { if (!(silent_mode && p_verbose == 0)) { // NL --> CR NL translation (for Unix, not for "--version") p = &buf[0]; @@ -2447,9 +2454,9 @@ void msg_check(void) * May write a string to the redirection file. * When "maxlen" is -1 write the whole string, otherwise up to "maxlen" bytes. */ -static void redir_write(char_u *str, int maxlen) +static void redir_write(const char *const str, const ptrdiff_t maxlen) { - char_u *s = str; + const char_u *s = (char_u *)str; static int cur_col = 0; if (maxlen == 0) { @@ -2493,23 +2500,28 @@ static void redir_write(char_u *str, int maxlen) write_reg_contents(redir_reg, s, len, true); } if (redir_vname) { - var_redir_str(s, maxlen); + var_redir_str((char_u *)s, maxlen); } - /* Write and adjust the current column. */ - while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen)) { - if (!redir_reg && !redir_vname && !capture_ga) - if (redir_fd != NULL) + // Write and adjust the current column. + while (*s != NUL + && (maxlen < 0 || (int)(s - (const char_u *)str) < maxlen)) { + if (!redir_reg && !redir_vname && !capture_ga) { + if (redir_fd != NULL) { putc(*s, redir_fd); - if (verbose_fd != NULL) + } + } + if (verbose_fd != NULL) { putc(*s, verbose_fd); - if (*s == '\r' || *s == '\n') + } + if (*s == '\r' || *s == '\n') { cur_col = 0; - else if (*s == '\t') + } else if (*s == '\t') { cur_col += (8 - cur_col % 8); - else - ++cur_col; - ++s; + } else { + cur_col++; + } + s++; } if (msg_silent != 0) /* should update msg_col */ @@ -2615,14 +2627,16 @@ void give_warning(char_u *message, bool hl) FUNC_ATTR_NONNULL_ARG(1) set_vim_var_string(VV_WARNINGMSG, (char *) message, -1); xfree(keep_msg); keep_msg = NULL; - if (hl) + if (hl) { keep_msg_attr = hl_attr(HLF_W); - else + } else { keep_msg_attr = 0; - if (msg_attr(message, keep_msg_attr) && msg_scrolled == 0) + } + if (msg_attr((const char *)message, keep_msg_attr) && msg_scrolled == 0) { set_keep_msg(message, keep_msg_attr); - msg_didout = FALSE; /* overwrite this message */ - msg_nowait = TRUE; /* don't wait for this message */ + } + msg_didout = false; // Overwrite this message. + msg_nowait = true; // Don't wait for this message. msg_col = 0; --no_wait_return; @@ -2958,11 +2972,12 @@ static void copy_hotkeys_and_msg(const char_u *message, char_u *buttons, */ void display_confirm_msg(void) { - /* avoid that 'q' at the more prompt truncates the message here */ - ++confirm_msg_used; - if (confirm_msg != NULL) - msg_puts_attr(confirm_msg, hl_attr(HLF_M)); - --confirm_msg_used; + // Avoid that 'q' at the more prompt truncates the message here. + confirm_msg_used++; + if (confirm_msg != NULL) { + msg_puts_attr((const char *)confirm_msg, hl_attr(HLF_M)); + } + confirm_msg_used--; } int vim_dialog_yesno(int type, char_u *title, char_u *message, int dflt) diff --git a/src/nvim/message.h b/src/nvim/message.h index d3a16fff93..d3280f729d 100644 --- a/src/nvim/message.h +++ b/src/nvim/message.h @@ -29,7 +29,7 @@ #define MSG(s) msg((char_u *)(s)) /// Show message highlighted according to the attr -#define MSG_ATTR(s, attr) msg_attr((char_u *)(s), (attr)) +#define MSG_ATTR(s, attr) msg_attr((const char *)(s), (attr)) /// Display error message /// @@ -49,13 +49,13 @@ #define EMSGU(s, n) emsgf((const char *) (s), (uint64_t)(n)) /// Display message at the recorded position -#define MSG_PUTS(s) msg_puts((char_u *)(s)) +#define MSG_PUTS(s) msg_puts((const char *)(s)) /// Display message at the recorded position, highlighted -#define MSG_PUTS_ATTR(s, a) msg_puts_attr((char_u *)(s), (a)) +#define MSG_PUTS_ATTR(s, a) msg_puts_attr((const char *)(s), (a)) /// Like #MSG_PUTS, but highlight like title -#define MSG_PUTS_TITLE(s) msg_puts_title((char_u *)(s)) +#define MSG_PUTS_TITLE(s) msg_puts_title((const char *)(s)) /// Like #MSG_PUTS, but if middle part of too long messages it will be replaced #define MSG_PUTS_LONG(s) msg_puts_long_attr((char_u *)(s), 0) diff --git a/src/nvim/misc1.c b/src/nvim/misc1.c index ba26381e23..f528c9e15a 100644 --- a/src/nvim/misc1.c +++ b/src/nvim/misc1.c @@ -2545,7 +2545,7 @@ void vim_beep(unsigned val) * function give the user a hint where the beep comes from. */ if (vim_strchr(p_debug, 'e') != NULL) { msg_source(hl_attr(HLF_W)); - msg_attr((char_u *)_("Beep!"), hl_attr(HLF_W)); + msg_attr(_("Beep!"), hl_attr(HLF_W)); } } } diff --git a/src/nvim/normal.c b/src/nvim/normal.c index 5d7a8faeba..641658532d 100644 --- a/src/nvim/normal.c +++ b/src/nvim/normal.c @@ -617,7 +617,7 @@ static void normal_redraw_mode_message(NormalState *s) update_screen(0); // now reset it, otherwise it's put in the history again keep_msg = kmsg; - msg_attr(kmsg, keep_msg_attr); + msg_attr((const char *)kmsg, keep_msg_attr); xfree(kmsg); } setcursor(); @@ -1276,7 +1276,7 @@ static void normal_redraw(NormalState *s) // msg_attr_keep() will set keep_msg to NULL, must free the string here. // Don't reset keep_msg, msg_attr_keep() uses it to check for duplicates. char *p = (char *)keep_msg; - msg_attr((uint8_t *)p, keep_msg_attr); + msg_attr(p, keep_msg_attr); xfree(p); } diff --git a/src/nvim/option.c b/src/nvim/option.c index a218323dac..b1cbe3fb59 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2569,8 +2569,7 @@ did_set_string_option ( init_highlight(FALSE, FALSE); - if (dark != (*p_bg == 'd') - && get_var_value((char_u *)"g:colors_name") != NULL) { + if (dark != (*p_bg == 'd') && get_var_value("g:colors_name") != NULL) { /* The color scheme must have set 'background' back to another * value, that's not what we want here. Disable the color * scheme and set the colors again. */ @@ -3886,7 +3885,7 @@ set_bool_option ( "W17: Arabic requires UTF-8, do ':set encoding=utf-8'"); msg_source(hl_attr(HLF_W)); - MSG_ATTR(_(w_arabic), hl_attr(HLF_W)); + msg_attr(_(w_arabic), hl_attr(HLF_W)); set_vim_var_string(VV_WARNINGMSG, _(w_arabic), -1); } diff --git a/src/nvim/pos.h b/src/nvim/pos.h index 864f3fe866..966255e6a4 100644 --- a/src/nvim/pos.h +++ b/src/nvim/pos.h @@ -2,6 +2,8 @@ #define NVIM_POS_H typedef long linenr_T; // line number type +/// Format used to print values which have linenr_T type +#define PRIdLINENR "ld" /// Column number type typedef int colnr_T; diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index c40403e3f6..3b86662f05 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -2068,21 +2068,20 @@ void qf_list(exarg_T *eap) if (qfp->qf_lnum == 0) { IObuff[0] = NUL; } else if (qfp->qf_col == 0) { - vim_snprintf((char *)IObuff, IOSIZE, ":%" PRId64, - (int64_t)qfp->qf_lnum); + vim_snprintf((char *)IObuff, IOSIZE, ":%" PRIdLINENR, qfp->qf_lnum); } else { - vim_snprintf((char *)IObuff, IOSIZE, ":%" PRId64 " col %d", - (int64_t)qfp->qf_lnum, qfp->qf_col); + vim_snprintf((char *)IObuff, IOSIZE, ":%" PRIdLINENR " col %d", + qfp->qf_lnum, qfp->qf_col); } vim_snprintf((char *)IObuff + STRLEN(IObuff), IOSIZE, "%s:", (char *)qf_types(qfp->qf_type, qfp->qf_nr)); - msg_puts_attr(IObuff, hl_attr(HLF_N)); + msg_puts_attr((const char *)IObuff, hl_attr(HLF_N)); if (qfp->qf_pattern != NULL) { qf_fmt_text(qfp->qf_pattern, IObuff, IOSIZE); - STRCAT(IObuff, ":"); - msg_puts(IObuff); + STRNCAT(IObuff, ":", IOSIZE); + msg_puts((const char *)IObuff); } - msg_puts((char_u *)" "); + msg_puts(" "); /* Remove newlines and leading whitespace from the text. For an * unrecognized line keep the indent, the compiler may mark a word diff --git a/src/nvim/screen.c b/src/nvim/screen.c index 3823fb2a23..de16572dc2 100644 --- a/src/nvim/screen.c +++ b/src/nvim/screen.c @@ -6719,17 +6719,19 @@ int showmode(void) if (edit_submode_pre != NULL) length -= vim_strsize(edit_submode_pre); if (length - vim_strsize(edit_submode) > 0) { - if (edit_submode_pre != NULL) - msg_puts_attr(edit_submode_pre, attr); - msg_puts_attr(edit_submode, attr); + if (edit_submode_pre != NULL) { + msg_puts_attr((const char *)edit_submode_pre, attr); + } + msg_puts_attr((const char *)edit_submode, attr); } if (edit_submode_extra != NULL) { MSG_PUTS_ATTR(" ", attr); /* add a space in between */ - if ((int)edit_submode_highl < (int)HLF_COUNT) + if ((int)edit_submode_highl < (int)HLF_COUNT) { sub_attr = hl_attr(edit_submode_highl); - else + } else { sub_attr = attr; - msg_puts_attr(edit_submode_extra, sub_attr); + } + msg_puts_attr((const char *)edit_submode_extra, sub_attr); } } } else { diff --git a/src/nvim/search.c b/src/nvim/search.c index 2a087276e7..a9766a406e 100644 --- a/src/nvim/search.c +++ b/src/nvim/search.c @@ -4656,12 +4656,12 @@ static void show_pat_in_path(char_u *line, int type, int did_show, int action, F *(p + 1) = NUL; } if (action == ACTION_SHOW_ALL) { - sprintf((char *)IObuff, "%3ld: ", count); /* show match nr */ - msg_puts(IObuff); - sprintf((char *)IObuff, "%4ld", *lnum); /* show line nr */ - /* Highlight line numbers */ - msg_puts_attr(IObuff, hl_attr(HLF_N)); - MSG_PUTS(" "); + snprintf((char *)IObuff, IOSIZE, "%3ld: ", count); // Show match nr. + msg_puts((const char *)IObuff); + snprintf((char *)IObuff, IOSIZE, "%4ld", *lnum); // Show line nr. + // Highlight line numbers. + msg_puts_attr((const char *)IObuff, hl_attr(HLF_N)); + msg_puts(" "); } msg_prt_line(line, FALSE); ui_flush(); /* show one line at a time */ diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 1ace39344d..16370ffdc3 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -3094,10 +3094,11 @@ count_common_word ( } hash = hash_hash(p); - hi = hash_lookup(&lp->sl_wordcount, p, hash); + const size_t p_len = STRLEN(p); + hi = hash_lookup(&lp->sl_wordcount, (const char *)p, p_len, hash); if (HASHITEM_EMPTY(hi)) { - wc = xmalloc(sizeof(wordcount_T) + STRLEN(p)); - STRCPY(wc->wc_word, p); + wc = xmalloc(sizeof(wordcount_T) + p_len); + memcpy(wc->wc_word, p, p_len + 1); wc->wc_count = count; hash_add_item(&lp->sl_wordcount, hi, wc->wc_word, hash); } else { @@ -5513,7 +5514,7 @@ static int spell_read_dic(spellinfo_T *spin, char_u *fname, afffile_T *affile) } hash = hash_hash(dw); - hi = hash_lookup(&ht, dw, hash); + hi = hash_lookup(&ht, (const char *)dw, STRLEN(dw), hash); if (!HASHITEM_EMPTY(hi)) { if (p_verbose > 0) smsg(_("Duplicate word in %s line %d: %s"), @@ -6343,7 +6344,7 @@ static int tree_add_word(spellinfo_T *spin, char_u *word, wordnode_T *root, int if (spin->si_verbose) { msg_start(); - msg_puts((char_u *)_(msg_compressing)); + msg_puts(_(msg_compressing)); msg_clr_eos(); msg_didout = FALSE; msg_col = 0; @@ -6519,7 +6520,8 @@ node_compress ( // Try to find an identical child. hash = hash_hash(child->wn_u1.hashkey); - hi = hash_lookup(ht, child->wn_u1.hashkey, hash); + hi = hash_lookup(ht, (const char *)child->wn_u1.hashkey, + STRLEN(child->wn_u1.hashkey), hash); if (!HASHITEM_EMPTY(hi)) { // There are children we encountered before with a hash value // identical to the current child. Now check if there is one @@ -8515,7 +8517,7 @@ void spell_suggest(int count) vim_snprintf((char *)IObuff, IOSIZE, ":ot \"%.*s\" egnahC", sug.su_badlen, sug.su_badptr); } - msg_puts(IObuff); + msg_puts((const char *)IObuff); msg_clr_eos(); msg_putchar('\n'); @@ -8531,18 +8533,19 @@ void spell_suggest(int count) sug.su_badptr + stp->st_orglen, sug.su_badlen - stp->st_orglen + 1); vim_snprintf((char *)IObuff, IOSIZE, "%2d", i + 1); - if (cmdmsg_rl) + if (cmdmsg_rl) { rl_mirror(IObuff); - msg_puts(IObuff); + } + msg_puts((const char *)IObuff); vim_snprintf((char *)IObuff, IOSIZE, " \"%s\"", wcopy); - msg_puts(IObuff); + msg_puts((const char *)IObuff); // The word may replace more than "su_badlen". if (sug.su_badlen < stp->st_orglen) { vim_snprintf((char *)IObuff, IOSIZE, _(" < \"%.*s\""), - stp->st_orglen, sug.su_badptr); - msg_puts(IObuff); + stp->st_orglen, sug.su_badptr); + msg_puts((const char *)IObuff); } if (p_verbose > 0) { @@ -8558,7 +8561,7 @@ void spell_suggest(int count) // Mirror the numbers, but keep the leading space. rl_mirror(IObuff + 1); msg_advance(30); - msg_puts(IObuff); + msg_puts((const char *)IObuff); } msg_putchar('\n'); } @@ -11182,11 +11185,13 @@ add_sound_suggest ( // the words that have a better score than before. Use a hashtable to // remember the words that have been done. hash = hash_hash(goodword); - hi = hash_lookup(&slang->sl_sounddone, goodword, hash); + const size_t goodword_len = STRLEN(goodword); + hi = hash_lookup(&slang->sl_sounddone, (const char *)goodword, goodword_len, + hash); if (HASHITEM_EMPTY(hi)) { - sft = xmalloc(sizeof(sftword_T) + STRLEN(goodword)); + sft = xmalloc(sizeof(sftword_T) + goodword_len); sft->sft_score = score; - STRCPY(sft->sft_word, goodword); + memcpy(sft->sft_word, goodword, goodword_len + 1); hash_add_item(&slang->sl_sounddone, hi, sft->sft_word, hash); } else { sft = HI2SFT(hi); @@ -11453,10 +11458,10 @@ static void set_map_str(slang_T *lp, char_u *map) mb_char2bytes(headc, b + cl + 1); b[cl + 1 + headcl] = NUL; hash = hash_hash(b); - hi = hash_lookup(&lp->sl_map_hash, b, hash); - if (HASHITEM_EMPTY(hi)) + hi = hash_lookup(&lp->sl_map_hash, (const char *)b, STRLEN(b), hash); + if (HASHITEM_EMPTY(hi)) { hash_add_item(&lp->sl_map_hash, hi, b, hash); - else { + } else { // This should have been checked when generating the .spl // file. EMSG(_("E783: duplicate char in MAP entry")); @@ -11661,9 +11666,10 @@ static void add_banned(suginfo_T *su, char_u *word) hashitem_T *hi; hash = hash_hash(word); - hi = hash_lookup(&su->su_banned, word, hash); + const size_t word_len = STRLEN(word); + hi = hash_lookup(&su->su_banned, (const char *)word, word_len, hash); if (HASHITEM_EMPTY(hi)) { - s = vim_strsave(word); + s = xmemdupz(word, word_len); hash_add_item(&su->su_banned, hi, s, hash); } } @@ -12995,19 +13001,17 @@ pop: // ":spellinfo" void ex_spellinfo(exarg_T *eap) { - langp_T *lp; - char_u *p; - - if (no_spell_checking(curwin)) + if (no_spell_checking(curwin)) { return; + } msg_start(); for (int lpi = 0; lpi < curwin->w_s->b_langp.ga_len && !got_int; ++lpi) { - lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); - msg_puts((char_u *)"file: "); - msg_puts(lp->lp_slang->sl_fname); + langp_T *const lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); + msg_puts("file: "); + msg_puts((const char *)lp->lp_slang->sl_fname); msg_putchar('\n'); - p = lp->lp_slang->sl_info; + const char *const p = (const char *)lp->lp_slang->sl_info; if (p != NULL) { msg_puts(p); msg_putchar('\n'); diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 37e5542dad..f13f7a702e 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -3576,22 +3576,24 @@ syn_list_one ( } syn_list_flags(namelist1, spp->sp_flags, attr); - if (spp->sp_cont_list != NULL) - put_id_list((char_u *)"contains", spp->sp_cont_list, attr); + if (spp->sp_cont_list != NULL) { + put_id_list("contains", spp->sp_cont_list, attr); + } - if (spp->sp_syn.cont_in_list != NULL) - put_id_list((char_u *)"containedin", - spp->sp_syn.cont_in_list, attr); + if (spp->sp_syn.cont_in_list != NULL) { + put_id_list("containedin", spp->sp_syn.cont_in_list, attr); + } if (spp->sp_next_list != NULL) { - put_id_list((char_u *)"nextgroup", spp->sp_next_list, attr); + put_id_list("nextgroup", spp->sp_next_list, attr); syn_list_flags(namelist2, spp->sp_flags, attr); } if (spp->sp_flags & (HL_SYNC_HERE|HL_SYNC_THERE)) { - if (spp->sp_flags & HL_SYNC_HERE) - msg_puts_attr((char_u *)"grouphere", attr); - else - msg_puts_attr((char_u *)"groupthere", attr); + if (spp->sp_flags & HL_SYNC_HERE) { + msg_puts_attr("grouphere", attr); + } else { + msg_puts_attr("groupthere", attr); + } msg_putchar(' '); if (spp->sp_sync_idx >= 0) msg_outtrans(HL_TABLE()[SYN_ITEMS(curwin->w_s) @@ -3605,7 +3607,7 @@ syn_list_one ( /* list the link, if there is one */ if (HL_TABLE()[id - 1].sg_link && (did_header || link_only) && !got_int) { (void)syn_list_header(did_header, 999, id); - msg_puts_attr((char_u *)"links to", attr); + msg_puts_attr("links to", attr); msg_putchar(' '); msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name); } @@ -3617,7 +3619,7 @@ static void syn_list_flags(struct name_list *nlist, int flags, int attr) for (i = 0; nlist[i].flag != 0; ++i) if (flags & nlist[i].flag) { - msg_puts_attr((char_u *)nlist[i].name, attr); + msg_puts_attr(nlist[i].name, attr); msg_putchar(' '); } } @@ -3640,15 +3642,14 @@ static void syn_list_cluster(int id) msg_advance(endcol); if (SYN_CLSTR(curwin->w_s)[id].scl_list != NULL) { - put_id_list((char_u *)"cluster", SYN_CLSTR(curwin->w_s)[id].scl_list, - hl_attr(HLF_D)); + put_id_list("cluster", SYN_CLSTR(curwin->w_s)[id].scl_list, hl_attr(HLF_D)); } else { - msg_puts_attr((char_u *)"cluster", hl_attr(HLF_D)); - msg_puts((char_u *)"=NONE"); + msg_puts_attr("cluster", hl_attr(HLF_D)); + msg_puts("=NONE"); } } -static void put_id_list(char_u *name, short *list, int attr) +static void put_id_list(const char *name, short *list, int attr) { short *p; @@ -3656,14 +3657,15 @@ static void put_id_list(char_u *name, short *list, int attr) msg_putchar('='); for (p = list; *p; ++p) { if (*p >= SYNID_ALLBUT && *p < SYNID_TOP) { - if (p[1]) - MSG_PUTS("ALLBUT"); - else - MSG_PUTS("ALL"); + if (p[1]) { + msg_puts("ALLBUT"); + } else { + msg_puts("ALL"); + } } else if (*p >= SYNID_TOP && *p < SYNID_CONTAINED) { - MSG_PUTS("TOP"); + msg_puts("TOP"); } else if (*p >= SYNID_CONTAINED && *p < SYNID_CLUSTER) { - MSG_PUTS("CONTAINED"); + msg_puts("CONTAINED"); } else if (*p >= SYNID_CLUSTER) { short scl_id = *p - SYNID_CLUSTER; @@ -3688,7 +3690,7 @@ static void put_pattern(char *s, int c, synpat_T *spp, int attr) /* May have to write "matchgroup=group" */ if (last_matchgroup != spp->sp_syn_match_id) { last_matchgroup = spp->sp_syn_match_id; - msg_puts_attr((char_u *)"matchgroup", attr); + msg_puts_attr("matchgroup", attr); msg_putchar('='); if (last_matchgroup == 0) msg_outtrans((char_u *)"NONE"); @@ -3697,8 +3699,8 @@ static void put_pattern(char *s, int c, synpat_T *spp, int attr) msg_putchar(' '); } - /* output the name of the pattern and an '=' or ' ' */ - msg_puts_attr((char_u *)s, attr); + // Output the name of the pattern and an '=' or ' '. + msg_puts_attr(s, attr); msg_putchar(c); /* output the pattern, in between a char that is not in the pattern */ @@ -3718,9 +3720,10 @@ static void put_pattern(char *s, int c, synpat_T *spp, int attr) if (!(spp->sp_off_flags & (mask + (mask << SPO_COUNT)))) { continue; } - if (!first) - msg_putchar(','); /* separate with commas */ - msg_puts((char_u *)spo_name_tab[i]); + if (!first) { + msg_putchar(','); // Separate with commas. + } + msg_puts(spo_name_tab[i]); n = spp->sp_offsets[i]; if (i != SPO_LC_OFF) { if (spp->sp_off_flags & mask) @@ -3792,32 +3795,31 @@ syn_list_keywords ( } did_header = TRUE; if (prev_contained != (kp->flags & HL_CONTAINED)) { - msg_puts_attr((char_u *)"contained", attr); + msg_puts_attr("contained", attr); msg_putchar(' '); prev_contained = (kp->flags & HL_CONTAINED); } if (kp->k_syn.cont_in_list != prev_cont_in_list) { - put_id_list((char_u *)"containedin", - kp->k_syn.cont_in_list, attr); + put_id_list("containedin", kp->k_syn.cont_in_list, attr); msg_putchar(' '); prev_cont_in_list = kp->k_syn.cont_in_list; } if (kp->next_list != prev_next_list) { - put_id_list((char_u *)"nextgroup", kp->next_list, attr); + put_id_list("nextgroup", kp->next_list, attr); msg_putchar(' '); prev_next_list = kp->next_list; if (kp->flags & HL_SKIPNL) { - msg_puts_attr((char_u *)"skipnl", attr); + msg_puts_attr("skipnl", attr); msg_putchar(' '); prev_skipnl = (kp->flags & HL_SKIPNL); } if (kp->flags & HL_SKIPWHITE) { - msg_puts_attr((char_u *)"skipwhite", attr); + msg_puts_attr("skipwhite", attr); msg_putchar(' '); prev_skipwhite = (kp->flags & HL_SKIPWHITE); } if (kp->flags & HL_SKIPEMPTY) { - msg_puts_attr((char_u *)"skipempty", attr); + msg_puts_attr("skipempty", attr); msg_putchar(' '); prev_skipempty = (kp->flags & HL_SKIPEMPTY); } @@ -3929,7 +3931,8 @@ static void add_keyword(char_u *name, hash_T hash = hash_hash(kp->keyword); hashtab_T *ht = (curwin->w_s->b_syn_ic) ? &curwin->w_s->b_keywtab_ic : &curwin->w_s->b_keywtab; - hashitem_T *hi = hash_lookup(ht, kp->keyword, hash); + hashitem_T *hi = hash_lookup(ht, (const char *)kp->keyword, + STRLEN(kp->keyword), hash); // even though it looks like only the kp->keyword member is // being used here, vim uses some pointer trickery to get the orignal @@ -5517,7 +5520,7 @@ void ex_ownsyntax(exarg_T *eap) } /* save value of b:current_syntax */ - old_value = get_var_value((char_u *)"b:current_syntax"); + old_value = get_var_value("b:current_syntax"); if (old_value != NULL) old_value = vim_strsave(old_value); @@ -5526,7 +5529,7 @@ void ex_ownsyntax(exarg_T *eap) apply_autocmds(EVENT_SYNTAX, eap->arg, curbuf->b_fname, TRUE, curbuf); /* move value of b:current_syntax to w:current_syntax */ - new_value = get_var_value((char_u *)"b:current_syntax"); + new_value = get_var_value("b:current_syntax"); if (new_value != NULL) set_internal_string_var((char_u *)"w:current_syntax", new_value); @@ -5988,7 +5991,7 @@ init_highlight ( * Try finding the color scheme file. Used when a color file was loaded * and 'background' or 't_Co' is changed. */ - char_u *p = get_var_value((char_u *)"g:colors_name"); + char_u *p = get_var_value("g:colors_name"); if (p != NULL) { // Value of g:colors_name could be freed in load_colors() and make // p invalid, so copy it. @@ -6042,7 +6045,7 @@ init_highlight ( /* * If syntax highlighting is enabled load the highlighting for it. */ - if (get_var_value((char_u *)"g:syntax_on") != NULL) { + if (get_var_value("g:syntax_on") != NULL) { static int recursive = 0; if (recursive >= 5) { @@ -6871,8 +6874,8 @@ static void highlight_list_one(int id) if (sgp->sg_link && !got_int) { (void)syn_list_header(didh, 9999, id); - didh = TRUE; - msg_puts_attr((char_u *)"links to", hl_attr(HLF_D)); + didh = true; + msg_puts_attr("links to", hl_attr(HLF_D)); msg_putchar(' '); msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name); } @@ -7057,7 +7060,7 @@ syn_list_header ( /* Show "xxx" with the attributes. */ if (!did_header) { - msg_puts_attr((char_u *)"xxx", syn_id2attr(id)); + msg_puts_attr("xxx", syn_id2attr(id)); msg_putchar(' '); } @@ -7517,7 +7520,7 @@ static void highlight_list(void) static void highlight_list_two(int cnt, int attr) { - msg_puts_attr((char_u *)&("N \bI \b! \b"[cnt / 11]), attr); + msg_puts_attr(&("N \bI \b! \b"[cnt / 11]), attr); msg_clr_eos(); ui_flush(); os_delay(cnt == 99 ? 40L : (long)cnt * 50L, false); @@ -7528,22 +7531,25 @@ static void highlight_list_two(int cnt, int attr) * Function given to ExpandGeneric() to obtain the list of group names. * Also used for synIDattr() function. */ -char_u *get_highlight_name(expand_T *xp, int idx) +const char *get_highlight_name(expand_T *const xp, const int idx) + FUNC_ATTR_WARN_UNUSED_RESULT { - //TODO: 'xp' is unused - if (idx == highlight_ga.ga_len && include_none != 0) - return (char_u *)"none"; - if (idx == highlight_ga.ga_len + include_none && include_default != 0) - return (char_u *)"default"; - if (idx == highlight_ga.ga_len + include_none + include_default - && include_link != 0) - return (char_u *)"link"; - if (idx == highlight_ga.ga_len + include_none + include_default + 1 - && include_link != 0) - return (char_u *)"clear"; - if (idx < 0 || idx >= highlight_ga.ga_len) + // TODO: 'xp' is unused + if (idx == highlight_ga.ga_len && include_none != 0) { + return "none"; + } else if (idx == highlight_ga.ga_len + include_none + && include_default != 0) { + return "default"; + } else if (idx == highlight_ga.ga_len + include_none + include_default + && include_link != 0) { + return "link"; + } else if (idx == highlight_ga.ga_len + include_none + include_default + 1 + && include_link != 0) { + return "clear"; + } else if (idx < 0 || idx >= highlight_ga.ga_len) { return NULL; - return HL_TABLE()[idx].sg_name; + } + return (const char *)HL_TABLE()[idx].sg_name; } color_name_table_T color_name_table[] = { diff --git a/src/nvim/tag.c b/src/nvim/tag.c index 0b76e36a6b..404b58a7eb 100644 --- a/src/nvim/tag.c +++ b/src/nvim/tag.c @@ -540,7 +540,7 @@ do_tag ( } vim_snprintf((char *)IObuff + 1, IOSIZE - 1, "%2d %s ", i + 1, mt_names[matches[i][0] & MT_MASK]); - msg_puts(IObuff); + msg_puts((const char *)IObuff); if (tagp.tagkind != NULL) msg_outtrans_len(tagp.tagkind, (int)(tagp.tagkind_end - tagp.tagkind)); @@ -595,7 +595,7 @@ do_tag ( } p = msg_outtrans_one(p, attr); if (*p == TAB) { - msg_puts_attr((char_u *)" ", attr); + msg_puts_attr(" ", attr); break; } if (*p == ':') @@ -858,11 +858,12 @@ do_tag ( STRCAT(IObuff, _(" Using tag with different case!")); if ((num_matches > prev_num_matches || new_tag) && num_matches > 1) { - if (ic) - msg_attr(IObuff, hl_attr(HLF_W)); - else + if (ic) { + msg_attr((const char *)IObuff, hl_attr(HLF_W)); + } else { msg(IObuff); - msg_scroll = TRUE; /* don't overwrite this message */ + } + msg_scroll = true; // Don't overwrite this message. } else give_warning(IObuff, ic); if (ic && !msg_scrolled && msg_silent == 0) { diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 4b267a1627..8470a8303e 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -2512,13 +2512,14 @@ void ex_undolist(exarg_T *eap) sort_strings((char_u **)ga.ga_data, ga.ga_len); msg_start(); - msg_puts_attr((char_u *)_("number changes when saved"), - hl_attr(HLF_T)); + msg_puts_attr(_("number changes when saved"), + hl_attr(HLF_T)); for (int i = 0; i < ga.ga_len && !got_int; ++i) { msg_putchar('\n'); - if (got_int) + if (got_int) { break; - msg_puts(((char_u **)ga.ga_data)[i]); + } + msg_puts(((const char **)ga.ga_data)[i]); } msg_end(); diff --git a/src/nvim/version.c b/src/nvim/version.c index 5e33597568..096af415ba 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -2572,7 +2572,7 @@ static void list_features(void) int idx = (i / ncol) + (i % ncol) * nrow; if (idx < nfeat) { int last_col = (i + 1) % ncol == 0; - msg_puts((char_u *)features[idx]); + msg_puts(features[idx]); if (last_col) { if (msg_col > 0) { msg_putchar('\n'); diff --git a/test/functional/eval/let_spec.lua b/test/functional/eval/let_spec.lua new file mode 100644 index 0000000000..c3ab3cc367 --- /dev/null +++ b/test/functional/eval/let_spec.lua @@ -0,0 +1,22 @@ +local helpers = require('test.functional.helpers')(after_each) + +local eq = helpers.eq +local clear = helpers.clear +local meths = helpers.meths +local redir_exec = helpers.redir_exec + +before_each(clear) + +describe(':let command', function() + it('correctly lists variables with curly-braces', function() + meths.set_var('v', {0}) + eq('\nv [0]', redir_exec('let {"v"}')) + end) + + it('correctly lists variables with subscript', function() + meths.set_var('v', {0}) + eq('\nv[0] #0', redir_exec('let v[0]')) + eq('\ng:["v"][0] #0', redir_exec('let g:["v"][0]')) + eq('\n{"g:"}["v"][0] #0', redir_exec('let {"g:"}["v"][0]')) + end) +end)