1 #ifndef RS_FUNCTION_H_
2 #define RS_FUNCTION_H_
3 
4 #include <value.h>
5 #include <util/block_alloc.h>
6 #include <result_processor.h>
7 #include <query_error.h>
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11 
12 #define VALIDATE_ARGS(fname, minargs, maxargs, err)                                           \
13   if (argc < minargs || argc > maxargs) {                                                     \
14     QueryError_SetError(err, QUERY_EPARSEARGS, "Invalid arguments for function '" fname "'"); \
15     return EXPR_EVAL_ERR;                                                                     \
16   }
17 
18 #define VALIDATE_ARG__COMMON(fname, args, idx, verifier, varg)                                 \
19   {                                                                                            \
20     RSValue *dref = RSValue_Dereference(args[idx]);                                            \
21     if (!verifier(dref, varg)) {                                                               \
22                                                                                                \
23       QueryError_SetErrorFmt(                                                                  \
24           err, QUERY_EPARSEARGS,                                                               \
25           "Invalid type (%d) for argument %d in function '%s'. %s(v, %s) was false.", dref->t, \
26           idx, fname, #verifier, #varg);                                                       \
27       return EXPR_EVAL_ERR;                                                                    \
28     }                                                                                          \
29   }
30 
31 #define VALIDATE_ARG__TYPE(arg, t_) ((arg)->t == t_)
32 #define VALIDATE_ARG_TYPE(fname, args, idx, t) \
33   VALIDATE_ARG__COMMON(fname, args, idx, VALIDATE_ARG__TYPE, t)
34 
35 #define VALIDATE_ARG__STRING(arg, unused) RSValue_IsString(arg)
36 #define VALIDATE_ARG_ISSTRING(fname, args, idx) \
37   VALIDATE_ARG__COMMON(fname, args, idx, VALIDATE_ARG__STRING, 0)
38 
39 struct ExprEval;
40 
41 /**
42  * Function callback for arguments.
43  * @param e Evaluator context. Can be used for allocations and other goodies
44  * @param[out] result Store the result of the function here. Can be a reference
45  * @param args The arguments passed to the function. This can be:
46  *  NULL (no arguments)
47  *  String value (raw)
48  *  Converted value (numeric, reference, etc.)
49  * @nargs the number of arguments passed
50  * @err If an error occurs, return EXPR_EVAL_ERR with the error set here.
51  *
52  * @return EXPR_EVAL_ERR or EXPR_EVAL_OK
53  */
54 typedef int (*RSFunction)(struct ExprEval *e, RSValue *result, RSValue **args, size_t nargs,
55                           QueryError *err);
56 
57 typedef struct {
58   size_t len;
59   size_t cap;
60   struct RSFunctionInfo {
61     RSFunction f;
62     const char *name;
63     RSValueType retType;
64     unsigned minargs;
65     int maxargs;
66   } * funcs;
67 } RSFunctionRegistry;
68 
69 typedef struct RSFunctionInfo RSFunctionInfo;
70 
71 RSFunction RSFunctionRegistry_Get(const char *name, size_t len);
72 
73 int RSFunctionRegistry_RegisterFunction(const char *name, RSFunction f, RSValueType retType);
74 
75 void RegisterMathFunctions();
76 void RegisterStringFunctions();
77 void RegisterDateFunctions();
78 void RegisterAllFunctions();
79 
80 void FunctionRegistry_Free(void);
81 #ifdef __cplusplus
82 }
83 #endif
84 #endif
85