diff options
Diffstat (limited to 'src/nvim/eval/typval.c')
| -rw-r--r-- | src/nvim/eval/typval.c | 118 | 
1 files changed, 111 insertions, 7 deletions
| diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c index ca635dcae9..78eca15fec 100644 --- a/src/nvim/eval/typval.c +++ b/src/nvim/eval/typval.c @@ -796,7 +796,7 @@ static bool tv_dict_watcher_matches(DictWatcher *watcher, const char *const key)    // of the string means it should match everything up to the '*' instead of the    // whole string.    const size_t len = strlen(watcher->key_pattern); -  if (watcher->key_pattern[len - 1] == '*') { +  if (len && watcher->key_pattern[len - 1] == '*') {      return strncmp(key, watcher->key_pattern, len - 1) == 0;    } else {      return strcmp(key, watcher->key_pattern) == 0; @@ -2020,7 +2020,7 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic,  ///  /// @return true if everything is OK, false otherwise.  bool tv_check_str_or_nr(const typval_T *const tv) -  FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE +  FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL  {    switch (tv->v_type) {      case VAR_NUMBER: @@ -2072,7 +2072,7 @@ static const char *const num_errors[] = {  /// Check that given value is a number or can be converted to it  /// -/// Error messages are compatible with tv_get_number() previously used for +/// Error messages are compatible with tv_get_number_chk() previously used for  /// the same purpose.  ///  /// @param[in]  tv  Value to check. @@ -2101,6 +2101,50 @@ bool tv_check_num(const typval_T *const tv)    return false;  } +#define FUNC_ERROR "E729: using Funcref as a String" + +static const char *const str_errors[] = { +  [VAR_PARTIAL]=N_(FUNC_ERROR), +  [VAR_FUNC]=N_(FUNC_ERROR), +  [VAR_LIST]=N_("E730: using List as a String"), +  [VAR_DICT]=N_("E731: using Dictionary as a String"), +  [VAR_FLOAT]=((const char *)e_float_as_string), +  [VAR_UNKNOWN]=N_("E908: using an invalid value as a String"), +}; + +#undef FUNC_ERROR + +/// Check that given value is a string or can be converted to it +/// +/// Error messages are compatible with tv_get_string_chk() previously used for +/// the same purpose. +/// +/// @param[in]  tv  Value to check. +/// +/// @return true if everything is OK, false otherwise. +bool tv_check_str(const typval_T *const tv) +  FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +{ +  switch (tv->v_type) { +    case VAR_NUMBER: +    case VAR_SPECIAL: +    case VAR_STRING: { +      return true; +    } +    case VAR_PARTIAL: +    case VAR_FUNC: +    case VAR_LIST: +    case VAR_DICT: +    case VAR_FLOAT: +    case VAR_UNKNOWN: { +      EMSG(_(str_errors[tv->v_type])); +      return false; +    } +  } +  assert(false); +  return false; +} +  //{{{2 Get  /// Get the number value of a VimL object @@ -2247,12 +2291,73 @@ float_T tv_get_float(const typval_T *const tv)  /// Get the string value of a VimL object  /// +/// @param[in]  tv  Object to get value of. +/// @param  buf  Buffer used to hold numbers and special variables converted to +///              string. When function encounters one of these stringified value +///              will be written to buf and buf will be returned. +/// +///              Buffer must have NUMBUFLEN size. +/// +/// @return Object value if it is VAR_STRING object, number converted to +///         a string for VAR_NUMBER, v: variable name for VAR_SPECIAL or NULL. +const char *tv_get_string_buf_chk(const typval_T *const tv, char *const buf) +  FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +{ +  switch (tv->v_type) { +    case VAR_NUMBER: { +      snprintf(buf, NUMBUFLEN, "%" PRIdVARNUMBER, tv->vval.v_number); +      return buf; +    } +    case VAR_STRING: { +      if (tv->vval.v_string != NULL) { +        return (const char *)tv->vval.v_string; +      } +      return ""; +    } +    case VAR_SPECIAL: { +      STRCPY(buf, encode_special_var_names[tv->vval.v_special]); +      return buf; +    } +    case VAR_PARTIAL: +    case VAR_FUNC: +    case VAR_LIST: +    case VAR_DICT: +    case VAR_FLOAT: +    case VAR_UNKNOWN: { +      EMSG(_(str_errors[tv->v_type])); +      return false; +    } +  } +  return NULL; +} + +/// Get the string value of a VimL object +/// +/// @warning For number and special values it uses a single, static buffer. It +///          may be used only once, next call to get_tv_string may reuse it. Use +///          tv_get_string_buf() if you need to use tv_get_string() output after +///          calling it again. +/// +/// @param[in]  tv  Object to get value of. +/// +/// @return Object value if it is VAR_STRING object, number converted to +///         a string for VAR_NUMBER, v: variable name for VAR_SPECIAL or NULL. +const char *tv_get_string_chk(const typval_T *const tv) +  FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT +{ +  static char mybuf[NUMBUFLEN]; + +  return tv_get_string_buf_chk(tv, mybuf); +} + +/// Get the string value of a VimL object +///  /// @warning For number and special values it uses a single, static buffer. It  ///          may be used only once, next call to get_tv_string may reuse it. Use  ///          tv_get_string_buf() if you need to use tv_get_string() output after  ///          calling it again.  /// -/// @note get_tv_string_chk() and get_tv_string_buf_chk() are similar, but +/// @note tv_get_string_chk() and tv_get_string_buf_chk() are similar, but  ///       return NULL on error.  ///  /// @param[in]  tv  Object to get value of. @@ -2269,7 +2374,7 @@ const char *tv_get_string(const typval_T *const tv)  /// Get the string value of a VimL object  /// -/// @note get_tv_string_chk() and get_tv_string_buf_chk() are similar, but +/// @note tv_get_string_chk() and tv_get_string_buf_chk() are similar, but  ///       return NULL on error.  ///  /// @param[in]  tv  Object to get value of. @@ -2285,8 +2390,7 @@ const char *tv_get_string(const typval_T *const tv)  const char *tv_get_string_buf(const typval_T *const tv, char *const buf)    FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT  { -  const char *const res = (const char *)get_tv_string_buf_chk( -      (typval_T *)tv, (char_u *)buf); +  const char *const res = (const char *)tv_get_string_buf_chk(tv, buf);    return res != NULL ? res : "";  } | 
