diff options
Diffstat (limited to 'src/nvim/eval')
-rw-r--r-- | src/nvim/eval/decode.c | 8 | ||||
-rw-r--r-- | src/nvim/eval/executor.c | 6 | ||||
-rw-r--r-- | src/nvim/eval/typval.c | 29 | ||||
-rw-r--r-- | src/nvim/eval/typval.h | 13 |
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; |