summaryrefslogtreecommitdiffstats
path: root/src/evalvars.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2020-06-06 18:37:51 +0200
committerBram Moolenaar <Bram@vim.org>2020-06-06 18:37:51 +0200
commitadc17a5f9d207fd1623fd923457a46efc9214777 (patch)
tree9c80498c748b98ef43576c925ee9646a78cecb53 /src/evalvars.c
parentd8df304c59040ef6689a1e4af1dac27ce566909e (diff)
patch 8.2.0915: search() cannot skip over matches like searchpair() canv8.2.0915
Problem: Search() cannot skip over matches like searchpair() can. Solution: Add an optional "skip" argument. (Christian Brabandt, closes #861)
Diffstat (limited to 'src/evalvars.c')
-rw-r--r--src/evalvars.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/evalvars.c b/src/evalvars.c
index 8b3ce2e903..84e9a7a9c2 100644
--- a/src/evalvars.c
+++ b/src/evalvars.c
@@ -3811,4 +3811,79 @@ free_callback(callback_T *callback)
callback->cb_name = NULL;
}
+/*
+ * Process a function argument that can be a string expression or a function
+ * reference.
+ * "tv" must remain valid until calling evalarg_clean()!
+ * Returns FAIL when the argument is invalid.
+ */
+ int
+evalarg_get(typval_T *tv, evalarg_T *eva)
+{
+ if (tv->v_type == VAR_STRING
+ || tv->v_type == VAR_NUMBER
+ || tv->v_type == VAR_BOOL
+ || tv->v_type == VAR_SPECIAL)
+ {
+ eva->eva_string = tv_get_string_buf(tv, eva->eva_buf);
+ return OK;
+ }
+
+ eva->eva_callback = get_callback(tv);
+ return eva->eva_callback.cb_name == NULL ? FAIL : OK;
+}
+
+/*
+ * Return whether "eva" has a valid expression or callback.
+ */
+ int
+evalarg_valid(evalarg_T *eva)
+{
+ return eva->eva_string != NULL || eva->eva_callback.cb_name != NULL;
+}
+
+/*
+ * Invoke the expression or callback "eva" and return the result in "tv".
+ * Returns FAIL if something failed
+ */
+ int
+evalarg_call(evalarg_T *eva, typval_T *tv)
+{
+ typval_T argv[1];
+
+ if (eva->eva_string != NULL)
+ return eval0(eva->eva_string, tv, NULL, EVAL_EVALUATE);
+
+ argv[0].v_type = VAR_UNKNOWN;
+ return call_callback(&eva->eva_callback, -1, tv, 0, argv);
+}
+
+/*
+ * Like evalarg_call(), but just return TRUE of FALSE.
+ * Sets "error" to TRUE if evaluation failed.
+ */
+ int
+evalarg_call_bool(evalarg_T *eva, int *error)
+{
+ typval_T tv;
+ int r;
+
+ if (evalarg_call(eva, &tv) == FAIL)
+ {
+ *error = TRUE;
+ return FALSE;
+ }
+ r = tv_get_number(&tv);
+ clear_tv(&tv);
+ *error = FALSE;
+ return r;
+}
+
+ void
+evalarg_clean(evalarg_T *eva)
+{
+ if (eva->eva_string == NULL)
+ free_callback(&eva->eva_callback);
+}
+
#endif // FEAT_EVAL