File: //home/ubuntu/neovim/src/nvim/eval/typval_encode.h
/// @file eval/typval_encode.h
///
/// Contains common definitions for eval/typval_encode.c.h. Most of time should
/// not be included directly.
#pragma once
#include <assert.h>
#include <inttypes.h>
#include <stddef.h>
#include <string.h>
#include "klib/kvec.h"
#include "nvim/eval/typval_defs.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/typval_encode.h.inline.generated.h"
#endif
/// Type of the stack entry
typedef enum {
kMPConvDict, ///< Convert dict_T *dictionary.
kMPConvList, ///< Convert list_T *list.
kMPConvPairs, ///< Convert mapping represented as a list_T* of pairs.
kMPConvPartial, ///< Convert partial_T* partial.
kMPConvPartialList, ///< Convert argc/argv pair coming from a partial.
} MPConvStackValType;
/// Stage at which partial is being converted
typedef enum {
kMPConvPartialArgs, ///< About to convert arguments.
kMPConvPartialSelf, ///< About to convert self dictionary.
kMPConvPartialEnd, ///< Already converted everything.
} MPConvPartialStage;
/// Structure representing current Vimscript to messagepack conversion state
typedef struct {
MPConvStackValType type; ///< Type of the stack entry.
typval_T *tv; ///< Currently converted typval_T.
int saved_copyID; ///< copyID item used to have.
union {
struct {
dict_T *dict; ///< Currently converted dictionary.
dict_T **dictp; ///< Location where that dictionary is stored.
///< Normally it is &.tv->vval.v_dict, but not when
///< converting partials.
hashitem_T *hi; ///< Currently converted dictionary item.
size_t todo; ///< Amount of items left to process.
} d; ///< State of dictionary conversion.
struct {
list_T *list; ///< Currently converted list.
listitem_T *li; ///< Currently converted list item.
} l; ///< State of list or generic mapping conversion.
struct {
MPConvPartialStage stage; ///< Stage at which partial is being converted.
partial_T *pt; ///< Currently converted partial.
} p; ///< State of partial conversion.
struct {
typval_T *arg; ///< Currently converted argument.
typval_T *argv; ///< Start of the argument list.
size_t todo; ///< Number of items left to process.
} a; ///< State of list or generic mapping conversion.
} data; ///< Data to convert.
} MPConvStackVal;
/// Stack used to convert Vimscript values to messagepack.
typedef kvec_withinit_t(MPConvStackVal, 8) MPConvStack;
/// Length of the string stored in typval_T
///
/// @param[in] tv String for which to compute length for. Must be typval_T
/// with VAR_STRING.
///
/// @return Length of the string stored in typval_T, including 0 for NULL
/// string.
static inline size_t tv_strlen(const typval_T *const tv)
FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
FUNC_ATTR_NONNULL_ALL
{
assert(tv->v_type == VAR_STRING);
return (tv->vval.v_string == NULL ? 0 : strlen(tv->vval.v_string));
}
/// Code for checking whether container references itself
///
/// @param[in,out] val Container to check.
/// @param copyID_attr Name of the container attribute that holds copyID.
/// After checking whether value of this attribute is
/// copyID (variable) it is set to copyID.
/// @param[in] copyID CopyID used by the caller.
/// @param conv_type Type of the conversion, @see MPConvStackValType.
#define TYPVAL_ENCODE_DO_CHECK_SELF_REFERENCE(val, copyID_attr, copyID, \
conv_type) \
do { \
const int te_csr_ret = TYPVAL_ENCODE_CHECK_SELF_REFERENCE(TYPVAL_ENCODE_FIRST_ARG_NAME, \
(val), &(val)->copyID_attr, mpstack, \
copyID, conv_type, objname); \
if (te_csr_ret != NOTDONE) { \
return te_csr_ret; \
} \
} while (0)
#define TYPVAL_ENCODE_FUNC_NAME_INNER_2(pref, name, suf) \
pref##name##suf
#define TYPVAL_ENCODE_FUNC_NAME_INNER(pref, name, suf) \
TYPVAL_ENCODE_FUNC_NAME_INNER_2(pref, name, suf)
/// Construct function name, possibly using macros
///
/// Is used to expand macros that may appear in arguments.
///
/// @note Expands all arguments, even if only one is needed.
///
/// @param[in] pref Prefix.
/// @param[in] suf Suffix.
///
/// @return Concat: pref + #TYPVAL_ENCODE_NAME + suf.
#define TYPVAL_ENCODE_FUNC_NAME(pref, suf) \
TYPVAL_ENCODE_FUNC_NAME_INNER(pref, TYPVAL_ENCODE_NAME, suf)
/// Self reference checker function name
#define TYPVAL_ENCODE_CHECK_SELF_REFERENCE \
TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _check_self_reference)
/// Entry point function name
#define TYPVAL_ENCODE_ENCODE \
TYPVAL_ENCODE_FUNC_NAME(encode_vim_to_, )
/// Name of the …convert_one_value function
#define TYPVAL_ENCODE_CONVERT_ONE_VALUE \
TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _convert_one_value)
/// Name of the dummy const dict_T *const variable
#define TYPVAL_ENCODE_NODICT_VAR \
TYPVAL_ENCODE_FUNC_NAME(_typval_encode_, _nodict_var)