(* 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
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)
| 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 &&
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
* 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
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 ... : << >> *)
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