resolver: script compilation, function lookup and execution, and more.
authorKrisztian Litkey <krisztian.litkey@intel.com>
Mon, 3 Sep 2012 06:21:31 +0000 (09:21 +0300)
committerKrisztian Litkey <krisztian.litkey@intel.com>
Fri, 26 Oct 2012 16:00:09 +0000 (19:00 +0300)
Added basic script compilation, function lookup, and script execution
code. Also some of the supporting scripting code (script.c, context.c)
has been lifted over to core.

The current (dres-like) named variable model with nested scoping
probably does not make much sense any more. Needs a bit more thinking
and probably a rewrite...

18 files changed:
src/resolver/context.c [deleted file]
src/resolver/context.h [deleted file]
src/resolver/murphy-resolver.pc.in
src/resolver/parser.y
src/resolver/resolver-types.h
src/resolver/resolver.c
src/resolver/resolver.h
src/resolver/script.c [deleted file]
src/resolver/script.h [deleted file]
src/resolver/scripting/simple/call.c
src/resolver/scripting/simple/call.h
src/resolver/scripting/simple/simple-script.c
src/resolver/scripting/simple/simple-script.h
src/resolver/target.c
src/resolver/test-input
src/resolver/test-input-audio
src/resolver/test-input-video
src/resolver/tests/parser-test.c

diff --git a/src/resolver/context.c b/src/resolver/context.c
deleted file mode 100644 (file)
index 686604b..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-#include <errno.h>
-
-#include <murphy/common/mm.h>
-#include <murphy/common/debug.h>
-#include <murphy/common/list.h>
-#include <murphy/common/hashtbl.h>
-#include <murphy/common/utils.h>
-
-#include "resolver-types.h"
-
-
-int init_context_table(mrp_resolver_t *r)
-{
-    context_tbl_t     *tbl;
-    mrp_htbl_config_t  hcfg;
-
-    tbl = mrp_allocz(sizeof(*tbl));
-    tbl->frame = NULL;
-
-    if (tbl != NULL) {
-        mrp_clear(&hcfg);
-        hcfg.comp = mrp_string_comp;
-        hcfg.hash = mrp_string_hash;
-        hcfg.free = NULL;
-
-        tbl->names = mrp_htbl_create(&hcfg);
-
-        if (tbl->names != NULL) {
-            r->ctbl = tbl;
-
-            return 0;
-        }
-
-        mrp_free(tbl);
-    }
-
-    return -1;
-}
-
-
-void cleanup_context_table(mrp_resolver_t *r)
-{
-    if (r->ctbl != NULL) {
-        mrp_htbl_destroy(r->ctbl->names, FALSE);
-    }
-}
-
-
-static context_var_t *lookup_context_var(mrp_resolver_t *r, const char *name)
-{
-    context_tbl_t *tbl;
-    int            id;
-
-    tbl = r->ctbl;
-    id  = (int)(ptrdiff_t)mrp_htbl_lookup(tbl->names, (void *)name);
-
-    if (0 < id && id <= tbl->nvariable)
-        return tbl->variables + id - 1;
-    else
-        return NULL;
-}
-
-
-int declare_context_variable(mrp_resolver_t *r, const char *name,
-                             mrp_script_type_t type)
-{
-    context_tbl_t *tbl;
-    context_var_t *var;
-
-    var = lookup_context_var(r, name);
-
-    if (var != NULL) {
-        if (!var->type) {
-            var->type = type;
-            return var->id;
-        }
-
-        if (!type || var->type == type)
-            return var->id;
-
-        errno = EEXIST;
-        return -1;
-    }
-    else {
-        size_t o, n;
-
-        tbl = r->ctbl;
-        o   = sizeof(*tbl->variables) * tbl->nvariable;
-        n   = sizeof(*tbl->variables) * (tbl->nvariable + 1);
-
-        if (!mrp_reallocz(tbl->variables, o, n))
-            return -1;
-
-        var = tbl->variables + tbl->nvariable++;
-
-        var->name = mrp_strdup(name);
-        var->type = type;
-        var->id   = tbl->nvariable;        /* this is a 1-based index... */
-
-        if (var->name != NULL) {
-            if (mrp_htbl_insert(tbl->names, (void *)var->name,
-                                (void *)(ptrdiff_t)var->id))
-                return var->id;
-        }
-
-        return -1;
-    }
-}
-
-
-int push_context_frame(mrp_resolver_t *r)
-{
-    context_tbl_t   *tbl;
-    context_frame_t *f;
-
-    tbl = r->ctbl;
-    f   = mrp_allocz(sizeof(*f));
-
-    if (f != NULL) {
-        f->values  = NULL;
-        f->prev    = tbl->frame;
-        tbl->frame = f;
-
-        mrp_debug("pushed new context frame...");
-
-        return 0;
-    }
-    else
-        return -1;
-}
-
-
-int pop_context_frame(mrp_resolver_t *r)
-{
-    context_tbl_t   *tbl;
-    context_frame_t *f;
-    context_value_t *v, *n;
-
-    tbl = r->ctbl;
-    f   = tbl->frame;
-
-    if (f != NULL) {
-        for (v = f->values; v != NULL; v = n) {
-            n = v->next;
-
-            if (v->value.type == MRP_SCRIPT_TYPE_STRING)
-                mrp_free(v->value.str);
-
-            mrp_debug("popped variable <%d>", v->id);
-            mrp_free(v);
-        }
-
-        tbl->frame = f->prev;
-        mrp_free(f);
-
-        mrp_debug("popped context frame");
-
-        return 0;
-    }
-    else {
-        errno = ENOENT;
-        return -1;
-    }
-}
-
-
-int get_context_id(mrp_resolver_t *r, const char *name)
-{
-    context_tbl_t *tbl;
-
-    tbl = r->ctbl;
-
-    return (int)(ptrdiff_t)mrp_htbl_lookup(tbl->names, (void *)name);
-}
-
-
-int get_context_value(mrp_resolver_t *r, int id, mrp_script_value_t *value)
-{
-    context_tbl_t   *tbl;
-    context_frame_t *f;
-    context_value_t *v;
-
-    tbl = r->ctbl;
-
-    if (0 < id && id <= tbl->nvariable) {
-        for (f = tbl->frame; f != NULL; f = f->prev) {
-            for (v = f->values; v != NULL; v = v->next) {
-                if (v->id == id) {
-                    *value = v->value;
-                    return 0;
-                }
-            }
-        }
-    }
-
-    value->type = MRP_SCRIPT_TYPE_INVALID;
-    errno       = ENOENT;
-
-    return -1;
-}
-
-
-int set_context_value(mrp_resolver_t *r, int id, mrp_script_value_t *value)
-{
-    context_tbl_t   *tbl;
-    context_frame_t *f;
-    context_var_t   *var;
-    context_value_t *val;
-    char             vbuf[64];
-
-    tbl = r->ctbl;
-
-    if (!(0 < id && id <= tbl->nvariable)) {
-        errno = ENOENT;
-        return -1;
-    }
-
-    var = tbl->variables + id - 1;
-    if (var->type != MRP_SCRIPT_TYPE_INVALID && var->type != value->type) {
-        errno = EINVAL;
-        return -1;
-    }
-
-    f = tbl->frame;
-    if (f != NULL) {
-        val = mrp_allocz(sizeof(*val));
-
-        if (val != NULL) {
-            val->id    = id;
-            val->value = *value;
-
-            if (val->value.type != MRP_SCRIPT_TYPE_STRING ||
-                ((val->value.str = mrp_strdup(val->value.str)) != NULL)) {
-                val->next = f->values;
-                f->values = val;
-
-                mrp_debug("set &%s=%s", var->name,
-                          mrp_print_value(vbuf, sizeof(vbuf), value));
-
-                return 0;
-            }
-            else
-                mrp_free(val);
-        }
-    }
-    else
-        errno = ENOSPC;
-
-    return -1;
-}
-
-
-int set_context_values(mrp_resolver_t *r, int *ids, mrp_script_value_t *values,
-                       int nid)
-{
-    int i;
-
-    for (i = 0; i < nid; i++) {
-        if (set_context_value(r, ids[i], values + i) < 0)
-            return -1;
-    }
-
-    return 0;
-}
diff --git a/src/resolver/context.h b/src/resolver/context.h
deleted file mode 100644 (file)
index 6261a0b..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __MRP_RESOLVER_CONTEXT_H__
-#define __MRP_RESOLVER_CONTEXT_H__
-
-int init_context_table(mrp_resolver_t *r);
-void cleanup_context_table(mrp_resolver_t *r);
-int declare_context_variable(mrp_resolver_t *r, const char *name,
-                             mrp_script_type_t type);
-
-int push_context_frame(mrp_resolver_t *r);
-int pop_context_frame(mrp_resolver_t *r);
-int get_context_id(mrp_resolver_t *r, const char *name);
-int get_context_value(mrp_resolver_t *r, int id, mrp_script_value_t *value);
-int set_context_values(mrp_resolver_t *r, int *ids, mrp_script_value_t *values,
-                       int nid);
-int set_context_value(mrp_resolver_t *r, int id, mrp_script_value_t *value);
-
-#endif /* __MRP_RESOLVER_CONTEXT_H__ */
index dbc83bc..cec8e79 100644 (file)
@@ -5,7 +5,7 @@ includedir=@includedir@
 
 Name: murphy-resolver
 Description: Murphy policy framework, resolver library.
