Skip to content
Snippets Groups Projects
Commit ced97002 authored by Erwan Jahier's avatar Erwan Jahier
Browse files

Fixing the previous change: instead of instanciating nodes that are

aliasing polymorphic operators afterwards,  use the rigth type in the
first     place    when     building    the     alias     node    (in
Lazycompiler.make_alias_node).
parent 5d726755
No related branches found
No related tags found
No related merge requests found
(** Time-stamp: <modified the 03/03/2009 (at 17:43) by Erwan Jahier> *) (** Time-stamp: <modified the 04/03/2009 (at 10:29) by Erwan Jahier> *)
open Lxm open Lxm
...@@ -342,13 +342,13 @@ and (const_check_interface_do: t -> Ident.long -> Lxm.t -> SymbolTab.t -> ...@@ -342,13 +342,13 @@ and (const_check_interface_do: t -> Ident.long -> Lxm.t -> SymbolTab.t ->
match prov_const_eff, body_const_eff with match prov_const_eff, body_const_eff with
| Eff.Extern_const_eff (_), _ -> assert false | Eff.Extern_const_eff (_), _ -> assert false
| Eff.Abstract_const_eff (id, teff, v, is_exported), | Eff.Abstract_const_eff (id, teff, v, is_exported),
Eff.Abstract_const_eff (body_id, body_teff, body_v, body_is_exported) Eff.Abstract_const_eff (body_id, body_teff, body_v, body_is_exported)
-> ->
assert false assert false
(* indeed, how can a body constant be extern and have a value? *) (* indeed, how can a body constant be extern and have a value? *)
| Eff.Abstract_const_eff (id, teff, v, is_exported), | Eff.Abstract_const_eff (id, teff, v, is_exported),
Eff.Extern_const_eff (body_id, body_teff) Eff.Extern_const_eff (body_id, body_teff)
-> ->
if (id <> cn) then assert false if (id <> cn) then assert false
else if not (Eff.type_are_compatible teff body_teff) then else if not (Eff.type_are_compatible teff body_teff) then
...@@ -380,8 +380,8 @@ and (const_check_interface_do: t -> Ident.long -> Lxm.t -> SymbolTab.t -> ...@@ -380,8 +380,8 @@ and (const_check_interface_do: t -> Ident.long -> Lxm.t -> SymbolTab.t ->
raise(Compile_error (const_def.src, " constant values mismatch")) raise(Compile_error (const_def.src, " constant values mismatch"))
else else
Eff.Abstract_const_eff (id, teff, body_const_eff, is_exported) Eff.Abstract_const_eff (id, teff, body_const_eff, is_exported)
| Eff.Enum_const_eff (_, _), _ | Eff.Enum_const_eff (_, _), _
| Eff.Bool_const_eff _, _ | Eff.Bool_const_eff _, _
...@@ -389,7 +389,7 @@ and (const_check_interface_do: t -> Ident.long -> Lxm.t -> SymbolTab.t -> ...@@ -389,7 +389,7 @@ and (const_check_interface_do: t -> Ident.long -> Lxm.t -> SymbolTab.t ->
| Eff.Real_const_eff _, _ | Eff.Real_const_eff _, _
| Eff.Struct_const_eff (_,_), _ | Eff.Struct_const_eff (_,_), _
| Eff.Array_const_eff (_,_), _ | Eff.Array_const_eff (_,_), _
-> ->
if prov_const_eff = body_const_eff then if prov_const_eff = body_const_eff then
body_const_eff body_const_eff
else else
...@@ -463,7 +463,7 @@ and (type_check_do: t -> Ident.long -> Lxm.t -> SymbolTab.t -> bool -> ...@@ -463,7 +463,7 @@ and (type_check_do: t -> Ident.long -> Lxm.t -> SymbolTab.t -> bool ->
| Struct_type_eff(_) -> true | Struct_type_eff(_) -> true
| Any | Overload | Bool_type_eff | Int_type_eff | Real_type_eff | Any | Overload | Bool_type_eff | Int_type_eff | Real_type_eff
| External_type_eff(_) | Abstract_type_eff(_) | Enum_type_eff(_) | External_type_eff(_) | Abstract_type_eff(_) | Enum_type_eff(_)
-> false -> false
in in
if if
(not provide_flag) (not provide_flag)
...@@ -502,29 +502,29 @@ and (const_check_do : t -> Ident.long -> Lxm.t -> SymbolTab.t -> bool -> ...@@ -502,29 +502,29 @@ and (const_check_do : t -> Ident.long -> Lxm.t -> SymbolTab.t -> bool ->
| ExternalConst (id, texp, val_opt) -> | ExternalConst (id, texp, val_opt) ->
let lid = Ident.make_long currpack id in let lid = Ident.make_long currpack id in
let teff = GetEff.typ id_solver texp in let teff = GetEff.typ id_solver texp in
if provide_flag then if provide_flag then
match val_opt with match val_opt with
| None -> | None ->
(* we put a fake value here as we don't know yet the (* we put a fake value here as we don't know yet the
concrete value. this will be filled in concrete value. this will be filled in
const_check_interface_do. I could have put an option const_check_interface_do. I could have put an option
type, but that would make quite a lot of noise in the type, but that would make quite a lot of noise in the
remaining... remaining...
*) *)
Abstract_const_eff(lid, teff, Int_const_eff (-666), false) Abstract_const_eff(lid, teff, Int_const_eff (-666), false)
| Some c -> | Some c ->
let ceff = match EvalConst.f id_solver c with let ceff = match EvalConst.f id_solver c with
| [ceff] -> ceff | [ceff] -> ceff
| _ -> assert false | _ -> assert false
in in
Abstract_const_eff(lid, teff, ceff, true) Abstract_const_eff(lid, teff, ceff, true)
else else
(match val_opt with (match val_opt with
| None -> Extern_const_eff(lid, teff) | None -> Extern_const_eff(lid, teff)
| Some c -> assert false | Some c -> assert false
(* indeed, how can a body constant be extern and have a value? *) (* indeed, how can a body constant be extern and have a value? *)
) )
| EnumConst (id, texp) -> | EnumConst (id, texp) ->
Enum_const_eff ((Ident.make_long currpack id), GetEff.typ id_solver texp) Enum_const_eff ((Ident.make_long currpack id), GetEff.typ id_solver texp)
...@@ -539,14 +539,14 @@ and (const_check_do : t -> Ident.long -> Lxm.t -> SymbolTab.t -> bool -> ...@@ -539,14 +539,14 @@ and (const_check_do : t -> Ident.long -> Lxm.t -> SymbolTab.t -> bool ->
if (tdecl = teff ) then ceff else if (tdecl = teff ) then ceff else
raise raise
(Compile_error (const_def.src, Printf.sprintf (Compile_error (const_def.src, Printf.sprintf
" this constant is declared as '%s' but evaluated as '%s'" " this constant is declared as '%s' but evaluated as '%s'"
(LicDump.string_of_type_eff4msg tdecl) (LicDump.string_of_type_eff4msg tdecl)
(LicDump.string_of_type_eff4msg teff) (LicDump.string_of_type_eff4msg teff)
))) )))
) )
| [] -> assert false (* should not occur *) | [] -> assert false (* should not occur *)
| _::_ -> raise (Compile_error(const_def.src, | _::_ -> raise (Compile_error(const_def.src,
"bad constant value: tuple not allowed")) "bad constant value: tuple not allowed"))
) )
in in
let is_struct_or_array = match const_eff with let is_struct_or_array = match const_eff with
...@@ -559,8 +559,8 @@ and (const_check_do : t -> Ident.long -> Lxm.t -> SymbolTab.t -> bool -> ...@@ -559,8 +559,8 @@ and (const_check_do : t -> Ident.long -> Lxm.t -> SymbolTab.t -> bool ->
in in
if if
(not provide_flag (not provide_flag
&& (not (!Global.expand_structs & is_struct_or_array)) && (not (!Global.expand_structs & is_struct_or_array))
&& not !Global.ec (* ec does not need constant decl *) && not !Global.ec (* ec does not need constant decl *)
) || is_extern_const ) || is_extern_const
then then
output_string !Global.oc (LicDump.const_decl cn const_eff); output_string !Global.oc (LicDump.const_decl cn const_eff);
...@@ -625,7 +625,7 @@ and (node_check_interface_do: t -> Eff.node_key -> Lxm.t -> ...@@ -625,7 +625,7 @@ and (node_check_interface_do: t -> Eff.node_key -> Lxm.t ->
else if else if
(List.exists2 type_is_not_comp (List.exists2 type_is_not_comp
prov_node_exp_eff.outlist_eff body_node_exp_eff.outlist_eff) prov_node_exp_eff.outlist_eff body_node_exp_eff.outlist_eff)
(* ougth to be checked above: well, it eats no bread to keep that check *) (* ougth to be checked above: well, it eats no bread to keep that check *)
then then
let msg = msg_prefix ^ "bad output profile. \n*** " ^ let msg = msg_prefix ^ "bad output profile. \n*** " ^
(String.concat "*" (List.map str_of_var prov_node_exp_eff.outlist_eff)) ^ (String.concat "*" (List.map str_of_var prov_node_exp_eff.outlist_eff)) ^
...@@ -668,14 +668,14 @@ and (node_check_do: t -> Eff.node_key -> Lxm.t -> SymbolTab.t -> ...@@ -668,14 +668,14 @@ and (node_check_do: t -> Eff.node_key -> Lxm.t -> SymbolTab.t ->
lxm, lxm,
"\n*** '"^(Ident.string_of_idref id)^ "\n*** '"^(Ident.string_of_idref id)^
"': Unknown variable.\n*** Current variables are: " ^ "': Unknown variable.\n*** Current variables are: " ^
(Hashtbl.fold (Hashtbl.fold
(fun id vi_eff acc -> (fun id vi_eff acc ->
acc ^ (Format.sprintf acc ^ (Format.sprintf
"\n\t%s" (LicDump.string_of_var_info_eff4msg vi_eff)) "\n\t%s" (LicDump.string_of_var_info_eff4msg vi_eff))
) )
local_env.lenv_vars local_env.lenv_vars
"" ""
)))); ))));
id2const = id2const =
(fun id lxm -> (fun id lxm ->
try lookup_const local_env id lxm try lookup_const local_env id lxm
...@@ -689,10 +689,10 @@ and (node_check_do: t -> Eff.node_key -> Lxm.t -> SymbolTab.t -> ...@@ -689,10 +689,10 @@ and (node_check_do: t -> Eff.node_key -> Lxm.t -> SymbolTab.t ->
id2node = id2node =
(fun id sargs lxm -> (fun id sargs lxm ->
(try (try
let node_id, inlist, outlist = lookup_node local_env id sargs lxm in let node_id, inlist, outlist = lookup_node local_env id sargs lxm in
let node_id = Ident.idref_of_long node_id in let node_id = Ident.idref_of_long node_id in
solve_node_idref this symbols provide_flag pack_name node_id [] lxm solve_node_idref this symbols provide_flag pack_name node_id [] lxm
(* node_check this (node_id,[]) lxm *) (* node_check this (node_id,[]) lxm *)
with with
Not_found -> Not_found ->
...@@ -735,7 +735,7 @@ and (node_check_do: t -> Eff.node_key -> Lxm.t -> SymbolTab.t -> ...@@ -735,7 +735,7 @@ and (node_check_do: t -> Eff.node_key -> Lxm.t -> SymbolTab.t ->
let (sort_vars : Ident.t list -> Ident.t list) = let (sort_vars : Ident.t list -> Ident.t list) =
fun l -> fun l ->
(* I cannot use List.sort as I only have a partial order on vars (* I cannot use List.sort as I only have a partial order on vars
-> hence I perform a topological sort *) -> hence I perform a topological sort *)
let rec depends_on v1 v2 = let rec depends_on v1 v2 =
match (find_var_info lxm vars v1).it.var_clock with match (find_var_info lxm vars v1).it.var_clock with
| Base -> false | Base -> false
...@@ -763,7 +763,7 @@ and (node_check_do: t -> Eff.node_key -> Lxm.t -> SymbolTab.t -> ...@@ -763,7 +763,7 @@ and (node_check_do: t -> Eff.node_key -> Lxm.t -> SymbolTab.t ->
(Ident.to_string v) ^ " depends on " ^ (Ident.to_string v) ^ " depends on " ^
(Ident.to_string v2) ^ ", which depends on " ^ (Ident.to_string v2) ^ ", which depends on " ^
(Ident.to_string v)) (Ident.to_string v))
) )
else else
let l1,l2 = List.partition (fun v -> v=v2) l in let l1,l2 = List.partition (fun v -> v=v2) l in
if l1 = [] then if l1 = [] then
...@@ -804,44 +804,84 @@ and (node_check_do: t -> Eff.node_key -> Lxm.t -> SymbolTab.t -> ...@@ -804,44 +804,84 @@ and (node_check_do: t -> Eff.node_key -> Lxm.t -> SymbolTab.t ->
is_polym_eff = !is_polymorphic is_polym_eff = !is_polymorphic
} }
in in
let (make_alias_node : Eff.node_exp -> Eff.node_exp) = let (make_alias_node : Eff.node_exp -> node_vars option -> Eff.node_exp) =
fun aliased_node -> fun aliased_node vars_opt ->
(* builds a node that calls the aliased node. It looks like: (* builds a node that calls the aliased node. It looks like:
node alias_node( ins ) returns ( outs ); node alias_node(ins) returns (outs);
let let
outs = aliased_node(ins); outs = aliased_node(ins);
tel tel
When instanciating models with polymorphic operators, it
may happen that some exported user nodes become
polymorphic (via node alias precisely). But in that case,
a non-polymorphic profile is given in the package provided
part. In such a case, we can use the types of the provided
part (itl and otl) instead of the polymorphic ones.
*) *)
let (outs:Eff.left list) = let (il,ol) = Eff.profile_of_node_exp aliased_node in
List.map (fun vi -> LeftVarEff (vi, lxm)) aliased_node.outlist_eff let (il_decl, ol_decl) =
match vars_opt with
| None -> (il,ol) (* no type profile is declared; we use the alias one *)
| Some vars ->
(* a type profile is declared; let's check there are compatible *)
let vi_il, vi_ol =
List.map (fun id -> find_var_info lxm vars id) vars.inlist,
List.map (fun id -> find_var_info lxm vars id) vars.outlist
in
let aux vi = GetEff.typ node_id_solver vi.it.var_type in
let (il_decl, ol_decl) = List.map aux vi_il, List.map aux vi_ol in
let i_unif_res = UnifyType.f il_decl il
and o_unif_res = UnifyType.f ol_decl ol
in
(match i_unif_res with
| UnifyType.Ko msg -> raise(Compile_error(lxm, msg))
| UnifyType.Equal -> ()
| UnifyType.Unif t -> GetEff.dump_polymorphic_nodes t
);
(match o_unif_res with
| UnifyType.Ko msg -> raise(Compile_error (lxm, msg))
| UnifyType.Equal -> ()
| UnifyType.Unif t -> GetEff.dump_polymorphic_nodes t
);
(* ok, there are compatible. We use the declared profile. *)
(il_decl, ol_decl)
in
let instanciate_var_info vi t = { vi with var_type_eff = t } in
let vil = List.map2 instanciate_var_info aliased_node.inlist_eff il_decl
and vol = List.map2 instanciate_var_info aliased_node.outlist_eff ol_decl in
let (outs:Eff.left list) = List.map (fun vi -> LeftVarEff (vi, lxm)) vol
and (aliased_node_call : Eff.val_exp) = and (aliased_node_call : Eff.val_exp) =
CallByPosEff( CallByPosEff(
(Lxm.flagit (Eff.CALL(Lxm.flagit aliased_node lxm)) lxm, (Lxm.flagit (Eff.CALL(Lxm.flagit aliased_node lxm)) lxm,
OperEff OperEff
(List.map (List.map
(fun vi -> (* build operands*) (fun vi -> (* build operands*)
let ve = CallByPosEff( let ve = CallByPosEff(
Lxm.flagit (Eff.IDENT Lxm.flagit (Eff.IDENT
(Ident.to_idref vi.var_name_eff)) lxm, OperEff []) (Ident.to_idref vi.var_name_eff)) lxm, OperEff [])
in in
EvalType.add ve [vi.var_type_eff]; EvalType.add ve [vi.var_type_eff];
EvalClock.add ve [vi.var_clock_eff]; EvalClock.add ve [vi.var_clock_eff];
ve ve
) )
aliased_node.inlist_eff))) vil)))
in in
let tl = List.map Eff.type_of_left outs in let tl = List.map Eff.type_of_left outs in
let cl = List.map (fun l -> (Eff.var_info_of_left l).var_clock_eff) outs in let cl = List.map (fun l -> (Eff.var_info_of_left l).var_clock_eff) outs in
EvalType.add aliased_node_call tl; EvalType.add aliased_node_call tl;
EvalClock.add aliased_node_call cl; EvalClock.add aliased_node_call cl;
{ {
aliased_node with aliased_node with
node_key_eff = nk; node_key_eff = nk;
inlist_eff = vil;
outlist_eff = vol;
loclist_eff = None; loclist_eff = None;
def_eff = BodyEff( def_eff = BodyEff(
{ asserts_eff = []; { asserts_eff = [];
eqs_eff = [Lxm.flagit (outs, aliased_node_call) lxm] eqs_eff = [Lxm.flagit (outs, aliased_node_call) lxm]
}); });
is_polym_eff = List.exists Eff.is_polymorphic (il_decl@ol_decl);
} }
in in
(* let's go *) (* let's go *)
...@@ -888,110 +928,48 @@ and (node_check_do: t -> Eff.node_key -> Lxm.t -> SymbolTab.t -> ...@@ -888,110 +928,48 @@ and (node_check_do: t -> Eff.node_key -> Lxm.t -> SymbolTab.t ->
-> ->
raise (Compile_error (lxm, "can not alias this operator, sorry")) raise (Compile_error (lxm, "can not alias this operator, sorry"))
(* does it make sense to alias when, pre, etc? *) (* does it make sense to alias when, pre, etc? *)
in
let (alias_node : Eff.node_exp) = make_alias_node aliased_node in
(* update the local_env table *)
let _ =
let update_local_env_table vi =
Hashtbl.add local_env.lenv_vars vi.var_name_eff vi
in in
List.iter update_local_env_table alias_node.inlist_eff; let (alias_node : Eff.node_exp) =
List.iter update_local_env_table alias_node.outlist_eff; try make_alias_node aliased_node node_def.it.vars
match alias_node.loclist_eff with with Not_found -> assert false (* defense against List.assoc *)
None -> () | Some l -> List.iter update_local_env_table l;
in
let instanciate_node n itl otl =
(** replace the types i/o of n by [itl] (input type list)
and [otl] (output type list).
Indeed, when instanciating models with polymorphic
operators, it may happen that some exported user
nodes become polymorphic (via node alias
precisely). But in that case, a non-polymorphic
profile is given in the package provided part. In
such a case, we can use the types of the provided
part (itl and otl) instead of the polymorphic ones.
The tricky part is that it is not enough to modify the
inlist_eff and the outlist_eff fields: i/o vars (var_info) migth
appear in left part.
It also changes the is_polym_eff field.
I hope this is all...
*)
let instanciate_var_info vi t = (vi, { vi with var_type_eff = t }) in
let instanciate_type t1 t2 = match t1 with Any | Overload -> t2 | _ -> t1
in in
let si = List.map2 instanciate_var_info n.inlist_eff itl
and so = List.map2 instanciate_var_info n.outlist_eff otl in (* update the local_env table *)
let s = List.rev_append si so in let _ =
let instanciate_left left = let update_local_env_table vi =
let rec aux = function Hashtbl.add local_env.lenv_vars vi.var_name_eff vi
| LeftVarEff (vi,lxm) ->
let nvi = List.assoc vi s in
LeftVarEff(nvi,lxm), nvi.var_type_eff
| LeftFieldEff(l,id,t) ->
let nl,nt = aux l in
LeftFieldEff(nl, id, instanciate_type t nt), nt
| LeftArrayEff(l,i,t) ->
let nl,nt = aux l in
LeftArrayEff(nl, i, instanciate_type t nt), nt
| LeftSliceEff(l,si,t) ->
let nl,nt = aux l in
LeftSliceEff(nl, si, instanciate_type t nt), nt
in in
fst (aux left) List.iter update_local_env_table alias_node.inlist_eff;
List.iter update_local_env_table alias_node.outlist_eff;
match alias_node.loclist_eff with
None -> () | Some l -> List.iter update_local_env_table l;
in in
let instanciate_eq { it = (ll,ve); src = lxm } = (* Check that the declared profile (if any) matches with the alias *)
{ it = (List.map instanciate_left ll,ve); src = lxm } match node_def.it.vars with
in | None -> alias_node
{ n with | Some vars ->
inlist_eff = List.map2 let vi_il, vi_ol =
(fun vi texp -> { vi with var_type_eff = texp }) n.inlist_eff itl; List.map (fun id -> find_var_info lxm vars id) vars.inlist,
List.map (fun id -> find_var_info lxm vars id) vars.outlist
outlist_eff = List.map2 in
(fun vi texp -> { vi with var_type_eff = texp }) n.outlist_eff otl; let aux vi = GetEff.typ node_id_solver vi.it.var_type
in
def_eff = (match n.def_eff with let (il,ol) = Eff.profile_of_node_exp alias_node in
| ExternEff | AbstractEff -> n.def_eff let (il_exp, ol_exp) = List.map aux vi_il, List.map aux vi_ol in
| BodyEff nb -> BodyEff let i_unif_res = UnifyType.f il_exp il
{ nb with eqs_eff = List.map instanciate_eq nb.eqs_eff }); and o_unif_res = UnifyType.f ol_exp ol
in
is_polym_eff = List.exists Eff.is_polymorphic (itl @ otl); (match i_unif_res with
} | UnifyType.Ko msg -> raise(Compile_error(lxm, msg))
in | UnifyType.Equal -> ()
(* end of [instanciate_node] *) | UnifyType.Unif t -> GetEff.dump_polymorphic_nodes t
(* Check that the declared profile (if any) matches with the alias *) );
match node_def.it.vars with (match o_unif_res with
| None -> alias_node | UnifyType.Ko msg -> raise(Compile_error (lxm, msg))
| Some vars -> | UnifyType.Equal -> ()
let vi_il, vi_ol = | UnifyType.Unif t -> GetEff.dump_polymorphic_nodes t
List.map (fun id -> find_var_info lxm vars id) vars.inlist, );
List.map (fun id -> find_var_info lxm vars id) vars.outlist alias_node
in
let aux vi = GetEff.typ node_id_solver vi.it.var_type
in
let (il,ol) = Eff.profile_of_node_exp alias_node in
let (il_exp, ol_exp) = List.map aux vi_il, List.map aux vi_ol in
let i_unif_res = UnifyType.f il_exp il
and o_unif_res = UnifyType.f ol_exp ol
in
(match i_unif_res with
| UnifyType.Ko msg -> raise(Compile_error(lxm, msg))
| UnifyType.Equal -> ()
| UnifyType.Unif t -> GetEff.dump_polymorphic_nodes t
);
(match o_unif_res with
| UnifyType.Ko msg -> raise(Compile_error (lxm, msg))
| UnifyType.Equal -> ()
| UnifyType.Unif t -> GetEff.dump_polymorphic_nodes t
);
try
instanciate_node alias_node il_exp ol_exp
with
Not_found -> assert false (* defense against List.assoc *)
) )
(* End Alias *) (* End Alias *)
in in
...@@ -1042,7 +1020,7 @@ and (node_check_do: t -> Eff.node_key -> Lxm.t -> SymbolTab.t -> ...@@ -1042,7 +1020,7 @@ and (node_check_do: t -> Eff.node_key -> Lxm.t -> SymbolTab.t ->
(* nb: we print res_struct, but we return res, because the structure and (* nb: we print res_struct, but we return res, because the structure and
array expansion modify the node profiles. array expansion modify the node profiles.
*) *)
res res
......
...@@ -99,7 +99,7 @@ test_ec: ...@@ -99,7 +99,7 @@ test_ec:
(ec2c /tmp/xx.ec >> test_ec.res 2>&1 && echo -n "ok ") || echo " KO!";\ (ec2c /tmp/xx.ec >> test_ec.res 2>&1 && echo -n "ok ") || echo " KO!";\
done; \ done; \
diff -u test_ec.res.exp test_ec.res > test_ec.diff || \ diff -u test_ec.res.exp test_ec.res > test_ec.diff || \
(cat test.diff ; echo "cf test.diff"; exit 1) (cat test_ec.diff ; echo "cf test_ec.diff"; exit 1)
utest_ec: utest_ec:
...@@ -115,7 +115,7 @@ test_lv4: ...@@ -115,7 +115,7 @@ test_lv4:
(lus2ec /tmp/xx.lus `lusinfo /tmp/xx.lus nodes | head -n 1` >> test_lv4.res 2>&1 && echo -n "ok ") || echo " KO!";\ (lus2ec /tmp/xx.lus `lusinfo /tmp/xx.lus nodes | head -n 1` >> test_lv4.res 2>&1 && echo -n "ok ") || echo " KO!";\
done; \ done; \
diff -u test_lv4.res.exp test_lv4.res > test_lv4.diff || \ diff -u test_lv4.res.exp test_lv4.res > test_lv4.diff || \
(cat test.diff ; echo "cf test.diff"; exit 1) (cat test_lv4.diff ; echo "cf test_lv4.diff"; exit 1)
utest_lv4: utest_lv4:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment