2 * Copyright (c) 2012, Intel Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of Intel Corporation nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #ifndef __MURPHY_CORE_SCRIPTING_H__
31 #define __MURPHY_CORE_SCRIPTING_H__
36 #include <murphy/common/macros.h>
37 #include <murphy/common/list.h>
38 #include <murphy/common/log.h>
43 typedef struct mrp_interpreter_s mrp_interpreter_t;
44 typedef struct mrp_scriptlet_s mrp_scriptlet_t;
45 typedef struct mrp_context_tbl_s mrp_context_tbl_t;
46 typedef struct mrp_script_value_s mrp_script_value_t;
50 * call/execution context passed to exported boilerplate methods
52 * This context is used to pass positional and keyword arguments
53 * when calling exported scripting boilerplate methods. For instance
54 * the primitive resolver scriptlet interpreter uses this to execute
59 mrp_script_value_t *args; /* positional arguments */
60 int narg; /* number of arguments */
61 mrp_context_tbl_t *ctbl; /* named arguments */
66 * supported data types to pass to/from scripts (XXX TODO: arrays...)
69 #define A(t) MRP_SCRIPT_TYPE_##t
71 MRP_SCRIPT_TYPE_UNKNOWN = 0x00,
72 MRP_SCRIPT_TYPE_INVALID = 0x00, /* defined invalid type */
73 MRP_SCRIPT_TYPE_STRING = 0x01, /* string */
74 MRP_SCRIPT_TYPE_BOOL = 0x02, /* boolean */
75 MRP_SCRIPT_TYPE_UINT8 = 0x03, /* signed 8-bit integer */
76 MRP_SCRIPT_TYPE_SINT8 = 0x04, /* unsigned 8-bit integer */
77 MRP_SCRIPT_TYPE_INT8 = A(SINT8), /* alias for SINT8 */
78 MRP_SCRIPT_TYPE_UINT16 = 0x05, /* unsigned 16-bit integer */
79 MRP_SCRIPT_TYPE_SINT16 = 0x06, /* signed 16-bit integer */
80 MRP_SCRIPT_TYPE_INT16 = A(SINT16), /* alias for SINT16 */
81 MRP_SCRIPT_TYPE_UINT32 = 0x07, /* unsigned 32-bit integer */
82 MRP_SCRIPT_TYPE_SINT32 = 0x08, /* signed 32-bit integer */
83 MRP_SCRIPT_TYPE_INT32 = A(SINT32), /* alias for SINT32 */
84 MRP_SCRIPT_TYPE_UINT64 = 0x09, /* unsigned 64-bit integer */
85 MRP_SCRIPT_TYPE_SINT64 = 0x0a, /* signed 64-bit integer */
86 MRP_SCRIPT_TYPE_INT64 = A(SINT64), /* alias for SINT64 */
87 MRP_SCRIPT_TYPE_DOUBLE = 0x0b, /* double-prec. floating point */
88 MRP_SCRIPT_TYPE_ARRAY = 0x80, /* type/marker for arrays */
92 #define MRP_SCRIPT_VALUE_UNION union { \
106 typedef MRP_SCRIPT_VALUE_UNION mrp_script_value_u;
108 struct mrp_script_value_s {
109 mrp_script_type_t type;
110 MRP_SCRIPT_VALUE_UNION;
113 /** Helper macros for passing values to variadic arglist functions. */
114 #define MRP_SCRIPT_STRING(s) MRP_SCRIPT_TYPE_STRING, s
115 #define MRP_SCRIPT_BOOL(b) MRP_SCRIPT_TYPE_BOOL , b
116 #define MRP_SCRIPT_UINT8(u) MRP_SCRIPT_TYPE_UINT8 , u
117 #define MRP_SCRIPT_SINT8(s) MRP_SCRIPT_TYPE_SINT8 , s
118 #define MRP_SCRIPT_UINT16(u) MRP_SCRIPT_TYPE_UINT16, u
119 #define MRP_SCRIPT_SINT16(s) MRP_SCRIPT_TYPE_SINT16, s
120 #define MRP_SCRIPT_UINT32(u) MRP_SCRIPT_TYPE_UINT32, u
121 #define MRP_SCRIPT_SINT32(s) MRP_SCRIPT_TYPE_SINT32, s
122 #define MRP_SCRIPT_UINT64(u) MRP_SCRIPT_TYPE_UINT64, u
123 #define MRP_SCRIPT_DOUBLE(d) MRP_SCRIPT_TYPE_DOUBLE, d
125 /** Helper macro for initializing/assigning to value arrays. */
126 #define __MRP_SCRIPT_VALUE(_t, _m, _v) \
127 (mrp_script_value_t){ .type = MRP_SCRIPT_TYPE_##_t, ._m = _v }
129 #define MRP_SCRIPT_VALUE_STRING(v) __MRP_SCRIPT_VALUE(STRING, str, v)
130 #define MRP_SCRIPT_VALUE_BOOL(v) __MRP_SCRIPT_VALUE(BOOL , bln, v)
131 #define MRP_SCRIPT_VALUE_UINT8(v) __MRP_SCRIPT_VALUE(UINT8 , u8 , v)
132 #define MRP_SCRIPT_VALUE_SINT8(v) __MRP_SCRIPT_VALUE(SINT8 , s8 , v)
133 #define MRP_SCRIPT_VALUE_UINT16(v) __MRP_SCRIPT_VALUE(UINT16, u16, v)
134 #define MRP_SCRIPT_VALUE_SINT16(v) __MRP_SCRIPT_VALUE(SINT16, s16, v)
135 #define MRP_SCRIPT_VALUE_UINT32(v) __MRP_SCRIPT_VALUE(UINT32, u32, v)
136 #define MRP_SCRIPT_VALUE_SINT32(v) __MRP_SCRIPT_VALUE(SINT32, s32, v)
137 #define MRP_SCRIPT_VALUE_UINT64(v) __MRP_SCRIPT_VALUE(UINT64, u64, v)
138 #define MRP_SCRIPT_VALUE_SINT64(v) __MRP_SCRIPT_VALUE(SINT64, s64, v)
139 #define MRP_SCRIPT_VALUE_DOUBLE(v) __MRP_SCRIPT_VALUE(DOUBLE, dbl, v)
141 /** Print the given value to the given buffer. */
142 char *mrp_print_value(char *buf, size_t size, mrp_script_value_t *value);
146 * a script interpreter as exposed to the resolver
149 struct mrp_interpreter_s {
150 mrp_list_hook_t hook; /* to list of interpreters */
151 const char *name; /* interpreter identifier */
152 void *data; /* opaque global interpreter data */
153 /* interpreter operations */
154 int (*compile)(mrp_scriptlet_t *script);
155 int (*prepare)(mrp_scriptlet_t *script);
156 int (*execute)(mrp_scriptlet_t *script, mrp_context_tbl_t *ctbl);
157 void (*cleanup)(mrp_scriptlet_t *script);
160 /** Macro to automatically register an interpreter on startup. */
161 #define MRP_REGISTER_INTERPRETER(_type, _compile, _prepare, _execute, \
163 static void auto_register_interpreter(void) \
164 __attribute__((constructor)); \
166 static void auto_register_interpreter(void) { \
167 static mrp_interpreter_t interpreter = { \
169 .compile = _compile, \
170 .prepare = _prepare, \
171 .execute = _execute, \
172 .cleanup = _cleanup \
175 if (!mrp_register_interpreter(&interpreter)) \
176 mrp_log_error("Failed to register interpreter '%s'.", \
179 mrp_log_info("Registered interpreter '%s'.", _type); \
181 struct mrp_allow_trailing_semicolon
184 /** Register a new scriptlet interpreter. */
185 int mrp_register_interpreter(mrp_interpreter_t *i);
187 /** Unregister a scriptlet interpreter. */
188 int mrp_unregister_interpreter(const char *type);
190 /** Find a scriptlet interpreter by type. */
191 mrp_interpreter_t *mrp_lookup_interpreter(const char *type);
195 * a resolver target update script
198 struct mrp_scriptlet_s {
199 char *source; /* scriptlet code */
200 mrp_interpreter_t *interpreter; /* interpreter handling this */
201 void *data; /* opaque interpreter data */
202 void *compiled; /* compiled scriptlet */
205 /** Create a scriptlet of the given type and source. */
206 mrp_scriptlet_t *mrp_create_script(const char *type, const char *source);
208 /** Destroy the given scriptlet, freeing all of its resources. */
209 void mrp_destroy_script(mrp_scriptlet_t *script);
211 /** Compile the given scriptlet. */
212 int mrp_compile_script(mrp_scriptlet_t *s);
214 /** Prepare the given scriptlet for execution. */
215 int mrp_prepare_script(mrp_scriptlet_t *s);
217 /** Execute the given scriptlet with the given context variables. */
218 int mrp_execute_script(mrp_scriptlet_t *s, mrp_context_tbl_t *ctbl);
223 * Context variable (keyword argument) handling.
224 * XXX TODO: Uhmm... this needs to be rethought/redone. :-(
227 mrp_context_tbl_t *mrp_create_context_table(void);
228 void mrp_destroy_context_table(mrp_context_tbl_t *tbl);
229 int mrp_declare_context_variable(mrp_context_tbl_t *tbl, const char *name,
230 mrp_script_type_t type);
231 int mrp_push_context_frame(mrp_context_tbl_t *tbl);
232 int mrp_pop_context_frame(mrp_context_tbl_t *tbl);
233 int mrp_get_context_id(mrp_context_tbl_t *tbl, const char *name);
234 int mrp_get_context_value(mrp_context_tbl_t *tbl, int id,
235 mrp_script_value_t *value);
236 int mrp_set_context_value(mrp_context_tbl_t *tbl, int id,
237 mrp_script_value_t *value);
238 int mrp_get_context_value_by_name(mrp_context_tbl_t *tbl, const char *name,
239 mrp_script_value_t *value);
240 int mrp_set_context_value_by_name(mrp_context_tbl_t *tbl, const char *name,
241 mrp_script_value_t *value);
251 #endif /* __MURPHY_CORE_SCRIPTING_H__ */