-Requires: murphy-common @PACKAGE_VERSION@
+Requires: murphy-core murphy-common @PACKAGE_VERSION@
 Version: @PACKAGE_VERSION@
-Libs: -L${libdir} -lmurphy-common
+Libs: -L${libdir} -lmurphy-core -lmurphy-common
 Cflags: -I${includedir}
index 0901312..b3c5dd6 100644 (file)
@@ -131,7 +131,7 @@ optional_script:
     $$.source = NULL;
   }
 | KEY_UPDATE_SCRIPT script_source KEY_END_SCRIPT {
-    $$.type   = "default";
+    $$.type   = "simple"; /* "default"; */
     $$.source = $2.value;
   }
 ;
index d8c1380..a1e90da 100644 (file)
@@ -4,7 +4,7 @@
 #include <stdint.h>
 
 #include <murphy/common/hashtbl.h>
-#include <murphy/resolver/script.h>
+#include <murphy/core/scripting.h>
 
 typedef struct target_s target_t;        /* opaque type for resolver targets */
 typedef struct fact_s   fact_t;          /* opaque type for tracked facts */
@@ -13,13 +13,13 @@ typedef struct fact_s   fact_t;          /* opaque type for tracked facts */
  * a resolver target
  */
 struct target_s {
-    char         *name;                  /* target name */
-    uint32_t      stamp;                 /* touch-stamp */
-    char        **depends;               /* dependencies stated in the input */
-    int           ndepend;               /* number of dependencies */
-    int          *update_facts;          /* facts to check when updating */
-    int          *update_targets;        /* targets to check when updating */
-    mrp_script_t *script;                /* update script if any, or NULL */
+    char            *name;               /* target name */
+    uint32_t         stamp;              /* touch-stamp */
+    char           **depends;            /* dependencies stated in the input */
+    int              ndepend;            /* number of dependencies */
+    int             *update_facts;       /* facts to check when updating */
+    int             *update_targets;     /* targets to check when updating */
+    mrp_scriptlet_t *script;             /* update script if any, or NULL */
 };
 
 
