Remove Whenutils.no_job_private and refactor prev-related code.
authorRichard W.M. Jones <rjones@redhat.com>
Tue, 21 Feb 2012 17:13:32 +0000 (17:13 +0000)
committerRichard W.M. Jones <rjones@redhat.com>
Tue, 21 Feb 2012 17:57:32 +0000 (17:57 +0000)
lib/whenfile.ml
lib/whenutils.ml
lib/whenutils.mli

index 8fdca1e..89a09b0 100644 (file)
@@ -27,15 +27,11 @@ let init () = jobs := []
 
 let add_when_job _loc name e sh =
   let e = expr_of_ast _loc e in
-  let job = { job_loc = _loc; job_name = name;
-              job_cond = When_job e; job_script = sh;
-              job_private = no_job_private } in
+  let job = make_when_job _loc name e sh in
   jobs := job :: !jobs
 
 let add_every_job _loc name e sh =
-  let job = { job_loc = _loc; job_name = name;
-              job_cond = Every_job e; job_script = sh;
-              job_private = no_job_private } in
+  let job = make_every_job _loc name e sh in
   jobs := job :: !jobs
 
 let get_jobs () =
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.
+   *
+   * [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.
+   *
+   * [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
@@ -157,6 +158,18 @@ type job = {
   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)
 
@@ -371,7 +384,7 @@ let rec eval_whenexpr job variables onload = function
   | 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 &&
@@ -480,21 +493,27 @@ let rec eval_whenexpr job variables onload = function
       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 =
-  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
 
+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
@@ -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
-    | 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
 
-    | 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
 
index 13bc68c..4d5ccc7 100644 (file)
@@ -183,9 +183,6 @@ type variables = variable StringMap.t
 type job_private
 (** Private state associated with a job, used for evaluation. *)
 
-val no_job_private : job_private
-(* XXX any use of no_job_private is wrong XXX *)
-
 type job_cond =
   | When_job of whenexpr                (** when ... : << >> *)
   | Every_job of periodexpr             (** every ... : << >> *)
@@ -197,7 +194,15 @@ type job = {
   job_script : shell_script;
   job_private : job_private;
 }
-(** A job. *)
+(** A job.  Note that because of the [job_private] field, these cannot
+    be constructed directly.  Use {!make_when_job} or {!make_every_job}
+    to construct one. *)
+
+val make_when_job : Camlp4.PreCast.Loc.t -> string -> whenexpr -> shell_script -> job
+(** Make a when-statement job. *)
+
+val make_every_job : Camlp4.PreCast.Loc.t -> string -> periodexpr -> shell_script -> job
+(** Make an every-statement job. *)
 
 val expr_of_ast : Camlp4.PreCast.Ast.Loc.t -> Camlp4.PreCast.Ast.expr -> whenexpr
 (** Convert OCaml AST to an expression.  Since OCaml ASTs are much