aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/eval')
-rw-r--r--src/nvim/eval/encode.c13
-rw-r--r--src/nvim/eval/typval.c42
-rw-r--r--src/nvim/eval/typval.h18
3 files changed, 56 insertions, 17 deletions
diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c
index e32f893faa..742497c1ca 100644
--- a/src/nvim/eval/encode.c
+++ b/src/nvim/eval/encode.c
@@ -182,9 +182,9 @@ static int conv_error(const char *const msg, const MPConvStack *const mpstack,
}
}
}
- EMSG3(msg, objname, (kv_size(*mpstack) == 0
- ? _("itself")
- : (char *) msg_ga.ga_data));
+ emsgf(msg, _(objname), (kv_size(*mpstack) == 0
+ ? _("itself")
+ : (char *)msg_ga.ga_data));
ga_clear(&msg_ga);
return FAIL;
}
@@ -793,7 +793,7 @@ char *encode_tv2string(typval_T *tv, size_t *len)
garray_T ga;
ga_init(&ga, (int)sizeof(char), 80);
const int evs_ret = encode_vim_to_string(&ga, tv,
- "encode_tv2string() argument");
+ N_("encode_tv2string() argument"));
(void)evs_ret;
assert(evs_ret == OK);
did_echo_string_emsg = false;
@@ -821,7 +821,7 @@ char *encode_tv2echo(typval_T *tv, size_t *len)
ga_concat(&ga, tv->vval.v_string);
}
} else {
- const int eve_ret = encode_vim_to_echo(&ga, tv, ":echo argument");
+ const int eve_ret = encode_vim_to_echo(&ga, tv, N_(":echo argument"));
(void)eve_ret;
assert(eve_ret == OK);
}
@@ -844,7 +844,8 @@ char *encode_tv2json(typval_T *tv, size_t *len)
{
garray_T ga;
ga_init(&ga, (int)sizeof(char), 80);
- const int evj_ret = encode_vim_to_json(&ga, tv, "encode_tv2json() argument");
+ const int evj_ret = encode_vim_to_json(&ga, tv,
+ N_("encode_tv2json() argument"));
if (!evj_ret) {
ga_clear(&ga);
}
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index a57dd42f6e..786b766689 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -1801,11 +1801,13 @@ static inline void _nothing_conv_dict_end(typval_T *const tv,
#define TYPVAL_ENCODE_NAME nothing
#define TYPVAL_ENCODE_FIRST_ARG_TYPE const void *const
#define TYPVAL_ENCODE_FIRST_ARG_NAME ignored
+#define TYPVAL_ENCODE_TRANSLATE_OBJECT_NAME
#include "nvim/eval/typval_encode.c.h"
#undef TYPVAL_ENCODE_SCOPE
#undef TYPVAL_ENCODE_NAME
#undef TYPVAL_ENCODE_FIRST_ARG_TYPE
#undef TYPVAL_ENCODE_FIRST_ARG_NAME
+#undef TYPVAL_ENCODE_TRANSLATE_OBJECT_NAME
#undef TYPVAL_ENCODE_ALLOW_SPECIALS
#undef TYPVAL_ENCODE_CONV_NIL
@@ -1839,12 +1841,14 @@ static inline void _nothing_conv_dict_end(typval_T *const tv,
/// @param[in,out] tv Value to free.
void tv_clear(typval_T *const tv)
{
- static char *objname = NULL; // cached because gettext() is slow. #6437
- if (objname == NULL) {
- objname = xstrdup(_("tv_clear() argument"));
- }
if (tv != NULL && tv->v_type != VAR_UNKNOWN) {
- const int evn_ret = encode_vim_to_nothing(NULL, tv, objname);
+ // WARNING: do not translate the string here, gettext is slow and function
+ // is used *very* often. At the current state encode_vim_to_nothing() does
+ // not error out and does not use the argument anywhere.
+ //
+ // If situation changes and this argument will be used, translate it in the
+ // place where it is used.
+ const int evn_ret = encode_vim_to_nothing(NULL, tv, "tv_clear() argument");
(void)evn_ret;
assert(evn_ret == OK);
}
@@ -2047,11 +2051,20 @@ bool tv_islocked(const typval_T *const tv)
///
/// @param[in] lock Lock status.
/// @param[in] name Variable name, used in the error message.
-/// @param[in] name_len Variable name length.
+/// @param[in] name_len Variable name length. Use #TV_TRANSLATE to translate
+/// variable name and compute the length. Use #TV_CSTRING
+/// to compute the length with strlen() without
+/// translating.
+///
+/// Both #TV_… values are used for optimization purposes:
+/// variable name with its length is needed only in case
+/// of error, when no error occurs computing them is
+/// a waste of CPU resources. This especially applies to
+/// gettext.
///
/// @return true if variable is locked, false otherwise.
-bool tv_check_lock(const VarLockStatus lock, const char *const name,
- const size_t name_len)
+bool tv_check_lock(const VarLockStatus lock, const char *name,
+ size_t name_len)
FUNC_ATTR_WARN_UNUSED_RESULT
{
const char *error_message = NULL;
@@ -2070,10 +2083,17 @@ bool tv_check_lock(const VarLockStatus lock, const char *const name,
}
assert(error_message != NULL);
- const char *const unknown_name = _("Unknown");
+ if (name == NULL) {
+ name = _("Unknown");
+ name_len = strlen(name);
+ } else if (name_len == TV_TRANSLATE) {
+ name = _(name);
+ name_len = strlen(name);
+ } else if (name_len == TV_CSTRING) {
+ name_len = strlen(name);
+ }
- emsgf(_(error_message), (name != NULL ? name_len : strlen(unknown_name)),
- (name != NULL ? name : unknown_name));
+ emsgf(_(error_message), (int)name_len, name);
return true;
}
diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h
index 7eab22bc12..0f659727ee 100644
--- a/src/nvim/eval/typval.h
+++ b/src/nvim/eval/typval.h
@@ -17,6 +17,7 @@
#include "nvim/pos.h" // for linenr_T
#include "nvim/gettext.h"
#include "nvim/message.h"
+#include "nvim/macros.h"
/// Type used for VimL VAR_NUMBER values
typedef int varnumber_T;
@@ -423,6 +424,23 @@ static inline bool tv_is_func(const typval_T tv)
return tv.v_type == VAR_FUNC || tv.v_type == VAR_PARTIAL;
}
+/// Specify that argument needs to be translated
+///
+/// Used for size_t length arguments to avoid calling gettext() and strlen()
+/// unless needed.
+#define TV_TRANSLATE (SIZE_MAX)
+
+/// Specify that argument is a NUL-terminated C string
+///
+/// Used for size_t length arguments to avoid calling strlen() unless needed.
+#define TV_CSTRING (SIZE_MAX - 1)
+
+#ifdef UNIT_TESTING
+// Do not use enum constants, see commit message.
+EXTERN const size_t kTVCstring INIT(= TV_CSTRING);
+EXTERN const size_t kTVTranslate INIT(= TV_TRANSLATE);
+#endif
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/typval.h.generated.h"
#endif