aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/eval.c')
-rw-r--r--src/nvim/eval.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index c197754685..2d8d1694d1 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -3381,6 +3381,67 @@ static int eval_func(char_u **const arg, char_u *const name, const int name_len,
return ret;
}
+/// Process a function argument that can be a string expression or a function
+/// reference.
+/// "tv" must remain valid until calling evalarg_clean()!
+/// @return false when the argument is invalid.
+bool evalarg_get(typval_T *const tv, evalarg_T *const eva)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (tv->v_type == VAR_STRING || tv->v_type == VAR_NUMBER || tv->v_type == VAR_BOOL
+ || tv->v_type == VAR_SPECIAL) {
+ char numbuf[NUMBUFLEN];
+ eva->eva_string = tv_get_string_buf(tv, numbuf);
+ return true;
+ }
+
+ return callback_from_typval(&eva->eva_callback, tv);
+}
+
+/// @return whether "eva" has a valid expression or callback.
+bool evalarg_valid(const evalarg_T *const eva)
+ FUNC_ATTR_NONNULL_ALL FUNC_ATTR_CONST
+{
+ return eva->eva_string != NULL || eva->eva_callback.type != kCallbackNone;
+}
+
+/// Invoke the expression or callback "eva" and return the result in "tv".
+/// @return false if something failed
+bool evalarg_call(evalarg_T *const eva, typval_T *const tv)
+ FUNC_ATTR_NONNULL_ALL
+{
+ if (eva->eva_string != NULL) {
+ return eval0((char_u *)eva->eva_string, tv, NULL, true);
+ }
+
+ typval_T argv[1];
+ argv[0].v_type = VAR_UNKNOWN;
+ return callback_call(&eva->eva_callback, 0, argv, tv);
+}
+
+/// Like evalarg_call(), but just return true or false.
+/// Sets "error" to true if evaluation failed.
+bool evalarg_call_bool(evalarg_T *const eva, bool *const error)
+ FUNC_ATTR_NONNULL_ALL
+{
+ typval_T tv;
+ if (!evalarg_call(eva, &tv)) {
+ *error = true;
+ return false;
+ }
+
+ const bool r = tv_get_number(&tv);
+ tv_clear(&tv);
+ *error = false;
+ return r;
+}
+
+void evalarg_clean(evalarg_T *const eva)
+ FUNC_ATTR_NONNULL_ALL
+{
+ callback_free(&eva->eva_callback);
+}
+
// TODO(ZyX-I): move to eval/expressions
/*