Remove Whenutils.no_job_private and refactor prev-related code.
[whenjobs.git] / lib / whenutils.ml
index fd066b4..e43dcf6 100644 (file)
@@ -133,18 +133,19 @@ type job_private = {
   (* The result of the previous evaluation.  This is used for
    * implementing edge-triggering, since we only trigger the job to run
    * when the state changes from false -> true.
   (* The result of the previous evaluation.  This is used for
    * implementing edge-triggering, since we only trigger the job to run
    * when the state changes from false -> true.
+   *
+   * [None] means there has been no previous evaluation.
    *)
    *)
-  job_prev_eval_state : bool;
+  job_prev_eval_state : bool option;
 
   (* When the job {i ran} last time, we take a copy of the variables.
    * This allows us to implement the 'changes' operator.
 
   (* When the job {i ran} last time, we take a copy of the variables.
    * This allows us to implement the 'changes' operator.
+   *
+   * [None] means there has been no previous run.
    *)
    *)
-  job_prev_variables : variables;
+  job_prev_variables : variables option;
 }
 
 }
 
-let no_job_private =
-  { job_prev_eval_state = false; job_prev_variables = StringMap.empty }
-
 type job_cond =
   | When_job of whenexpr
   | Every_job of periodexpr
 type job_cond =
   | When_job of whenexpr
   | Every_job of periodexpr
@@ -157,6 +158,18 @@ type job = {
   job_private : job_private;
 }
 
   job_private : job_private;
 }
 
+let make_when_job _loc name e sh =
+  { job_loc = _loc; job_name = name;
+    job_cond = When_job e; job_script = sh;
+    job_private = { job_prev_eval_state = None;
+                    job_prev_variables = None } }
+
+let make_every_job _loc name e sh =
+  { job_loc = _loc; job_name = name;
+    job_cond = Every_job e; job_script = sh;
+    job_private = { job_prev_eval_state = None;
+                    job_prev_variables = None } }
+
 let rec expr_of_ast _loc ast =
   expr_of_iexpr _loc (iexpr_of_ast _loc ast)
 
 let rec expr_of_ast _loc ast =
   expr_of_iexpr _loc (iexpr_of_ast _loc ast)
 
@@ -371,7 +384,7 @@ let rec eval_whenexpr job variables onload = function
   | Expr_float f -> T_float f
 
   | Expr_var v ->
   | Expr_float f -> T_float f
 
   | Expr_var v ->
-    (try StringMap.find v variables with Not_found -> T_string "")
+    get_variable variables v
 
   | Expr_and (e1, e2) ->
     if eval_whenexpr_as_bool job variables onload e1 &&
 
   | Expr_and (e1, e2) ->
     if eval_whenexpr_as_bool job variables onload e1 &&
@@ -480,21 +493,27 @@ let rec eval_whenexpr job variables onload = function
       T_bool false
 
   | Expr_prev v ->
       T_bool false
 
   | Expr_prev v ->
-    (try StringMap.find v job.job_private.job_prev_variables
-     with Not_found -> T_string "")
+    get_prev_variable job v
 
   | Expr_reloaded ->
     T_bool onload
 
 and get_prev_curr_value job variables v =
 
   | Expr_reloaded ->
     T_bool onload
 
 and get_prev_curr_value job variables v =
-  let prev_value =
-    try StringMap.find v job.job_private.job_prev_variables
-    with Not_found -> T_string "" in
-  let curr_value =
-    try StringMap.find v variables
-    with Not_found -> T_string "" in
+  let prev_value = get_prev_variable job v in
+  let curr_value = get_variable variables v in
   prev_value, curr_value
 
   prev_value, curr_value
 
+and get_variable variables v =
+  try StringMap.find v variables with Not_found -> T_string ""
+
+and get_prev_variable job v =
+  match job.job_private.job_prev_variables with
+  | None ->
+    (* Job has never run.  XXX Should do better here. *)
+    T_string ""
+  | Some prev_variables ->
+    get_variable prev_variables v
+
 (* Call {!eval_whenexpr} and cast the result to a boolean. *)
 and eval_whenexpr_as_bool job variables onload expr =
   match eval_whenexpr job variables onload expr with
 (* Call {!eval_whenexpr} and cast the result to a boolean. *)
 and eval_whenexpr_as_bool job variables onload expr =
   match eval_whenexpr job variables onload expr with
@@ -605,16 +624,18 @@ let job_evaluate job variables onload =
      * case where the evaluation state changes from false -> true.
      *)
     match job.job_private.job_prev_eval_state, state with
      * case where the evaluation state changes from false -> true.
      *)
     match job.job_private.job_prev_eval_state, state with
-    | false, false
-    | true, true
-    | true, false ->
-      let jobp = { job.job_private with job_prev_eval_state = state } in
+    | None, false
+    | Some false, false
+    | Some true, true
+    | Some true, false ->
+      let jobp = { job.job_private with job_prev_eval_state = Some state } in
       let job = { job with job_private = jobp } in
       false, job
 
       let job = { job with job_private = jobp } in
       false, job
 
-    | false, true ->
-      let jobp = { job_prev_eval_state = true;
-                   job_prev_variables = variables } in
+    | None, true
+    | Some false, true ->
+      let jobp = { job_prev_eval_state = Some true;
+                   job_prev_variables = Some variables } in
       let job = { job with job_private = jobp } in
       true, job
 
       let job = { job with job_private = jobp } in
       true, job