aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/api/private
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/api/private')
-rw-r--r--src/nvim/api/private/converter.c43
-rw-r--r--src/nvim/api/private/defs.h24
-rw-r--r--src/nvim/api/private/helpers.c86
-rw-r--r--src/nvim/api/private/helpers.h10
-rw-r--r--src/nvim/api/private/validate.c2
-rw-r--r--src/nvim/api/private/validate.h8
6 files changed, 85 insertions, 88 deletions
diff --git a/src/nvim/api/private/converter.c b/src/nvim/api/private/converter.c
index a78d78c057..59e7373f68 100644
--- a/src/nvim/api/private/converter.c
+++ b/src/nvim/api/private/converter.c
@@ -7,7 +7,9 @@
#include "nvim/api/private/converter.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/ascii_defs.h"
#include "nvim/assert_defs.h"
+#include "nvim/eval/decode.h"
#include "nvim/eval/typval.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/eval/userfunc.h"
@@ -28,6 +30,7 @@ typedef struct {
#endif
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
+#define TYPVAL_ENCODE_CHECK_BEFORE
#define TYPVAL_ENCODE_CONV_NIL(tv) \
kvi_push(edata->stack, NIL)
@@ -91,8 +94,7 @@ static Object typval_cbuf_to_obj(EncodedData *edata, const char *data, size_t le
kvi_push(edata->stack, ARRAY_OBJ(((Array) { .capacity = 0, .size = 0 })))
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
- kvi_push(edata->stack, \
- DICTIONARY_OBJ(((Dictionary) { .capacity = 0, .size = 0 })))
+ kvi_push(edata->stack, DICT_OBJ(((Dict) { .capacity = 0, .size = 0 })))
static inline void typval_encode_list_start(EncodedData *const edata, const size_t len)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
@@ -134,7 +136,7 @@ static inline void typval_encode_list_end(EncodedData *const edata)
static inline void typval_encode_dict_start(EncodedData *const edata, const size_t len)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
{
- kvi_push(edata->stack, DICTIONARY_OBJ(arena_dict(edata->arena, len)));
+ kvi_push(edata->stack, DICT_OBJ(arena_dict(edata->arena, len)));
}
#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
@@ -149,13 +151,13 @@ static inline void typval_encode_after_key(EncodedData *const edata)
{
Object key = kv_pop(edata->stack);
Object *const dict = &kv_last(edata->stack);
- assert(dict->type == kObjectTypeDictionary);
- assert(dict->data.dictionary.size < dict->data.dictionary.capacity);
+ assert(dict->type == kObjectTypeDict);
+ assert(dict->data.dict.size < dict->data.dict.capacity);
if (key.type == kObjectTypeString) {
- dict->data.dictionary.items[dict->data.dictionary.size].key
+ dict->data.dict.items[dict->data.dict.size].key
= key.data.string;
} else {
- dict->data.dictionary.items[dict->data.dictionary.size].key
+ dict->data.dict.items[dict->data.dict.size].key
= STATIC_CSTR_AS_STRING("__INVALID_KEY__");
}
}
@@ -168,9 +170,9 @@ static inline void typval_encode_between_dict_items(EncodedData *const edata)
{
Object val = kv_pop(edata->stack);
Object *const dict = &kv_last(edata->stack);
- assert(dict->type == kObjectTypeDictionary);
- assert(dict->data.dictionary.size < dict->data.dictionary.capacity);
- dict->data.dictionary.items[dict->data.dictionary.size++].value = val;
+ assert(dict->type == kObjectTypeDict);
+ assert(dict->data.dict.size < dict->data.dict.capacity);
+ dict->data.dict.items[dict->data.dict.size++].value = val;
}
#define TYPVAL_ENCODE_CONV_DICT_BETWEEN_ITEMS(tv, dict) \
@@ -182,7 +184,7 @@ static inline void typval_encode_dict_end(EncodedData *const edata)
typval_encode_between_dict_items(edata);
#ifndef NDEBUG
const Object *const dict = &kv_last(edata->stack);
- assert(dict->data.dictionary.size == dict->data.dictionary.capacity);
+ assert(dict->data.dict.size == dict->data.dict.capacity);
#endif
}
@@ -217,6 +219,7 @@ static inline void typval_encode_dict_end(EncodedData *const edata)
#undef TYPVAL_ENCODE_CONV_LIST_START
#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
+#undef TYPVAL_ENCODE_CHECK_BEFORE
#undef TYPVAL_ENCODE_CONV_NIL
#undef TYPVAL_ENCODE_CONV_BOOL
#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
@@ -300,15 +303,11 @@ void object_to_vim_take_luaref(Object *obj, typval_T *tv, bool take_luaref, Erro
tv->vval.v_float = obj->data.floating;
break;
- case kObjectTypeString:
- tv->v_type = VAR_STRING;
- if (obj->data.string.data == NULL) {
- tv->vval.v_string = NULL;
- } else {
- tv->vval.v_string = xmemdupz(obj->data.string.data,
- obj->data.string.size);
- }
+ case kObjectTypeString: {
+ String s = obj->data.string;
+ *tv = decode_string(s.data, s.size, false, false);
break;
+ }
case kObjectTypeArray: {
list_T *const list = tv_list_alloc((ptrdiff_t)obj->data.array.size);
@@ -325,11 +324,11 @@ void object_to_vim_take_luaref(Object *obj, typval_T *tv, bool take_luaref, Erro
break;
}
- case kObjectTypeDictionary: {
+ case kObjectTypeDict: {
dict_T *const dict = tv_dict_alloc();
- for (uint32_t i = 0; i < obj->data.dictionary.size; i++) {
- KeyValuePair *item = &obj->data.dictionary.items[i];
+ for (uint32_t i = 0; i < obj->data.dict.size; i++) {
+ KeyValuePair *item = &obj->data.dict.items[i];
String key = item->key;
dictitem_T *const di = tv_dict_item_alloc(key.data);
object_to_vim_take_luaref(&item->value, &di->di_tv, take_luaref, err);
diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h
index ca088d7a55..26d5ac09a8 100644
--- a/src/nvim/api/private/defs.h
+++ b/src/nvim/api/private/defs.h
@@ -5,7 +5,6 @@
#include <string.h>
#include "klib/kvec.h"
-#include "nvim/func_attr.h"
#include "nvim/types_defs.h"
#define ARRAY_DICT_INIT KV_INITIAL_VALUE
@@ -18,8 +17,11 @@
#ifdef INCLUDE_GENERATED_DECLARATIONS
# define ArrayOf(...) Array
-# define DictionaryOf(...) Dictionary
+# define DictOf(...) Dict
# define Dict(name) KeyDict_##name
+# define DictHash(name) KeyDict_##name##_get_field
+# define DictKey(name)
+# include "api/private/defs.h.inline.generated.h"
#endif
// Basic types
@@ -47,15 +49,13 @@ typedef enum {
/// Internal call from Lua code
#define LUA_INTERNAL_CALL (VIML_INTERNAL_CALL + 1)
-static inline bool is_internal_call(uint64_t channel_id)
- REAL_FATTR_ALWAYS_INLINE REAL_FATTR_CONST;
-
/// Check whether call is internal
///
/// @param[in] channel_id Channel id.
///
/// @return true if channel_id refers to internal channel.
static inline bool is_internal_call(const uint64_t channel_id)
+ FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_CONST
{
return !!(channel_id & INTERNAL_CALL_MASK);
}
@@ -88,7 +88,9 @@ typedef struct object Object;
typedef kvec_t(Object) Array;
typedef struct key_value_pair KeyValuePair;
-typedef kvec_t(KeyValuePair) Dictionary;
+typedef kvec_t(KeyValuePair) Dict;
+
+typedef kvec_t(String) StringArray;
typedef enum {
kObjectTypeNil = 0,
@@ -97,7 +99,7 @@ typedef enum {
kObjectTypeFloat,
kObjectTypeString,
kObjectTypeArray,
- kObjectTypeDictionary,
+ kObjectTypeDict,
kObjectTypeLuaRef,
// EXT types, cannot be split or reordered, see #EXT_OBJECT_TYPE_SHIFT
kObjectTypeBuffer,
@@ -105,6 +107,10 @@ typedef enum {
kObjectTypeTabpage,
} ObjectType;
+typedef enum {
+ kUnpackTypeStringArray = -1,
+} UnpackType;
+
/// Value by which objects represented as EXT type are shifted
///
/// Subtracted when packing, added when unpacking. Used to allow moving
@@ -121,7 +127,7 @@ struct object {
Float floating;
String string;
Array array;
- Dictionary dictionary;
+ Dict dict;
LuaRef luaref;
} data;
};
@@ -142,7 +148,7 @@ typedef struct {
typedef struct {
char *str;
size_t ptr_off;
- ObjectType type; // kObjectTypeNil == untyped
+ int type; // ObjectType or UnpackType. kObjectTypeNil == untyped
int opt_index;
bool is_hlgroup;
} KeySetLink;
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index a17e78cc31..e1fb4ed732 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -1,6 +1,5 @@
#include <assert.h>
#include <limits.h>
-#include <msgpack/unpack.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
@@ -199,7 +198,7 @@ dictitem_T *dict_check_writable(dict_T *dict, String key, bool del, Error *err)
api_set_error(err, kErrorTypeException, "Key is fixed: %s", key.data);
}
} else if (dict->dv_lock) {
- api_set_error(err, kErrorTypeException, "Dictionary is locked");
+ api_set_error(err, kErrorTypeException, "Dict is locked");
} else if (key.size == 0) {
api_set_error(err, kErrorTypeValidation, "Key name is empty");
} else if (key.size > INT_MAX) {
@@ -529,29 +528,19 @@ String buf_get_text(buf_T *buf, int64_t lnum, int64_t start_col, int64_t end_col
start_col = start_col < 0 ? line_length + start_col + 1 : start_col;
end_col = end_col < 0 ? line_length + end_col + 1 : end_col;
- if (start_col >= MAXCOL || end_col >= MAXCOL) {
- api_set_error(err, kErrorTypeValidation, "Column index is too high");
- return rv;
- }
+ start_col = MIN(MAX(0, start_col), line_length);
+ end_col = MIN(MAX(0, end_col), line_length);
if (start_col > end_col) {
- api_set_error(err, kErrorTypeValidation, "start_col must be less than end_col");
- return rv;
- }
-
- if (start_col >= line_length) {
+ api_set_error(err, kErrorTypeValidation, "start_col must be less than or equal to end_col");
return rv;
}
- return cstrn_as_string(&bufstr[start_col], (size_t)(end_col - start_col));
+ return cbuf_as_string(bufstr + start_col, (size_t)(end_col - start_col));
}
void api_free_string(String value)
{
- if (!value.data) {
- return;
- }
-
xfree(value.data);
}
@@ -562,9 +551,9 @@ Array arena_array(Arena *arena, size_t max_size)
return arr;
}
-Dictionary arena_dict(Arena *arena, size_t max_size)
+Dict arena_dict(Arena *arena, size_t max_size)
{
- Dictionary dict = ARRAY_DICT_INIT;
+ Dict dict = ARRAY_DICT_INIT;
kv_fixsize_arena(arena, dict, max_size);
return dict;
}
@@ -607,8 +596,8 @@ void api_free_object(Object value)
api_free_array(value.data.array);
break;
- case kObjectTypeDictionary:
- api_free_dictionary(value.data.dictionary);
+ case kObjectTypeDict:
+ api_free_dict(value.data.dict);
break;
case kObjectTypeLuaRef:
@@ -626,7 +615,7 @@ void api_free_array(Array value)
xfree(value.items);
}
-void api_free_dictionary(Dictionary value)
+void api_free_dict(Dict value)
{
for (size_t i = 0; i < value.size; i++) {
api_free_string(value.items[i].key);
@@ -659,7 +648,7 @@ Object api_metadata(void)
Arena arena = ARENA_EMPTY;
Error err = ERROR_INIT;
metadata = unpack((char *)packed_api_metadata, sizeof(packed_api_metadata), &arena, &err);
- if (ERROR_SET(&err) || metadata.type != kObjectTypeDictionary) {
+ if (ERROR_SET(&err) || metadata.type != kObjectTypeDict) {
abort();
}
mem_for_metadata = arena_finish(&arena);
@@ -695,9 +684,9 @@ Array copy_array(Array array, Arena *arena)
return rv;
}
-Dictionary copy_dictionary(Dictionary dict, Arena *arena)
+Dict copy_dict(Dict dict, Arena *arena)
{
- Dictionary rv = arena_dict(arena, dict.size);
+ Dict rv = arena_dict(arena, dict.size);
for (size_t i = 0; i < dict.size; i++) {
KeyValuePair item = dict.items[i];
PUT_C(rv, copy_string(item.key, arena).data, copy_object(item.value, arena));
@@ -724,8 +713,8 @@ Object copy_object(Object obj, Arena *arena)
case kObjectTypeArray:
return ARRAY_OBJ(copy_array(obj.data.array, arena));
- case kObjectTypeDictionary:
- return DICTIONARY_OBJ(copy_dictionary(obj.data.dictionary, arena));
+ case kObjectTypeDict:
+ return DICT_OBJ(copy_dict(obj.data.dict, arena));
case kObjectTypeLuaRef:
return LUAREF_OBJ(api_new_luaref(obj.data.luaref));
@@ -779,7 +768,8 @@ int object_to_hl_id(Object obj, const char *what, Error *err)
String str = obj.data.string;
return str.size ? syn_check_group(str.data, str.size) : 0;
} else if (obj.type == kObjectTypeInteger) {
- return MAX((int)obj.data.integer, 0);
+ int id = (int)obj.data.integer;
+ return (1 <= id && id <= highlight_num_groups()) ? id : 0;
} else {
api_set_error(err, kErrorTypeValidation, "Invalid highlight: %s", what);
return 0;
@@ -801,7 +791,7 @@ char *api_typename(ObjectType t)
return "String";
case kObjectTypeArray:
return "Array";
- case kObjectTypeDictionary:
+ case kObjectTypeDict:
return "Dict";
case kObjectTypeLuaRef:
return "Function";
@@ -854,7 +844,7 @@ free_exit:
}
// see also nlua_pop_keydict for the lua specific implementation
-bool api_dict_to_keydict(void *retval, FieldHashfn hashy, Dictionary dict, Error *err)
+bool api_dict_to_keydict(void *retval, FieldHashfn hashy, Dict dict, Error *err)
{
for (size_t i = 0; i < dict.size; i++) {
String k = dict.items[i].key;
@@ -918,23 +908,25 @@ bool api_dict_to_keydict(void *retval, FieldHashfn hashy, Dictionary dict, Error
return false;
});
*(Array *)mem = value->data.array;
- } else if (field->type == kObjectTypeDictionary) {
- Dictionary *val = (Dictionary *)mem;
+ } else if (field->type == kObjectTypeDict) {
+ Dict *val = (Dict *)mem;
// allow empty array as empty dict for lua (directly or via lua-client RPC)
if (value->type == kObjectTypeArray && value->data.array.size == 0) {
- *val = (Dictionary)ARRAY_DICT_INIT;
- } else if (value->type == kObjectTypeDictionary) {
- *val = value->data.dictionary;
+ *val = (Dict)ARRAY_DICT_INIT;
+ } else if (value->type == kObjectTypeDict) {
+ *val = value->data.dict;
} else {
- api_err_exp(err, field->str, api_typename(field->type), api_typename(value->type));
+ api_err_exp(err, field->str, api_typename((ObjectType)field->type),
+ api_typename(value->type));
return false;
}
} else if (field->type == kObjectTypeBuffer || field->type == kObjectTypeWindow
|| field->type == kObjectTypeTabpage) {
- if (value->type == kObjectTypeInteger || value->type == field->type) {
+ if (value->type == kObjectTypeInteger || value->type == (ObjectType)field->type) {
*(handle_T *)mem = (handle_T)value->data.integer;
} else {
- api_err_exp(err, field->str, api_typename(field->type), api_typename(value->type));
+ api_err_exp(err, field->str, api_typename((ObjectType)field->type),
+ api_typename(value->type));
return false;
}
} else if (field->type == kObjectTypeLuaRef) {
@@ -949,9 +941,9 @@ bool api_dict_to_keydict(void *retval, FieldHashfn hashy, Dictionary dict, Error
return true;
}
-Dictionary api_keydict_to_dict(void *value, KeySetLink *table, size_t max_size, Arena *arena)
+Dict api_keydict_to_dict(void *value, KeySetLink *table, size_t max_size, Arena *arena)
{
- Dictionary rv = arena_dict(arena, max_size);
+ Dict rv = arena_dict(arena, max_size);
for (size_t i = 0; table[i].str; i++) {
KeySetLink *field = &table[i];
bool is_set = true;
@@ -979,12 +971,12 @@ Dictionary api_keydict_to_dict(void *value, KeySetLink *table, size_t max_size,
val = STRING_OBJ(*(String *)mem);
} else if (field->type == kObjectTypeArray) {
val = ARRAY_OBJ(*(Array *)mem);
- } else if (field->type == kObjectTypeDictionary) {
- val = DICTIONARY_OBJ(*(Dictionary *)mem);
+ } else if (field->type == kObjectTypeDict) {
+ val = DICT_OBJ(*(Dict *)mem);
} else if (field->type == kObjectTypeBuffer || field->type == kObjectTypeWindow
|| field->type == kObjectTypeTabpage) {
val.data.integer = *(handle_T *)mem;
- val.type = field->type;
+ val.type = (ObjectType)field->type;
} else if (field->type == kObjectTypeLuaRef) {
// do nothing
} else {
@@ -1010,8 +1002,8 @@ void api_luarefs_free_object(Object value)
api_luarefs_free_array(value.data.array);
break;
- case kObjectTypeDictionary:
- api_luarefs_free_dict(value.data.dictionary);
+ case kObjectTypeDict:
+ api_luarefs_free_dict(value.data.dict);
break;
default:
@@ -1027,8 +1019,8 @@ void api_luarefs_free_keydict(void *dict, KeySetLink *table)
api_luarefs_free_object(*(Object *)mem);
} else if (table[i].type == kObjectTypeLuaRef) {
api_free_luaref(*(LuaRef *)mem);
- } else if (table[i].type == kObjectTypeDictionary) {
- api_luarefs_free_dict(*(Dictionary *)mem);
+ } else if (table[i].type == kObjectTypeDict) {
+ api_luarefs_free_dict(*(Dict *)mem);
}
}
}
@@ -1040,7 +1032,7 @@ void api_luarefs_free_array(Array value)
}
}
-void api_luarefs_free_dict(Dictionary value)
+void api_luarefs_free_dict(Dict value)
{
for (size_t i = 0; i < value.size; i++) {
api_luarefs_free_object(value.items[i].value);
diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h
index 7eda8ffaf6..57932e067e 100644
--- a/src/nvim/api/private/helpers.h
+++ b/src/nvim/api/private/helpers.h
@@ -53,9 +53,9 @@
.type = kObjectTypeArray, \
.data.array = a })
-#define DICTIONARY_OBJ(d) ((Object) { \
- .type = kObjectTypeDictionary, \
- .data.dictionary = d })
+#define DICT_OBJ(d) ((Object) { \
+ .type = kObjectTypeDict, \
+ .data.dict = d })
#define LUAREF_OBJ(r) ((Object) { \
.type = kObjectTypeLuaRef, \
@@ -90,7 +90,7 @@
name.items = name##__items; \
#define MAXSIZE_TEMP_DICT(name, maxsize) \
- Dictionary name = ARRAY_DICT_INIT; \
+ Dict name = ARRAY_DICT_INIT; \
KeyValuePair name##__items[maxsize]; \
name.capacity = maxsize; \
name.items = name##__items; \
@@ -121,7 +121,7 @@ typedef kvec_withinit_t(Object, 16) ArrayBuilder;
#define api_init_tabpage
#define api_init_object = NIL
#define api_init_array = ARRAY_DICT_INIT
-#define api_init_dictionary = ARRAY_DICT_INIT
+#define api_init_dict = ARRAY_DICT_INIT
#define KEYDICT_INIT { 0 }
diff --git a/src/nvim/api/private/validate.c b/src/nvim/api/private/validate.c
index e198c671eb..9fd7d3bfa6 100644
--- a/src/nvim/api/private/validate.c
+++ b/src/nvim/api/private/validate.c
@@ -17,7 +17,7 @@ void api_err_invalid(Error *err, const char *name, const char *val_s, int64_t va
char *has_space = strchr(name, ' ');
// No value.
- if (val_s && val_s[0] == '\0') {
+ if (val_s && val_s[0] == NUL) {
api_set_error(err, errtype, has_space ? "Invalid %s" : "Invalid '%s'", name);
return;
}
diff --git a/src/nvim/api/private/validate.h b/src/nvim/api/private/validate.h
index 2c1d1a241d..67af8adea8 100644
--- a/src/nvim/api/private/validate.h
+++ b/src/nvim/api/private/validate.h
@@ -42,7 +42,7 @@
#define VALIDATE_T(name, expected_t, actual_t, code) \
do { \
- STATIC_ASSERT(expected_t != kObjectTypeDictionary, "use VALIDATE_T_DICT"); \
+ STATIC_ASSERT(expected_t != kObjectTypeDict, "use VALIDATE_T_DICT"); \
if (expected_t != actual_t) { \
api_err_exp(err, name, api_typename(expected_t), api_typename(actual_t)); \
code; \
@@ -52,7 +52,7 @@
/// Checks that `obj_` has type `expected_t`.
#define VALIDATE_T2(obj_, expected_t, code) \
do { \
- STATIC_ASSERT(expected_t != kObjectTypeDictionary, "use VALIDATE_T_DICT"); \
+ STATIC_ASSERT(expected_t != kObjectTypeDict, "use VALIDATE_T_DICT"); \
if ((obj_).type != expected_t) { \
api_err_exp(err, STR(obj_), api_typename(expected_t), api_typename((obj_).type)); \
code; \
@@ -62,11 +62,11 @@
/// Checks that `obj_` has Dict type. Also allows empty Array in a Lua context.
#define VALIDATE_T_DICT(name, obj_, code) \
do { \
- if ((obj_).type != kObjectTypeDictionary \
+ if ((obj_).type != kObjectTypeDict \
&& !(channel_id == LUA_INTERNAL_CALL \
&& (obj_).type == kObjectTypeArray \
&& (obj_).data.array.size == 0)) { \
- api_err_exp(err, name, api_typename(kObjectTypeDictionary), api_typename((obj_).type)); \
+ api_err_exp(err, name, api_typename(kObjectTypeDict), api_typename((obj_).type)); \
code; \
} \
} while (0)