X-Git-Url: http://git.annexia.org/?p=whenjobs.git;a=blobdiff_plain;f=lib%2Fwhenutils.ml;h=e43dcf61ea2f4dbf1d2fe2708f10b1a2d42fafe8;hp=fd066b4f3f64e052e237d4aebaa232b7a8b473d3;hb=df2cdcfdc29af0080b9b3eace17325d2a1d83e72;hpb=2701d3a832514ee94d110dfbd4f46f2ab6d9637e diff --git a/lib/whenutils.ml b/lib/whenutils.ml index fd066b4..e43dcf6 100644 --- a/lib/whenutils.ml +++ b/lib/whenutils.ml @@ -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