@@ -59,21 +59,21 @@ struct context_frame_s {
 };
 
 
-typedef struct {
+struct mrp_context_tbl_s {
     context_var_t   *variables;          /* known/declared context variables */
     int              nvariable;          /* number of variables */
     mrp_htbl_t      *names;              /* variable name to id mapping */
     context_frame_t *frame;              /* active frame */
-} context_tbl_t;
+};
 
 
 struct mrp_resolver_s {
-    target_t      *targets;              /* targets defined in the ruleset */
-    int            ntarget;              /* number of targets */
-    fact_t        *facts;                /* facts tracked as dependencies */
-    int            nfact;                /* number of tracked facts */
-    uint32_t       stamp;                /* update stamp */
-    context_tbl_t *ctbl;                 /* context variable table */
+    target_t          *targets;          /* targets defined in the ruleset */
+    int                ntarget;          /* number of targets */
+    fact_t            *facts;            /* facts tracked as dependencies */
+    int                nfact;            /* number of tracked facts */
+    uint32_t           stamp;            /* update stamp */
+    mrp_context_tbl_t *ctbl;             /* context variable table */
 };
 
 
index 1647b10..30d1395 100644 (file)
@@ -10,7 +10,6 @@
 #include "target.h"
 #include "target-sorter.h"
 #include "fact.h"
-#include "context.h"
 #include "resolver.h"
 
 mrp_resolver_t *mrp_resolver_parse(const char *path)
@@ -26,7 +25,7 @@ mrp_resolver_t *mrp_resolver_parse(const char *path)
             if (create_targets(r, &parser) == 0 &&
                 sort_targets(r)            == 0 &&
                 compile_target_scripts(r)  == 0 &&
-                init_context_table(r)      == 0) {
+                (r->ctbl = mrp_create_context_table()) != NULL) {
                 parser_cleanup(&parser);
                 return r;
             }
