Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ambrop72/badvpn.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmbroz Bizjak <ambrop7@gmail.com>2014-12-05 23:16:11 +0300
committerAmbroz Bizjak <ambrop7@gmail.com>2014-12-06 00:18:01 +0300
commitf662d54df72ca71c307dd9a783886508a463de89 (patch)
treee29bfbcde5a03b6c5153e1b9e8bd6414369f219f
parente5206baa26ea2c6a355d967573feee4eaa9c0c7d (diff)
ncd: Implement backtrack_point::rgo.
-rw-r--r--ncd/modules/backtrack.c58
-rw-r--r--ncd/tests/backtracking.ncd30
2 files changed, 88 insertions, 0 deletions
diff --git a/ncd/modules/backtrack.c b/ncd/modules/backtrack.c
index 7b75744..468315c 100644
--- a/ncd/modules/backtrack.c
+++ b/ncd/modules/backtrack.c
@@ -31,6 +31,7 @@
* Synopsis:
* backtrack_point()
* backtrack_point::go()
+ * backtrack_point::rgo()
*
* Description:
* The backtrack_point() statement creates a backtrack point, going up immedietely.
@@ -38,12 +39,20 @@
* backtrack_point() statement go down and back up at atomically. The go() method
* itself goes up immedietely, but side effects of triggering backtracking have
* priority.
+ * The rgo() method triggers backtracking when it deinitializes. In this case,
+ * the immediate effects of rgo() deinitialization happen before the immediate
+ * effects of triggering backtracking in the backtrack_point().
*/
#include <ncd/module_common.h>
#include <generated/blog_channel_ncd_backtrack.h>
+struct rgo_instance {
+ NCDModuleInst *i;
+ NCDObjRef bp_ref;
+};
+
static void func_new (void *unused, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
{
// check arguments
@@ -82,6 +91,50 @@ fail0:
NCDModuleInst_Backend_DeadError(i);
}
+static void rgo_func_new (void *vo, NCDModuleInst *i, const struct NCDModuleInst_new_params *params)
+{
+ struct rgo_instance *o = vo;
+ o->i = i;
+
+ // check arguments
+ if (!NCDVal_ListRead(params->args, 0)) {
+ ModuleLog(i, BLOG_ERROR, "wrong arity");
+ goto fail0;
+ }
+
+ // get backtrack point
+ NCDModuleInst *backtrack_point_inst = params->method_user;
+
+ // init object reference to the backtrack_point
+ NCDObject obj = NCDModuleInst_Object(backtrack_point_inst);
+ NCDObjRef_Init(&o->bp_ref, NCDObject_Pobj(&obj));
+
+ // go up
+ NCDModuleInst_Backend_Up(i);
+ return;
+
+fail0:
+ NCDModuleInst_Backend_DeadError(i);
+}
+
+static void rgo_func_die (void *vo)
+{
+ struct rgo_instance *o = vo;
+
+ // toggle backtrack point
+ NCDObject rgo_obj;
+ if (NCDObjRef_Deref(&o->bp_ref, &rgo_obj)) {
+ NCDModuleInst *backtrack_point_inst = NCDObject_MethodUser(&rgo_obj);
+ NCDModuleInst_Backend_DownUp(backtrack_point_inst);
+ }
+
+ // free object reference
+ NCDObjRef_Free(&o->bp_ref);
+
+ // die
+ NCDModuleInst_Backend_Dead(o->i);
+}
+
static struct NCDModule modules[] = {
{
.type = "backtrack_point",
@@ -90,6 +143,11 @@ static struct NCDModule modules[] = {
.type = "backtrack_point::go",
.func_new2 = go_func_new
}, {
+ .type = "backtrack_point::rgo",
+ .func_new2 = rgo_func_new,
+ .func_die = rgo_func_die,
+ .alloc_size = sizeof(struct rgo_instance)
+ }, {
.type = NULL
}
};
diff --git a/ncd/tests/backtracking.ncd b/ncd/tests/backtracking.ncd
index 1faf3b7..c239df8 100644
--- a/ncd/tests/backtracking.ncd
+++ b/ncd/tests/backtracking.ncd
@@ -27,5 +27,35 @@ process main {
val_equal(list.length, "100") a;
assert(a);
+ var("true") start;
+ var("false") flag;
+ backtrack_point() point;
+ If (start) {
+ blocker() blk;
+ blk->up();
+ spawn("helper1", {});
+ imperative("<none>", {}, "helper3", {}, "1000");
+ start->set("false");
+ blk->down();
+ if("false");
+ } Else {
+ assert(flag);
+ };
+
exit("0");
}
+
+template helper1 {
+ _caller.blk->use();
+ imperative("<none>", {}, "helper2", {}, "1000");
+ _caller.point->rgo();
+}
+
+template helper2 {
+ _caller._caller.flag->set("true");
+}
+
+template helper3 {
+ val_equal(_caller.flag, "true") a;
+ assert(a);
+}