1 /*
2   Copyright 2021 Northern.tech AS
3 
4   This file is part of CFEngine 3 - written and maintained by Northern.tech AS.
5 
6   This program is free software; you can redistribute it and/or modify it
7   under the terms of the GNU General Public License as published by the
8   Free Software Foundation; version 3.
9 
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14 
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
18 
19   To the extent this program is licensed as part of the Enterprise
20   versions of CFEngine, the applicable Commercial Open Source License
21   (COSL) may apply to this file if you as a licensee so wish it. See
22   included file COSL.txt.
23 */
24 
25 #ifndef CFENGINE_FNCALL_H
26 #define CFENGINE_FNCALL_H
27 
28 #include <cf3.defs.h>
29 
30 struct FnCall_
31 {
32     char *name;
33     Rlist *args;
34 
35     const Promise *caller;
36 };
37 
38 typedef enum FnCallStatus
39 {
40     FNCALL_SUCCESS,
41     FNCALL_FAILURE
42 } FnCallStatus;
43 
44 typedef struct
45 {
46     FnCallStatus status;
47     Rval rval;
48 } FnCallResult;
49 
50 typedef struct
51 {
52     const char *pattern;
53     DataType dtype;
54     const char *description;
55 } FnCallArg;
56 
57 typedef enum
58 {
59     FNCALL_OPTION_NONE = 0,
60     // Functions with variable arguments don't require a fixed number
61     // of arguments.
62     FNCALL_OPTION_VARARG = 1 << 0,
63     // Cached functions are evaluated once per run (memoized). The
64     // hash key is the function name and all the arguments.
65     FNCALL_OPTION_CACHED = 1 << 1,
66     // Collecting functions take a variable reference OR can accept a
67     // nested function call. Either way, those parameters are
68     // collected into a data container.
69     FNCALL_OPTION_COLLECTING = 1 << 2,
70     // Delayed-evaluation functions will evaluate their arguments directly,
71     // so they can do things like maplist(canonify($(this)), mylist)
72     FNCALL_OPTION_DELAYED_EVALUATION = 1 << 3,
73     // Unsafe functions (with side effects) that should not be evaluated in
74     // simulate mode(s).
75     FNCALL_OPTION_UNSAFE = 1 << 4,
76 } FnCallOption;
77 
78 typedef struct
79 {
80     const char *name;
81     DataType dtype;
82     const FnCallArg *args;
83     FnCallResult (*impl)(EvalContext *, const Policy *, const FnCall *, const Rlist *);
84     const char *description;
85     FnCallOption options;
86     FnCallCategory category;
87     SyntaxStatus status;
88 } FnCallType;
89 
90 extern const FnCallType CF_FNCALL_TYPES[];
91 
92 bool FnCallIsBuiltIn(Rval rval);
93 
94 FnCall *FnCallNew(const char *name, Rlist *args);
95 FnCall *FnCallCopy(const FnCall *f);
96 FnCall *FnCallCopyRewriter(const FnCall *f, JsonElement *map);
97 void FnCallDestroy(FnCall *fp);
98 unsigned FnCallHash(const FnCall *fp, unsigned seed);
99 void FnCallWrite(Writer *writer, const FnCall *call);
100 
101 
102 FnCallResult FnCallEvaluate(EvalContext *ctx, const Policy *policy, FnCall *fp, const Promise *caller);
103 
104 const FnCallType *FnCallTypeGet(const char *name);
105 
106 FnCall *ExpandFnCall(const EvalContext *ctx, const char *ns, const char *scope, const FnCall *f);
107 Rlist *NewExpArgs(EvalContext *ctx, const Policy *policy, const FnCall *fp, const FnCallType *fp_type);
108 
109 // TODO: should probably demolish this eventually
110 void FnCallShow(FILE *fout, const char *prefix, const FnCall *fp, const Rlist *args);
111 
112 #endif
113