@@ -45,7 +44,7 @@ mrp_resolver_t *mrp_resolver_parse(const char *path)
 void mrp_resolver_cleanup(mrp_resolver_t *r)
 {
     if (r != NULL) {
-        cleanup_context_table(r);
+        mrp_destroy_context_table(r->ctbl);
         destroy_targets(r);
         destroy_facts(r);
 
@@ -61,10 +60,10 @@ int mrp_resolver_update_targetl(mrp_resolver_t *r, const char *target, ...)
     va_list             ap;
     int                 id, status;
 
-    if (push_context_frame(r) == 0) {
+    if (mrp_push_context_frame(r->ctbl) == 0) {
         va_start(ap, target);
         while ((name = va_arg(ap, char *)) != NULL) {
-            id = get_context_id(r, name);
+            id = mrp_get_context_id(r->ctbl, name);
 
             if (id > 0) {
                 value.type = va_arg(ap, int);
@@ -94,7 +93,7 @@ int mrp_resolver_update_targetl(mrp_resolver_t *r, const char *target, ...)
                 }
 #undef          HANDLE_TYPE
 
-                if (set_context_value(r, id, &value) < 0) {
+                if (mrp_set_context_value(r->ctbl, id, &value) < 0) {
                     status = -1;
                     goto pop_frame;
                 }
@@ -109,7 +108,7 @@ int mrp_resolver_update_targetl(mrp_resolver_t *r, const char *target, ...)
         status = update_target_by_name(r, target);
 
     pop_frame:
-        pop_context_frame(r);
+        mrp_pop_context_frame(r->ctbl);
         va_end(ap);
     }
     else
@@ -128,14 +127,14 @@ int mrp_resolver_update_targetv(mrp_resolver_t *r, const char *target,
     mrp_script_value_t *value;
     int                 id, i, status;
 
-    if (push_context_frame(r) == 0) {
+    if (mrp_push_context_frame(r->ctbl) == 0) {
         for (i = 0; i < nvariable; i++) {
             name  = variables[i];
             value = values + i;
-            id    = get_context_id(r, name);
+            id    = mrp_get_context_id(r->ctbl, name);
 
             if (id > 0) {
-                if (set_context_value(r, id, value) < 0) {
+                if (mrp_set_context_value(r->ctbl, id, value) < 0) {
                     status = -1;
                     goto pop_frame;
                 }
@@ -150,7 +149,7 @@ int mrp_resolver_update_targetv(mrp_resolver_t *r, const char *target,
         status = update_target_by_name(r, target);
 
     pop_frame:
-        pop_context_frame(r);
+        mrp_pop_context_frame(r->ctbl);
     }
     else
         status = -1;
@@ -180,42 +179,31 @@ void mrp_resolver_dump_facts(mrp_resolver_t *r, FILE *fp)
 
 int mrp_resolver_register_interpreter(mrp_interpreter_t *i)
 {
-    return register_interpreter(i);
+    return mrp_register_interpreter(i);
 }
 
 
 int mrp_resolver_unregister_interpreter(const char *name)
 {
-    mrp_interpreter_t *i;
-
-    i = lookup_interpreter(name);
-
-    if (i != NULL) {
-        unregister_interpreter(i);
-
-        return TRUE;
-    }
-    else
-        return FALSE;
-
+    return mrp_unregister_interpreter(name);
 }
 
 
 int mrp_resolver_declare_variable(mrp_resolver_t *r, const char *name,
                                   mrp_script_type_t type)
 {
-    return declare_context_variable(r, name, type);
+    return mrp_declare_context_variable(r->ctbl, name, type);
 }
 
 
 int mrp_resolver_get_value(mrp_resolver_t *r, int id, mrp_script_value_t *v)
 {
-    return get_context_value(r, id, v);
+    return mrp_get_context_value(r->ctbl, id, v);
 }
 
 
 int mrp_resolver_get_value_by_name(mrp_resolver_t *r, const char *name,
                                    mrp_script_value_t *v)
 {
-    return get_context_value(r, get_context_id(r, name), v);
+    return mrp_get_context_value(r->ctbl, mrp_get_context_id(r->ctbl, name), v);
 }
index 0c5c5a4..77a1968 100644 (file)
 #include <stdbool.h>
 
 #include <murphy/common/macros.h>
+#include <murphy/core/scripting.h>
 
 MRP_CDECL_BEGIN
 
-typedef struct mrp_resolver_s    mrp_resolver_t;
-typedef struct mrp_interpreter_s mrp_interpreter_t;
-typedef struct mrp_script_s      mrp_script_t;
-
-
-/*
- * data types to pass to/from scripts
- */
-
-#define A(t) MRP_SCRIPT_TYPE_##t
-typedef enum {
-    MRP_SCRIPT_TYPE_UNKNOWN = 0x00,
-    MRP_SCRIPT_TYPE_INVALID = 0x00,      /* defined invalid type */
-    MRP_SCRIPT_TYPE_STRING  = 0x01,      /* string */
-    MRP_SCRIPT_TYPE_BOOL    = 0x02,      /* boolean */
-    MRP_SCRIPT_TYPE_UINT8   = 0x03,      /* signed 8-bit integer */
-    MRP_SCRIPT_TYPE_SINT8   = 0x04,      /* unsigned 8-bit integer */
-    MRP_SCRIPT_TYPE_INT8    = A(SINT8),  /* alias for SINT8 */
-    MRP_SCRIPT_TYPE_UINT16  = 0x05,      /* unsigned 16-bit integer */
-    MRP_SCRIPT_TYPE_SINT16  = 0x06,      /* signed 16-bit integer */
-    MRP_SCRIPT_TYPE_INT16   = A(SINT16), /* alias for SINT16 */
-    MRP_SCRIPT_TYPE_UINT32  = 0x07,      /* unsigned 32-bit integer */
-    MRP_SCRIPT_TYPE_SINT32  = 0x08,      /* signed 32-bit integer */
-    MRP_SCRIPT_TYPE_INT32   = A(SINT32), /* alias for SINT32 */
-    MRP_SCRIPT_TYPE_UINT64  = 0x09,      /* unsigned 64-bit integer */
-    MRP_SCRIPT_TYPE_SINT64  = 0x0a,      /* signed 64-bit integer */
-    MRP_SCRIPT_TYPE_INT64   = A(SINT64), /* alias for SINT64 */
-    MRP_SCRIPT_TYPE_DOUBLE  = 0x0b,      /* double-prec. floating point */
-    MRP_SCRIPT_TYPE_ARRAY   = 0x80,      /* type/marker for arrays */
-} mrp_script_type_t;
-
-#define MRP_SCRIPT_VALUE_UNION union {          \
-        char      *str;                         \
-        bool       bln;                         \
-        uint8_t    u8;                          \
-        int8_t     s8;                          \
-        uint16_t   u16;                         \
-        int16_t    s16;                         \
-        uint32_t   u32;                         \
-        int32_t    s32;                         \
-        uint64_t   u64;                         \
-        int64_t    s64;                         \
-        double     dbl;                         \
-    }
-
-typedef MRP_SCRIPT_VALUE_UNION mrp_script_value_u;
-
-typedef struct {
-    mrp_script_type_t type;
-    MRP_SCRIPT_VALUE_UNION;
-} mrp_script_value_t;
-
-#define mrp_script_typed_value_t mrp_script_value_t
-
-#define MRP_SCRIPT_STRING(s) MRP_SCRIPT_TYPE_STRING, s
-#define MRP_SCRIPT_BOOL(b)   MRP_SCRIPT_TYPE_BOOL  , b
-#define MRP_SCRIPT_UINT8(u)  MRP_SCRIPT_TYPE_UINT8 , u
-#define MRP_SCRIPT_SINT8(s)  MRP_SCRIPT_TYPE_SINT8 , s
-#define MRP_SCRIPT_UINT16(u) MRP_SCRIPT_TYPE_UINT16, u
-#define MRP_SCRIPT_SINT16(s) MRP_SCRIPT_TYPE_SINT16, s
-#define MRP_SCRIPT_UINT32(u) MRP_SCRIPT_TYPE_UINT32, u
-#define MRP_SCRIPT_SINT32(s) MRP_SCRIPT_TYPE_SINT32, s
-#define MRP_SCRIPT_UINT64(u) MRP_SCRIPT_TYPE_UINT64, u
-#define MRP_SCRIPT_DOUBLE(d) MRP_SCRIPT_TYPE_DOUBLE, d
-
-/*
- * a script interpreter
- */
-
-struct mrp_interpreter_s {
-    mrp_list_hook_t    hook;             /* to list of interpreters */
-    const char        *name;             /* interpreter identifier */
-    void              *data;             /* opaque global interpreter data */
-    /*                                      interpreter operations */
-    int  (*compile)(mrp_script_t *script);
-    int  (*execute)(mrp_script_t *script);
-    void (*cleanup)(mrp_script_t *script);
-#if 0
-    void (*print)(char *buf, size_t size, mrp_script_t *script);
-#endif
-};
-
-/** Macro to automatically register an interpreter on startup. */
-#define MRP_REGISTER_INTERPRETER(_type, _compile, _execute, _cleanup)   \
-    static void auto_register_interpreter(void)                         \
-         __attribute__((constructor));                                  \
-                                                                        \
-    static void auto_register_interpreter(void) {                       \
-        static mrp_interpreter_t interpreter = {                        \
-            .name    = _type,                                           \
-            .compile = _compile,                                        \
-            .execute = _execute,                                        \
-            .cleanup = _cleanup                                         \
-        };                                                              \
-                                                                        \
-        mrp_list_init(&interpreter.hook);                               \
-                                                                        \
-        if (!mrp_resolver_register_interpreter(&interpreter))           \
-            mrp_log_error("Failed to register interpreter '%s'.",       \
-                          _type);                                       \
-        else                                                            \
-            mrp_log_info("Registered interpreter '%s'.", _type);        \
-    }                                                                   \
-    struct mrp_allow_trailing_semicolon
-
-
-
-/*
- * (execution context for) a script
- */
-
-struct mrp_script_s {
-    char              *source;           /* script in source form */
-    mrp_interpreter_t *interpreter;      /* interpreter for this */
-    void              *data;             /* interpreter data */
-    void              *compiled;         /* script in compiled form */
-};
-
+typedef struct mrp_resolver_s mrp_resolver_t;
 
 /** Parse the given resolver input file into a resolver context. */
 mrp_resolver_t *mrp_resolver_parse(const char *path);
@@ -174,7 +58,6 @@ int mrp_resolver_register_interpreter(mrp_interpreter_t *i);
 /** Unregister a script interpreter. */
 int mrp_resolver_unregister_interpreter(const char *name);
 
-
 MRP_CDECL_END
 
 #endif /* __MURPHY_RESOLVER_H__ */
diff --git a/src/resolver/script.c b/src/resolver/script.c
deleted file mode 100644 (file)
index dc2be7e..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-#include <stdio.h>
-#include <stdarg.h>
-#include <stddef.h>
-#include <string.h>
-#include <errno.h>
-
-#include <murphy/common/macros.h>
-#include <murphy/common/mm.h>
-#include <murphy/common/list.h>
-
-#include "resolver.h"
-
-
-/*
- * With the low expected number of interpreters it is probably
- * much faster to keep interpreters in a linked list than to
- * hash them in...
- */
-static MRP_LIST_HOOK(interpreters);                /* registered interpreters */
-static const char *default_interpreter = "simple"; /* the default interpreter */
-
-
-void set_default_interpreter(const char *type)
-{
-    default_interpreter = type;
-}
-
-
-int register_interpreter(mrp_interpreter_t *i)
-{
-    mrp_list_append(&interpreters, &i->hook);
-
-    return TRUE;
-}
-
-
-void unregister_interpreter(mrp_interpreter_t *i)
-{
-    mrp_list_delete(&i->hook);
-}
-
-
-mrp_interpreter_t *lookup_interpreter(const char *name)
-{
-    mrp_list_hook_t   *p, *n;
-    mrp_interpreter_t *i;
-
-    if (!strcmp(name, "default"))
-        name = default_interpreter;
-
-    mrp_list_foreach(&interpreters, p, n) {
-        i = mrp_list_entry(p, typeof(*i), hook);
-        if (!strcmp(i->name, name))
-            return i;
-    }
-
-    return NULL;
-}
-
-
-mrp_script_t *create_script(char *type, const char *source)
-{
-    mrp_interpreter_t *i;
-    mrp_script_t      *s;
-
-    s = NULL;
-    i = lookup_interpreter(type);
-
-    if (i != NULL) {
-        s = mrp_allocz(sizeof(*s));
-
-        if (s != NULL) {
-            s->interpreter = i;
-            s->source      = mrp_strdup(source);
-
-            if (s->source != NULL)
-                return s;
-            else {
-                mrp_free(s);
-                s = NULL;
-            }
-        }
-    }
-    else
-        errno = ENOENT;
-
-    return NULL;
-}
-
-
-void destroy_script(mrp_script_t *script)
-{
-    if (script != NULL) {
-        script->interpreter->cleanup(script);
-
-        mrp_free(script->source);
-        mrp_free(script);
-    }
-}
-
-
-int compile_script(mrp_script_t *s)
-{
-    if (s != NULL)
-        return s->interpreter->compile(s);
-    else
-        return 0;
-}
-
-
-int execute_script(mrp_resolver_t *r, mrp_script_t *s)
-{
-    MRP_UNUSED(r);
-
-    if (s != NULL)
-        return s->interpreter->execute(s);
-    else
-        return TRUE;
-}
-
-
-int eval_script(mrp_resolver_t *r, char *script)
-{
-    MRP_UNUSED(r);
-
-    if (script == NULL)
-        return TRUE;
-    else {
-        printf("----- running update script -----\n");
-        printf("%s", script);
-        printf("---------------------------------\n");
-
-        return TRUE;
-    }
-}
-
-
-char *mrp_print_value(char *buf, size_t size, mrp_script_value_t *value)
-{
-#define HANDLE_TYPE(type, fmt, val)                     \
-        case MRP_SCRIPT_TYPE_##type:                    \
-            snprintf(buf, size, fmt, val);              \
-            break
-
-    switch (value->type) {
-        HANDLE_TYPE(UNKNOWN, "%s"     , "<unknown/invalid type>");
-        HANDLE_TYPE(STRING , "'%s'"   , value->str);
-        HANDLE_TYPE(BOOL   , "%s"     , value->bln ? "true" : "false");
-        HANDLE_TYPE(UINT8  , "%uU8"   , value->u8);
-        HANDLE_TYPE(SINT8  , "%dS8"   , value->s8);
-        HANDLE_TYPE(UINT16 , "%uU16"  , value->u16);
-        HANDLE_TYPE(SINT16 , "%dS16"  , value->s16);
-        HANDLE_TYPE(UINT32 , "%uU32"  , value->u32);
-        HANDLE_TYPE(SINT32 , "%dS32"  , value->s32);
-        HANDLE_TYPE(UINT64 , "%lluU64", (unsigned long long)value->u64);
-        HANDLE_TYPE(SINT64 , "%lldS64", (  signed long long)value->s64);
-        HANDLE_TYPE(DOUBLE , "%f"     , value->dbl);
-    default:
-        snprintf(buf, size, "<invalid type 0x%x>", value->type);
-    }
-
-#undef HANDLE_TYPE
-
-    return buf;
-}
diff --git a/src/resolver/script.h b/src/resolver/script.h
deleted file mode 100644 (file)
index 4163357..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#ifndef __MRP_RESOLVER_SCRIPT_H__
-#define __MRP_RESOLVER_SCRIPT_H__
-
-#include <stdint.h>
-#include <stdbool.h>
-
-#include <murphy/common/macros.h>
-#include <murphy/common/list.h>
-
-MRP_CDECL_BEGIN
-
-#include "resolver.h"
-
-
-/** Set the default interpreter type. */
-void set_default_interpreter(const char *type);
-
-/** Register the given script interpreter. */
-int register_interpreter(mrp_interpreter_t *i);
-
-/** Unregister the given interpreter. */
-void unregister_interpreter(mrp_interpreter_t *i);
-
-/** Lookup an interpreter by name. */
-mrp_interpreter_t *lookup_interpreter(const char *name);
-
-/** Create (prepare) a script of the given type with the given source. */
-mrp_script_t *create_script(char *type, const char *source);
-
-/** Destroy the given script freeing all associated resources. */
-void destroy_script(mrp_script_t *script);
-
-/** Compile the given script, preparing it for execution. */
-int compile_script(mrp_script_t *script);
-
-/** Execute the given script. */
-int execute_script(mrp_resolver_t *r, mrp_script_t *s);
-
-/** Dummy routine that just prints the script to be evaluated. */
-int eval_script(mrp_resolver_t *r, char *script);
-
-MRP_CDECL_END
-
-#endif /* __MRP_RESOLVER_SCRIPT_H__ */
index acf759d..b8060ff 100644 (file)
@@ -1,4 +1,8 @@
+#include <errno.h>
+
 #include <murphy/common/mm.h>
+#include <murphy/core/plugin.h>       /* XXX TODO, needed for method.h */
+#include <murphy/core/method.h>
 
 #include "call.h"
 
@@ -106,6 +110,76 @@ void destroy_arguments(arg_t *args, int narg)
 }
 
 
+static int resolve_function(function_call_t *c)
+{
+    mrp_plugin_t  *plugin;
+    int          (*script_ptr)(mrp_plugin_t *plugin, const char *name,
+                               mrp_script_env_t *env);
+
+    if (mrp_import_method(c->name, NULL, NULL, &script_ptr, &plugin) < 0)
+        return FALSE;
+    else {
+        c->script_ptr = script_ptr;
+        c->plugin     = plugin;
+
+        return TRUE;
+    }
+}
+
+int execute_call(function_call_t *c, mrp_context_tbl_t *tbl)
+{
+    mrp_script_env_t   env;
+    mrp_script_value_t args[c->narg];
+    arg_t             *a;
+    int                narg, n, status;
+
+    if (MRP_UNLIKELY(c->script_ptr == NULL)) {
+        if (!resolve_function(c))
+            return -ENOENT;
+    }
+
+    mrp_push_context_frame(tbl);
+
+    for (n = narg = 0, a = c->args; n < (int)MRP_ARRAY_SIZE(args); n++, a++) {
+        switch (a->type) {
+        case ARG_CONST_VALUE:
+            args[narg++] = a->cst.value;
+            break;
+        case ARG_CONTEXT_VAR:
+            if (a->val.id <= 0)
+                a->val.id = mrp_get_context_id(tbl, a->val.name);
+            if (mrp_get_context_value(tbl, a->val.id, args + narg) < 0) {
+                status = -ENOENT;
+                goto pop_frame;
+            }
+            narg++;
+            break;
+        case ARG_CONTEXT_SET:
+            if (a->set.id <= 0)
+                a->set.id = mrp_get_context_id(tbl, a->set.name);
+            if (mrp_set_context_value(tbl, a->set.id, &a->set.value) < 0) {
+                status = -errno;
+                goto pop_frame;
+            }
+        default:
+            status = -EINVAL;
+            goto pop_frame;
+        }
+    }
+
+    env.args = args;
+    env.narg = narg;
+    env.ctbl = tbl;
+
+    status = c->script_ptr(c->plugin, c->name, &env);
+
+ pop_frame:
+    mrp_pop_context_frame(tbl);
+
+    return status;
+}
+
+
 static void dump_arg(FILE *fp, arg_t *arg)
 {
     mrp_script_value_t *val;
index e921a60..634dfb5 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __MURPHY_SIMPLE_SCRIPT_CALL_H__
 #define __MURPHY_SIMPLE_SCRIPT_CALL_H__
 
-#include <murphy/resolver/script.h>
+#include <murphy/core/scripting.h>
 
 #include "simple-script.h"
 
@@ -14,6 +14,6 @@ int set_context_value_arg(arg_t *arg, char *name);
 int set_context_set_arg(arg_t *arg, char *name,
                         mrp_script_value_t *value);
 void destroy_arguments(arg_t *args, int narg);
-
+int execute_call(function_call_t *c, mrp_context_tbl_t *tbl);
 
 #endif /* __MURPHY_SIMPLE_SCRIPT_CALL_H__ */
index 3830ea9..0d40d93 100644 (file)
@@ -23,7 +23,7 @@ static void simple_dump(FILE *fp, simple_script_t *ss)
 }
 
 
-static int simple_compile(mrp_script_t *script)
+static int simple_compile(mrp_scriptlet_t *script)
 {
     yy_smpl_parser_t  parser;
     simple_script_t  *ss;
@@ -47,21 +47,29 @@ static int simple_compile(mrp_script_t *script)
 }
 
 
-static int simple_execute(mrp_script_t *s)
+static int simple_execute(mrp_scriptlet_t *s, mrp_context_tbl_t *tbl)
 {
     simple_script_t *ss = s->compiled;
+    mrp_list_hook_t *p, *n;
+    function_call_t *c;
+    int              status;
 
     if (ss != NULL) {
-        printf("----- should execute simple script -----\n");
-        simple_dump(stdout, ss);
-        printf("----------------------------------------\n");
+        mrp_list_foreach(&ss->statements, p, n) {
+            c = mrp_list_entry(p, typeof(*c), hook);
+
+            status = execute_call(c, tbl);
+
+            if (status <= 0)
+                return status;
+        }
     }
 
     return TRUE;
 }
 
 
-static void simple_cleanup(mrp_script_t *s)
+static void simple_cleanup(mrp_scriptlet_t *s)
 {
     MRP_UNUSED(s);
 
index 1180172..25610aa 100644 (file)
@@ -1,7 +1,8 @@
 #ifndef __MURPHY_SIMPLE_SCRIPT_H__
 #define __MURPHY_SIMPLE_SCRIPT_H__
 
-#include <murphy/resolver/script.h>
+#include <murphy/core/plugin.h>
+#include <murphy/core/scripting.h>
 
 typedef struct {
     mrp_list_hook_t statements;          /* list of (call) statements */
@@ -30,10 +31,10 @@ typedef struct {
 
 
 typedef struct {
-    arg_type_t                type;      /* ARG_CONTEXT_SET */
-    char                     *name;      /* name of variable */
-    int                       id;        /* variable id */
-    mrp_script_typed_value_t  value;     /* value to set to */
+    arg_type_t          type;            /* ARG_CONTEXT_SET */
+    char               *name;            /* name of variable */
+    int                 id;              /* variable id */
+    mrp_script_value_t  value;           /* value to set to */
 } ctx_set_arg_t;
 
 
@@ -50,6 +51,10 @@ typedef struct {
     arg_t                    *args;      /* arguments to pass */
     int                       narg;      /* number of arguments */
     mrp_list_hook_t           hook;      /* to list of statements */
+
+    int          (*script_ptr)(mrp_plugin_t *plugin, const char *name,
+                               mrp_script_env_t *env);
+    mrp_plugin_t  *plugin;
 } function_call_t;
 
 
index aa7f8b8..598305f 100644 (file)
@@ -5,12 +5,13 @@
 #include <murphy/common/mm.h>
 #include <murphy/common/list.h>
 
+#include <murphy/core/scripting.h>
+
 #include "resolver-types.h"
 #include "resolver.h"
 #include "db.h"
 #include "fact.h"
 #include "target.h"
-#include "script.h"
 
 
 int create_targets(mrp_resolver_t *r, yy_res_parser_t *parser)
@@ -39,12 +40,12 @@ int create_targets(mrp_resolver_t *r, yy_res_parser_t *parser)
         pt->ndepend = 0;
 
         if (pt->script_source != NULL) {
-            t->script = create_script(pt->script_type, pt->script_source);
+            t->script = mrp_create_script(pt->script_type, pt->script_source);
 
             if (t->script == NULL) {
                 if (errno == ENOENT)
                     mrp_log_error("Unsupported script type '%s' used in "
-                                  "target '%s'.", t->name, pt->script_type);
+                                  "target '%s'.", pt->script_type, t->name);
                 else
                     mrp_log_error("Failed to set up script for target '%s'.",
                                   t->name);
@@ -78,7 +79,7 @@ void destroy_targets(mrp_resolver_t *r)
             mrp_free(t->depends[j]);
         mrp_free(t->depends);
 
-        destroy_script(t->script);
+        mrp_destroy_script(t->script);
     }
 
     mrp_free(r->targets);
@@ -91,12 +92,9 @@ int compile_target_scripts(mrp_resolver_t *r)
     int       i;
 
     for (i = 0, t = r->targets; i < r->ntarget; i++, t++) {
-        if (t->script != NULL) {
-            if (compile_script(t->script) < 0) {
-                mrp_log_error("Failed to compile script for target '%s'.",
-                              t->name);
-                return -1;
-            }
+        if (mrp_compile_script(t->script) < 0) {
+            mrp_log_error("Failed to compile script for target '%s'.", t->name);
+            return -1;
         }
     }
 
@@ -223,7 +221,7 @@ static int update_target(mrp_resolver_t *r, target_t *t)
         /*                              hmm... is this really needed? */
         if (older_than_facts(r, dep) || older_than_targets(r, dep)) {
             needs_update = TRUE;
-            status       = execute_script(r, dep->script);
+            status       = mrp_execute_script(dep->script, r->ctbl);
 
             if (status <= 0)
                 break;
@@ -233,7 +231,7 @@ static int update_target(mrp_resolver_t *r, target_t *t)
     }
 
     if (needs_update && status > 0) {
-        status = execute_script(r, t->script);
+        status = mrp_execute_script(t->script, r->ctbl);
 
         if (status > 0)
             t->stamp = r->stamp;
index 51ec044..302f650 100644 (file)
@@ -2,10 +2,12 @@ target all
     depends on video_route audio_route \
                audio_volume audio_cork audio_mute \
                $vibra $backlight
+# signal_enforcement_points(&target='all', 'audio', 'video', 1, -2, +3)
+# foobar(&just='a test', +1, -2, 3.141, -1U8, 0xffffffffffU64)
+# hex(-0xf)
     update script
-        signal_enforcement_points(&target='all', 'audio', 'video', 1, -2, +3)
-        foobar(&just='a test', +1, -2, 3.141, -1U8, 0xffffffffffU64)
-        hex(-0xf)
+        echo('Running actions for target "all"...')
+        echo('foo', 'bar', 'foobar...', 1, 2, 3.141, -9.81)
     end script
 
 include "/u/src/work/murphy/src/resolver/test-input-video"
index 92824d4..56a7d56 100644 (file)
@@ -2,23 +2,23 @@ target audio_route
     depends on $audio_device_selectable $audio_output_configuration \
                $resource_owner
     update script
-        update_audio_routing()
+        echo('Running audio_route actions...', 3, 2, 1, 0)
     end script
 
 target audio_volume
     depends on $resource_owner $resource_set
     update script
-        update_audio_volume()
+        echo('Running actions for target "audio_volume"...')
     end script
 
 target audio_cork
     depends on $resource_owner
     update script
-        cork_audio_stream('telephony')
+        echo('Running actions for target "audio_cork"...')
     end script
 
 target audio_mute
     depends on $mute
     update script
-        mute_audio_input_devices()
+        echo('Running actions for target "audio_mute"...')
     end script
index df40fb8..9bc3027 100644 (file)
@@ -1,5 +1,5 @@
 target video_route
     depends on $video_device_selectable $gconf
     update script
-        prolog('set_video_routes')
+        echo('Running actions for target "video_route"...')
     end script
index 561d2ae..5171d73 100644 (file)
@@ -5,6 +5,8 @@
 #include <getopt.h>
 
 #include <murphy/common.h>
+#include <murphy/core/plugin.h>          /* XXX TODO, needed before method.h */
+#include <murphy/core/method.h>
 #include <murphy/resolver/resolver.h>
 
 
@@ -122,6 +124,47 @@ int parse_cmdline(context_t *ctx, int argc, char **argv)
 }
 
 
+static int echo_function(mrp_plugin_t *plugin, const char *name,
+                         mrp_script_env_t *env)
+{
+    mrp_script_value_t *arg;
+    int                 i;
+    char                buf[512], *t;
+
+    MRP_UNUSED(plugin);
+    MRP_UNUSED(name);
+
+    for (i = 0, arg = env->args, t = ""; i < env->narg; i++, arg++, t=" ")
+        printf("%s%s", t, mrp_print_value(buf, sizeof(buf), arg));
+
+    printf("\n");
+
+    return TRUE;
+}
+
+
+void export_test_functions(void)
+{
+    mrp_method_descr_t methods[] = {
+        {
+            .name       = "echo",
+            .signature  = NULL  ,
+            .native_ptr = NULL  ,
+            .script_ptr = echo_function,
+            .plugin     = NULL
+        },
+        { NULL, NULL, NULL, NULL, NULL }
+    }, *m;
+
+    for (m = methods; m->name != NULL; m++) {
+        if (mrp_export_method(m) < 0) {
+            mrp_log_error("Failed to export function '%s'.", m->name);
+            exit(1);
+        }
+    }
+}
+
+
 int main(int argc, char *argv[])
 {
     context_t  c;
@@ -142,6 +185,8 @@ int main(int argc, char *argv[])
     if (c.r == NULL)
         mrp_log_error("Failed to parse input file '%s'.", c.file);
     else {
+        export_test_functions();
+
         mrp_log_info("Input file '%s' parsed successfully.", c.file);
         mrp_resolver_dump_targets(c.r, stdout);
         mrp_resolver_dump_facts(c.r, stdout);
@@ -168,6 +213,33 @@ int main(int argc, char *argv[])
                 printf("Resolved OK.\n");
             else
                 printf("Resolving FAILED.\n");
+
+#if 0
+            {
+                int nvariable = 6;
+                const char *variables[nvariable];
+                mrp_script_value_t values[nvariable];
+
+                variables[0] = "var1";
+                values[0]    = MRP_SCRIPT_VALUE_STRING("foo");
+                variables[1] = "var2";
+                values[1]    = MRP_SCRIPT_VALUE_STRING("bar");
+                variables[2] = "var3";
+                values[2]    = MRP_SCRIPT_VALUE_BOOL(TRUE);
+                variables[3] = "var4";
+                values[3]    = MRP_SCRIPT_VALUE_SINT32(-3);
+                variables[4] = "var5";
+                values[4]    = MRP_SCRIPT_VALUE_UINT32(369);
+                variables[5] = "var6";
+                values[5]    = MRP_SCRIPT_VALUE_SINT32(-3141);
+
+            if (mrp_resolver_update_targetv(c.r, argv[i], variables, values,
+                                            nvariable) > 0)
+                printf("Resolved OK.\n");
+            else
+                printf("Resolving FAILED.\n");
+            }
+#endif
         }
     }