aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/eval')
-rw-r--r--src/nvim/eval/decode.c8
-rw-r--r--src/nvim/eval/executor.c6
-rw-r--r--src/nvim/eval/typval.c29
-rw-r--r--src/nvim/eval/typval.h13
4 files changed, 38 insertions, 18 deletions
diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c
index 935c98fb84..9c9c2c2dc8 100644
--- a/src/nvim/eval/decode.c
+++ b/src/nvim/eval/decode.c
@@ -435,8 +435,8 @@ static inline int parse_json_string(const char *const buf, const size_t buf_len,
case 'u': {
const char ubuf[] = { t[1], t[2], t[3], t[4] };
t += 4;
- unsigned long ch;
- vim_str2nr((char_u *) ubuf, NULL, NULL,
+ uvarnumber_T ch;
+ vim_str2nr((char_u *)ubuf, NULL, NULL,
STR2NR_HEX | STR2NR_FORCE, NULL, &ch, 4);
if (ch == 0) {
hasnul = true;
@@ -609,7 +609,7 @@ parse_json_number_check:
tv.v_type = VAR_FLOAT;
} else {
// Convert integer
- long nr;
+ varnumber_T nr;
int num_len;
vim_str2nr((char_u *) s, NULL, &num_len, 0, &nr, NULL, (int) (p - s));
if ((int) exp_num_len != num_len) {
@@ -617,7 +617,7 @@ parse_json_number_check:
"to integer vim_str2nr consumed %i bytes in place of %zu"),
(int) exp_num_len, s, num_len, exp_num_len);
}
- tv.vval.v_number = (varnumber_T) nr;
+ tv.vval.v_number = nr;
}
if (json_decoder_pop(OBJ(tv, false, *didcomma, *didcolon),
stack, container_stack,
diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c
index 91bb61323f..99298cbbcf 100644
--- a/src/nvim/eval/executor.c
+++ b/src/nvim/eval/executor.c
@@ -25,7 +25,7 @@ char *e_listidx = N_("E684: list index out of range: %" PRId64);
/// @return OK or FAIL.
int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
const char *const op)
- FUNC_ATTR_NONNULL_ALL
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NO_SANITIZE_UNDEFINED
{
// Can't do anything with a Funcref, a Dict or special value on the right.
if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) {
@@ -55,7 +55,7 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
// nr += nr or nr -= nr
varnumber_T n = tv_get_number(tv1);
if (tv2->v_type == VAR_FLOAT) {
- float_T f = n;
+ float_T f = (float_T)n;
if (*op == '+') {
f += tv2->vval.v_float;
@@ -99,7 +99,7 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
}
const float_T f = (tv2->v_type == VAR_FLOAT
? tv2->vval.v_float
- : tv_get_number(tv2));
+ : (float_T)tv_get_number(tv2));
if (*op == '+') {
tv1->vval.v_float += f;
} else {
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index f017f57b12..c339a5cdd2 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -1387,11 +1387,32 @@ int tv_dict_add_str(dict_T *const d,
const char *const val)
FUNC_ATTR_NONNULL_ALL
{
+ return tv_dict_add_allocated_str(d, key, key_len, xstrdup(val));
+}
+
+/// Add a string entry to dictionary
+///
+/// Unlike tv_dict_add_str() saves val to the new dictionary item in place of
+/// creating a new copy.
+///
+/// @warning String will be freed even in case addition fails.
+///
+/// @param[out] d Dictionary to add entry to.
+/// @param[in] key Key to add.
+/// @param[in] key_len Key length.
+/// @param[in] val String to add.
+///
+/// @return OK in case of success, FAIL when key already exists.
+int tv_dict_add_allocated_str(dict_T *const d,
+ const char *const key, const size_t key_len,
+ char *const val)
+ FUNC_ATTR_NONNULL_ALL
+{
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
item->di_tv.v_lock = VAR_UNLOCKED;
item->di_tv.v_type = VAR_STRING;
- item->di_tv.vval.v_string = (char_u *)xstrdup(val);
+ item->di_tv.vval.v_string = (char_u *)val;
if (tv_dict_add(d, item) == FAIL) {
tv_dict_item_free(item);
return FAIL;
@@ -2405,9 +2426,7 @@ varnumber_T tv_get_number_chk(const typval_T *const tv, bool *const ret_error)
case VAR_STRING: {
varnumber_T n = 0;
if (tv->vval.v_string != NULL) {
- long nr;
- vim_str2nr(tv->vval.v_string, NULL, NULL, STR2NR_ALL, &nr, NULL, 0);
- n = (varnumber_T)nr;
+ vim_str2nr(tv->vval.v_string, NULL, NULL, STR2NR_ALL, &n, NULL, 0);
}
return n;
}
@@ -2444,7 +2463,7 @@ varnumber_T tv_get_number_chk(const typval_T *const tv, bool *const ret_error)
linenr_T tv_get_lnum(const typval_T *const tv)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
{
- linenr_T lnum = tv_get_number_chk(tv, NULL);
+ linenr_T lnum = (linenr_T)tv_get_number_chk(tv, NULL);
if (lnum == 0) { // No valid number, try using same function as line() does.
int fnum;
pos_T *const fp = var2fpos(tv, true, &fnum);
diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h
index 0f659727ee..3f8ed3b3f9 100644
--- a/src/nvim/eval/typval.h
+++ b/src/nvim/eval/typval.h
@@ -1,7 +1,7 @@
#ifndef NVIM_EVAL_TYPVAL_H
#define NVIM_EVAL_TYPVAL_H
-#include <limits.h>
+#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
@@ -20,20 +20,21 @@
#include "nvim/macros.h"
/// Type used for VimL VAR_NUMBER values
-typedef int varnumber_T;
+typedef int64_t varnumber_T;
+typedef uint64_t uvarnumber_T;
/// Type used for VimL VAR_FLOAT values
typedef double float_T;
/// Maximal possible value of varnumber_T variable
-#define VARNUMBER_MAX INT_MAX
+#define VARNUMBER_MAX INT64_MAX
+#define UVARNUMBER_MAX UINT64_MAX
/// Mimimal possible value of varnumber_T variable
-#define VARNUMBER_MIN INT_MIN
-#define PRIdVARNUMBER "d"
+#define VARNUMBER_MIN INT64_MIN
/// %d printf format specifier for varnumber_T
-#define PRIdVARNUMBER "d"
+#define PRIdVARNUMBER PRId64
typedef struct listvar_S list_T;
typedef struct dictvar_S dict_T;